CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/main/_static/underscore-1.3.1.js
Views: 494
// Underscore.js 1.3.11// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.2// Underscore is freely distributable under the MIT license.3// Portions of Underscore are inspired or borrowed from Prototype,4// Oliver Steele's Functional, and John Resig's Micro-Templating.5// For all details and documentation:6// https://documentcloud.github.com/underscore78(function() {910// Baseline setup11// --------------1213// Establish the root object, `window` in the browser, or `global` on the server.14var root = this;1516// Save the previous value of the `_` variable.17var previousUnderscore = root._;1819// Establish the object that gets returned to break out of a loop iteration.20var breaker = {};2122// Save bytes in the minified (but not gzipped) version:23var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;2425// Create quick reference variables for speed access to core prototypes.26var slice = ArrayProto.slice,27unshift = ArrayProto.unshift,28toString = ObjProto.toString,29hasOwnProperty = ObjProto.hasOwnProperty;3031// All **ECMAScript 5** native function implementations that we hope to use32// are declared here.33var34nativeForEach = ArrayProto.forEach,35nativeMap = ArrayProto.map,36nativeReduce = ArrayProto.reduce,37nativeReduceRight = ArrayProto.reduceRight,38nativeFilter = ArrayProto.filter,39nativeEvery = ArrayProto.every,40nativeSome = ArrayProto.some,41nativeIndexOf = ArrayProto.indexOf,42nativeLastIndexOf = ArrayProto.lastIndexOf,43nativeIsArray = Array.isArray,44nativeKeys = Object.keys,45nativeBind = FuncProto.bind;4647// Create a safe reference to the Underscore object for use below.48var _ = function(obj) { return new wrapper(obj); };4950// Export the Underscore object for **Node.js**, with51// backwards-compatibility for the old `require()` API. If we're in52// the browser, add `_` as a global object via a string identifier,53// for Closure Compiler "advanced" mode.54if (typeof exports !== 'undefined') {55if (typeof module !== 'undefined' && module.exports) {56exports = module.exports = _;57}58exports._ = _;59} else {60root['_'] = _;61}6263// Current version.64_.VERSION = '1.3.1';6566// Collection Functions67// --------------------6869// The cornerstone, an `each` implementation, aka `forEach`.70// Handles objects with the built-in `forEach`, arrays, and raw objects.71// Delegates to **ECMAScript 5**'s native `forEach` if available.72var each = _.each = _.forEach = function(obj, iterator, context) {73if (obj == null) return;74if (nativeForEach && obj.forEach === nativeForEach) {75obj.forEach(iterator, context);76} else if (obj.length === +obj.length) {77for (var i = 0, l = obj.length; i < l; i++) {78if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;79}80} else {81for (var key in obj) {82if (_.has(obj, key)) {83if (iterator.call(context, obj[key], key, obj) === breaker) return;84}85}86}87};8889// Return the results of applying the iterator to each element.90// Delegates to **ECMAScript 5**'s native `map` if available.91_.map = _.collect = function(obj, iterator, context) {92var results = [];93if (obj == null) return results;94if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);95each(obj, function(value, index, list) {96results[results.length] = iterator.call(context, value, index, list);97});98if (obj.length === +obj.length) results.length = obj.length;99return results;100};101102// **Reduce** builds up a single result from a list of values, aka `inject`,103// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.104_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {105var initial = arguments.length > 2;106if (obj == null) obj = [];107if (nativeReduce && obj.reduce === nativeReduce) {108if (context) iterator = _.bind(iterator, context);109return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);110}111each(obj, function(value, index, list) {112if (!initial) {113memo = value;114initial = true;115} else {116memo = iterator.call(context, memo, value, index, list);117}118});119if (!initial) throw new TypeError('Reduce of empty array with no initial value');120return memo;121};122123// The right-associative version of reduce, also known as `foldr`.124// Delegates to **ECMAScript 5**'s native `reduceRight` if available.125_.reduceRight = _.foldr = function(obj, iterator, memo, context) {126var initial = arguments.length > 2;127if (obj == null) obj = [];128if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {129if (context) iterator = _.bind(iterator, context);130return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);131}132var reversed = _.toArray(obj).reverse();133if (context && !initial) iterator = _.bind(iterator, context);134return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);135};136137// Return the first value which passes a truth test. Aliased as `detect`.138_.find = _.detect = function(obj, iterator, context) {139var result;140any(obj, function(value, index, list) {141if (iterator.call(context, value, index, list)) {142result = value;143return true;144}145});146return result;147};148149// Return all the elements that pass a truth test.150// Delegates to **ECMAScript 5**'s native `filter` if available.151// Aliased as `select`.152_.filter = _.select = function(obj, iterator, context) {153var results = [];154if (obj == null) return results;155if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);156each(obj, function(value, index, list) {157if (iterator.call(context, value, index, list)) results[results.length] = value;158});159return results;160};161162// Return all the elements for which a truth test fails.163_.reject = function(obj, iterator, context) {164var results = [];165if (obj == null) return results;166each(obj, function(value, index, list) {167if (!iterator.call(context, value, index, list)) results[results.length] = value;168});169return results;170};171172// Determine whether all of the elements match a truth test.173// Delegates to **ECMAScript 5**'s native `every` if available.174// Aliased as `all`.175_.every = _.all = function(obj, iterator, context) {176var result = true;177if (obj == null) return result;178if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);179each(obj, function(value, index, list) {180if (!(result = result && iterator.call(context, value, index, list))) return breaker;181});182return result;183};184185// Determine if at least one element in the object matches a truth test.186// Delegates to **ECMAScript 5**'s native `some` if available.187// Aliased as `any`.188var any = _.some = _.any = function(obj, iterator, context) {189iterator || (iterator = _.identity);190var result = false;191if (obj == null) return result;192if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);193each(obj, function(value, index, list) {194if (result || (result = iterator.call(context, value, index, list))) return breaker;195});196return !!result;197};198199// Determine if a given value is included in the array or object using `===`.200// Aliased as `contains`.201_.include = _.contains = function(obj, target) {202var found = false;203if (obj == null) return found;204if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;205found = any(obj, function(value) {206return value === target;207});208return found;209};210211// Invoke a method (with arguments) on every item in a collection.212_.invoke = function(obj, method) {213var args = slice.call(arguments, 2);214return _.map(obj, function(value) {215return (_.isFunction(method) ? method || value : value[method]).apply(value, args);216});217};218219// Convenience version of a common use case of `map`: fetching a property.220_.pluck = function(obj, key) {221return _.map(obj, function(value){ return value[key]; });222};223224// Return the maximum element or (element-based computation).225_.max = function(obj, iterator, context) {226if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);227if (!iterator && _.isEmpty(obj)) return -Infinity;228var result = {computed : -Infinity};229each(obj, function(value, index, list) {230var computed = iterator ? iterator.call(context, value, index, list) : value;231computed >= result.computed && (result = {value : value, computed : computed});232});233return result.value;234};235236// Return the minimum element (or element-based computation).237_.min = function(obj, iterator, context) {238if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);239if (!iterator && _.isEmpty(obj)) return Infinity;240var result = {computed : Infinity};241each(obj, function(value, index, list) {242var computed = iterator ? iterator.call(context, value, index, list) : value;243computed < result.computed && (result = {value : value, computed : computed});244});245return result.value;246};247248// Shuffle an array.249_.shuffle = function(obj) {250var shuffled = [], rand;251each(obj, function(value, index, list) {252if (index == 0) {253shuffled[0] = value;254} else {255rand = Math.floor(Math.random() * (index + 1));256shuffled[index] = shuffled[rand];257shuffled[rand] = value;258}259});260return shuffled;261};262263// Sort the object's values by a criterion produced by an iterator.264_.sortBy = function(obj, iterator, context) {265return _.pluck(_.map(obj, function(value, index, list) {266return {267value : value,268criteria : iterator.call(context, value, index, list)269};270}).sort(function(left, right) {271var a = left.criteria, b = right.criteria;272return a < b ? -1 : a > b ? 1 : 0;273}), 'value');274};275276// Groups the object's values by a criterion. Pass either a string attribute277// to group by, or a function that returns the criterion.278_.groupBy = function(obj, val) {279var result = {};280var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };281each(obj, function(value, index) {282var key = iterator(value, index);283(result[key] || (result[key] = [])).push(value);284});285return result;286};287288// Use a comparator function to figure out at what index an object should289// be inserted so as to maintain order. Uses binary search.290_.sortedIndex = function(array, obj, iterator) {291iterator || (iterator = _.identity);292var low = 0, high = array.length;293while (low < high) {294var mid = (low + high) >> 1;295iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;296}297return low;298};299300// Safely convert anything iterable into a real, live array.301_.toArray = function(iterable) {302if (!iterable) return [];303if (iterable.toArray) return iterable.toArray();304if (_.isArray(iterable)) return slice.call(iterable);305if (_.isArguments(iterable)) return slice.call(iterable);306return _.values(iterable);307};308309// Return the number of elements in an object.310_.size = function(obj) {311return _.toArray(obj).length;312};313314// Array Functions315// ---------------316317// Get the first element of an array. Passing **n** will return the first N318// values in the array. Aliased as `head`. The **guard** check allows it to work319// with `_.map`.320_.first = _.head = function(array, n, guard) {321return (n != null) && !guard ? slice.call(array, 0, n) : array[0];322};323324// Returns everything but the last entry of the array. Especcialy useful on325// the arguments object. Passing **n** will return all the values in326// the array, excluding the last N. The **guard** check allows it to work with327// `_.map`.328_.initial = function(array, n, guard) {329return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));330};331332// Get the last element of an array. Passing **n** will return the last N333// values in the array. The **guard** check allows it to work with `_.map`.334_.last = function(array, n, guard) {335if ((n != null) && !guard) {336return slice.call(array, Math.max(array.length - n, 0));337} else {338return array[array.length - 1];339}340};341342// Returns everything but the first entry of the array. Aliased as `tail`.343// Especially useful on the arguments object. Passing an **index** will return344// the rest of the values in the array from that index onward. The **guard**345// check allows it to work with `_.map`.346_.rest = _.tail = function(array, index, guard) {347return slice.call(array, (index == null) || guard ? 1 : index);348};349350// Trim out all falsy values from an array.351_.compact = function(array) {352return _.filter(array, function(value){ return !!value; });353};354355// Return a completely flattened version of an array.356_.flatten = function(array, shallow) {357return _.reduce(array, function(memo, value) {358if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));359memo[memo.length] = value;360return memo;361}, []);362};363364// Return a version of the array that does not contain the specified value(s).365_.without = function(array) {366return _.difference(array, slice.call(arguments, 1));367};368369// Produce a duplicate-free version of the array. If the array has already370// been sorted, you have the option of using a faster algorithm.371// Aliased as `unique`.372_.uniq = _.unique = function(array, isSorted, iterator) {373var initial = iterator ? _.map(array, iterator) : array;374var result = [];375_.reduce(initial, function(memo, el, i) {376if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {377memo[memo.length] = el;378result[result.length] = array[i];379}380return memo;381}, []);382return result;383};384385// Produce an array that contains the union: each distinct element from all of386// the passed-in arrays.387_.union = function() {388return _.uniq(_.flatten(arguments, true));389};390391// Produce an array that contains every item shared between all the392// passed-in arrays. (Aliased as "intersect" for back-compat.)393_.intersection = _.intersect = function(array) {394var rest = slice.call(arguments, 1);395return _.filter(_.uniq(array), function(item) {396return _.every(rest, function(other) {397return _.indexOf(other, item) >= 0;398});399});400};401402// Take the difference between one array and a number of other arrays.403// Only the elements present in just the first array will remain.404_.difference = function(array) {405var rest = _.flatten(slice.call(arguments, 1));406return _.filter(array, function(value){ return !_.include(rest, value); });407};408409// Zip together multiple lists into a single array -- elements that share410// an index go together.411_.zip = function() {412var args = slice.call(arguments);413var length = _.max(_.pluck(args, 'length'));414var results = new Array(length);415for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);416return results;417};418419// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),420// we need this function. Return the position of the first occurrence of an421// item in an array, or -1 if the item is not included in the array.422// Delegates to **ECMAScript 5**'s native `indexOf` if available.423// If the array is large and already in sort order, pass `true`424// for **isSorted** to use binary search.425_.indexOf = function(array, item, isSorted) {426if (array == null) return -1;427var i, l;428if (isSorted) {429i = _.sortedIndex(array, item);430return array[i] === item ? i : -1;431}432if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);433for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;434return -1;435};436437// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.438_.lastIndexOf = function(array, item) {439if (array == null) return -1;440if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);441var i = array.length;442while (i--) if (i in array && array[i] === item) return i;443return -1;444};445446// Generate an integer Array containing an arithmetic progression. A port of447// the native Python `range()` function. See448// [the Python documentation](https://docs.python.org/library/functions.html#range).449_.range = function(start, stop, step) {450if (arguments.length <= 1) {451stop = start || 0;452start = 0;453}454step = arguments[2] || 1;455456var len = Math.max(Math.ceil((stop - start) / step), 0);457var idx = 0;458var range = new Array(len);459460while(idx < len) {461range[idx++] = start;462start += step;463}464465return range;466};467468// Function (ahem) Functions469// ------------------470471// Reusable constructor function for prototype setting.472var ctor = function(){};473474// Create a function bound to a given object (assigning `this`, and arguments,475// optionally). Binding with arguments is also known as `curry`.476// Delegates to **ECMAScript 5**'s native `Function.bind` if available.477// We check for `func.bind` first, to fail fast when `func` is undefined.478_.bind = function bind(func, context) {479var bound, args;480if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));481if (!_.isFunction(func)) throw new TypeError;482args = slice.call(arguments, 2);483return bound = function() {484if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));485ctor.prototype = func.prototype;486var self = new ctor;487var result = func.apply(self, args.concat(slice.call(arguments)));488if (Object(result) === result) return result;489return self;490};491};492493// Bind all of an object's methods to that object. Useful for ensuring that494// all callbacks defined on an object belong to it.495_.bindAll = function(obj) {496var funcs = slice.call(arguments, 1);497if (funcs.length == 0) funcs = _.functions(obj);498each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });499return obj;500};501502// Memoize an expensive function by storing its results.503_.memoize = function(func, hasher) {504var memo = {};505hasher || (hasher = _.identity);506return function() {507var key = hasher.apply(this, arguments);508return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));509};510};511512// Delays a function for the given number of milliseconds, and then calls513// it with the arguments supplied.514_.delay = function(func, wait) {515var args = slice.call(arguments, 2);516return setTimeout(function(){ return func.apply(func, args); }, wait);517};518519// Defers a function, scheduling it to run after the current call stack has520// cleared.521_.defer = function(func) {522return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));523};524525// Returns a function, that, when invoked, will only be triggered at most once526// during a given window of time.527_.throttle = function(func, wait) {528var context, args, timeout, throttling, more;529var whenDone = _.debounce(function(){ more = throttling = false; }, wait);530return function() {531context = this; args = arguments;532var later = function() {533timeout = null;534if (more) func.apply(context, args);535whenDone();536};537if (!timeout) timeout = setTimeout(later, wait);538if (throttling) {539more = true;540} else {541func.apply(context, args);542}543whenDone();544throttling = true;545};546};547548// Returns a function, that, as long as it continues to be invoked, will not549// be triggered. The function will be called after it stops being called for550// N milliseconds.551_.debounce = function(func, wait) {552var timeout;553return function() {554var context = this, args = arguments;555var later = function() {556timeout = null;557func.apply(context, args);558};559clearTimeout(timeout);560timeout = setTimeout(later, wait);561};562};563564// Returns a function that will be executed at most one time, no matter how565// often you call it. Useful for lazy initialization.566_.once = function(func) {567var ran = false, memo;568return function() {569if (ran) return memo;570ran = true;571return memo = func.apply(this, arguments);572};573};574575// Returns the first function passed as an argument to the second,576// allowing you to adjust arguments, run code before and after, and577// conditionally execute the original function.578_.wrap = function(func, wrapper) {579return function() {580var args = [func].concat(slice.call(arguments, 0));581return wrapper.apply(this, args);582};583};584585// Returns a function that is the composition of a list of functions, each586// consuming the return value of the function that follows.587_.compose = function() {588var funcs = arguments;589return function() {590var args = arguments;591for (var i = funcs.length - 1; i >= 0; i--) {592args = [funcs[i].apply(this, args)];593}594return args[0];595};596};597598// Returns a function that will only be executed after being called N times.599_.after = function(times, func) {600if (times <= 0) return func();601return function() {602if (--times < 1) { return func.apply(this, arguments); }603};604};605606// Object Functions607// ----------------608609// Retrieve the names of an object's properties.610// Delegates to **ECMAScript 5**'s native `Object.keys`611_.keys = nativeKeys || function(obj) {612if (obj !== Object(obj)) throw new TypeError('Invalid object');613var keys = [];614for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;615return keys;616};617618// Retrieve the values of an object's properties.619_.values = function(obj) {620return _.map(obj, _.identity);621};622623// Return a sorted list of the function names available on the object.624// Aliased as `methods`625_.functions = _.methods = function(obj) {626var names = [];627for (var key in obj) {628if (_.isFunction(obj[key])) names.push(key);629}630return names.sort();631};632633// Extend a given object with all the properties in passed-in object(s).634_.extend = function(obj) {635each(slice.call(arguments, 1), function(source) {636for (var prop in source) {637obj[prop] = source[prop];638}639});640return obj;641};642643// Fill in a given object with default properties.644_.defaults = function(obj) {645each(slice.call(arguments, 1), function(source) {646for (var prop in source) {647if (obj[prop] == null) obj[prop] = source[prop];648}649});650return obj;651};652653// Create a (shallow-cloned) duplicate of an object.654_.clone = function(obj) {655if (!_.isObject(obj)) return obj;656return _.isArray(obj) ? obj.slice() : _.extend({}, obj);657};658659// Invokes interceptor with the obj, and then returns obj.660// The primary purpose of this method is to "tap into" a method chain, in661// order to perform operations on intermediate results within the chain.662_.tap = function(obj, interceptor) {663interceptor(obj);664return obj;665};666667// Internal recursive comparison function.668function eq(a, b, stack) {669// Identical objects are equal. `0 === -0`, but they aren't identical.670// See the Harmony `egal` proposal: https://wiki.ecmascript.org/doku.php?id=harmony:egal.671if (a === b) return a !== 0 || 1 / a == 1 / b;672// A strict comparison is necessary because `null == undefined`.673if (a == null || b == null) return a === b;674// Unwrap any wrapped objects.675if (a._chain) a = a._wrapped;676if (b._chain) b = b._wrapped;677// Invoke a custom `isEqual` method if one is provided.678if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);679if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);680// Compare `[[Class]]` names.681var className = toString.call(a);682if (className != toString.call(b)) return false;683switch (className) {684// Strings, numbers, dates, and booleans are compared by value.685case '[object String]':686// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is687// equivalent to `new String("5")`.688return a == String(b);689case '[object Number]':690// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for691// other numeric values.692return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);693case '[object Date]':694case '[object Boolean]':695// Coerce dates and booleans to numeric primitive values. Dates are compared by their696// millisecond representations. Note that invalid dates with millisecond representations697// of `NaN` are not equivalent.698return +a == +b;699// RegExps are compared by their source patterns and flags.700case '[object RegExp]':701return a.source == b.source &&702a.global == b.global &&703a.multiline == b.multiline &&704a.ignoreCase == b.ignoreCase;705}706if (typeof a != 'object' || typeof b != 'object') return false;707// Assume equality for cyclic structures. The algorithm for detecting cyclic708// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.709var length = stack.length;710while (length--) {711// Linear search. Performance is inversely proportional to the number of712// unique nested structures.713if (stack[length] == a) return true;714}715// Add the first object to the stack of traversed objects.716stack.push(a);717var size = 0, result = true;718// Recursively compare objects and arrays.719if (className == '[object Array]') {720// Compare array lengths to determine if a deep comparison is necessary.721size = a.length;722result = size == b.length;723if (result) {724// Deep compare the contents, ignoring non-numeric properties.725while (size--) {726// Ensure commutative equality for sparse arrays.727if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;728}729}730} else {731// Objects with different constructors are not equivalent.732if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;733// Deep compare objects.734for (var key in a) {735if (_.has(a, key)) {736// Count the expected number of properties.737size++;738// Deep compare each member.739if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;740}741}742// Ensure that both objects contain the same number of properties.743if (result) {744for (key in b) {745if (_.has(b, key) && !(size--)) break;746}747result = !size;748}749}750// Remove the first object from the stack of traversed objects.751stack.pop();752return result;753}754755// Perform a deep comparison to check if two objects are equal.756_.isEqual = function(a, b) {757return eq(a, b, []);758};759760// Is a given array, string, or object empty?761// An "empty" object has no enumerable own-properties.762_.isEmpty = function(obj) {763if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;764for (var key in obj) if (_.has(obj, key)) return false;765return true;766};767768// Is a given value a DOM element?769_.isElement = function(obj) {770return !!(obj && obj.nodeType == 1);771};772773// Is a given value an array?774// Delegates to ECMA5's native Array.isArray775_.isArray = nativeIsArray || function(obj) {776return toString.call(obj) == '[object Array]';777};778779// Is a given variable an object?780_.isObject = function(obj) {781return obj === Object(obj);782};783784// Is a given variable an arguments object?785_.isArguments = function(obj) {786return toString.call(obj) == '[object Arguments]';787};788if (!_.isArguments(arguments)) {789_.isArguments = function(obj) {790return !!(obj && _.has(obj, 'callee'));791};792}793794// Is a given value a function?795_.isFunction = function(obj) {796return toString.call(obj) == '[object Function]';797};798799// Is a given value a string?800_.isString = function(obj) {801return toString.call(obj) == '[object String]';802};803804// Is a given value a number?805_.isNumber = function(obj) {806return toString.call(obj) == '[object Number]';807};808809// Is the given value `NaN`?810_.isNaN = function(obj) {811// `NaN` is the only value for which `===` is not reflexive.812return obj !== obj;813};814815// Is a given value a boolean?816_.isBoolean = function(obj) {817return obj === true || obj === false || toString.call(obj) == '[object Boolean]';818};819820// Is a given value a date?821_.isDate = function(obj) {822return toString.call(obj) == '[object Date]';823};824825// Is the given value a regular expression?826_.isRegExp = function(obj) {827return toString.call(obj) == '[object RegExp]';828};829830// Is a given value equal to null?831_.isNull = function(obj) {832return obj === null;833};834835// Is a given variable undefined?836_.isUndefined = function(obj) {837return obj === void 0;838};839840// Has own property?841_.has = function(obj, key) {842return hasOwnProperty.call(obj, key);843};844845// Utility Functions846// -----------------847848// Run Underscore.js in *noConflict* mode, returning the `_` variable to its849// previous owner. Returns a reference to the Underscore object.850_.noConflict = function() {851root._ = previousUnderscore;852return this;853};854855// Keep the identity function around for default iterators.856_.identity = function(value) {857return value;858};859860// Run a function **n** times.861_.times = function (n, iterator, context) {862for (var i = 0; i < n; i++) iterator.call(context, i);863};864865// Escape a string for HTML interpolation.866_.escape = function(string) {867return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');868};869870// Add your own custom functions to the Underscore object, ensuring that871// they're correctly added to the OOP wrapper as well.872_.mixin = function(obj) {873each(_.functions(obj), function(name){874addToWrapper(name, _[name] = obj[name]);875});876};877878// Generate a unique integer id (unique within the entire client session).879// Useful for temporary DOM ids.880var idCounter = 0;881_.uniqueId = function(prefix) {882var id = idCounter++;883return prefix ? prefix + id : id;884};885886// By default, Underscore uses ERB-style template delimiters, change the887// following template settings to use alternative delimiters.888_.templateSettings = {889evaluate : /<%([\s\S]+?)%>/g,890interpolate : /<%=([\s\S]+?)%>/g,891escape : /<%-([\s\S]+?)%>/g892};893894// When customizing `templateSettings`, if you don't want to define an895// interpolation, evaluation or escaping regex, we need one that is896// guaranteed not to match.897var noMatch = /.^/;898899// Within an interpolation, evaluation, or escaping, remove HTML escaping900// that had been previously added.901var unescape = function(code) {902return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");903};904905// JavaScript micro-templating, similar to John Resig's implementation.906// Underscore templating handles arbitrary delimiters, preserves whitespace,907// and correctly escapes quotes within interpolated code.908_.template = function(str, data) {909var c = _.templateSettings;910var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +911'with(obj||{}){__p.push(\'' +912str.replace(/\\/g, '\\\\')913.replace(/'/g, "\\'")914.replace(c.escape || noMatch, function(match, code) {915return "',_.escape(" + unescape(code) + "),'";916})917.replace(c.interpolate || noMatch, function(match, code) {918return "'," + unescape(code) + ",'";919})920.replace(c.evaluate || noMatch, function(match, code) {921return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";922})923.replace(/\r/g, '\\r')924.replace(/\n/g, '\\n')925.replace(/\t/g, '\\t')926+ "');}return __p.join('');";927var func = new Function('obj', '_', tmpl);928if (data) return func(data, _);929return function(data) {930return func.call(this, data, _);931};932};933934// Add a "chain" function, which will delegate to the wrapper.935_.chain = function(obj) {936return _(obj).chain();937};938939// The OOP Wrapper940// ---------------941942// If Underscore is called as a function, it returns a wrapped object that943// can be used OO-style. This wrapper holds altered versions of all the944// underscore functions. Wrapped objects may be chained.945var wrapper = function(obj) { this._wrapped = obj; };946947// Expose `wrapper.prototype` as `_.prototype`948_.prototype = wrapper.prototype;949950// Helper function to continue chaining intermediate results.951var result = function(obj, chain) {952return chain ? _(obj).chain() : obj;953};954955// A method to easily add functions to the OOP wrapper.956var addToWrapper = function(name, func) {957wrapper.prototype[name] = function() {958var args = slice.call(arguments);959unshift.call(args, this._wrapped);960return result(func.apply(_, args), this._chain);961};962};963964// Add all of the Underscore functions to the wrapper object.965_.mixin(_);966967// Add all mutator Array functions to the wrapper.968each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {969var method = ArrayProto[name];970wrapper.prototype[name] = function() {971var wrapped = this._wrapped;972method.apply(wrapped, arguments);973var length = wrapped.length;974if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];975return result(wrapped, this._chain);976};977});978979// Add all accessor Array functions to the wrapper.980each(['concat', 'join', 'slice'], function(name) {981var method = ArrayProto[name];982wrapper.prototype[name] = function() {983return result(method.apply(this._wrapped, arguments), this._chain);984};985});986987// Start chaining a wrapped Underscore object.988wrapper.prototype.chain = function() {989this._chain = true;990return this;991};992993// Extracts the result from a wrapped and chained object.994wrapper.prototype.value = function() {995return this._wrapped;996};997998}).call(this);99910001001