react / wstein / node_modules / jest-cli / node_modules / cover / node_modules / underscore / underscore.js
80669 views// Underscore.js 1.2.41// (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// http://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** and **"CommonJS"**, with51// backwards-compatibility for the old `require()` API. If we're not in52// CommonJS, add `_` to the global object.53if (typeof exports !== 'undefined') {54if (typeof module !== 'undefined' && module.exports) {55exports = module.exports = _;56}57exports._ = _;58} else if (typeof define === 'function' && define.amd) {59// Register as a named module with AMD.60define('underscore', function() {61return _;62});63} else {64// Exported as a string, for Closure Compiler "advanced" mode.65root['_'] = _;66}6768// Current version.69_.VERSION = '1.2.4';7071// Collection Functions72// --------------------7374// The cornerstone, an `each` implementation, aka `forEach`.75// Handles objects with the built-in `forEach`, arrays, and raw objects.76// Delegates to **ECMAScript 5**'s native `forEach` if available.77var each = _.each = _.forEach = function(obj, iterator, context) {78if (obj == null) return;79if (nativeForEach && obj.forEach === nativeForEach) {80obj.forEach(iterator, context);81} else if (obj.length === +obj.length) {82for (var i = 0, l = obj.length; i < l; i++) {83if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;84}85} else {86for (var key in obj) {87if (hasOwnProperty.call(obj, key)) {88if (iterator.call(context, obj[key], key, obj) === breaker) return;89}90}91}92};9394// Return the results of applying the iterator to each element.95// Delegates to **ECMAScript 5**'s native `map` if available.96_.map = function(obj, iterator, context) {97var results = [];98if (obj == null) return results;99if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);100each(obj, function(value, index, list) {101results[results.length] = iterator.call(context, value, index, list);102});103if (obj.length === +obj.length) results.length = obj.length;104return results;105};106107// **Reduce** builds up a single result from a list of values, aka `inject`,108// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.109_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {110var initial = arguments.length > 2;111if (obj == null) obj = [];112if (nativeReduce && obj.reduce === nativeReduce) {113if (context) iterator = _.bind(iterator, context);114return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);115}116each(obj, function(value, index, list) {117if (!initial) {118memo = value;119initial = true;120} else {121memo = iterator.call(context, memo, value, index, list);122}123});124if (!initial) throw new TypeError('Reduce of empty array with no initial value');125return memo;126};127128// The right-associative version of reduce, also known as `foldr`.129// Delegates to **ECMAScript 5**'s native `reduceRight` if available.130_.reduceRight = _.foldr = function(obj, iterator, memo, context) {131var initial = arguments.length > 2;132if (obj == null) obj = [];133if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {134if (context) iterator = _.bind(iterator, context);135return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);136}137var reversed = _.toArray(obj).reverse();138if (context && !initial) iterator = _.bind(iterator, context);139return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);140};141142// Return the first value which passes a truth test. Aliased as `detect`.143_.find = _.detect = function(obj, iterator, context) {144var result;145any(obj, function(value, index, list) {146if (iterator.call(context, value, index, list)) {147result = value;148return true;149}150});151return result;152};153154// Return all the elements that pass a truth test.155// Delegates to **ECMAScript 5**'s native `filter` if available.156// Aliased as `select`.157_.filter = _.select = function(obj, iterator, context) {158var results = [];159if (obj == null) return results;160if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);161each(obj, function(value, index, list) {162if (iterator.call(context, value, index, list)) results[results.length] = value;163});164return results;165};166167// Return all the elements for which a truth test fails.168_.reject = function(obj, iterator, context) {169var results = [];170if (obj == null) return results;171each(obj, function(value, index, list) {172if (!iterator.call(context, value, index, list)) results[results.length] = value;173});174return results;175};176177// Determine whether all of the elements match a truth test.178// Delegates to **ECMAScript 5**'s native `every` if available.179// Aliased as `all`.180_.every = _.all = function(obj, iterator, context) {181var result = true;182if (obj == null) return result;183if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);184each(obj, function(value, index, list) {185if (!(result = result && iterator.call(context, value, index, list))) return breaker;186});187return result;188};189190// Determine if at least one element in the object matches a truth test.191// Delegates to **ECMAScript 5**'s native `some` if available.192// Aliased as `any`.193var any = _.some = _.any = function(obj, iterator, context) {194iterator || (iterator = _.identity);195var result = false;196if (obj == null) return result;197if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);198each(obj, function(value, index, list) {199if (result || (result = iterator.call(context, value, index, list))) return breaker;200});201return !!result;202};203204// Determine if a given value is included in the array or object using `===`.205// Aliased as `contains`.206_.include = _.contains = function(obj, target) {207var found = false;208if (obj == null) return found;209if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;210found = any(obj, function(value) {211return value === target;212});213return found;214};215216// Invoke a method (with arguments) on every item in a collection.217_.invoke = function(obj, method) {218var args = slice.call(arguments, 2);219return _.map(obj, function(value) {220return (_.isFunction(method) ? method || value : value[method]).apply(value, args);221});222};223224// Convenience version of a common use case of `map`: fetching a property.225_.pluck = function(obj, key) {226return _.map(obj, function(value){ return value[key]; });227};228229// Return the maximum element or (element-based computation).230_.max = function(obj, iterator, context) {231if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);232if (!iterator && _.isEmpty(obj)) return -Infinity;233var result = {computed : -Infinity};234each(obj, function(value, index, list) {235var computed = iterator ? iterator.call(context, value, index, list) : value;236computed >= result.computed && (result = {value : value, computed : computed});237});238return result.value;239};240241// Return the minimum element (or element-based computation).242_.min = function(obj, iterator, context) {243if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);244if (!iterator && _.isEmpty(obj)) return Infinity;245var result = {computed : Infinity};246each(obj, function(value, index, list) {247var computed = iterator ? iterator.call(context, value, index, list) : value;248computed < result.computed && (result = {value : value, computed : computed});249});250return result.value;251};252253// Shuffle an array.254_.shuffle = function(obj) {255var shuffled = [], rand;256each(obj, function(value, index, list) {257if (index == 0) {258shuffled[0] = value;259} else {260rand = Math.floor(Math.random() * (index + 1));261shuffled[index] = shuffled[rand];262shuffled[rand] = value;263}264});265return shuffled;266};267268// Sort the object's values by a criterion produced by an iterator.269_.sortBy = function(obj, iterator, context) {270return _.pluck(_.map(obj, function(value, index, list) {271return {272value : value,273criteria : iterator.call(context, value, index, list)274};275}).sort(function(left, right) {276var a = left.criteria, b = right.criteria;277return a < b ? -1 : a > b ? 1 : 0;278}), 'value');279};280281// Groups the object's values by a criterion. Pass either a string attribute282// to group by, or a function that returns the criterion.283_.groupBy = function(obj, val) {284var result = {};285var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };286each(obj, function(value, index) {287var key = iterator(value, index);288(result[key] || (result[key] = [])).push(value);289});290return result;291};292293// Use a comparator function to figure out at what index an object should294// be inserted so as to maintain order. Uses binary search.295_.sortedIndex = function(array, obj, iterator) {296iterator || (iterator = _.identity);297var low = 0, high = array.length;298while (low < high) {299var mid = (low + high) >> 1;300iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;301}302return low;303};304305// Safely convert anything iterable into a real, live array.306_.toArray = function(iterable) {307if (!iterable) return [];308if (iterable.toArray) return iterable.toArray();309if (_.isArray(iterable)) return slice.call(iterable);310if (_.isArguments(iterable)) return slice.call(iterable);311return _.values(iterable);312};313314// Return the number of elements in an object.315_.size = function(obj) {316return _.toArray(obj).length;317};318319// Array Functions320// ---------------321322// Get the first element of an array. Passing **n** will return the first N323// values in the array. Aliased as `head`. The **guard** check allows it to work324// with `_.map`.325_.first = _.head = function(array, n, guard) {326return (n != null) && !guard ? slice.call(array, 0, n) : array[0];327};328329// Returns everything but the last entry of the array. Especcialy useful on330// the arguments object. Passing **n** will return all the values in331// the array, excluding the last N. The **guard** check allows it to work with332// `_.map`.333_.initial = function(array, n, guard) {334return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));335};336337// Get the last element of an array. Passing **n** will return the last N338// values in the array. The **guard** check allows it to work with `_.map`.339_.last = function(array, n, guard) {340if ((n != null) && !guard) {341return slice.call(array, Math.max(array.length - n, 0));342} else {343return array[array.length - 1];344}345};346347// Returns everything but the first entry of the array. Aliased as `tail`.348// Especially useful on the arguments object. Passing an **index** will return349// the rest of the values in the array from that index onward. The **guard**350// check allows it to work with `_.map`.351_.rest = _.tail = function(array, index, guard) {352return slice.call(array, (index == null) || guard ? 1 : index);353};354355// Trim out all falsy values from an array.356_.compact = function(array) {357return _.filter(array, function(value){ return !!value; });358};359360// Return a completely flattened version of an array.361_.flatten = function(array, shallow) {362return _.reduce(array, function(memo, value) {363if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));364memo[memo.length] = value;365return memo;366}, []);367};368369// Return a version of the array that does not contain the specified value(s).370_.without = function(array) {371return _.difference(array, slice.call(arguments, 1));372};373374// Produce a duplicate-free version of the array. If the array has already375// been sorted, you have the option of using a faster algorithm.376// Aliased as `unique`.377_.uniq = _.unique = function(array, isSorted, iterator) {378var initial = iterator ? _.map(array, iterator) : array;379var result = [];380_.reduce(initial, function(memo, el, i) {381if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {382memo[memo.length] = el;383result[result.length] = array[i];384}385return memo;386}, []);387return result;388};389390// Produce an array that contains the union: each distinct element from all of391// the passed-in arrays.392_.union = function() {393return _.uniq(_.flatten(arguments, true));394};395396// Produce an array that contains every item shared between all the397// passed-in arrays. (Aliased as "intersect" for back-compat.)398_.intersection = _.intersect = function(array) {399var rest = slice.call(arguments, 1);400return _.filter(_.uniq(array), function(item) {401return _.every(rest, function(other) {402return _.indexOf(other, item) >= 0;403});404});405};406407// Take the difference between one array and a number of other arrays.408// Only the elements present in just the first array will remain.409_.difference = function(array) {410var rest = _.flatten(slice.call(arguments, 1));411return _.filter(array, function(value){ return !_.include(rest, value); });412};413414// Zip together multiple lists into a single array -- elements that share415// an index go together.416_.zip = function() {417var args = slice.call(arguments);418var length = _.max(_.pluck(args, 'length'));419var results = new Array(length);420for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);421return results;422};423424// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),425// we need this function. Return the position of the first occurrence of an426// item in an array, or -1 if the item is not included in the array.427// Delegates to **ECMAScript 5**'s native `indexOf` if available.428// If the array is large and already in sort order, pass `true`429// for **isSorted** to use binary search.430_.indexOf = function(array, item, isSorted) {431if (array == null) return -1;432var i, l;433if (isSorted) {434i = _.sortedIndex(array, item);435return array[i] === item ? i : -1;436}437if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);438for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;439return -1;440};441442// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.443_.lastIndexOf = function(array, item) {444if (array == null) return -1;445if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);446var i = array.length;447while (i--) if (i in array && array[i] === item) return i;448return -1;449};450451// Generate an integer Array containing an arithmetic progression. A port of452// the native Python `range()` function. See453// [the Python documentation](http://docs.python.org/library/functions.html#range).454_.range = function(start, stop, step) {455if (arguments.length <= 1) {456stop = start || 0;457start = 0;458}459step = arguments[2] || 1;460461var len = Math.max(Math.ceil((stop - start) / step), 0);462var idx = 0;463var range = new Array(len);464465while(idx < len) {466range[idx++] = start;467start += step;468}469470return range;471};472473// Function (ahem) Functions474// ------------------475476// Reusable constructor function for prototype setting.477var ctor = function(){};478479// Create a function bound to a given object (assigning `this`, and arguments,480// optionally). Binding with arguments is also known as `curry`.481// Delegates to **ECMAScript 5**'s native `Function.bind` if available.482// We check for `func.bind` first, to fail fast when `func` is undefined.483_.bind = function bind(func, context) {484var bound, args;485if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));486if (!_.isFunction(func)) throw new TypeError;487args = slice.call(arguments, 2);488return bound = function() {489if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));490ctor.prototype = func.prototype;491var self = new ctor;492var result = func.apply(self, args.concat(slice.call(arguments)));493if (Object(result) === result) return result;494return self;495};496};497498// Bind all of an object's methods to that object. Useful for ensuring that499// all callbacks defined on an object belong to it.500_.bindAll = function(obj) {501var funcs = slice.call(arguments, 1);502if (funcs.length == 0) funcs = _.functions(obj);503each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });504return obj;505};506507// Memoize an expensive function by storing its results.508_.memoize = function(func, hasher) {509var memo = {};510hasher || (hasher = _.identity);511return function() {512var key = hasher.apply(this, arguments);513return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));514};515};516517// Delays a function for the given number of milliseconds, and then calls518// it with the arguments supplied.519_.delay = function(func, wait) {520var args = slice.call(arguments, 2);521return setTimeout(function(){ return func.apply(func, args); }, wait);522};523524// Defers a function, scheduling it to run after the current call stack has525// cleared.526_.defer = function(func) {527return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));528};529530// Returns a function, that, when invoked, will only be triggered at most once531// during a given window of time.532_.throttle = function(func, wait) {533var context, args, timeout, throttling, more;534var whenDone = _.debounce(function(){ more = throttling = false; }, wait);535return function() {536context = this; args = arguments;537var later = function() {538timeout = null;539if (more) func.apply(context, args);540whenDone();541};542if (!timeout) timeout = setTimeout(later, wait);543if (throttling) {544more = true;545} else {546func.apply(context, args);547}548whenDone();549throttling = true;550};551};552553// Returns a function, that, as long as it continues to be invoked, will not554// be triggered. The function will be called after it stops being called for555// N milliseconds.556_.debounce = function(func, wait) {557var timeout;558return function() {559var context = this, args = arguments;560var later = function() {561timeout = null;562func.apply(context, args);563};564clearTimeout(timeout);565timeout = setTimeout(later, wait);566};567};568569// Returns a function that will be executed at most one time, no matter how570// often you call it. Useful for lazy initialization.571_.once = function(func) {572var ran = false, memo;573return function() {574if (ran) return memo;575ran = true;576return memo = func.apply(this, arguments);577};578};579580// Returns the first function passed as an argument to the second,581// allowing you to adjust arguments, run code before and after, and582// conditionally execute the original function.583_.wrap = function(func, wrapper) {584return function() {585var args = [func].concat(slice.call(arguments, 0));586return wrapper.apply(this, args);587};588};589590// Returns a function that is the composition of a list of functions, each591// consuming the return value of the function that follows.592_.compose = function() {593var funcs = arguments;594return function() {595var args = arguments;596for (var i = funcs.length - 1; i >= 0; i--) {597args = [funcs[i].apply(this, args)];598}599return args[0];600};601};602603// Returns a function that will only be executed after being called N times.604_.after = function(times, func) {605if (times <= 0) return func();606return function() {607if (--times < 1) { return func.apply(this, arguments); }608};609};610611// Object Functions612// ----------------613614// Retrieve the names of an object's properties.615// Delegates to **ECMAScript 5**'s native `Object.keys`616_.keys = nativeKeys || function(obj) {617if (obj !== Object(obj)) throw new TypeError('Invalid object');618var keys = [];619for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;620return keys;621};622623// Retrieve the values of an object's properties.624_.values = function(obj) {625return _.map(obj, _.identity);626};627628// Return a sorted list of the function names available on the object.629// Aliased as `methods`630_.functions = _.methods = function(obj) {631var names = [];632for (var key in obj) {633if (_.isFunction(obj[key])) names.push(key);634}635return names.sort();636};637638// Extend a given object with all the properties in passed-in object(s).639_.extend = function(obj) {640each(slice.call(arguments, 1), function(source) {641for (var prop in source) {642if (source[prop] !== void 0) obj[prop] = source[prop];643}644});645return obj;646};647648// Fill in a given object with default properties.649_.defaults = function(obj) {650each(slice.call(arguments, 1), function(source) {651for (var prop in source) {652if (obj[prop] == null) obj[prop] = source[prop];653}654});655return obj;656};657658// Create a (shallow-cloned) duplicate of an object.659_.clone = function(obj) {660if (!_.isObject(obj)) return obj;661return _.isArray(obj) ? obj.slice() : _.extend({}, obj);662};663664// Invokes interceptor with the obj, and then returns obj.665// The primary purpose of this method is to "tap into" a method chain, in666// order to perform operations on intermediate results within the chain.667_.tap = function(obj, interceptor) {668interceptor(obj);669return obj;670};671672// Internal recursive comparison function.673function eq(a, b, stack) {674// Identical objects are equal. `0 === -0`, but they aren't identical.675// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.676if (a === b) return a !== 0 || 1 / a == 1 / b;677// A strict comparison is necessary because `null == undefined`.678if (a == null || b == null) return a === b;679// Unwrap any wrapped objects.680if (a._chain) a = a._wrapped;681if (b._chain) b = b._wrapped;682// Invoke a custom `isEqual` method if one is provided.683if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);684if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);685// Compare `[[Class]]` names.686var className = toString.call(a);687if (className != toString.call(b)) return false;688switch (className) {689// Strings, numbers, dates, and booleans are compared by value.690case '[object String]':691// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is692// equivalent to `new String("5")`.693return a == String(b);694case '[object Number]':695// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for696// other numeric values.697return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);698case '[object Date]':699case '[object Boolean]':700// Coerce dates and booleans to numeric primitive values. Dates are compared by their701// millisecond representations. Note that invalid dates with millisecond representations702// of `NaN` are not equivalent.703return +a == +b;704// RegExps are compared by their source patterns and flags.705case '[object RegExp]':706return a.source == b.source &&707a.global == b.global &&708a.multiline == b.multiline &&709a.ignoreCase == b.ignoreCase;710}711if (typeof a != 'object' || typeof b != 'object') return false;712// Assume equality for cyclic structures. The algorithm for detecting cyclic713// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.714var length = stack.length;715while (length--) {716// Linear search. Performance is inversely proportional to the number of717// unique nested structures.718if (stack[length] == a) return true;719}720// Add the first object to the stack of traversed objects.721stack.push(a);722var size = 0, result = true;723// Recursively compare objects and arrays.724if (className == '[object Array]') {725// Compare array lengths to determine if a deep comparison is necessary.726size = a.length;727result = size == b.length;728if (result) {729// Deep compare the contents, ignoring non-numeric properties.730while (size--) {731// Ensure commutative equality for sparse arrays.732if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;733}734}735} else {736// Objects with different constructors are not equivalent.737if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;738// Deep compare objects.739for (var key in a) {740if (hasOwnProperty.call(a, key)) {741// Count the expected number of properties.742size++;743// Deep compare each member.744if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;745}746}747// Ensure that both objects contain the same number of properties.748if (result) {749for (key in b) {750if (hasOwnProperty.call(b, key) && !(size--)) break;751}752result = !size;753}754}755// Remove the first object from the stack of traversed objects.756stack.pop();757return result;758}759760// Perform a deep comparison to check if two objects are equal.761_.isEqual = function(a, b) {762return eq(a, b, []);763};764765// Is a given array, string, or object empty?766// An "empty" object has no enumerable own-properties.767_.isEmpty = function(obj) {768if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;769for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;770return true;771};772773// Is a given value a DOM element?774_.isElement = function(obj) {775return !!(obj && obj.nodeType == 1);776};777778// Is a given value an array?779// Delegates to ECMA5's native Array.isArray780_.isArray = nativeIsArray || function(obj) {781return toString.call(obj) == '[object Array]';782};783784// Is a given variable an object?785_.isObject = function(obj) {786return obj === Object(obj);787};788789// Is a given variable an arguments object?790_.isArguments = function(obj) {791return toString.call(obj) == '[object Arguments]';792};793if (!_.isArguments(arguments)) {794_.isArguments = function(obj) {795return !!(obj && hasOwnProperty.call(obj, 'callee'));796};797}798799// Is a given value a function?800_.isFunction = function(obj) {801return toString.call(obj) == '[object Function]';802};803804// Is a given value a string?805_.isString = function(obj) {806return toString.call(obj) == '[object String]';807};808809// Is a given value a number?810_.isNumber = function(obj) {811return toString.call(obj) == '[object Number]';812};813814// Is the given value `NaN`?815_.isNaN = function(obj) {816// `NaN` is the only value for which `===` is not reflexive.817return obj !== obj;818};819820// Is a given value a boolean?821_.isBoolean = function(obj) {822return obj === true || obj === false || toString.call(obj) == '[object Boolean]';823};824825// Is a given value a date?826_.isDate = function(obj) {827return toString.call(obj) == '[object Date]';828};829830// Is the given value a regular expression?831_.isRegExp = function(obj) {832return toString.call(obj) == '[object RegExp]';833};834835// Is a given value equal to null?836_.isNull = function(obj) {837return obj === null;838};839840// Is a given variable undefined?841_.isUndefined = function(obj) {842return obj === void 0;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// JavaScript micro-templating, similar to John Resig's implementation.900// Underscore templating handles arbitrary delimiters, preserves whitespace,901// and correctly escapes quotes within interpolated code.902_.template = function(str, data) {903var c = _.templateSettings;904var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +905'with(obj||{}){__p.push(\'' +906str.replace(/\\/g, '\\\\')907.replace(/'/g, "\\'")908.replace(c.escape || noMatch, function(match, code) {909return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";910})911.replace(c.interpolate || noMatch, function(match, code) {912return "'," + code.replace(/\\'/g, "'") + ",'";913})914.replace(c.evaluate || noMatch, function(match, code) {915return "');" + code.replace(/\\'/g, "'")916.replace(/[\r\n\t]/g, ' ')917.replace(/\\\\/g, '\\') + ";__p.push('";918})919.replace(/\r/g, '\\r')920.replace(/\n/g, '\\n')921.replace(/\t/g, '\\t')922+ "');}return __p.join('');";923var func = new Function('obj', '_', tmpl);924if (data) return func(data, _);925return function(data) {926return func.call(this, data, _);927};928};929930// Add a "chain" function, which will delegate to the wrapper.931_.chain = function(obj) {932return _(obj).chain();933};934935// The OOP Wrapper936// ---------------937938// If Underscore is called as a function, it returns a wrapped object that939// can be used OO-style. This wrapper holds altered versions of all the940// underscore functions. Wrapped objects may be chained.941var wrapper = function(obj) { this._wrapped = obj; };942943// Expose `wrapper.prototype` as `_.prototype`944_.prototype = wrapper.prototype;945946// Helper function to continue chaining intermediate results.947var result = function(obj, chain) {948return chain ? _(obj).chain() : obj;949};950951// A method to easily add functions to the OOP wrapper.952var addToWrapper = function(name, func) {953wrapper.prototype[name] = function() {954var args = slice.call(arguments);955unshift.call(args, this._wrapped);956return result(func.apply(_, args), this._chain);957};958};959960// Add all of the Underscore functions to the wrapper object.961_.mixin(_);962963// Add all mutator Array functions to the wrapper.964each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {965var method = ArrayProto[name];966wrapper.prototype[name] = function() {967var wrapped = this._wrapped;968method.apply(wrapped, arguments);969var length = wrapped.length;970if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];971return result(wrapped, this._chain);972};973});974975// Add all accessor Array functions to the wrapper.976each(['concat', 'join', 'slice'], function(name) {977var method = ArrayProto[name];978wrapper.prototype[name] = function() {979return result(method.apply(this._wrapped, arguments), this._chain);980};981});982983// Start chaining a wrapped Underscore object.984wrapper.prototype.chain = function() {985this._chain = true;986return this;987};988989// Extracts the result from a wrapped and chained object.990wrapper.prototype.value = function() {991return this._wrapped;992};993994}).call(this);995996997