2
// http://underscorejs.org
3
// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4
// Underscore may be freely distributed under the MIT license.
11
// Establish the root object, `window` in the browser, or `exports` on the server.
14
// Save the previous value of the `_` variable.
15
var previousUnderscore = root._;
17
// Establish the object that gets returned to break out of a loop iteration.
20
// Save bytes in the minified (but not gzipped) version:
21
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
23
// Create quick reference variables for speed access to core prototypes.
25
push = ArrayProto.push,
26
slice = ArrayProto.slice,
27
concat = ArrayProto.concat,
28
toString = ObjProto.toString,
29
hasOwnProperty = ObjProto.hasOwnProperty;
31
// All **ECMAScript 5** native function implementations that we hope to use
34
nativeForEach = ArrayProto.forEach,
35
nativeMap = ArrayProto.map,
36
nativeReduce = ArrayProto.reduce,
37
nativeReduceRight = ArrayProto.reduceRight,
38
nativeFilter = ArrayProto.filter,
39
nativeEvery = ArrayProto.every,
40
nativeSome = ArrayProto.some,
41
nativeIndexOf = ArrayProto.indexOf,
42
nativeLastIndexOf = ArrayProto.lastIndexOf,
43
nativeIsArray = Array.isArray,
44
nativeKeys = Object.keys,
45
nativeBind = FuncProto.bind;
47
// Create a safe reference to the Underscore object for use below.
48
var _ = function(obj) {
49
if (obj instanceof _) return obj;
50
if (!(this instanceof _)) return new _(obj);
54
// Export the Underscore object for **Node.js**, with
55
// backwards-compatibility for the old `require()` API. If we're in
56
// the browser, add `_` as a global object via a string identifier,
57
// for Closure Compiler "advanced" mode.
58
if (typeof exports !== 'undefined') {
59
if (typeof module !== 'undefined' && module.exports) {
60
exports = module.exports = _;
70
// Collection Functions
71
// --------------------
73
// The cornerstone, an `each` implementation, aka `forEach`.
74
// Handles objects with the built-in `forEach`, arrays, and raw objects.
75
// Delegates to **ECMAScript 5**'s native `forEach` if available.
76
var each = _.each = _.forEach = function(obj, iterator, context) {
77
if (obj == null) return;
78
if (nativeForEach && obj.forEach === nativeForEach) {
79
obj.forEach(iterator, context);
80
} else if (obj.length === +obj.length) {
81
for (var i = 0, length = obj.length; i < length; i++) {
82
if (iterator.call(context, obj[i], i, obj) === breaker) return;
85
var keys = _.keys(obj);
86
for (var i = 0, length = keys.length; i < length; i++) {
87
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
92
// Return the results of applying the iterator to each element.
93
// Delegates to **ECMAScript 5**'s native `map` if available.
94
_.map = _.collect = function(obj, iterator, context) {
96
if (obj == null) return results;
97
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
98
each(obj, function(value, index, list) {
99
results.push(iterator.call(context, value, index, list));
104
var reduceError = 'Reduce of empty array with no initial value';
106
// **Reduce** builds up a single result from a list of values, aka `inject`,
107
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
108
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
109
var initial = arguments.length > 2;
110
if (obj == null) obj = [];
111
if (nativeReduce && obj.reduce === nativeReduce) {
112
if (context) iterator = _.bind(iterator, context);
113
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
115
each(obj, function(value, index, list) {
120
memo = iterator.call(context, memo, value, index, list);
123
if (!initial) throw new TypeError(reduceError);
127
// The right-associative version of reduce, also known as `foldr`.
128
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
129
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
130
var initial = arguments.length > 2;
131
if (obj == null) obj = [];
132
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
133
if (context) iterator = _.bind(iterator, context);
134
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
136
var length = obj.length;
137
if (length !== +length) {
138
var keys = _.keys(obj);
139
length = keys.length;
141
each(obj, function(value, index, list) {
142
index = keys ? keys[--length] : --length;
147
memo = iterator.call(context, memo, obj[index], index, list);
150
if (!initial) throw new TypeError(reduceError);
154
// Return the first value which passes a truth test. Aliased as `detect`.
155
_.find = _.detect = function(obj, iterator, context) {
157
any(obj, function(value, index, list) {
158
if (iterator.call(context, value, index, list)) {
166
// Return all the elements that pass a truth test.
167
// Delegates to **ECMAScript 5**'s native `filter` if available.
168
// Aliased as `select`.
169
_.filter = _.select = function(obj, iterator, context) {
171
if (obj == null) return results;
172
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
173
each(obj, function(value, index, list) {
174
if (iterator.call(context, value, index, list)) results.push(value);
179
// Return all the elements for which a truth test fails.
180
_.reject = function(obj, iterator, context) {
181
return _.filter(obj, function(value, index, list) {
182
return !iterator.call(context, value, index, list);
186
// Determine whether all of the elements match a truth test.
187
// Delegates to **ECMAScript 5**'s native `every` if available.
189
_.every = _.all = function(obj, iterator, context) {
190
iterator || (iterator = _.identity);
192
if (obj == null) return result;
193
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
194
each(obj, function(value, index, list) {
195
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
200
// Determine if at least one element in the object matches a truth test.
201
// Delegates to **ECMAScript 5**'s native `some` if available.
203
var any = _.some = _.any = function(obj, iterator, context) {
204
iterator || (iterator = _.identity);
206
if (obj == null) return result;
207
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
208
each(obj, function(value, index, list) {
209
if (result || (result = iterator.call(context, value, index, list))) return breaker;
214
// Determine if the array or object contains a given value (using `===`).
215
// Aliased as `include`.
216
_.contains = _.include = function(obj, target) {
217
if (obj == null) return false;
218
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
219
return any(obj, function(value) {
220
return value === target;
224
// Invoke a method (with arguments) on every item in a collection.
225
_.invoke = function(obj, method) {
226
var args = slice.call(arguments, 2);
227
var isFunc = _.isFunction(method);
228
return _.map(obj, function(value) {
229
return (isFunc ? method : value[method]).apply(value, args);
233
// Convenience version of a common use case of `map`: fetching a property.
234
_.pluck = function(obj, key) {
235
return _.map(obj, function(value){ return value[key]; });
238
// Convenience version of a common use case of `filter`: selecting only objects
239
// containing specific `key:value` pairs.
240
_.where = function(obj, attrs, first) {
241
if (_.isEmpty(attrs)) return first ? void 0 : [];
242
return _[first ? 'find' : 'filter'](obj, function(value) {
243
for (var key in attrs) {
244
if (attrs[key] !== value[key]) return false;
250
// Convenience version of a common use case of `find`: getting the first object
251
// containing specific `key:value` pairs.
252
_.findWhere = function(obj, attrs) {
253
return _.where(obj, attrs, true);
256
// Return the maximum element or (element-based computation).
257
// Can't optimize arrays of integers longer than 65,535 elements.
258
// See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
259
_.max = function(obj, iterator, context) {
260
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
261
return Math.max.apply(Math, obj);
263
if (!iterator && _.isEmpty(obj)) return -Infinity;
264
var result = {computed : -Infinity, value: -Infinity};
265
each(obj, function(value, index, list) {
266
var computed = iterator ? iterator.call(context, value, index, list) : value;
267
computed > result.computed && (result = {value : value, computed : computed});
272
// Return the minimum element (or element-based computation).
273
_.min = function(obj, iterator, context) {
274
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
275
return Math.min.apply(Math, obj);
277
if (!iterator && _.isEmpty(obj)) return Infinity;
278
var result = {computed : Infinity, value: Infinity};
279
each(obj, function(value, index, list) {
280
var computed = iterator ? iterator.call(context, value, index, list) : value;
281
computed < result.computed && (result = {value : value, computed : computed});
286
// Shuffle an array, using the modern version of the
287
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
288
_.shuffle = function(obj) {
292
each(obj, function(value) {
293
rand = _.random(index++);
294
shuffled[index - 1] = shuffled[rand];
295
shuffled[rand] = value;
300
// Sample **n** random values from an array.
301
// If **n** is not specified, returns a single random element from the array.
302
// The internal `guard` argument allows it to work with `map`.
303
_.sample = function(obj, n, guard) {
304
if (arguments.length < 2 || guard) {
305
return obj[_.random(obj.length - 1)];
307
return _.shuffle(obj).slice(0, Math.max(0, n));
310
// An internal function to generate lookup iterators.
311
var lookupIterator = function(value) {
312
return _.isFunction(value) ? value : function(obj){ return obj[value]; };
315
// Sort the object's values by a criterion produced by an iterator.
316
_.sortBy = function(obj, value, context) {
317
var iterator = lookupIterator(value);
318
return _.pluck(_.map(obj, function(value, index, list) {
322
criteria: iterator.call(context, value, index, list)
324
}).sort(function(left, right) {
325
var a = left.criteria;
326
var b = right.criteria;
328
if (a > b || a === void 0) return 1;
329
if (a < b || b === void 0) return -1;
331
return left.index - right.index;
335
// An internal function used for aggregate "group by" operations.
336
var group = function(behavior) {
337
return function(obj, value, context) {
339
var iterator = value == null ? _.identity : lookupIterator(value);
340
each(obj, function(value, index) {
341
var key = iterator.call(context, value, index, obj);
342
behavior(result, key, value);
348
// Groups the object's values by a criterion. Pass either a string attribute
349
// to group by, or a function that returns the criterion.
350
_.groupBy = group(function(result, key, value) {
351
(_.has(result, key) ? result[key] : (result[key] = [])).push(value);
354
// Indexes the object's values by a criterion, similar to `groupBy`, but for
355
// when you know that your index values will be unique.
356
_.indexBy = group(function(result, key, value) {
360
// Counts instances of an object that group by a certain criterion. Pass
361
// either a string attribute to count by, or a function that returns the
363
_.countBy = group(function(result, key) {
364
_.has(result, key) ? result[key]++ : result[key] = 1;
367
// Use a comparator function to figure out the smallest index at which
368
// an object should be inserted so as to maintain order. Uses binary search.
369
_.sortedIndex = function(array, obj, iterator, context) {
370
iterator = iterator == null ? _.identity : lookupIterator(iterator);
371
var value = iterator.call(context, obj);
372
var low = 0, high = array.length;
374
var mid = (low + high) >>> 1;
375
iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
380
// Safely create a real, live array from anything iterable.
381
_.toArray = function(obj) {
383
if (_.isArray(obj)) return slice.call(obj);
384
if (obj.length === +obj.length) return _.map(obj, _.identity);
385
return _.values(obj);
388
// Return the number of elements in an object.
389
_.size = function(obj) {
390
if (obj == null) return 0;
391
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
397
// Get the first element of an array. Passing **n** will return the first N
398
// values in the array. Aliased as `head` and `take`. The **guard** check
399
// allows it to work with `_.map`.
400
_.first = _.head = _.take = function(array, n, guard) {
401
if (array == null) return void 0;
402
return (n == null) || guard ? array[0] : slice.call(array, 0, n);
405
// Returns everything but the last entry of the array. Especially useful on
406
// the arguments object. Passing **n** will return all the values in
407
// the array, excluding the last N. The **guard** check allows it to work with
409
_.initial = function(array, n, guard) {
410
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
413
// Get the last element of an array. Passing **n** will return the last N
414
// values in the array. The **guard** check allows it to work with `_.map`.
415
_.last = function(array, n, guard) {
416
if (array == null) return void 0;
417
if ((n == null) || guard) {
418
return array[array.length - 1];
420
return slice.call(array, Math.max(array.length - n, 0));
424
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
425
// Especially useful on the arguments object. Passing an **n** will return
426
// the rest N values in the array. The **guard**
427
// check allows it to work with `_.map`.
428
_.rest = _.tail = _.drop = function(array, n, guard) {
429
return slice.call(array, (n == null) || guard ? 1 : n);
432
// Trim out all falsy values from an array.
433
_.compact = function(array) {
434
return _.filter(array, _.identity);
437
// Internal implementation of a recursive `flatten` function.
438
var flatten = function(input, shallow, output) {
439
if (shallow && _.every(input, _.isArray)) {
440
return concat.apply(output, input);
442
each(input, function(value) {
443
if (_.isArray(value) || _.isArguments(value)) {
444
shallow ? push.apply(output, value) : flatten(value, shallow, output);
452
// Flatten out an array, either recursively (by default), or just one level.
453
_.flatten = function(array, shallow) {
454
return flatten(array, shallow, []);
457
// Return a version of the array that does not contain the specified value(s).
458
_.without = function(array) {
459
return _.difference(array, slice.call(arguments, 1));
462
// Produce a duplicate-free version of the array. If the array has already
463
// been sorted, you have the option of using a faster algorithm.
464
// Aliased as `unique`.
465
_.uniq = _.unique = function(array, isSorted, iterator, context) {
466
if (_.isFunction(isSorted)) {
471
var initial = iterator ? _.map(array, iterator, context) : array;
474
each(initial, function(value, index) {
475
if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
477
results.push(array[index]);
483
// Produce an array that contains the union: each distinct element from all of
484
// the passed-in arrays.
485
_.union = function() {
486
return _.uniq(_.flatten(arguments, true));
489
// Produce an array that contains every item shared between all the
491
_.intersection = function(array) {
492
var rest = slice.call(arguments, 1);
493
return _.filter(_.uniq(array), function(item) {
494
return _.every(rest, function(other) {
495
return _.indexOf(other, item) >= 0;
500
// Take the difference between one array and a number of other arrays.
501
// Only the elements present in just the first array will remain.
502
_.difference = function(array) {
503
var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
504
return _.filter(array, function(value){ return !_.contains(rest, value); });
507
// Zip together multiple lists into a single array -- elements that share
508
// an index go together.
510
var length = _.max(_.pluck(arguments, "length").concat(0));
511
var results = new Array(length);
512
for (var i = 0; i < length; i++) {
513
results[i] = _.pluck(arguments, '' + i);
518
// Converts lists into objects. Pass either a single array of `[key, value]`
519
// pairs, or two parallel arrays of the same length -- one of keys, and one of
520
// the corresponding values.
521
_.object = function(list, values) {
522
if (list == null) return {};
524
for (var i = 0, length = list.length; i < length; i++) {
526
result[list[i]] = values[i];
528
result[list[i][0]] = list[i][1];
534
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
535
// we need this function. Return the position of the first occurrence of an
536
// item in an array, or -1 if the item is not included in the array.
537
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
538
// If the array is large and already in sort order, pass `true`
539
// for **isSorted** to use binary search.
540
_.indexOf = function(array, item, isSorted) {
541
if (array == null) return -1;
542
var i = 0, length = array.length;
544
if (typeof isSorted == 'number') {
545
i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
547
i = _.sortedIndex(array, item);
548
return array[i] === item ? i : -1;
551
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
552
for (; i < length; i++) if (array[i] === item) return i;
556
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
557
_.lastIndexOf = function(array, item, from) {
558
if (array == null) return -1;
559
var hasIndex = from != null;
560
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
561
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
563
var i = (hasIndex ? from : array.length);
564
while (i--) if (array[i] === item) return i;
568
// Generate an integer Array containing an arithmetic progression. A port of
569
// the native Python `range()` function. See
570
// [the Python documentation](http://docs.python.org/library/functions.html#range).
571
_.range = function(start, stop, step) {
572
if (arguments.length <= 1) {
576
step = arguments[2] || 1;
578
var length = Math.max(Math.ceil((stop - start) / step), 0);
580
var range = new Array(length);
582
while(idx < length) {
583
range[idx++] = start;
590
// Function (ahem) Functions
591
// ------------------
593
// Reusable constructor function for prototype setting.
594
var ctor = function(){};
596
// Create a function bound to a given object (assigning `this`, and arguments,
597
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
599
_.bind = function(func, context) {
601
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
602
if (!_.isFunction(func)) throw new TypeError;
603
args = slice.call(arguments, 2);
604
return bound = function() {
605
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
606
ctor.prototype = func.prototype;
608
ctor.prototype = null;
609
var result = func.apply(self, args.concat(slice.call(arguments)));
610
if (Object(result) === result) return result;
615
// Partially apply a function by creating a version that has had some of its
616
// arguments pre-filled, without changing its dynamic `this` context.
617
_.partial = function(func) {
618
var args = slice.call(arguments, 1);
620
return func.apply(this, args.concat(slice.call(arguments)));
624
// Bind all of an object's methods to that object. Useful for ensuring that
625
// all callbacks defined on an object belong to it.
626
_.bindAll = function(obj) {
627
var funcs = slice.call(arguments, 1);
628
if (funcs.length === 0) throw new Error("bindAll must be passed function names");
629
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
633
// Memoize an expensive function by storing its results.
634
_.memoize = function(func, hasher) {
636
hasher || (hasher = _.identity);
638
var key = hasher.apply(this, arguments);
639
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
643
// Delays a function for the given number of milliseconds, and then calls
644
// it with the arguments supplied.
645
_.delay = function(func, wait) {
646
var args = slice.call(arguments, 2);
647
return setTimeout(function(){ return func.apply(null, args); }, wait);
650
// Defers a function, scheduling it to run after the current call stack has
652
_.defer = function(func) {
653
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
656
// Returns a function, that, when invoked, will only be triggered at most once
657
// during a given window of time. Normally, the throttled function will run
658
// as much as it can, without ever going more than once per `wait` duration;
659
// but if you'd like to disable the execution on the leading edge, pass
660
// `{leading: false}`. To disable execution on the trailing edge, ditto.
661
_.throttle = function(func, wait, options) {
662
var context, args, result;
665
options || (options = {});
666
var later = function() {
667
previous = options.leading === false ? 0 : new Date;
669
result = func.apply(context, args);
673
if (!previous && options.leading === false) previous = now;
674
var remaining = wait - (now - previous);
677
if (remaining <= 0) {
678
clearTimeout(timeout);
681
result = func.apply(context, args);
682
} else if (!timeout && options.trailing !== false) {
683
timeout = setTimeout(later, remaining);
689
// Returns a function, that, as long as it continues to be invoked, will not
690
// be triggered. The function will be called after it stops being called for
691
// N milliseconds. If `immediate` is passed, trigger the function on the
692
// leading edge, instead of the trailing.
693
_.debounce = function(func, wait, immediate) {
694
var timeout, args, context, timestamp, result;
698
timestamp = new Date();
699
var later = function() {
700
var last = (new Date()) - timestamp;
702
timeout = setTimeout(later, wait - last);
705
if (!immediate) result = func.apply(context, args);
708
var callNow = immediate && !timeout;
710
timeout = setTimeout(later, wait);
712
if (callNow) result = func.apply(context, args);
717
// Returns a function that will be executed at most one time, no matter how
718
// often you call it. Useful for lazy initialization.
719
_.once = function(func) {
720
var ran = false, memo;
722
if (ran) return memo;
724
memo = func.apply(this, arguments);
730
// Returns the first function passed as an argument to the second,
731
// allowing you to adjust arguments, run code before and after, and
732
// conditionally execute the original function.
733
_.wrap = function(func, wrapper) {
736
push.apply(args, arguments);
737
return wrapper.apply(this, args);
741
// Returns a function that is the composition of a list of functions, each
742
// consuming the return value of the function that follows.
743
_.compose = function() {
744
var funcs = arguments;
746
var args = arguments;
747
for (var i = funcs.length - 1; i >= 0; i--) {
748
args = [funcs[i].apply(this, args)];
754
// Returns a function that will only be executed after being called N times.
755
_.after = function(times, func) {
758
return func.apply(this, arguments);
766
// Retrieve the names of an object's properties.
767
// Delegates to **ECMAScript 5**'s native `Object.keys`
768
_.keys = nativeKeys || function(obj) {
769
if (obj !== Object(obj)) throw new TypeError('Invalid object');
771
for (var key in obj) if (_.has(obj, key)) keys.push(key);
775
// Retrieve the values of an object's properties.
776
_.values = function(obj) {
777
var keys = _.keys(obj);
778
var length = keys.length;
779
var values = new Array(length);
780
for (var i = 0; i < length; i++) {
781
values[i] = obj[keys[i]];
786
// Convert an object into a list of `[key, value]` pairs.
787
_.pairs = function(obj) {
788
var keys = _.keys(obj);
789
var length = keys.length;
790
var pairs = new Array(length);
791
for (var i = 0; i < length; i++) {
792
pairs[i] = [keys[i], obj[keys[i]]];
797
// Invert the keys and values of an object. The values must be serializable.
798
_.invert = function(obj) {
800
var keys = _.keys(obj);
801
for (var i = 0, length = keys.length; i < length; i++) {
802
result[obj[keys[i]]] = keys[i];
807
// Return a sorted list of the function names available on the object.
808
// Aliased as `methods`
809
_.functions = _.methods = function(obj) {
811
for (var key in obj) {
812
if (_.isFunction(obj[key])) names.push(key);
817
// Extend a given object with all the properties in passed-in object(s).
818
_.extend = function(obj) {
819
each(slice.call(arguments, 1), function(source) {
821
for (var prop in source) {
822
obj[prop] = source[prop];
829
// Return a copy of the object only containing the whitelisted properties.
830
_.pick = function(obj) {
832
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
833
each(keys, function(key) {
834
if (key in obj) copy[key] = obj[key];
839
// Return a copy of the object without the blacklisted properties.
840
_.omit = function(obj) {
842
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
843
for (var key in obj) {
844
if (!_.contains(keys, key)) copy[key] = obj[key];
849
// Fill in a given object with default properties.
850
_.defaults = function(obj) {
851
each(slice.call(arguments, 1), function(source) {
853
for (var prop in source) {
854
if (obj[prop] === void 0) obj[prop] = source[prop];
861
// Create a (shallow-cloned) duplicate of an object.
862
_.clone = function(obj) {
863
if (!_.isObject(obj)) return obj;
864
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
867
// Invokes interceptor with the obj, and then returns obj.
868
// The primary purpose of this method is to "tap into" a method chain, in
869
// order to perform operations on intermediate results within the chain.
870
_.tap = function(obj, interceptor) {
875
// Internal recursive comparison function for `isEqual`.
876
var eq = function(a, b, aStack, bStack) {
877
// Identical objects are equal. `0 === -0`, but they aren't identical.
878
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
879
if (a === b) return a !== 0 || 1 / a == 1 / b;
880
// A strict comparison is necessary because `null == undefined`.
881
if (a == null || b == null) return a === b;
882
// Unwrap any wrapped objects.
883
if (a instanceof _) a = a._wrapped;
884
if (b instanceof _) b = b._wrapped;
885
// Compare `[[Class]]` names.
886
var className = toString.call(a);
887
if (className != toString.call(b)) return false;
889
// Strings, numbers, dates, and booleans are compared by value.
890
case '[object String]':
891
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
892
// equivalent to `new String("5")`.
893
return a == String(b);
894
case '[object Number]':
895
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
896
// other numeric values.
897
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
898
case '[object Date]':
899
case '[object Boolean]':
900
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
901
// millisecond representations. Note that invalid dates with millisecond representations
902
// of `NaN` are not equivalent.
904
// RegExps are compared by their source patterns and flags.
905
case '[object RegExp]':
906
return a.source == b.source &&
907
a.global == b.global &&
908
a.multiline == b.multiline &&
909
a.ignoreCase == b.ignoreCase;
911
if (typeof a != 'object' || typeof b != 'object') return false;
912
// Assume equality for cyclic structures. The algorithm for detecting cyclic
913
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
914
var length = aStack.length;
916
// Linear search. Performance is inversely proportional to the number of
917
// unique nested structures.
918
if (aStack[length] == a) return bStack[length] == b;
920
// Objects with different constructors are not equivalent, but `Object`s
921
// from different frames are.
922
var aCtor = a.constructor, bCtor = b.constructor;
923
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
924
_.isFunction(bCtor) && (bCtor instanceof bCtor))) {
927
// Add the first object to the stack of traversed objects.
930
var size = 0, result = true;
931
// Recursively compare objects and arrays.
932
if (className == '[object Array]') {
933
// Compare array lengths to determine if a deep comparison is necessary.
935
result = size == b.length;
937
// Deep compare the contents, ignoring non-numeric properties.
939
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
943
// Deep compare objects.
946
// Count the expected number of properties.
948
// Deep compare each member.
949
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
952
// Ensure that both objects contain the same number of properties.
955
if (_.has(b, key) && !(size--)) break;
960
// Remove the first object from the stack of traversed objects.
966
// Perform a deep comparison to check if two objects are equal.
967
_.isEqual = function(a, b) {
968
return eq(a, b, [], []);
971
// Is a given array, string, or object empty?
972
// An "empty" object has no enumerable own-properties.
973
_.isEmpty = function(obj) {
974
if (obj == null) return true;
975
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
976
for (var key in obj) if (_.has(obj, key)) return false;
980
// Is a given value a DOM element?
981
_.isElement = function(obj) {
982
return !!(obj && obj.nodeType === 1);
985
// Is a given value an array?
986
// Delegates to ECMA5's native Array.isArray
987
_.isArray = nativeIsArray || function(obj) {
988
return toString.call(obj) == '[object Array]';
991
// Is a given variable an object?
992
_.isObject = function(obj) {
993
return obj === Object(obj);
996
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
997
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
998
_['is' + name] = function(obj) {
999
return toString.call(obj) == '[object ' + name + ']';
1003
// Define a fallback version of the method in browsers (ahem, IE), where
1004
// there isn't any inspectable "Arguments" type.
1005
if (!_.isArguments(arguments)) {
1006
_.isArguments = function(obj) {
1007
return !!(obj && _.has(obj, 'callee'));
1011
// Optimize `isFunction` if appropriate.
1012
if (typeof (/./) !== 'function') {
1013
_.isFunction = function(obj) {
1014
return typeof obj === 'function';
1018
// Is a given object a finite number?
1019
_.isFinite = function(obj) {
1020
return isFinite(obj) && !isNaN(parseFloat(obj));
1023
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
1024
_.isNaN = function(obj) {
1025
return _.isNumber(obj) && obj != +obj;
1028
// Is a given value a boolean?
1029
_.isBoolean = function(obj) {
1030
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
1033
// Is a given value equal to null?
1034
_.isNull = function(obj) {
1035
return obj === null;
1038
// Is a given variable undefined?
1039
_.isUndefined = function(obj) {
1040
return obj === void 0;
1043
// Shortcut function for checking if an object has a given property directly
1044
// on itself (in other words, not on a prototype).
1045
_.has = function(obj, key) {
1046
return hasOwnProperty.call(obj, key);
1049
// Utility Functions
1050
// -----------------
1052
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1053
// previous owner. Returns a reference to the Underscore object.
1054
_.noConflict = function() {
1055
root._ = previousUnderscore;
1059
// Keep the identity function around for default iterators.
1060
_.identity = function(value) {
1064
// Run a function **n** times.
1065
_.times = function(n, iterator, context) {
1066
var accum = Array(Math.max(0, n));
1067
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
1071
// Return a random integer between min and max (inclusive).
1072
_.random = function(min, max) {
1077
return min + Math.floor(Math.random() * (max - min + 1));
1080
// List of HTML entities for escaping.
1090
entityMap.unescape = _.invert(entityMap.escape);
1092
// Regexes containing the keys and values listed immediately above.
1093
var entityRegexes = {
1094
escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
1095
unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
1098
// Functions for escaping and unescaping strings to/from HTML interpolation.
1099
_.each(['escape', 'unescape'], function(method) {
1100
_[method] = function(string) {
1101
if (string == null) return '';
1102
return ('' + string).replace(entityRegexes[method], function(match) {
1103
return entityMap[method][match];
1108
// If the value of the named `property` is a function then invoke it with the
1109
// `object` as context; otherwise, return it.
1110
_.result = function(object, property) {
1111
if (object == null) return void 0;
1112
var value = object[property];
1113
return _.isFunction(value) ? value.call(object) : value;
1116
// Add your own custom functions to the Underscore object.
1117
_.mixin = function(obj) {
1118
each(_.functions(obj), function(name) {
1119
var func = _[name] = obj[name];
1120
_.prototype[name] = function() {
1121
var args = [this._wrapped];
1122
push.apply(args, arguments);
1123
return result.call(this, func.apply(_, args));
1128
// Generate a unique integer id (unique within the entire client session).
1129
// Useful for temporary DOM ids.
1131
_.uniqueId = function(prefix) {
1132
var id = ++idCounter + '';
1133
return prefix ? prefix + id : id;
1136
// By default, Underscore uses ERB-style template delimiters, change the
1137
// following template settings to use alternative delimiters.
1138
_.templateSettings = {
1139
evaluate : /<%([\s\S]+?)%>/g,
1140
interpolate : /<%=([\s\S]+?)%>/g,
1141
escape : /<%-([\s\S]+?)%>/g
1144
// When customizing `templateSettings`, if you don't want to define an
1145
// interpolation, evaluation or escaping regex, we need one that is
1146
// guaranteed not to match.
1147
var noMatch = /(.)^/;
1149
// Certain characters need to be escaped so that they can be put into a
1161
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
1163
// JavaScript micro-templating, similar to John Resig's implementation.
1164
// Underscore templating handles arbitrary delimiters, preserves whitespace,
1165
// and correctly escapes quotes within interpolated code.
1166
_.template = function(text, data, settings) {
1168
settings = _.defaults({}, settings, _.templateSettings);
1170
// Combine delimiters into one regular expression via alternation.
1171
var matcher = new RegExp([
1172
(settings.escape || noMatch).source,
1173
(settings.interpolate || noMatch).source,
1174
(settings.evaluate || noMatch).source
1175
].join('|') + '|$', 'g');
1177
// Compile the template source, escaping string literals appropriately.
1179
var source = "__p+='";
1180
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
1181
source += text.slice(index, offset)
1182
.replace(escaper, function(match) { return '\\' + escapes[match]; });
1185
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
1188
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
1191
source += "';\n" + evaluate + "\n__p+='";
1193
index = offset + match.length;
1198
// If a variable is not specified, place data values in local scope.
1199
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
1201
source = "var __t,__p='',__j=Array.prototype.join," +
1202
"print=function(){__p+=__j.call(arguments,'');};\n" +
1203
source + "return __p;\n";
1206
render = new Function(settings.variable || 'obj', '_', source);
1212
if (data) return render(data, _);
1213
var template = function(data) {
1214
return render.call(this, data, _);
1217
// Provide the compiled function source as a convenience for precompilation.
1218
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
1223
// Add a "chain" function, which will delegate to the wrapper.
1224
_.chain = function(obj) {
1225
return _(obj).chain();
1230
// If Underscore is called as a function, it returns a wrapped object that
1231
// can be used OO-style. This wrapper holds altered versions of all the
1232
// underscore functions. Wrapped objects may be chained.
1234
// Helper function to continue chaining intermediate results.
1235
var result = function(obj) {
1236
return this._chain ? _(obj).chain() : obj;
1239
// Add all of the Underscore functions to the wrapper object.
1242
// Add all mutator Array functions to the wrapper.
1243
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1244
var method = ArrayProto[name];
1245
_.prototype[name] = function() {
1246
var obj = this._wrapped;
1247
method.apply(obj, arguments);
1248
if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
1249
return result.call(this, obj);
1253
// Add all accessor Array functions to the wrapper.
1254
each(['concat', 'join', 'slice'], function(name) {
1255
var method = ArrayProto[name];
1256
_.prototype[name] = function() {
1257
return result.call(this, method.apply(this._wrapped, arguments));
1261
_.extend(_.prototype, {
1263
// Start chaining a wrapped Underscore object.
1269
// Extracts the result from a wrapped and chained object.
1271
return this._wrapped;
b'\\ No newline at end of file'