3 * Lo-Dash 1.0.2 (Custom Build) <http://lodash.com/>
4 * Build: `lodash -o ./dist/lodash.compat.js`
5 * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
6 * Based on Underscore.js 1.4.4 <http://underscorejs.org/>
7 * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
8 * Available under MIT license <http://lodash.com/license>
10 ;(function(window, undefined) {
12 /** Detect free variable `exports` */
13 var freeExports = typeof exports == 'object' && exports;
15 /** Detect free variable `module` */
16 var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
18 /** Detect free variable `global` and use it as `window` */
19 var freeGlobal = typeof global == 'object' && global;
20 if (freeGlobal.global === freeGlobal) {
24 /** Used for array and object method references */
28 /** Used to generate unique IDs */
31 /** Used internally to indicate various things */
32 var indicatorObject = objectRef;
34 /** Used by `cachedContains` as the default size when optimizations are enabled for large arrays */
35 var largeArraySize = 30;
37 /** Used to restore the original `_` reference in `noConflict` */
38 var oldDash = window._;
40 /** Used to match HTML entities */
41 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
43 /** Used to match empty string literals in compiled template source */
44 var reEmptyStringLeading = /\b__p \+= '';/g,
45 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
46 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
48 /** Used to match regexp flags from their coerced string values */
51 /** Used to detect if a method is native */
52 var reNative = RegExp('^' +
53 (objectRef.valueOf + '')
54 .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
55 .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
59 * Used to match ES6 template delimiters
60 * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
62 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
64 /** Used to match "interpolate" template delimiters */
65 var reInterpolate = /<%=([\s\S]+?)%>/g;
67 /** Used to ensure capturing order of template delimiters */
68 var reNoMatch = /($^)/;
70 /** Used to match HTML characters */
71 var reUnescapedHtml = /[&<>"']/g;
73 /** Used to match unescaped characters in compiled string literals */
74 var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
76 /** Used to fix the JScript [[DontEnum]] bug */
78 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
79 'toLocaleString', 'toString', 'valueOf'
82 /** Used to make template sourceURLs easier to identify */
83 var templateCounter = 0;
85 /** Native method shortcuts */
87 concat = arrayRef.concat,
89 getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
90 hasOwnProperty = objectRef.hasOwnProperty,
92 toString = objectRef.toString;
94 /* Native method shortcuts for methods with the same name as other `lodash` methods */
95 var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
96 nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
97 nativeIsFinite = window.isFinite,
98 nativeIsNaN = window.isNaN,
99 nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
100 nativeMax = Math.max,
101 nativeMin = Math.min,
102 nativeRandom = Math.random;
104 /** `Object#toString` result shortcuts */
105 var argsClass = '[object Arguments]',
106 arrayClass = '[object Array]',
107 boolClass = '[object Boolean]',
108 dateClass = '[object Date]',
109 funcClass = '[object Function]',
110 numberClass = '[object Number]',
111 objectClass = '[object Object]',
112 regexpClass = '[object RegExp]',
113 stringClass = '[object String]';
115 /** Detect various environments */
116 var isIeOpera = !!window.attachEvent,
117 isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
119 /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */
120 var isBindFast = nativeBind && !isV8;
122 /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */
123 var isKeysFast = nativeKeys && (isIeOpera || isV8);
126 * Detect the JScript [[DontEnum]] bug:
128 * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
129 * made non-enumerable as well.
134 * Detect if a `prototype` properties are enumerable by default:
136 * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
137 * (if the prototype or a property on the prototype has been set)
138 * incorrectly sets a function's `prototype` property [[Enumerable]]
141 var hasEnumPrototype;
143 /** Detect if own properties are iterated after inherited properties (IE < 9) */
147 * Detect if `Array#shift` and `Array#splice` augment array-like objects
150 * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
151 * and `splice()` functions that fail to remove the last element, `value[0]`,
152 * of array-like objects even though the `length` property is set to `0`.
153 * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
154 * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
156 var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 },
157 arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]);
159 /** Detect if `arguments` object indexes are non-enumerable (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1) */
160 var nonEnumArgs = true;
164 function ctor() { this.x = 1; }
165 ctor.prototype = { 'valueOf': 1, 'y': 1 };
166 for (var prop in new ctor) { props.push(prop); }
167 for (prop in arguments) { nonEnumArgs = !prop; }
169 hasDontEnumBug = !/valueOf/.test(props);
170 hasEnumPrototype = ctor.propertyIsEnumerable('prototype');
171 iteratesOwnLast = props[0] != 'x';
174 /** Detect if `arguments` objects are `Object` objects (all but Opera < 10.5) */
175 var argsAreObjects = arguments.constructor == Object;
177 /** Detect if `arguments` objects [[Class]] is unresolvable (Firefox < 4, IE < 9) */
178 var noArgsClass = !isArguments(arguments);
181 * Detect lack of support for accessing string characters by index:
183 * IE < 8 can't access characters by index and IE 8 can only access
184 * characters by index on string literals.
186 var noCharByIndex = ('x'[0] + Object('x')[0]) != 'xx';
189 * Detect if a DOM node's [[Class]] is unresolvable (IE < 9)
190 * and that the JS engine won't error when attempting to coerce an object to
191 * a string without a `toString` function.
194 var noNodeClass = toString.call(document) == objectClass && !({ 'toString': 0 } + '');
197 /** Used to identify object classifications that `_.clone` supports */
198 var cloneableClasses = {};
199 cloneableClasses[funcClass] = false;
200 cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
201 cloneableClasses[boolClass] = cloneableClasses[dateClass] =
202 cloneableClasses[numberClass] = cloneableClasses[objectClass] =
203 cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
205 /** Used to lookup a built-in constructor by [[Class]] */
206 var ctorByClass = {};
207 ctorByClass[arrayClass] = Array;
208 ctorByClass[boolClass] = Boolean;
209 ctorByClass[dateClass] = Date;
210 ctorByClass[objectClass] = Object;
211 ctorByClass[numberClass] = Number;
212 ctorByClass[regexpClass] = RegExp;
213 ctorByClass[stringClass] = String;
215 /** Used to determine if values are of the language type Object */
225 /** Used to escape characters for inclusion in compiled string literals */
226 var stringEscapes = {
236 /*--------------------------------------------------------------------------*/
239 * Creates a `lodash` object, that wraps the given `value`, to enable method
242 * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
243 * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
246 * The chainable wrapper functions are:
247 * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`,
248 * `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`,
249 * `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`,
250 * `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`,
251 * `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
252 * `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`,
253 * `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`,
254 * `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip`
256 * The non-chainable wrapper functions are:
257 * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`,
258 * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`,
259 * `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, `isObject`,
260 * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, `lastIndexOf`,
261 * `mixin`, `noConflict`, `pop`, `random`, `reduce`, `reduceRight`, `result`,
262 * `shift`, `size`, `some`, `sortedIndex`, `template`, `unescape`, and `uniqueId`
264 * The wrapper functions `first` and `last` return wrapped values when `n` is
265 * passed, otherwise they return unwrapped values.
270 * @param {Mixed} value The value to wrap in a `lodash` instance.
271 * @returns {Object} Returns a `lodash` instance.
273 function lodash(value) {
274 // exit early if already wrapped, even if wrapped by a different `lodash` constructor
275 if (value && typeof value == 'object' && value.__wrapped__) {
278 // allow invoking `lodash` without the `new` operator
279 if (!(this instanceof lodash)) {
280 return new lodash(value);
282 this.__wrapped__ = value;
286 * By default, the template delimiters used by Lo-Dash are similar to those in
287 * embedded Ruby (ERB). Change the following template settings to use alternative
294 lodash.templateSettings = {
297 * Used to detect `data` property values to be HTML-escaped.
299 * @memberOf _.templateSettings
302 'escape': /<%-([\s\S]+?)%>/g,
305 * Used to detect code to be evaluated.
307 * @memberOf _.templateSettings
310 'evaluate': /<%([\s\S]+?)%>/g,
313 * Used to detect `data` property values to inject.
315 * @memberOf _.templateSettings
318 'interpolate': reInterpolate,
321 * Used to reference the data object in the template text.
323 * @memberOf _.templateSettings
329 * Used to import variables into the compiled template.
331 * @memberOf _.templateSettings
337 * A reference to the `lodash` function.
339 * @memberOf _.templateSettings.imports
346 /*--------------------------------------------------------------------------*/
349 * The template used to create iterator functions.
352 * @param {Obect} data The data object used to populate the text.
353 * @returns {String} Returns the interpolated text.
355 var iteratorTemplate = function(obj) {
357 var __p = 'var index, iterable = ' +
359 ', result = iterable;\nif (!iterable) return result;\n' +
363 __p += 'var length = iterable.length; index = -1;\nif (' +
366 if (obj.noCharByIndex) {
367 __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
369 __p += '\n while (++index < length) {\n ' +
372 } else if (obj.nonEnumArgs) {
373 __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
378 if (obj.hasEnumPrototype) {
379 __p += '\n var skipProto = typeof iterable == \'function\';\n ';
382 if (obj.isKeysFast && obj.useHas) {
383 __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n ';
384 if (obj.hasEnumPrototype) {
385 __p += 'if (!(skipProto && index == \'prototype\')) {\n ';
390 if (obj.hasEnumPrototype) {
395 __p += '\n for (index in iterable) {';
396 if (obj.hasEnumPrototype || obj.useHas) {
398 if (obj.hasEnumPrototype) {
399 __p += '!(skipProto && index == \'prototype\')';
400 } if (obj.hasEnumPrototype && obj.useHas) {
403 __p += 'hasOwnProperty.call(iterable, index)';
410 if (obj.hasEnumPrototype || obj.useHas) {
416 if (obj.hasDontEnumBug) {
417 __p += '\n\n var ctor = iterable.constructor;\n ';
418 for (var k = 0; k < 7; k++) {
419 __p += '\n index = \'' +
422 if (obj.shadowed[k] == 'constructor') {
423 __p += '!(ctor && ctor.prototype === iterable) && ';
425 __p += 'hasOwnProperty.call(iterable, index)) {\n ' +
432 if (obj.arrays || obj.nonEnumArgs) {
443 /** Reusable iterator options for `assign` and `defaults` */
444 var defaultsIteratorOptions = {
445 'args': 'object, source, guard',
447 'var args = arguments,\n' +
448 ' argsIndex = 0,\n' +
449 " argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
450 'while (++argsIndex < argsLength) {\n' +
451 ' iterable = args[argsIndex];\n' +
452 ' if (iterable && objectTypes[typeof iterable]) {',
453 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
457 /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
458 var eachIteratorOptions = {
459 'args': 'collection, callback, thisArg',
460 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg)",
461 'arrays': "typeof length == 'number'",
462 'loop': 'if (callback(iterable[index], index, collection) === false) return result'
465 /** Reusable iterator options for `forIn` and `forOwn` */
466 var forOwnIteratorOptions = {
467 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
471 /*--------------------------------------------------------------------------*/
474 * Creates a function optimized to search large arrays for a given `value`,
475 * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
478 * @param {Array} array The array to search.
479 * @param {Mixed} value The value to search for.
480 * @param {Number} [fromIndex=0] The index to search from.
481 * @param {Number} [largeSize=30] The length at which an array is considered large.
482 * @returns {Boolean} Returns `true`, if `value` is found, else `false`.
484 function cachedContains(array, fromIndex, largeSize) {
485 fromIndex || (fromIndex = 0);
487 var length = array.length,
488 isLarge = (length - fromIndex) >= (largeSize || largeArraySize);
492 index = fromIndex - 1;
494 while (++index < length) {
495 // manually coerce `value` to a string because `hasOwnProperty`, in some
496 // older versions of Firefox, coerces objects incorrectly
497 var key = array[index] + '';
498 (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]);
501 return function(value) {
503 var key = value + '';
504 return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1;
506 return indexOf(array, value, fromIndex) > -1;
511 * Used by `_.max` and `_.min` as the default `callback` when a given
512 * `collection` is a string value.
515 * @param {String} value The character to inspect.
516 * @returns {Number} Returns the code unit of given character.
518 function charAtCallback(value) {
519 return value.charCodeAt(0);
523 * Used by `sortBy` to compare transformed `collection` values, stable sorting
524 * them in ascending order.
527 * @param {Object} a The object to compare to `b`.
528 * @param {Object} b The object to compare to `a`.
529 * @returns {Number} Returns the sort order indicator of `1` or `-1`.
531 function compareAscending(a, b) {
538 // ensure a stable sort in V8 and other engines
539 // http://code.google.com/p/v8/issues/detail?id=90
541 if (a > b || typeof a == 'undefined') {
544 if (a < b || typeof b == 'undefined') {
548 return ai < bi ? -1 : 1;
552 * Creates a function that, when called, invokes `func` with the `this` binding
553 * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
557 * @param {Function|String} func The function to bind or the method name.
558 * @param {Mixed} [thisArg] The `this` binding of `func`.
559 * @param {Array} partialArgs An array of arguments to be partially applied.
560 * @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right.
561 * @returns {Function} Returns the new bound function.
563 function createBound(func, thisArg, partialArgs, rightIndicator) {
564 var isFunc = isFunction(func),
565 isPartial = !partialArgs,
570 partialArgs = thisArg;
577 // `Function#bind` spec
578 // http://es5.github.com/#x15.3.4.5
579 var args = arguments,
580 thisBinding = isPartial ? this : thisArg;
585 if (partialArgs.length) {
587 ? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
590 if (this instanceof bound) {
591 // ensure `new bound` is an instance of `bound` and `func`
592 noop.prototype = func.prototype;
593 thisBinding = new noop;
594 noop.prototype = null;
596 // mimic the constructor's `return` behavior
597 // http://es5.github.com/#x13.2.2
598 var result = func.apply(thisBinding, args);
599 return isObject(result) ? result : thisBinding;
601 return func.apply(thisBinding, args);
607 * Produces a callback bound to an optional `thisArg`. If `func` is a property
608 * name, the created callback will return the property value for a given element.
609 * If `func` is an object, the created callback will return `true` for elements
610 * that contain the equivalent object properties, otherwise it will return `false`.
613 * @param {Mixed} [func=identity] The value to convert to a callback.
614 * @param {Mixed} [thisArg] The `this` binding of the created callback.
615 * @param {Number} [argCount=3] The number of arguments the callback accepts.
616 * @returns {Function} Returns a callback function.
618 function createCallback(func, thisArg, argCount) {
622 var type = typeof func;
623 if (type != 'function') {
624 if (type != 'object') {
625 return function(object) {
629 var props = keys(func);
630 return function(object) {
631 var length = props.length,
634 if (!(result = isEqual(object[props[length]], func[props[length]], indicatorObject))) {
641 if (typeof thisArg != 'undefined') {
642 if (argCount === 1) {
643 return function(value) {
644 return func.call(thisArg, value);
647 if (argCount === 2) {
648 return function(a, b) {
649 return func.call(thisArg, a, b);
652 if (argCount === 4) {
653 return function(accumulator, value, index, object) {
654 return func.call(thisArg, accumulator, value, index, object);
657 return function(value, index, object) {
658 return func.call(thisArg, value, index, object);
665 * Creates compiled iteration functions.
668 * @param {Object} [options1, options2, ...] The compile options object(s).
669 * arrays - A string of code to determine if the iterable is an array or array-like.
670 * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
671 * args - A string of comma separated arguments the iteration function will accept.
672 * top - A string of code to execute before the iteration branches.
673 * loop - A string of code to execute in the object loop.
674 * bottom - A string of code to execute after the iteration branches.
676 * @returns {Function} Returns the compiled function.
678 function createIterator() {
680 // support properties
681 'hasDontEnumBug': hasDontEnumBug,
682 'hasEnumPrototype': hasEnumPrototype,
683 'isKeysFast': isKeysFast,
684 'nonEnumArgs': nonEnumArgs,
685 'noCharByIndex': noCharByIndex,
686 'shadowed': shadowed,
689 'arrays': 'isArray(iterable)',
696 // merge options into a template data object
697 for (var object, index = 0; object = arguments[index]; index++) {
698 for (var key in object) {
699 data[key] = object[key];
702 var args = data.args;
703 data.firstArg = /^[^,]+/.exec(args)[0];
705 // create the function factory
706 var factory = Function(
707 'createCallback, hasOwnProperty, isArguments, isArray, isString, ' +
708 'objectTypes, nativeKeys',
709 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
711 // return the compiled function
713 createCallback, hasOwnProperty, isArguments, isArray, isString,
714 objectTypes, nativeKeys
719 * A function compiled to iterate `arguments` objects, arrays, objects, and
720 * strings consistenly across environments, executing the `callback` for each
721 * element in the `collection`. The `callback` is bound to `thisArg` and invoked
722 * with three arguments; (value, index|key, collection). Callbacks may exit
723 * iteration early by explicitly returning `false`.
727 * @param {Array|Object|String} collection The collection to iterate over.
728 * @param {Function} [callback=identity] The function called per iteration.
729 * @param {Mixed} [thisArg] The `this` binding of `callback`.
730 * @returns {Array|Object|String} Returns `collection`.
732 var each = createIterator(eachIteratorOptions);
735 * Used by `template` to escape characters for inclusion in compiled
739 * @param {String} match The matched character to escape.
740 * @returns {String} Returns the escaped character.
742 function escapeStringChar(match) {
743 return '\\' + stringEscapes[match];
747 * Used by `escape` to convert characters to HTML entities.
750 * @param {String} match The matched character to escape.
751 * @returns {String} Returns the escaped character.
753 function escapeHtmlChar(match) {
754 return htmlEscapes[match];
758 * Checks if `value` is a DOM node in IE < 9.
761 * @param {Mixed} value The value to check.
762 * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
764 function isNode(value) {
765 // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
766 // methods that are `typeof` "string" and still can coerce nodes to strings
767 return typeof value.toString != 'function' && typeof (value + '') == 'string';
771 * A no-operation function.
776 // no operation performed
780 * Slices the `collection` from the `start` index up to, but not including,
783 * Note: This function is used, instead of `Array#slice`, to support node lists
784 * in IE < 9 and to ensure dense arrays are returned.
787 * @param {Array|Object|String} collection The collection to slice.
788 * @param {Number} start The start index.
789 * @param {Number} end The end index.
790 * @returns {Array} Returns the new array.
792 function slice(array, start, end) {
793 start || (start = 0);
794 if (typeof end == 'undefined') {
795 end = array ? array.length : 0;
798 length = end - start || 0,
799 result = Array(length < 0 ? 0 : length);
801 while (++index < length) {
802 result[index] = array[start + index];
808 * Used by `unescape` to convert HTML entities to characters.
811 * @param {String} match The matched character to unescape.
812 * @returns {String} Returns the unescaped character.
814 function unescapeHtmlChar(match) {
815 return htmlUnescapes[match];
818 /*--------------------------------------------------------------------------*/
821 * Checks if `value` is an `arguments` object.
826 * @param {Mixed} value The value to check.
827 * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
830 * (function() { return _.isArguments(arguments); })(1, 2, 3);
833 * _.isArguments([1, 2, 3]);
836 function isArguments(value) {
837 return toString.call(value) == argsClass;
839 // fallback for browsers that can't detect `arguments` objects by [[Class]]
841 isArguments = function(value) {
842 return value ? hasOwnProperty.call(value, 'callee') : false;
847 * Iterates over `object`'s own and inherited enumerable properties, executing
848 * the `callback` for each property. The `callback` is bound to `thisArg` and
849 * invoked with three arguments; (value, key, object). Callbacks may exit iteration
850 * early by explicitly returning `false`.
856 * @param {Object} object The object to iterate over.
857 * @param {Function} [callback=identity] The function called per iteration.
858 * @param {Mixed} [thisArg] The `this` binding of `callback`.
859 * @returns {Object} Returns `object`.
862 * function Dog(name) {
866 * Dog.prototype.bark = function() {
867 * alert('Woof, woof!');
870 * _.forIn(new Dog('Dagny'), function(value, key) {
873 * // => alerts 'name' and 'bark' (order is not guaranteed)
875 var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
880 * Iterates over an object's own enumerable properties, executing the `callback`
881 * for each property. The `callback` is bound to `thisArg` and invoked with three
882 * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
889 * @param {Object} object The object to iterate over.
890 * @param {Function} [callback=identity] The function called per iteration.
891 * @param {Mixed} [thisArg] The `this` binding of `callback`.
892 * @returns {Object} Returns `object`.
895 * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
898 * // => alerts '0', '1', and 'length' (order is not guaranteed)
900 var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
903 * Checks if `value` is an array.
908 * @param {Mixed} value The value to check.
909 * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
912 * (function() { return _.isArray(arguments); })();
915 * _.isArray([1, 2, 3]);
918 var isArray = nativeIsArray || function(value) {
919 // `instanceof` may cause a memory leak in IE 7 if `value` is a host object
920 // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
921 return (argsAreObjects && value instanceof Array) || toString.call(value) == arrayClass;
925 * Creates an array composed of the own enumerable property names of `object`.
930 * @param {Object} object The object to inspect.
931 * @returns {Array} Returns a new array of property names.
934 * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
935 * // => ['one', 'two', 'three'] (order is not guaranteed)
937 var keys = !nativeKeys ? shimKeys : function(object) {
938 if (!isObject(object)) {
941 if ((hasEnumPrototype && typeof object == 'function') ||
942 (nonEnumArgs && object.length && isArguments(object))) {
943 return shimKeys(object);
945 return nativeKeys(object);
949 * A fallback implementation of `isPlainObject` that checks if a given `value`
950 * is an object created by the `Object` constructor, assuming objects created
951 * by the `Object` constructor have no inherited enumerable properties and that
952 * there are no `Object.prototype` extensions.
955 * @param {Mixed} value The value to check.
956 * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
958 function shimIsPlainObject(value) {
959 // avoid non-objects and false positives for `arguments` objects
961 if (!(value && typeof value == 'object') || isArguments(value)) {
964 // check that the constructor is `Object` (i.e. `Object instanceof Object`)
965 var ctor = value.constructor;
966 if ((!isFunction(ctor) && (!noNodeClass || !isNode(value))) || ctor instanceof ctor) {
967 // IE < 9 iterates inherited properties before own properties. If the first
968 // iterated property is an object's own property then there are no inherited
969 // enumerable properties.
970 if (iteratesOwnLast) {
971 forIn(value, function(value, key, object) {
972 result = !hasOwnProperty.call(object, key);
975 return result === false;
977 // In most environments an object's own properties are iterated before
978 // its inherited properties. If the last iterated property is an object's
979 // own property then there are no inherited enumerable properties.
980 forIn(value, function(value, key) {
983 return result === false || hasOwnProperty.call(value, result);
989 * A fallback implementation of `Object.keys` that produces an array of the
990 * given object's own enumerable property names.
993 * @param {Object} object The object to inspect.
994 * @returns {Array} Returns a new array of property names.
996 function shimKeys(object) {
998 forOwn(object, function(value, key) {
1005 * Used to convert characters to HTML entities:
1007 * Though the `>` character is escaped for symmetry, characters like `>` and `/`
1008 * don't require escaping in HTML and have no special meaning unless they're part
1009 * of a tag or an unquoted attribute value.
1010 * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
1020 /** Used to convert HTML entities to characters */
1021 var htmlUnescapes = invert(htmlEscapes);
1023 /*--------------------------------------------------------------------------*/
1026 * Assigns own enumerable properties of source object(s) to the destination
1027 * object. Subsequent sources will overwrite propery assignments of previous
1028 * sources. If a `callback` function is passed, it will be executed to produce
1029 * the assigned values. The `callback` is bound to `thisArg` and invoked with
1030 * two arguments; (objectValue, sourceValue).
1037 * @param {Object} object The destination object.
1038 * @param {Object} [source1, source2, ...] The source objects.
1039 * @param {Function} [callback] The function to customize assigning values.
1040 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1041 * @returns {Object} Returns the destination object.
1044 * _.assign({ 'name': 'moe' }, { 'age': 40 });
1045 * // => { 'name': 'moe', 'age': 40 }
1047 * var defaults = _.partialRight(_.assign, function(a, b) {
1048 * return typeof a == 'undefined' ? b : a;
1051 * var food = { 'name': 'apple' };
1052 * defaults(food, { 'name': 'banana', 'type': 'fruit' });
1053 * // => { 'name': 'apple', 'type': 'fruit' }
1055 var assign = createIterator(defaultsIteratorOptions, {
1057 defaultsIteratorOptions.top.replace(';',
1059 "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
1060 ' var callback = createCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
1061 "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
1062 ' callback = args[--argsLength];\n' +
1065 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
1069 * Creates a clone of `value`. If `deep` is `true`, nested objects will also
1070 * be cloned, otherwise they will be assigned by reference. If a `callback`
1071 * function is passed, it will be executed to produce the cloned values. If
1072 * `callback` returns `undefined`, cloning will be handled by the method instead.
1073 * The `callback` is bound to `thisArg` and invoked with one argument; (value).
1078 * @param {Mixed} value The value to clone.
1079 * @param {Boolean} [deep=false] A flag to indicate a deep clone.
1080 * @param {Function} [callback] The function to customize cloning values.
1081 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1082 * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
1083 * @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts.
1084 * @returns {Mixed} Returns the cloned `value`.
1088 * { 'name': 'moe', 'age': 40 },
1089 * { 'name': 'larry', 'age': 50 }
1092 * var shallow = _.clone(stooges);
1093 * shallow[0] === stooges[0];
1096 * var deep = _.clone(stooges, true);
1097 * deep[0] === stooges[0];
1101 * 'clone': _.partialRight(_.clone, function(value) {
1102 * return _.isElement(value) ? value.cloneNode(false) : undefined;
1106 * var clone = _.clone(document.body);
1107 * clone.childNodes.length;
1110 function clone(value, deep, callback, thisArg, stackA, stackB) {
1113 // allows working with "Collections" methods without using their `callback`
1114 // argument, `index|key`, for this method's `callback`
1115 if (typeof deep == 'function') {
1120 if (typeof callback == 'function') {
1121 callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 1);
1122 result = callback(result);
1124 var done = typeof result != 'undefined';
1129 // inspect [[Class]]
1130 var isObj = isObject(result);
1132 var className = toString.call(result);
1133 if (!cloneableClasses[className] || (noNodeClass && isNode(result))) {
1136 var isArr = isArray(result);
1139 if (!isObj || !deep) {
1140 return isObj && !done
1141 ? (isArr ? slice(result) : assign({}, result))
1144 var ctor = ctorByClass[className];
1145 switch (className) {
1148 return done ? result : new ctor(+result);
1152 return done ? result : new ctor(result);
1155 return done ? result : ctor(result.source, reFlags.exec(result));
1157 // check for circular references and return corresponding clone
1158 stackA || (stackA = []);
1159 stackB || (stackB = []);
1161 var length = stackA.length;
1163 if (stackA[length] == value) {
1164 return stackB[length];
1167 // init cloned object
1169 result = isArr ? ctor(result.length) : {};
1171 // add array properties assigned by `RegExp#exec`
1173 if (hasOwnProperty.call(value, 'index')) {
1174 result.index = value.index;
1176 if (hasOwnProperty.call(value, 'input')) {
1177 result.input = value.input;
1181 // add the source value to the stack of traversed objects
1182 // and associate it with its clone
1184 stackB.push(result);
1186 // recursively populate clone (susceptible to call stack limits)
1187 (isArr ? forEach : forOwn)(done ? result : value, function(objValue, key) {
1188 result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
1195 * Creates a deep clone of `value`. If a `callback` function is passed, it will
1196 * be executed to produce the cloned values. If `callback` returns the value it
1197 * was passed, cloning will be handled by the method instead. The `callback` is
1198 * bound to `thisArg` and invoked with one argument; (value).
1200 * Note: This function is loosely based on the structured clone algorithm. Functions
1201 * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
1202 * objects created by constructors other than `Object` are cloned to plain `Object` objects.
1203 * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
1208 * @param {Mixed} value The value to deep clone.
1209 * @param {Function} [callback] The function to customize cloning values.
1210 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1211 * @returns {Mixed} Returns the deep cloned `value`.
1215 * { 'name': 'moe', 'age': 40 },
1216 * { 'name': 'larry', 'age': 50 }
1219 * var deep = _.cloneDeep(stooges);
1220 * deep[0] === stooges[0];
1228 * var clone = _.cloneDeep(view, function(value) {
1229 * return _.isElement(value) ? value.cloneNode(true) : value;
1232 * clone.node == view.node;
1235 function cloneDeep(value, callback, thisArg) {
1236 return clone(value, true, callback, thisArg);
1240 * Assigns own enumerable properties of source object(s) to the destination
1241 * object for all destination properties that resolve to `undefined`. Once a
1242 * property is set, additional defaults of the same property will be ignored.
1248 * @param {Object} object The destination object.
1249 * @param {Object} [source1, source2, ...] The source objects.
1250 * @param- {Object} [guard] Internally used to allow working with `_.reduce`
1251 * without using its callback's `key` and `object` arguments as sources.
1252 * @returns {Object} Returns the destination object.
1255 * var food = { 'name': 'apple' };
1256 * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
1257 * // => { 'name': 'apple', 'type': 'fruit' }
1259 var defaults = createIterator(defaultsIteratorOptions);
1262 * Creates a sorted array of all enumerable properties, own and inherited,
1263 * of `object` that have function values.
1269 * @param {Object} object The object to inspect.
1270 * @returns {Array} Returns a new array of property names that have function values.
1274 * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
1276 function functions(object) {
1278 forIn(object, function(value, key) {
1279 if (isFunction(value)) {
1283 return result.sort();
1287 * Checks if the specified object `property` exists and is a direct property,
1288 * instead of an inherited property.
1293 * @param {Object} object The object to check.
1294 * @param {String} property The property to check for.
1295 * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
1298 * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
1301 function has(object, property) {
1302 return object ? hasOwnProperty.call(object, property) : false;
1306 * Creates an object composed of the inverted keys and values of the given `object`.
1311 * @param {Object} object The object to invert.
1312 * @returns {Object} Returns the created inverted object.
1315 * _.invert({ 'first': 'moe', 'second': 'larry' });
1316 * // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed)
1318 function invert(object) {
1320 props = keys(object),
1321 length = props.length,
1324 while (++index < length) {
1325 var key = props[index];
1326 result[object[key]] = key;
1332 * Checks if `value` is a boolean value.
1337 * @param {Mixed} value The value to check.
1338 * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
1341 * _.isBoolean(null);
1344 function isBoolean(value) {
1345 return value === true || value === false || toString.call(value) == boolClass;
1349 * Checks if `value` is a date.
1354 * @param {Mixed} value The value to check.
1355 * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
1358 * _.isDate(new Date);
1361 function isDate(value) {
1362 return value instanceof Date || toString.call(value) == dateClass;
1366 * Checks if `value` is a DOM element.
1371 * @param {Mixed} value The value to check.
1372 * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
1375 * _.isElement(document.body);
1378 function isElement(value) {
1379 return value ? value.nodeType === 1 : false;
1383 * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
1384 * length of `0` and objects with no own enumerable properties are considered
1390 * @param {Array|Object|String} value The value to inspect.
1391 * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
1394 * _.isEmpty([1, 2, 3]);
1403 function isEmpty(value) {
1408 var className = toString.call(value),
1409 length = value.length;
1411 if ((className == arrayClass || className == stringClass ||
1412 className == argsClass || (noArgsClass && isArguments(value))) ||
1413 (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
1416 forOwn(value, function() {
1417 return (result = false);
1423 * Performs a deep comparison between two values to determine if they are
1424 * equivalent to each other. If `callback` is passed, it will be executed to
1425 * compare values. If `callback` returns `undefined`, comparisons will be handled
1426 * by the method instead. The `callback` is bound to `thisArg` and invoked with
1427 * two arguments; (a, b).
1432 * @param {Mixed} a The value to compare.
1433 * @param {Mixed} b The other value to compare.
1434 * @param {Function} [callback] The function to customize comparing values.
1435 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1436 * @param- {Object} [stackA=[]] Internally used track traversed `a` objects.
1437 * @param- {Object} [stackB=[]] Internally used track traversed `b` objects.
1438 * @returns {Boolean} Returns `true`, if the values are equvalent, else `false`.
1441 * var moe = { 'name': 'moe', 'age': 40 };
1442 * var copy = { 'name': 'moe', 'age': 40 };
1447 * _.isEqual(moe, copy);
1450 * var words = ['hello', 'goodbye'];
1451 * var otherWords = ['hi', 'goodbye'];
1453 * _.isEqual(words, otherWords, function(a, b) {
1454 * var reGreet = /^(?:hello|hi)$/i,
1455 * aGreet = _.isString(a) && reGreet.test(a),
1456 * bGreet = _.isString(b) && reGreet.test(b);
1458 * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
1462 function isEqual(a, b, callback, thisArg, stackA, stackB) {
1463 // used to indicate that when comparing objects, `a` has at least the properties of `b`
1464 var whereIndicator = callback === indicatorObject;
1465 if (callback && !whereIndicator) {
1466 callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 2);
1467 var result = callback(a, b);
1468 if (typeof result != 'undefined') {
1472 // exit early for identical values
1474 // treat `+0` vs. `-0` as not equal
1475 return a !== 0 || (1 / a == 1 / b);
1477 var type = typeof a,
1478 otherType = typeof b;
1480 // exit early for unlike primitive values
1482 (!a || (type != 'function' && type != 'object')) &&
1483 (!b || (otherType != 'function' && otherType != 'object'))) {
1486 // exit early for `null` and `undefined`, avoiding ES3's Function#call behavior
1487 // http://es5.github.com/#x15.3.4.4
1488 if (a == null || b == null) {
1491 // compare [[Class]] names
1492 var className = toString.call(a),
1493 otherClass = toString.call(b);
1495 if (className == argsClass) {
1496 className = objectClass;
1498 if (otherClass == argsClass) {
1499 otherClass = objectClass;
1501 if (className != otherClass) {
1504 switch (className) {
1507 // coerce dates and booleans to numbers, dates to milliseconds and booleans
1508 // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal
1512 // treat `NaN` vs. `NaN` as equal
1515 // but treat `+0` vs. `-0` as not equal
1516 : (a == 0 ? (1 / a == 1 / b) : a == +b);
1520 // coerce regexes to strings (http://es5.github.com/#x15.10.6.4)
1521 // treat string primitives and their corresponding object instances as equal
1524 var isArr = className == arrayClass;
1526 // unwrap any `lodash` wrapped values
1527 if (a.__wrapped__ || b.__wrapped__) {
1528 return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, thisArg, stackA, stackB);
1530 // exit for functions and DOM nodes
1531 if (className != objectClass || (noNodeClass && (isNode(a) || isNode(b)))) {
1534 // in older versions of Opera, `arguments` objects have `Array` constructors
1535 var ctorA = !argsAreObjects && isArguments(a) ? Object : a.constructor,
1536 ctorB = !argsAreObjects && isArguments(b) ? Object : b.constructor;
1538 // non `Object` object instances with different constructors are not equal
1539 if (ctorA != ctorB && !(
1540 isFunction(ctorA) && ctorA instanceof ctorA &&
1541 isFunction(ctorB) && ctorB instanceof ctorB
1546 // assume cyclic structures are equal
1547 // the algorithm for detecting cyclic structures is adapted from ES 5.1
1548 // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
1549 stackA || (stackA = []);
1550 stackB || (stackB = []);
1552 var length = stackA.length;
1554 if (stackA[length] == a) {
1555 return stackB[length] == b;
1561 // add `a` and `b` to the stack of traversed objects
1565 // recursively compare objects and arrays (susceptible to call stack limits)
1570 // compare lengths to determine if a deep comparison is necessary
1571 result = size == a.length;
1572 if (!result && !whereIndicator) {
1575 // deep compare the contents, ignoring non-numeric properties
1580 if (whereIndicator) {
1582 if ((result = isEqual(a[index], value, callback, thisArg, stackA, stackB))) {
1586 } else if (!(result = isEqual(a[size], value, callback, thisArg, stackA, stackB))) {
1592 // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
1593 // which, in this case, is more costly
1594 forIn(b, function(value, key, b) {
1595 if (hasOwnProperty.call(b, key)) {
1596 // count the number of properties.
1598 // deep compare each property value.
1599 return (result = hasOwnProperty.call(a, key) && isEqual(a[key], value, callback, thisArg, stackA, stackB));
1603 if (result && !whereIndicator) {
1604 // ensure both objects have the same number of properties
1605 forIn(a, function(value, key, a) {
1606 if (hasOwnProperty.call(a, key)) {
1607 // `size` will be `-1` if `a` has more properties than `b`
1608 return (result = --size > -1);
1616 * Checks if `value` is, or can be coerced to, a finite number.
1618 * Note: This is not the same as native `isFinite`, which will return true for
1619 * booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
1624 * @param {Mixed} value The value to check.
1625 * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
1640 * _.isFinite(Infinity);
1643 function isFinite(value) {
1644 return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
1648 * Checks if `value` is a function.
1653 * @param {Mixed} value The value to check.
1654 * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
1660 function isFunction(value) {
1661 return typeof value == 'function';
1663 // fallback for older versions of Chrome and Safari
1664 if (isFunction(/x/)) {
1665 isFunction = function(value) {
1666 return value instanceof Function || toString.call(value) == funcClass;
1671 * Checks if `value` is the language type of Object.
1672 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
1677 * @param {Mixed} value The value to check.
1678 * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
1684 * _.isObject([1, 2, 3]);
1690 function isObject(value) {
1691 // check if the value is the ECMAScript language type of Object
1692 // http://es5.github.com/#x8
1693 // and avoid a V8 bug
1694 // http://code.google.com/p/v8/issues/detail?id=2291
1695 return value ? objectTypes[typeof value] : false;
1699 * Checks if `value` is `NaN`.
1701 * Note: This is not the same as native `isNaN`, which will return `true` for
1702 * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
1707 * @param {Mixed} value The value to check.
1708 * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
1714 * _.isNaN(new Number(NaN));
1720 * _.isNaN(undefined);
1723 function isNaN(value) {
1724 // `NaN` as a primitive is the only value that is not equal to itself
1725 // (perform the [[Class]] check first to avoid errors with some host objects in IE)
1726 return isNumber(value) && value != +value
1730 * Checks if `value` is `null`.
1735 * @param {Mixed} value The value to check.
1736 * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`.
1742 * _.isNull(undefined);
1745 function isNull(value) {
1746 return value === null;
1750 * Checks if `value` is a number.
1755 * @param {Mixed} value The value to check.
1756 * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`.
1759 * _.isNumber(8.4 * 5);
1762 function isNumber(value) {
1763 return typeof value == 'number' || toString.call(value) == numberClass;
1767 * Checks if a given `value` is an object created by the `Object` constructor.
1772 * @param {Mixed} value The value to check.
1773 * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
1776 * function Stooge(name, age) {
1781 * _.isPlainObject(new Stooge('moe', 40));
1784 * _.isPlainObject([1, 2, 3]);
1787 * _.isPlainObject({ 'name': 'moe', 'age': 40 });
1790 var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
1791 if (!(value && typeof value == 'object')) {
1794 var valueOf = value.valueOf,
1795 objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
1798 ? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value))
1799 : shimIsPlainObject(value);
1803 * Checks if `value` is a regular expression.
1808 * @param {Mixed} value The value to check.
1809 * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`.
1812 * _.isRegExp(/moe/);
1815 function isRegExp(value) {
1816 return value instanceof RegExp || toString.call(value) == regexpClass;
1820 * Checks if `value` is a string.
1825 * @param {Mixed} value The value to check.
1826 * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`.
1829 * _.isString('moe');
1832 function isString(value) {
1833 return typeof value == 'string' || toString.call(value) == stringClass;
1837 * Checks if `value` is `undefined`.
1842 * @param {Mixed} value The value to check.
1843 * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`.
1846 * _.isUndefined(void 0);
1849 function isUndefined(value) {
1850 return typeof value == 'undefined';
1854 * Recursively merges own enumerable properties of the source object(s), that
1855 * don't resolve to `undefined`, into the destination object. Subsequent sources
1856 * will overwrite propery assignments of previous sources. If a `callback` function
1857 * is passed, it will be executed to produce the merged values of the destination
1858 * and source properties. If `callback` returns `undefined`, merging will be
1859 * handled by the method instead. The `callback` is bound to `thisArg` and
1860 * invoked with two arguments; (objectValue, sourceValue).
1865 * @param {Object} object The destination object.
1866 * @param {Object} [source1, source2, ...] The source objects.
1867 * @param {Function} [callback] The function to customize merging properties.
1868 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1869 * @param- {Object} [deepIndicator] Internally used to indicate that `stackA`
1870 * and `stackB` are arrays of traversed objects instead of source objects.
1871 * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
1872 * @param- {Array} [stackB=[]] Internally used to associate values with their
1873 * source counterparts.
1874 * @returns {Object} Returns the destination object.
1879 * { 'name': 'moe' },
1880 * { 'name': 'larry' }
1891 * _.merge(names, ages);
1892 * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] }
1895 * 'fruits': ['apple'],
1896 * 'vegetables': ['beet']
1900 * 'fruits': ['banana'],
1901 * 'vegetables': ['carrot']
1904 * _.merge(food, otherFood, function(a, b) {
1905 * return _.isArray(a) ? a.concat(b) : undefined;
1907 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
1909 function merge(object, source, deepIndicator) {
1910 var args = arguments,
1914 if (!isObject(object)) {
1917 if (deepIndicator === indicatorObject) {
1918 var callback = args[3],
1925 // allows working with `_.reduce` and `_.reduceRight` without
1926 // using their `callback` arguments, `index|key` and `collection`
1927 if (typeof deepIndicator != 'number') {
1928 length = args.length;
1930 if (length > 3 && typeof args[length - 2] == 'function') {
1931 callback = createCallback(args[--length - 1], args[length--], 2);
1932 } else if (length > 2 && typeof args[length - 1] == 'function') {
1933 callback = args[--length];
1936 while (++index < length) {
1937 (isArray(args[index]) ? forEach : forOwn)(args[index], function(source, key) {
1941 value = object[key];
1943 if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
1944 // avoid merging previously merged cyclic sources
1945 var stackLength = stackA.length;
1946 while (stackLength--) {
1947 if ((found = stackA[stackLength] == source)) {
1948 value = stackB[stackLength];
1954 ? (isArray(value) ? value : [])
1955 : (isPlainObject(value) ? value : {});
1958 result = callback(value, source);
1959 if (typeof result != 'undefined') {
1963 // add `source` and associated `value` to the stack of traversed objects
1964 stackA.push(source);
1967 // recursively merge objects and arrays (susceptible to call stack limits)
1969 value = merge(value, source, indicatorObject, callback, stackA, stackB);
1975 result = callback(value, source);
1976 if (typeof result == 'undefined') {
1980 if (typeof result != 'undefined') {
1984 object[key] = value;
1991 * Creates a shallow clone of `object` excluding the specified properties.
1992 * Property names may be specified as individual arguments or as arrays of
1993 * property names. If a `callback` function is passed, it will be executed
1994 * for each property in the `object`, omitting the properties `callback`
1995 * returns truthy for. The `callback` is bound to `thisArg` and invoked
1996 * with three arguments; (value, key, object).
2001 * @param {Object} object The source object.
2002 * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit
2003 * or the function called per iteration.
2004 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2005 * @returns {Object} Returns an object without the omitted properties.
2008 * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
2009 * // => { 'name': 'moe' }
2011 * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
2012 * return typeof value == 'number';
2014 * // => { 'name': 'moe' }
2016 function omit(object, callback, thisArg) {
2017 var isFunc = typeof callback == 'function',
2021 callback = createCallback(callback, thisArg);
2023 var props = concat.apply(arrayRef, arguments);
2025 forIn(object, function(value, key, object) {
2027 ? !callback(value, key, object)
2028 : indexOf(props, key, 1) < 0
2030 result[key] = value;
2037 * Creates a two dimensional array of the given object's key-value pairs,
2038 * i.e. `[[key1, value1], [key2, value2]]`.
2043 * @param {Object} object The object to inspect.
2044 * @returns {Array} Returns new array of key-value pairs.
2047 * _.pairs({ 'moe': 30, 'larry': 40 });
2048 * // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
2050 function pairs(object) {
2052 props = keys(object),
2053 length = props.length,
2054 result = Array(length);
2056 while (++index < length) {
2057 var key = props[index];
2058 result[index] = [key, object[key]];
2064 * Creates a shallow clone of `object` composed of the specified properties.
2065 * Property names may be specified as individual arguments or as arrays of property
2066 * names. If `callback` is passed, it will be executed for each property in the
2067 * `object`, picking the properties `callback` returns truthy for. The `callback`
2068 * is bound to `thisArg` and invoked with three arguments; (value, key, object).
2073 * @param {Object} object The source object.
2074 * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called
2075 * per iteration or properties to pick, either as individual arguments or arrays.
2076 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2077 * @returns {Object} Returns an object composed of the picked properties.
2080 * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
2081 * // => { 'name': 'moe' }
2083 * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
2084 * return key.charAt(0) != '_';
2086 * // => { 'name': 'moe' }
2088 function pick(object, callback, thisArg) {
2090 if (typeof callback != 'function') {
2092 props = concat.apply(arrayRef, arguments),
2093 length = isObject(object) ? props.length : 0;
2095 while (++index < length) {
2096 var key = props[index];
2097 if (key in object) {
2098 result[key] = object[key];
2102 callback = createCallback(callback, thisArg);
2103 forIn(object, function(value, key, object) {
2104 if (callback(value, key, object)) {
2105 result[key] = value;
2113 * Creates an array composed of the own enumerable property values of `object`.
2118 * @param {Object} object The object to inspect.
2119 * @returns {Array} Returns a new array of property values.
2122 * _.values({ 'one': 1, 'two': 2, 'three': 3 });
2125 function values(object) {
2127 props = keys(object),
2128 length = props.length,
2129 result = Array(length);
2131 while (++index < length) {
2132 result[index] = object[props[index]];
2137 /*--------------------------------------------------------------------------*/
2140 * Creates an array of elements from the specified indexes, or keys, of the
2141 * `collection`. Indexes may be specified as individual arguments or as arrays
2146 * @category Collections
2147 * @param {Array|Object|String} collection The collection to iterate over.
2148 * @param {Array|Number|String} [index1, index2, ...] The indexes of
2149 * `collection` to retrieve, either as individual arguments or arrays.
2150 * @returns {Array} Returns a new array of elements corresponding to the
2154 * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
2155 * // => ['a', 'c', 'e']
2157 * _.at(['moe', 'larry', 'curly'], 0, 2);
2158 * // => ['moe', 'curly']
2160 function at(collection) {
2162 props = concat.apply(arrayRef, slice(arguments, 1)),
2163 length = props.length,
2164 result = Array(length);
2166 if (noCharByIndex && isString(collection)) {
2167 collection = collection.split('');
2169 while(++index < length) {
2170 result[index] = collection[props[index]];
2176 * Checks if a given `target` element is present in a `collection` using strict
2177 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
2178 * as the offset from the end of the collection.
2183 * @category Collections
2184 * @param {Array|Object|String} collection The collection to iterate over.
2185 * @param {Mixed} target The value to check for.
2186 * @param {Number} [fromIndex=0] The index to search from.
2187 * @returns {Boolean} Returns `true` if the `target` element is found, else `false`.
2190 * _.contains([1, 2, 3], 1);
2193 * _.contains([1, 2, 3], 1, 2);
2196 * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
2199 * _.contains('curly', 'ur');
2202 function contains(collection, target, fromIndex) {
2204 length = collection ? collection.length : 0,
2207 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
2208 if (typeof length == 'number') {
2209 result = (isString(collection)
2210 ? collection.indexOf(target, fromIndex)
2211 : indexOf(collection, target, fromIndex)
2214 each(collection, function(value) {
2215 if (++index >= fromIndex) {
2216 return !(result = value === target);
2224 * Creates an object composed of keys returned from running each element of the
2225 * `collection` through the given `callback`. The corresponding value of each key
2226 * is the number of times the key was returned by the `callback`. The `callback`
2227 * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
2229 * If a property name is passed for `callback`, the created "_.pluck" style
2230 * callback will return the property value of the given element.
2232 * If an object is passed for `callback`, the created "_.where" style callback
2233 * will return `true` for elements that have the propeties of the given object,
2238 * @category Collections
2239 * @param {Array|Object|String} collection The collection to iterate over.
2240 * @param {Function|Object|String} [callback=identity] The function called per
2241 * iteration. If a property name or object is passed, it will be used to create
2242 * a "_.pluck" or "_.where" style callback, respectively.
2243 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2244 * @returns {Object} Returns the composed aggregate object.
2247 * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
2248 * // => { '4': 1, '6': 2 }
2250 * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
2251 * // => { '4': 1, '6': 2 }
2253 * _.countBy(['one', 'two', 'three'], 'length');
2254 * // => { '3': 2, '5': 1 }
2256 function countBy(collection, callback, thisArg) {
2258 callback = createCallback(callback, thisArg);
2260 forEach(collection, function(value, key, collection) {
2261 key = callback(value, key, collection) + '';
2262 (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
2268 * Checks if the `callback` returns a truthy value for **all** elements of a
2269 * `collection`. The `callback` is bound to `thisArg` and invoked with three
2270 * arguments; (value, index|key, collection).
2272 * If a property name is passed for `callback`, the created "_.pluck" style
2273 * callback will return the property value of the given element.
2275 * If an object is passed for `callback`, the created "_.where" style callback
2276 * will return `true` for elements that have the propeties of the given object,
2282 * @category Collections
2283 * @param {Array|Object|String} collection The collection to iterate over.
2284 * @param {Function|Object|String} [callback=identity] The function called per
2285 * iteration. If a property name or object is passed, it will be used to create
2286 * a "_.pluck" or "_.where" style callback, respectively.
2287 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2288 * @returns {Boolean} Returns `true` if all elements pass the callback check,
2292 * _.every([true, 1, null, 'yes'], Boolean);
2296 * { 'name': 'moe', 'age': 40 },
2297 * { 'name': 'larry', 'age': 50 }
2300 * // using "_.pluck" callback shorthand
2301 * _.every(stooges, 'age');
2304 * // using "_.where" callback shorthand
2305 * _.every(stooges, { 'age': 50 });
2308 function every(collection, callback, thisArg) {
2310 callback = createCallback(callback, thisArg);
2312 if (isArray(collection)) {
2314 length = collection.length;
2316 while (++index < length) {
2317 if (!(result = !!callback(collection[index], index, collection))) {
2322 each(collection, function(value, index, collection) {
2323 return (result = !!callback(value, index, collection));
2330 * Examines each element in a `collection`, returning an array of all elements
2331 * the `callback` returns truthy for. The `callback` is bound to `thisArg` and
2332 * invoked with three arguments; (value, index|key, collection).
2334 * If a property name is passed for `callback`, the created "_.pluck" style
2335 * callback will return the property value of the given element.
2337 * If an object is passed for `callback`, the created "_.where" style callback
2338 * will return `true` for elements that have the propeties of the given object,
2344 * @category Collections
2345 * @param {Array|Object|String} collection The collection to iterate over.
2346 * @param {Function|Object|String} [callback=identity] The function called per
2347 * iteration. If a property name or object is passed, it will be used to create
2348 * a "_.pluck" or "_.where" style callback, respectively.
2349 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2350 * @returns {Array} Returns a new array of elements that passed the callback check.
2353 * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2357 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2358 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
2361 * // using "_.pluck" callback shorthand
2362 * _.filter(food, 'organic');
2363 * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
2365 * // using "_.where" callback shorthand
2366 * _.filter(food, { 'type': 'fruit' });
2367 * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
2369 function filter(collection, callback, thisArg) {
2371 callback = createCallback(callback, thisArg);
2373 if (isArray(collection)) {
2375 length = collection.length;
2377 while (++index < length) {
2378 var value = collection[index];
2379 if (callback(value, index, collection)) {
2384 each(collection, function(value, index, collection) {
2385 if (callback(value, index, collection)) {
2394 * Examines each element in a `collection`, returning the first that the `callback`
2395 * returns truthy for. The `callback` is bound to `thisArg` and invoked with three
2396 * arguments; (value, index|key, collection).
2398 * If a property name is passed for `callback`, the created "_.pluck" style
2399 * callback will return the property value of the given element.
2401 * If an object is passed for `callback`, the created "_.where" style callback
2402 * will return `true` for elements that have the propeties of the given object,
2408 * @category Collections
2409 * @param {Array|Object|String} collection The collection to iterate over.
2410 * @param {Function|Object|String} [callback=identity] The function called per
2411 * iteration. If a property name or object is passed, it will be used to create
2412 * a "_.pluck" or "_.where" style callback, respectively.
2413 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2414 * @returns {Mixed} Returns the element that passed the callback check,
2418 * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2422 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2423 * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
2424 * { 'name': 'beet', 'organic': false, 'type': 'vegetable' },
2425 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
2428 * // using "_.where" callback shorthand
2429 * var veggie = _.find(food, { 'type': 'vegetable' });
2430 * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
2432 * // using "_.pluck" callback shorthand
2433 * var healthy = _.find(food, 'organic');
2434 * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
2436 function find(collection, callback, thisArg) {
2438 callback = createCallback(callback, thisArg);
2440 forEach(collection, function(value, index, collection) {
2441 if (callback(value, index, collection)) {
2450 * Iterates over a `collection`, executing the `callback` for each element in
2451 * the `collection`. The `callback` is bound to `thisArg` and invoked with three
2452 * arguments; (value, index|key, collection). Callbacks may exit iteration early
2453 * by explicitly returning `false`.
2458 * @category Collections
2459 * @param {Array|Object|String} collection The collection to iterate over.
2460 * @param {Function} [callback=identity] The function called per iteration.
2461 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2462 * @returns {Array|Object|String} Returns `collection`.
2465 * _([1, 2, 3]).forEach(alert).join(',');
2466 * // => alerts each number and returns '1,2,3'
2468 * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert);
2469 * // => alerts each number value (order is not guaranteed)
2471 function forEach(collection, callback, thisArg) {
2472 if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
2474 length = collection.length;
2476 while (++index < length) {
2477 if (callback(collection[index], index, collection) === false) {
2482 each(collection, callback, thisArg);
2488 * Creates an object composed of keys returned from running each element of the
2489 * `collection` through the `callback`. The corresponding value of each key is
2490 * an array of elements passed to `callback` that returned the key. The `callback`
2491 * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
2493 * If a property name is passed for `callback`, the created "_.pluck" style
2494 * callback will return the property value of the given element.
2496 * If an object is passed for `callback`, the created "_.where" style callback
2497 * will return `true` for elements that have the propeties of the given object,
2502 * @category Collections
2503 * @param {Array|Object|String} collection The collection to iterate over.
2504 * @param {Function|Object|String} [callback=identity] The function called per
2505 * iteration. If a property name or object is passed, it will be used to create
2506 * a "_.pluck" or "_.where" style callback, respectively.
2507 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2508 * @returns {Object} Returns the composed aggregate object.
2511 * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
2512 * // => { '4': [4.2], '6': [6.1, 6.4] }
2514 * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
2515 * // => { '4': [4.2], '6': [6.1, 6.4] }
2517 * // using "_.pluck" callback shorthand
2518 * _.groupBy(['one', 'two', 'three'], 'length');
2519 * // => { '3': ['one', 'two'], '5': ['three'] }
2521 function groupBy(collection, callback, thisArg) {
2523 callback = createCallback(callback, thisArg);
2525 forEach(collection, function(value, key, collection) {
2526 key = callback(value, key, collection) + '';
2527 (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
2533 * Invokes the method named by `methodName` on each element in the `collection`,
2534 * returning an array of the results of each invoked method. Additional arguments
2535 * will be passed to each invoked method. If `methodName` is a function, it will
2536 * be invoked for, and `this` bound to, each element in the `collection`.
2540 * @category Collections
2541 * @param {Array|Object|String} collection The collection to iterate over.
2542 * @param {Function|String} methodName The name of the method to invoke or
2543 * the function invoked per iteration.
2544 * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
2545 * @returns {Array} Returns a new array of the results of each invoked method.
2548 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
2549 * // => [[1, 5, 7], [1, 2, 3]]
2551 * _.invoke([123, 456], String.prototype.split, '');
2552 * // => [['1', '2', '3'], ['4', '5', '6']]
2554 function invoke(collection, methodName) {
2555 var args = slice(arguments, 2),
2557 isFunc = typeof methodName == 'function',
2558 length = collection ? collection.length : 0,
2559 result = Array(typeof length == 'number' ? length : 0);
2561 forEach(collection, function(value) {
2562 result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
2568 * Creates an array of values by running each element in the `collection`
2569 * through the `callback`. The `callback` is bound to `thisArg` and invoked with
2570 * three arguments; (value, index|key, collection).
2572 * If a property name is passed for `callback`, the created "_.pluck" style
2573 * callback will return the property value of the given element.
2575 * If an object is passed for `callback`, the created "_.where" style callback
2576 * will return `true` for elements that have the propeties of the given object,
2582 * @category Collections
2583 * @param {Array|Object|String} collection The collection to iterate over.
2584 * @param {Function|Object|String} [callback=identity] The function called per
2585 * iteration. If a property name or object is passed, it will be used to create
2586 * a "_.pluck" or "_.where" style callback, respectively.
2587 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2588 * @returns {Array} Returns a new array of the results of each `callback` execution.
2591 * _.map([1, 2, 3], function(num) { return num * 3; });
2594 * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
2595 * // => [3, 6, 9] (order is not guaranteed)
2598 * { 'name': 'moe', 'age': 40 },
2599 * { 'name': 'larry', 'age': 50 }
2602 * // using "_.pluck" callback shorthand
2603 * _.map(stooges, 'name');
2604 * // => ['moe', 'larry']
2606 function map(collection, callback, thisArg) {
2608 length = collection ? collection.length : 0,
2609 result = Array(typeof length == 'number' ? length : 0);
2611 callback = createCallback(callback, thisArg);
2612 if (isArray(collection)) {
2613 while (++index < length) {
2614 result[index] = callback(collection[index], index, collection);
2617 each(collection, function(value, key, collection) {
2618 result[++index] = callback(value, key, collection);
2625 * Retrieves the maximum value of an `array`. If `callback` is passed,
2626 * it will be executed for each value in the `array` to generate the
2627 * criterion by which the value is ranked. The `callback` is bound to
2628 * `thisArg` and invoked with three arguments; (value, index, collection).
2630 * If a property name is passed for `callback`, the created "_.pluck" style
2631 * callback will return the property value of the given element.
2633 * If an object is passed for `callback`, the created "_.where" style callback
2634 * will return `true` for elements that have the propeties of the given object,
2639 * @category Collections
2640 * @param {Array|Object|String} collection The collection to iterate over.
2641 * @param {Function|Object|String} [callback=identity] The function called per
2642 * iteration. If a property name or object is passed, it will be used to create
2643 * a "_.pluck" or "_.where" style callback, respectively.
2644 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2645 * @returns {Mixed} Returns the maximum value.
2648 * _.max([4, 2, 8, 6]);
2652 * { 'name': 'moe', 'age': 40 },
2653 * { 'name': 'larry', 'age': 50 }
2656 * _.max(stooges, function(stooge) { return stooge.age; });
2657 * // => { 'name': 'larry', 'age': 50 };
2659 * // using "_.pluck" callback shorthand
2660 * _.max(stooges, 'age');
2661 * // => { 'name': 'larry', 'age': 50 };
2663 function max(collection, callback, thisArg) {
2664 var computed = -Infinity,
2667 if (!callback && isArray(collection)) {
2669 length = collection.length;
2671 while (++index < length) {
2672 var value = collection[index];
2673 if (value > result) {
2678 callback = !callback && isString(collection)
2680 : createCallback(callback, thisArg);
2682 each(collection, function(value, index, collection) {
2683 var current = callback(value, index, collection);
2684 if (current > computed) {
2694 * Retrieves the minimum value of an `array`. If `callback` is passed,
2695 * it will be executed for each value in the `array` to generate the
2696 * criterion by which the value is ranked. The `callback` is bound to `thisArg`
2697 * and invoked with three arguments; (value, index, collection).
2699 * If a property name is passed for `callback`, the created "_.pluck" style
2700 * callback will return the property value of the given element.
2702 * If an object is passed for `callback`, the created "_.where" style callback
2703 * will return `true` for elements that have the propeties of the given object,
2708 * @category Collections
2709 * @param {Array|Object|String} collection The collection to iterate over.
2710 * @param {Function|Object|String} [callback=identity] The function called per
2711 * iteration. If a property name or object is passed, it will be used to create
2712 * a "_.pluck" or "_.where" style callback, respectively.
2713 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2714 * @returns {Mixed} Returns the minimum value.
2717 * _.min([4, 2, 8, 6]);
2721 * { 'name': 'moe', 'age': 40 },
2722 * { 'name': 'larry', 'age': 50 }
2725 * _.min(stooges, function(stooge) { return stooge.age; });
2726 * // => { 'name': 'moe', 'age': 40 };
2728 * // using "_.pluck" callback shorthand
2729 * _.min(stooges, 'age');
2730 * // => { 'name': 'moe', 'age': 40 };
2732 function min(collection, callback, thisArg) {
2733 var computed = Infinity,
2736 if (!callback && isArray(collection)) {
2738 length = collection.length;
2740 while (++index < length) {
2741 var value = collection[index];
2742 if (value < result) {
2747 callback = !callback && isString(collection)
2749 : createCallback(callback, thisArg);
2751 each(collection, function(value, index, collection) {
2752 var current = callback(value, index, collection);
2753 if (current < computed) {
2763 * Retrieves the value of a specified property from all elements in the `collection`.
2768 * @category Collections
2769 * @param {Array|Object|String} collection The collection to iterate over.
2770 * @param {String} property The property to pluck.
2771 * @returns {Array} Returns a new array of property values.
2775 * { 'name': 'moe', 'age': 40 },
2776 * { 'name': 'larry', 'age': 50 }
2779 * _.pluck(stooges, 'name');
2780 * // => ['moe', 'larry']
2785 * Reduces a `collection` to a value that is the accumulated result of running
2786 * each element in the `collection` through the `callback`, where each successive
2787 * `callback` execution consumes the return value of the previous execution.
2788 * If `accumulator` is not passed, the first element of the `collection` will be
2789 * used as the initial `accumulator` value. The `callback` is bound to `thisArg`
2790 * and invoked with four arguments; (accumulator, value, index|key, collection).
2794 * @alias foldl, inject
2795 * @category Collections
2796 * @param {Array|Object|String} collection The collection to iterate over.
2797 * @param {Function} [callback=identity] The function called per iteration.
2798 * @param {Mixed} [accumulator] Initial value of the accumulator.
2799 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2800 * @returns {Mixed} Returns the accumulated value.
2803 * var sum = _.reduce([1, 2, 3], function(sum, num) {
2808 * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
2809 * result[key] = num * 3;
2812 * // => { 'a': 3, 'b': 6, 'c': 9 }
2814 function reduce(collection, callback, accumulator, thisArg) {
2815 var noaccum = arguments.length < 3;
2816 callback = createCallback(callback, thisArg, 4);
2818 if (isArray(collection)) {
2820 length = collection.length;
2823 accumulator = collection[++index];
2825 while (++index < length) {
2826 accumulator = callback(accumulator, collection[index], index, collection);
2829 each(collection, function(value, index, collection) {
2830 accumulator = noaccum
2831 ? (noaccum = false, value)
2832 : callback(accumulator, value, index, collection)
2839 * This method is similar to `_.reduce`, except that it iterates over a
2840 * `collection` from right to left.
2845 * @category Collections
2846 * @param {Array|Object|String} collection The collection to iterate over.
2847 * @param {Function} [callback=identity] The function called per iteration.
2848 * @param {Mixed} [accumulator] Initial value of the accumulator.
2849 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2850 * @returns {Mixed} Returns the accumulated value.
2853 * var list = [[0, 1], [2, 3], [4, 5]];
2854 * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
2855 * // => [4, 5, 2, 3, 0, 1]
2857 function reduceRight(collection, callback, accumulator, thisArg) {
2858 var iterable = collection,
2859 length = collection ? collection.length : 0,
2860 noaccum = arguments.length < 3;
2862 if (typeof length != 'number') {
2863 var props = keys(collection);
2864 length = props.length;
2865 } else if (noCharByIndex && isString(collection)) {
2866 iterable = collection.split('');
2868 callback = createCallback(callback, thisArg, 4);
2869 forEach(collection, function(value, index, collection) {
2870 index = props ? props[--length] : --length;
2871 accumulator = noaccum
2872 ? (noaccum = false, iterable[index])
2873 : callback(accumulator, iterable[index], index, collection);
2879 * The opposite of `_.filter`, this method returns the elements of a
2880 * `collection` that `callback` does **not** return truthy for.
2882 * If a property name is passed for `callback`, the created "_.pluck" style
2883 * callback will return the property value of the given element.
2885 * If an object is passed for `callback`, the created "_.where" style callback
2886 * will return `true` for elements that have the propeties of the given object,
2891 * @category Collections
2892 * @param {Array|Object|String} collection The collection to iterate over.
2893 * @param {Function|Object|String} [callback=identity] The function called per
2894 * iteration. If a property name or object is passed, it will be used to create
2895 * a "_.pluck" or "_.where" style callback, respectively.
2896 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2897 * @returns {Array} Returns a new array of elements that did **not** pass the
2901 * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2905 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2906 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
2909 * // using "_.pluck" callback shorthand
2910 * _.reject(food, 'organic');
2911 * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
2913 * // using "_.where" callback shorthand
2914 * _.reject(food, { 'type': 'fruit' });
2915 * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
2917 function reject(collection, callback, thisArg) {
2918 callback = createCallback(callback, thisArg);
2919 return filter(collection, function(value, index, collection) {
2920 return !callback(value, index, collection);
2925 * Creates an array of shuffled `array` values, using a version of the
2926 * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
2930 * @category Collections
2931 * @param {Array|Object|String} collection The collection to shuffle.
2932 * @returns {Array} Returns a new shuffled collection.
2935 * _.shuffle([1, 2, 3, 4, 5, 6]);
2936 * // => [4, 1, 6, 3, 5, 2]
2938 function shuffle(collection) {
2940 length = collection ? collection.length : 0,
2941 result = Array(typeof length == 'number' ? length : 0);
2943 forEach(collection, function(value) {
2944 var rand = floor(nativeRandom() * (++index + 1));
2945 result[index] = result[rand];
2946 result[rand] = value;
2952 * Gets the size of the `collection` by returning `collection.length` for arrays
2953 * and array-like objects or the number of own enumerable properties for objects.
2957 * @category Collections
2958 * @param {Array|Object|String} collection The collection to inspect.
2959 * @returns {Number} Returns `collection.length` or number of own enumerable properties.
2965 * _.size({ 'one': 1, 'two': 2, 'three': 3 });
2971 function size(collection) {
2972 var length = collection ? collection.length : 0;
2973 return typeof length == 'number' ? length : keys(collection).length;
2977 * Checks if the `callback` returns a truthy value for **any** element of a
2978 * `collection`. The function returns as soon as it finds passing value, and
2979 * does not iterate over the entire `collection`. The `callback` is bound to
2980 * `thisArg` and invoked with three arguments; (value, index|key, collection).
2982 * If a property name is passed for `callback`, the created "_.pluck" style
2983 * callback will return the property value of the given element.
2985 * If an object is passed for `callback`, the created "_.where" style callback
2986 * will return `true` for elements that have the propeties of the given object,
2992 * @category Collections
2993 * @param {Array|Object|String} collection The collection to iterate over.
2994 * @param {Function|Object|String} [callback=identity] The function called per
2995 * iteration. If a property name or object is passed, it will be used to create
2996 * a "_.pluck" or "_.where" style callback, respectively.
2997 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2998 * @returns {Boolean} Returns `true` if any element passes the callback check,
3002 * _.some([null, 0, 'yes', false], Boolean);
3006 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
3007 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
3010 * // using "_.pluck" callback shorthand
3011 * _.some(food, 'organic');
3014 * // using "_.where" callback shorthand
3015 * _.some(food, { 'type': 'meat' });
3018 function some(collection, callback, thisArg) {
3020 callback = createCallback(callback, thisArg);
3022 if (isArray(collection)) {
3024 length = collection.length;
3026 while (++index < length) {
3027 if ((result = callback(collection[index], index, collection))) {
3032 each(collection, function(value, index, collection) {
3033 return !(result = callback(value, index, collection));
3040 * Creates an array of elements, sorted in ascending order by the results of
3041 * running each element in the `collection` through the `callback`. This method
3042 * performs a stable sort, that is, it will preserve the original sort order of
3043 * equal elements. The `callback` is bound to `thisArg` and invoked with three
3044 * arguments; (value, index|key, collection).
3046 * If a property name is passed for `callback`, the created "_.pluck" style
3047 * callback will return the property value of the given element.
3049 * If an object is passed for `callback`, the created "_.where" style callback
3050 * will return `true` for elements that have the propeties of the given object,
3055 * @category Collections
3056 * @param {Array|Object|String} collection The collection to iterate over.
3057 * @param {Function|Object|String} [callback=identity] The function called per
3058 * iteration. If a property name or object is passed, it will be used to create
3059 * a "_.pluck" or "_.where" style callback, respectively.
3060 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3061 * @returns {Array} Returns a new array of sorted elements.
3064 * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
3067 * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
3070 * // using "_.pluck" callback shorthand
3071 * _.sortBy(['banana', 'strawberry', 'apple'], 'length');
3072 * // => ['apple', 'banana', 'strawberry']
3074 function sortBy(collection, callback, thisArg) {
3076 length = collection ? collection.length : 0,
3077 result = Array(typeof length == 'number' ? length : 0);
3079 callback = createCallback(callback, thisArg);
3080 forEach(collection, function(value, key, collection) {
3082 'criteria': callback(value, key, collection),
3088 length = result.length;
3089 result.sort(compareAscending);
3091 result[length] = result[length].value;
3097 * Converts the `collection` to an array.
3101 * @category Collections
3102 * @param {Array|Object|String} collection The collection to convert.
3103 * @returns {Array} Returns the new converted array.
3106 * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
3109 function toArray(collection) {
3110 if (collection && typeof collection.length == 'number') {
3111 return noCharByIndex && isString(collection)
3112 ? collection.split('')
3113 : slice(collection);
3115 return values(collection);
3119 * Examines each element in a `collection`, returning an array of all elements
3120 * that have the given `properties`. When checking `properties`, this method
3121 * performs a deep comparison between values to determine if they are equivalent
3127 * @category Collections
3128 * @param {Array|Object|String} collection The collection to iterate over.
3129 * @param {Object} properties The object of property values to filter by.
3130 * @returns {Array} Returns a new array of elements that have the given `properties`.
3134 * { 'name': 'moe', 'age': 40 },
3135 * { 'name': 'larry', 'age': 50 }
3138 * _.where(stooges, { 'age': 40 });
3139 * // => [{ 'name': 'moe', 'age': 40 }]
3143 /*--------------------------------------------------------------------------*/
3146 * Creates an array with all falsey values of `array` removed. The values
3147 * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey.
3152 * @param {Array} array The array to compact.
3153 * @returns {Array} Returns a new filtered array.
3156 * _.compact([0, 1, false, 2, '', 3]);
3159 function compact(array) {
3161 length = array ? array.length : 0,
3164 while (++index < length) {
3165 var value = array[index];
3174 * Creates an array of `array` elements not present in the other arrays
3175 * using strict equality for comparisons, i.e. `===`.
3180 * @param {Array} array The array to process.
3181 * @param {Array} [array1, array2, ...] Arrays to check.
3182 * @returns {Array} Returns a new array of `array` elements not present in the
3186 * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
3189 function difference(array) {
3191 length = array ? array.length : 0,
3192 flattened = concat.apply(arrayRef, arguments),
3193 contains = cachedContains(flattened, length),
3196 while (++index < length) {
3197 var value = array[index];
3198 if (!contains(value)) {
3206 * Gets the first element of the `array`. If a number `n` is passed, the first
3207 * `n` elements of the `array` are returned. If a `callback` function is passed,
3208 * the first elements the `callback` returns truthy for are returned. The `callback`
3209 * is bound to `thisArg` and invoked with three arguments; (value, index, array).
3211 * If a property name is passed for `callback`, the created "_.pluck" style
3212 * callback will return the property value of the given element.
3214 * If an object is passed for `callback`, the created "_.where" style callback
3215 * will return `true` for elements that have the propeties of the given object,
3222 * @param {Array} array The array to query.
3223 * @param {Function|Object|Number|String} [callback|n] The function called
3224 * per element or the number of elements to return. If a property name or
3225 * object is passed, it will be used to create a "_.pluck" or "_.where"
3226 * style callback, respectively.
3227 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3228 * @returns {Mixed} Returns the first element(s) of `array`.
3231 * _.first([1, 2, 3]);
3234 * _.first([1, 2, 3], 2);
3237 * _.first([1, 2, 3], function(num) {
3243 * { 'name': 'banana', 'organic': true },
3244 * { 'name': 'beet', 'organic': false },
3247 * // using "_.pluck" callback shorthand
3248 * _.first(food, 'organic');
3249 * // => [{ 'name': 'banana', 'organic': true }]
3252 * { 'name': 'apple', 'type': 'fruit' },
3253 * { 'name': 'banana', 'type': 'fruit' },
3254 * { 'name': 'beet', 'type': 'vegetable' }
3257 * // using "_.where" callback shorthand
3258 * _.first(food, { 'type': 'fruit' });
3259 * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
3261 function first(array, callback, thisArg) {
3264 length = array.length;
3266 if (typeof callback != 'number' && callback != null) {
3268 callback = createCallback(callback, thisArg);
3269 while (++index < length && callback(array[index], index, array)) {
3274 if (n == null || thisArg) {
3278 return slice(array, 0, nativeMin(nativeMax(0, n), length));
3283 * Flattens a nested array (the nesting can be to any depth). If `shallow` is
3284 * truthy, `array` will only be flattened a single level.
3289 * @param {Array} array The array to compact.
3290 * @param {Boolean} shallow A flag to indicate only flattening a single level.
3291 * @returns {Array} Returns a new flattened array.
3294 * _.flatten([1, [2], [3, [[4]]]]);
3295 * // => [1, 2, 3, 4];
3297 * _.flatten([1, [2], [3, [[4]]]], true);
3298 * // => [1, 2, 3, [[4]]];
3300 function flatten(array, shallow) {
3302 length = array ? array.length : 0,
3305 while (++index < length) {
3306 var value = array[index];
3308 // recursively flatten arrays (susceptible to call stack limits)
3309 if (isArray(value)) {
3310 push.apply(result, shallow ? value : flatten(value));
3319 * Gets the index at which the first occurrence of `value` is found using
3320 * strict equality for comparisons, i.e. `===`. If the `array` is already
3321 * sorted, passing `true` for `fromIndex` will run a faster binary search.
3326 * @param {Array} array The array to search.
3327 * @param {Mixed} value The value to search for.
3328 * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to
3329 * perform a binary search on a sorted `array`.
3330 * @returns {Number} Returns the index of the matched value or `-1`.
3333 * _.indexOf([1, 2, 3, 1, 2, 3], 2);
3336 * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
3339 * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
3342 function indexOf(array, value, fromIndex) {
3344 length = array ? array.length : 0;
3346 if (typeof fromIndex == 'number') {
3347 index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1;
3348 } else if (fromIndex) {
3349 index = sortedIndex(array, value);
3350 return array[index] === value ? index : -1;
3352 while (++index < length) {
3353 if (array[index] === value) {
3361 * Gets all but the last element of `array`. If a number `n` is passed, the
3362 * last `n` elements are excluded from the result. If a `callback` function
3363 * is passed, the last elements the `callback` returns truthy for are excluded
3364 * from the result. The `callback` is bound to `thisArg` and invoked with three
3365 * arguments; (value, index, array).
3367 * If a property name is passed for `callback`, the created "_.pluck" style
3368 * callback will return the property value of the given element.
3370 * If an object is passed for `callback`, the created "_.where" style callback
3371 * will return `true` for elements that have the propeties of the given object,
3377 * @param {Array} array The array to query.
3378 * @param {Function|Object|Number|String} [callback|n=1] The function called
3379 * per element or the number of elements to exclude. If a property name or
3380 * object is passed, it will be used to create a "_.pluck" or "_.where"
3381 * style callback, respectively.
3382 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3383 * @returns {Array} Returns a slice of `array`.
3386 * _.initial([1, 2, 3]);
3389 * _.initial([1, 2, 3], 2);
3392 * _.initial([1, 2, 3], function(num) {
3398 * { 'name': 'beet', 'organic': false },
3399 * { 'name': 'carrot', 'organic': true }
3402 * // using "_.pluck" callback shorthand
3403 * _.initial(food, 'organic');
3404 * // => [{ 'name': 'beet', 'organic': false }]
3407 * { 'name': 'banana', 'type': 'fruit' },
3408 * { 'name': 'beet', 'type': 'vegetable' },
3409 * { 'name': 'carrot', 'type': 'vegetable' }
3412 * // using "_.where" callback shorthand
3413 * _.initial(food, { 'type': 'vegetable' });
3414 * // => [{ 'name': 'banana', 'type': 'fruit' }]
3416 function initial(array, callback, thisArg) {
3421 length = array.length;
3423 if (typeof callback != 'number' && callback != null) {
3425 callback = createCallback(callback, thisArg);
3426 while (index-- && callback(array[index], index, array)) {
3430 n = (callback == null || thisArg) ? 1 : callback || n;
3432 return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
3436 * Computes the intersection of all the passed-in arrays using strict equality
3437 * for comparisons, i.e. `===`.
3442 * @param {Array} [array1, array2, ...] Arrays to process.
3443 * @returns {Array} Returns a new array of unique elements that are present
3444 * in **all** of the arrays.
3447 * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
3450 function intersection(array) {
3451 var args = arguments,
3452 argsLength = args.length,
3453 cache = { '0': {} },
3455 length = array ? array.length : 0,
3456 isLarge = length >= 100,
3461 while (++index < length) {
3462 var value = array[index];
3464 var key = value + '';
3465 var inited = hasOwnProperty.call(cache[0], key)
3466 ? !(seen = cache[0][key])
3467 : (seen = cache[0][key] = []);
3469 if (inited || indexOf(seen, value) < 0) {
3473 var argsIndex = argsLength;
3474 while (--argsIndex) {
3475 if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(args[argsIndex], 0, 100)))(value)) {
3486 * Gets the last element of the `array`. If a number `n` is passed, the last
3487 * `n` elements of the `array` are returned. If a `callback` function is passed,
3488 * the last elements the `callback` returns truthy for are returned. The `callback`
3489 * is bound to `thisArg` and invoked with three arguments; (value, index, array).
3492 * If a property name is passed for `callback`, the created "_.pluck" style
3493 * callback will return the property value of the given element.
3495 * If an object is passed for `callback`, the created "_.where" style callback
3496 * will return `true` for elements that have the propeties of the given object,
3502 * @param {Array} array The array to query.
3503 * @param {Function|Object|Number|String} [callback|n] The function called
3504 * per element or the number of elements to return. If a property name or
3505 * object is passed, it will be used to create a "_.pluck" or "_.where"
3506 * style callback, respectively.
3507 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3508 * @returns {Mixed} Returns the last element(s) of `array`.
3511 * _.last([1, 2, 3]);
3514 * _.last([1, 2, 3], 2);
3517 * _.last([1, 2, 3], function(num) {
3523 * { 'name': 'beet', 'organic': false },
3524 * { 'name': 'carrot', 'organic': true }
3527 * // using "_.pluck" callback shorthand
3528 * _.last(food, 'organic');
3529 * // => [{ 'name': 'carrot', 'organic': true }]
3532 * { 'name': 'banana', 'type': 'fruit' },
3533 * { 'name': 'beet', 'type': 'vegetable' },
3534 * { 'name': 'carrot', 'type': 'vegetable' }
3537 * // using "_.where" callback shorthand
3538 * _.last(food, { 'type': 'vegetable' });
3539 * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
3541 function last(array, callback, thisArg) {
3544 length = array.length;
3546 if (typeof callback != 'number' && callback != null) {
3548 callback = createCallback(callback, thisArg);
3549 while (index-- && callback(array[index], index, array)) {
3554 if (n == null || thisArg) {
3555 return array[length - 1];
3558 return slice(array, nativeMax(0, length - n));
3563 * Gets the index at which the last occurrence of `value` is found using strict
3564 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
3565 * as the offset from the end of the collection.
3570 * @param {Array} array The array to search.
3571 * @param {Mixed} value The value to search for.
3572 * @param {Number} [fromIndex=array.length-1] The index to search from.
3573 * @returns {Number} Returns the index of the matched value or `-1`.
3576 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
3579 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
3582 function lastIndexOf(array, value, fromIndex) {
3583 var index = array ? array.length : 0;
3584 if (typeof fromIndex == 'number') {
3585 index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
3588 if (array[index] === value) {
3596 * Creates an object composed from arrays of `keys` and `values`. Pass either
3597 * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or
3598 * two arrays, one of `keys` and one of corresponding `values`.
3603 * @param {Array} keys The array of keys.
3604 * @param {Array} [values=[]] The array of values.
3605 * @returns {Object} Returns an object composed of the given keys and
3606 * corresponding values.
3609 * _.object(['moe', 'larry'], [30, 40]);
3610 * // => { 'moe': 30, 'larry': 40 }
3612 function object(keys, values) {
3614 length = keys ? keys.length : 0,
3617 while (++index < length) {
3618 var key = keys[index];
3620 result[key] = values[index];
3622 result[key[0]] = key[1];
3629 * Creates an array of numbers (positive and/or negative) progressing from
3630 * `start` up to but not including `end`.
3635 * @param {Number} [start=0] The start of the range.
3636 * @param {Number} end The end of the range.
3637 * @param {Number} [step=1] The value to increment or descrement by.
3638 * @returns {Array} Returns a new range array.
3642 * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3645 * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
3647 * _.range(0, 30, 5);
3648 * // => [0, 5, 10, 15, 20, 25]
3650 * _.range(0, -10, -1);
3651 * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
3656 function range(start, end, step) {
3657 start = +start || 0;
3664 // use `Array(length)` so V8 will avoid the slower "dictionary" mode
3665 // http://youtu.be/XAqIpGU8ZZk#t=17m25s
3667 length = nativeMax(0, ceil((end - start) / step)),
3668 result = Array(length);
3670 while (++index < length) {
3671 result[index] = start;
3678 * The opposite of `_.initial`, this method gets all but the first value of `array`.
3679 * If a number `n` is passed, the first `n` values are excluded from the result.
3680 * If a `callback` function is passed, the first elements the `callback` returns
3681 * truthy for are excluded from the result. The `callback` is bound to `thisArg`
3682 * and invoked with three arguments; (value, index, array).
3684 * If a property name is passed for `callback`, the created "_.pluck" style
3685 * callback will return the property value of the given element.
3687 * If an object is passed for `callback`, the created "_.where" style callback
3688 * will return `true` for elements that have the propeties of the given object,
3695 * @param {Array} array The array to query.
3696 * @param {Function|Object|Number|String} [callback|n=1] The function called
3697 * per element or the number of elements to exclude. If a property name or
3698 * object is passed, it will be used to create a "_.pluck" or "_.where"
3699 * style callback, respectively.
3700 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3701 * @returns {Array} Returns a slice of `array`.
3704 * _.rest([1, 2, 3]);
3707 * _.rest([1, 2, 3], 2);
3710 * _.rest([1, 2, 3], function(num) {
3716 * { 'name': 'banana', 'organic': true },
3717 * { 'name': 'beet', 'organic': false },
3720 * // using "_.pluck" callback shorthand
3721 * _.rest(food, 'organic');
3722 * // => [{ 'name': 'beet', 'organic': false }]
3725 * { 'name': 'apple', 'type': 'fruit' },
3726 * { 'name': 'banana', 'type': 'fruit' },
3727 * { 'name': 'beet', 'type': 'vegetable' }
3730 * // using "_.where" callback shorthand
3731 * _.rest(food, { 'type': 'fruit' });
3732 * // => [{ 'name': 'beet', 'type': 'vegetable' }]
3734 function rest(array, callback, thisArg) {
3735 if (typeof callback != 'number' && callback != null) {
3738 length = array ? array.length : 0;
3740 callback = createCallback(callback, thisArg);
3741 while (++index < length && callback(array[index], index, array)) {
3745 n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
3747 return slice(array, n);
3751 * Uses a binary search to determine the smallest index at which the `value`
3752 * should be inserted into `array` in order to maintain the sort order of the
3753 * sorted `array`. If `callback` is passed, it will be executed for `value` and
3754 * each element in `array` to compute their sort ranking. The `callback` is
3755 * bound to `thisArg` and invoked with one argument; (value).
3757 * If a property name is passed for `callback`, the created "_.pluck" style
3758 * callback will return the property value of the given element.
3760 * If an object is passed for `callback`, the created "_.where" style callback
3761 * will return `true` for elements that have the propeties of the given object,
3767 * @param {Array} array The array to iterate over.
3768 * @param {Mixed} value The value to evaluate.
3769 * @param {Function|Object|String} [callback=identity] The function called per
3770 * iteration. If a property name or object is passed, it will be used to create
3771 * a "_.pluck" or "_.where" style callback, respectively.
3772 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3773 * @returns {Number} Returns the index at which the value should be inserted
3777 * _.sortedIndex([20, 30, 50], 40);
3780 * // using "_.pluck" callback shorthand
3781 * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
3785 * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
3788 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3789 * return dict.wordToNumber[word];
3793 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3794 * return this.wordToNumber[word];
3798 function sortedIndex(array, value, callback, thisArg) {
3800 high = array ? array.length : low;
3802 // explicitly reference `identity` for better inlining in Firefox
3803 callback = callback ? createCallback(callback, thisArg, 1) : identity;
3804 value = callback(value);
3806 while (low < high) {
3807 var mid = (low + high) >>> 1;
3808 callback(array[mid]) < value
3816 * Computes the union of the passed-in arrays using strict equality for
3817 * comparisons, i.e. `===`.
3822 * @param {Array} [array1, array2, ...] Arrays to process.
3823 * @returns {Array} Returns a new array of unique values, in order, that are
3824 * present in one or more of the arrays.
3827 * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
3828 * // => [1, 2, 3, 101, 10]
3831 return uniq(concat.apply(arrayRef, arguments));
3835 * Creates a duplicate-value-free version of the `array` using strict equality
3836 * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
3837 * for `isSorted` will run a faster algorithm. If `callback` is passed, each
3838 * element of `array` is passed through a callback` before uniqueness is computed.
3839 * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
3841 * If a property name is passed for `callback`, the created "_.pluck" style
3842 * callback will return the property value of the given element.
3844 * If an object is passed for `callback`, the created "_.where" style callback
3845 * will return `true` for elements that have the propeties of the given object,
3852 * @param {Array} array The array to process.
3853 * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
3854 * @param {Function|Object|String} [callback=identity] The function called per
3855 * iteration. If a property name or object is passed, it will be used to create
3856 * a "_.pluck" or "_.where" style callback, respectively.
3857 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3858 * @returns {Array} Returns a duplicate-value-free array.
3861 * _.uniq([1, 2, 1, 3, 1]);
3864 * _.uniq([1, 1, 2, 2, 3], true);
3867 * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); });
3870 * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math);
3873 * // using "_.pluck" callback shorthand
3874 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
3875 * // => [{ 'x': 1 }, { 'x': 2 }]
3877 function uniq(array, isSorted, callback, thisArg) {
3879 length = array ? array.length : 0,
3884 if (typeof isSorted == 'function') {
3886 callback = isSorted;
3889 // init value cache for large arrays
3890 var isLarge = !isSorted && length >= 75;
3896 callback = createCallback(callback, thisArg);
3898 while (++index < length) {
3899 var value = array[index],
3900 computed = callback ? callback(value, index, array) : value;
3903 var key = computed + '';
3904 var inited = hasOwnProperty.call(cache, key)
3905 ? !(seen = cache[key])
3906 : (seen = cache[key] = []);
3909 ? !index || seen[seen.length - 1] !== computed
3910 : inited || indexOf(seen, computed) < 0
3912 if (callback || isLarge) {
3913 seen.push(computed);
3922 * Creates an array with all occurrences of the passed values removed using
3923 * strict equality for comparisons, i.e. `===`.
3928 * @param {Array} array The array to filter.
3929 * @param {Mixed} [value1, value2, ...] Values to remove.
3930 * @returns {Array} Returns a new filtered array.
3933 * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
3936 function without(array) {
3938 length = array ? array.length : 0,
3939 contains = cachedContains(arguments, 1),
3942 while (++index < length) {
3943 var value = array[index];
3944 if (!contains(value)) {
3952 * Groups the elements of each array at their corresponding indexes. Useful for
3953 * separate data sources that are coordinated through matching array indexes.
3954 * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix
3955 * in a similar fashion.
3960 * @param {Array} [array1, array2, ...] Arrays to process.
3961 * @returns {Array} Returns a new array of grouped elements.
3964 * _.zip(['moe', 'larry'], [30, 40], [true, false]);
3965 * // => [['moe', 30, true], ['larry', 40, false]]
3967 function zip(array) {
3969 length = array ? max(pluck(arguments, 'length')) : 0,
3970 result = Array(length);
3972 while (++index < length) {
3973 result[index] = pluck(arguments, index);
3978 /*--------------------------------------------------------------------------*/
3981 * Creates a function that is restricted to executing `func` only after it is
3982 * called `n` times. The `func` is executed with the `this` binding of the
3987 * @category Functions
3988 * @param {Number} n The number of times the function must be called before
3990 * @param {Function} func The function to restrict.
3991 * @returns {Function} Returns the new restricted function.
3994 * var renderNotes = _.after(notes.length, render);
3995 * _.forEach(notes, function(note) {
3996 * note.asyncSave({ 'success': renderNotes });
3998 * // `renderNotes` is run once, after all notes have saved
4000 function after(n, func) {
4006 return func.apply(this, arguments);
4012 * Creates a function that, when called, invokes `func` with the `this`
4013 * binding of `thisArg` and prepends any additional `bind` arguments to those
4014 * passed to the bound function.
4018 * @category Functions
4019 * @param {Function} func The function to bind.
4020 * @param {Mixed} [thisArg] The `this` binding of `func`.
4021 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
4022 * @returns {Function} Returns the new bound function.
4025 * var func = function(greeting) {
4026 * return greeting + ' ' + this.name;
4029 * func = _.bind(func, { 'name': 'moe' }, 'hi');
4033 function bind(func, thisArg) {
4034 // use `Function#bind` if it exists and is fast
4035 // (in V8 `Function#bind` is slower except when partially applied)
4036 return isBindFast || (nativeBind && arguments.length > 2)
4037 ? nativeBind.call.apply(nativeBind, arguments)
4038 : createBound(func, thisArg, slice(arguments, 2));
4042 * Binds methods on `object` to `object`, overwriting the existing method.
4043 * Method names may be specified as individual arguments or as arrays of method
4044 * names. If no method names are provided, all the function properties of `object`
4049 * @category Functions
4050 * @param {Object} object The object to bind and assign the bound methods to.
4051 * @param {String} [methodName1, methodName2, ...] Method names on the object to bind.
4052 * @returns {Object} Returns `object`.
4057 * 'onClick': function() { alert('clicked ' + this.label); }
4061 * jQuery('#docs').on('click', view.onClick);
4062 * // => alerts 'clicked docs', when the button is clicked
4064 function bindAll(object) {
4065 var funcs = concat.apply(arrayRef, arguments),
4066 index = funcs.length > 1 ? 0 : (funcs = functions(object), -1),
4067 length = funcs.length;
4069 while (++index < length) {
4070 var key = funcs[index];
4071 object[key] = bind(object[key], object);
4077 * Creates a function that, when called, invokes the method at `object[key]`
4078 * and prepends any additional `bindKey` arguments to those passed to the bound
4079 * function. This method differs from `_.bind` by allowing bound functions to
4080 * reference methods that will be redefined or don't yet exist.
4081 * See http://michaux.ca/articles/lazy-function-definition-pattern.
4085 * @category Functions
4086 * @param {Object} object The object the method belongs to.
4087 * @param {String} key The key of the method.
4088 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
4089 * @returns {Function} Returns the new bound function.
4094 * 'greet': function(greeting) {
4095 * return greeting + ' ' + this.name;
4099 * var func = _.bindKey(object, 'greet', 'hi');
4103 * object.greet = function(greeting) {
4104 * return greeting + ', ' + this.name + '!';
4110 function bindKey(object, key) {
4111 return createBound(object, key, slice(arguments, 2));
4115 * Creates a function that is the composition of the passed functions,
4116 * where each function consumes the return value of the function that follows.
4117 * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
4118 * Each function is executed with the `this` binding of the composed function.
4122 * @category Functions
4123 * @param {Function} [func1, func2, ...] Functions to compose.
4124 * @returns {Function} Returns the new composed function.
4127 * var greet = function(name) { return 'hi ' + name; };
4128 * var exclaim = function(statement) { return statement + '!'; };
4129 * var welcome = _.compose(exclaim, greet);
4133 function compose() {
4134 var funcs = arguments;
4136 var args = arguments,
4137 length = funcs.length;
4140 args = [funcs[length].apply(this, args)];
4147 * Creates a function that will delay the execution of `func` until after
4148 * `wait` milliseconds have elapsed since the last time it was invoked. Pass
4149 * `true` for `immediate` to cause debounce to invoke `func` on the leading,
4150 * instead of the trailing, edge of the `wait` timeout. Subsequent calls to
4151 * the debounced function will return the result of the last `func` call.
4155 * @category Functions
4156 * @param {Function} func The function to debounce.
4157 * @param {Number} wait The number of milliseconds to delay.
4158 * @param {Boolean} immediate A flag to indicate execution is on the leading
4159 * edge of the timeout.
4160 * @returns {Function} Returns the new debounced function.
4163 * var lazyLayout = _.debounce(calculateLayout, 300);
4164 * jQuery(window).on('resize', lazyLayout);
4166 function debounce(func, wait, immediate) {
4172 function delayed() {
4175 result = func.apply(thisArg, args);
4179 var isImmediate = immediate && !timeoutId;
4183 clearTimeout(timeoutId);
4184 timeoutId = setTimeout(delayed, wait);
4187 result = func.apply(thisArg, args);
4194 * Executes the `func` function after `wait` milliseconds. Additional arguments
4195 * will be passed to `func` when it is invoked.
4199 * @category Functions
4200 * @param {Function} func The function to delay.
4201 * @param {Number} wait The number of milliseconds to delay execution.
4202 * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
4203 * @returns {Number} Returns the `setTimeout` timeout id.
4206 * var log = _.bind(console.log, console);
4207 * _.delay(log, 1000, 'logged later');
4208 * // => 'logged later' (Appears after one second.)
4210 function delay(func, wait) {
4211 var args = slice(arguments, 2);
4212 return setTimeout(function() { func.apply(undefined, args); }, wait);
4216 * Defers executing the `func` function until the current call stack has cleared.
4217 * Additional arguments will be passed to `func` when it is invoked.
4221 * @category Functions
4222 * @param {Function} func The function to defer.
4223 * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
4224 * @returns {Number} Returns the `setTimeout` timeout id.
4227 * _.defer(function() { alert('deferred'); });
4228 * // returns from the function before `alert` is called
4230 function defer(func) {
4231 var args = slice(arguments, 1);
4232 return setTimeout(function() { func.apply(undefined, args); }, 1);
4234 // use `setImmediate` if it's available in Node.js
4235 if (isV8 && freeModule && typeof setImmediate == 'function') {
4236 defer = bind(setImmediate, window);
4240 * Creates a function that memoizes the result of `func`. If `resolver` is
4241 * passed, it will be used to determine the cache key for storing the result
4242 * based on the arguments passed to the memoized function. By default, the first
4243 * argument passed to the memoized function is used as the cache key. The `func`
4244 * is executed with the `this` binding of the memoized function.
4248 * @category Functions
4249 * @param {Function} func The function to have its output memoized.
4250 * @param {Function} [resolver] A function used to resolve the cache key.
4251 * @returns {Function} Returns the new memoizing function.
4254 * var fibonacci = _.memoize(function(n) {
4255 * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
4258 function memoize(func, resolver) {
4261 var key = (resolver ? resolver.apply(this, arguments) : arguments[0]) + '';
4262 return hasOwnProperty.call(cache, key)
4264 : (cache[key] = func.apply(this, arguments));
4269 * Creates a function that is restricted to execute `func` once. Repeat calls to
4270 * the function will return the value of the first call. The `func` is executed
4271 * with the `this` binding of the created function.
4275 * @category Functions
4276 * @param {Function} func The function to restrict.
4277 * @returns {Function} Returns the new restricted function.
4280 * var initialize = _.once(createApplication);
4283 * // `initialize` executes `createApplication` once
4285 function once(func) {
4294 result = func.apply(this, arguments);
4296 // clear the `func` variable so the function may be garbage collected
4303 * Creates a function that, when called, invokes `func` with any additional
4304 * `partial` arguments prepended to those passed to the new function. This
4305 * method is similar to `_.bind`, except it does **not** alter the `this` binding.
4309 * @category Functions
4310 * @param {Function} func The function to partially apply arguments to.
4311 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
4312 * @returns {Function} Returns the new partially applied function.
4315 * var greet = function(greeting, name) { return greeting + ' ' + name; };
4316 * var hi = _.partial(greet, 'hi');
4320 function partial(func) {
4321 return createBound(func, slice(arguments, 1));
4325 * This method is similar to `_.partial`, except that `partial` arguments are
4326 * appended to those passed to the new function.
4330 * @category Functions
4331 * @param {Function} func The function to partially apply arguments to.
4332 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
4333 * @returns {Function} Returns the new partially applied function.
4336 * var defaultsDeep = _.partialRight(_.merge, _.defaults);
4339 * 'variable': 'data',
4340 * 'imports': { 'jq': $ }
4343 * defaultsDeep(options, _.templateSettings);
4349 * // => { '_': _, 'jq': $ }
4351 function partialRight(func) {
4352 return createBound(func, slice(arguments, 1), null, indicatorObject);
4356 * Creates a function that, when executed, will only call the `func`
4357 * function at most once per every `wait` milliseconds. If the throttled
4358 * function is invoked more than once during the `wait` timeout, `func` will
4359 * also be called on the trailing edge of the timeout. Subsequent calls to the
4360 * throttled function will return the result of the last `func` call.
4364 * @category Functions
4365 * @param {Function} func The function to throttle.
4366 * @param {Number} wait The number of milliseconds to throttle executions to.
4367 * @returns {Function} Returns the new throttled function.
4370 * var throttled = _.throttle(updatePosition, 100);
4371 * jQuery(window).on('scroll', throttled);
4373 function throttle(func, wait) {
4380 function trailingCall() {
4381 lastCalled = new Date;
4383 result = func.apply(thisArg, args);
4387 remaining = wait - (now - lastCalled);
4392 if (remaining <= 0) {
4393 clearTimeout(timeoutId);
4396 result = func.apply(thisArg, args);
4398 else if (!timeoutId) {
4399 timeoutId = setTimeout(trailingCall, remaining);
4406 * Creates a function that passes `value` to the `wrapper` function as its
4407 * first argument. Additional arguments passed to the function are appended
4408 * to those passed to the `wrapper` function. The `wrapper` is executed with
4409 * the `this` binding of the created function.
4413 * @category Functions
4414 * @param {Mixed} value The value to wrap.
4415 * @param {Function} wrapper The wrapper function.
4416 * @returns {Function} Returns the new function.
4419 * var hello = function(name) { return 'hello ' + name; };
4420 * hello = _.wrap(hello, function(func) {
4421 * return 'before, ' + func('moe') + ', after';
4424 * // => 'before, hello moe, after'
4426 function wrap(value, wrapper) {
4429 push.apply(args, arguments);
4430 return wrapper.apply(this, args);
4434 /*--------------------------------------------------------------------------*/
4437 * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
4438 * corresponding HTML entities.
4442 * @category Utilities
4443 * @param {String} string The string to escape.
4444 * @returns {String} Returns the escaped string.
4447 * _.escape('Moe, Larry & Curly');
4448 * // => 'Moe, Larry & Curly'
4450 function escape(string) {
4451 return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar);
4455 * This function returns the first argument passed to it.
4459 * @category Utilities
4460 * @param {Mixed} value Any value.
4461 * @returns {Mixed} Returns `value`.
4464 * var moe = { 'name': 'moe' };
4465 * moe === _.identity(moe);
4468 function identity(value) {
4473 * Adds functions properties of `object` to the `lodash` function and chainable
4478 * @category Utilities
4479 * @param {Object} object The object of function properties to add to `lodash`.
4483 * 'capitalize': function(string) {
4484 * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
4488 * _.capitalize('moe');
4491 * _('moe').capitalize();
4494 function mixin(object) {
4495 forEach(functions(object), function(methodName) {
4496 var func = lodash[methodName] = object[methodName];
4498 lodash.prototype[methodName] = function() {
4499 var args = [this.__wrapped__];
4500 push.apply(args, arguments);
4501 return new lodash(func.apply(lodash, args));
4507 * Reverts the '_' variable to its previous value and returns a reference to
4508 * the `lodash` function.
4512 * @category Utilities
4513 * @returns {Function} Returns the `lodash` function.
4516 * var lodash = _.noConflict();
4518 function noConflict() {
4524 * Produces a random number between `min` and `max` (inclusive). If only one
4525 * argument is passed, a number between `0` and the given number will be returned.
4529 * @category Utilities
4530 * @param {Number} [min=0] The minimum possible value.
4531 * @param {Number} [max=1] The maximum possible value.
4532 * @returns {Number} Returns a random number.
4536 * // => a number between 0 and 5
4539 * // => also a number between 0 and 5
4541 function random(min, max) {
4542 if (min == null && max == null) {
4550 return min + floor(nativeRandom() * ((+max || 0) - min + 1));
4554 * Resolves the value of `property` on `object`. If `property` is a function,
4555 * it will be invoked and its result returned, else the property value is
4556 * returned. If `object` is falsey, then `null` is returned.
4560 * @category Utilities
4561 * @param {Object} object The object to inspect.
4562 * @param {String} property The property to get the value of.
4563 * @returns {Mixed} Returns the resolved value.
4567 * 'cheese': 'crumpets',
4568 * 'stuff': function() {
4569 * return 'nonsense';
4573 * _.result(object, 'cheese');
4576 * _.result(object, 'stuff');
4579 function result(object, property) {
4580 var value = object ? object[property] : undefined;
4581 return isFunction(value) ? object[property]() : value;
4585 * A micro-templating method that handles arbitrary delimiters, preserves
4586 * whitespace, and correctly escapes quotes within interpolated code.
4588 * Note: In the development build, `_.template` utilizes sourceURLs for easier
4589 * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
4591 * Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp`
4592 * build and using precompiled templates, or loading Lo-Dash in a sandbox.
4594 * For more information on precompiling templates see:
4595 * http://lodash.com/#custom-builds
4597 * For more information on Chrome extension sandboxes see:
4598 * http://developer.chrome.com/stable/extensions/sandboxingEval.html
4602 * @category Utilities
4603 * @param {String} text The template text.
4604 * @param {Obect} data The data object used to populate the text.
4605 * @param {Object} options The options object.
4606 * escape - The "escape" delimiter regexp.
4607 * evaluate - The "evaluate" delimiter regexp.
4608 * interpolate - The "interpolate" delimiter regexp.
4609 * sourceURL - The sourceURL of the template's compiled source.
4610 * variable - The data object variable name.
4612 * @returns {Function|String} Returns a compiled function when no `data` object
4613 * is given, else it returns the interpolated text.
4616 * // using a compiled template
4617 * var compiled = _.template('hello <%= name %>');
4618 * compiled({ 'name': 'moe' });
4621 * var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>';
4622 * _.template(list, { 'people': ['moe', 'larry'] });
4623 * // => '<li>moe</li><li>larry</li>'
4625 * // using the "escape" delimiter to escape HTML in data property values
4626 * _.template('<b><%- value %></b>', { 'value': '<script>' });
4627 * // => '<b><script></b>'
4629 * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
4630 * _.template('hello ${ name }', { 'name': 'curly' });
4631 * // => 'hello curly'
4633 * // using the internal `print` function in "evaluate" delimiters
4634 * _.template('<% print("hello " + epithet); %>!', { 'epithet': 'stooge' });
4635 * // => 'hello stooge!'
4637 * // using custom template delimiters
4638 * _.templateSettings = {
4639 * 'interpolate': /{{([\s\S]+?)}}/g
4642 * _.template('hello {{ name }}!', { 'name': 'mustache' });
4643 * // => 'hello mustache!'
4645 * // using the `sourceURL` option to specify a custom sourceURL for the template
4646 * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
4648 * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
4650 * // using the `variable` option to ensure a with-statement isn't used in the compiled template
4651 * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
4653 * // => function(data) {
4654 * var __t, __p = '', __e = _.escape;
4655 * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
4659 * // using the `source` property to inline compiled templates for meaningful
4660 * // line numbers in error messages and a stack trace
4661 * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
4663 * "main": ' + _.template(mainText).source + '\
4667 function template(text, data, options) {
4668 // based on John Resig's `tmpl` implementation
4669 // http://ejohn.org/blog/javascript-micro-templating/
4670 // and Laura Doktorova's doT.js
4671 // https://github.com/olado/doT
4672 var settings = lodash.templateSettings;
4673 text || (text = '');
4675 // avoid missing dependencies when `iteratorTemplate` is not defined
4676 options = defaults({}, options, settings);
4678 var imports = defaults({}, options.imports, settings.imports),
4679 importsKeys = keys(imports),
4680 importsValues = values(imports);
4684 interpolate = options.interpolate || reNoMatch,
4685 source = "__p += '";
4687 // compile regexp to match each delimiter
4688 var reDelimiters = RegExp(
4689 (options.escape || reNoMatch).source + '|' +
4690 interpolate.source + '|' +
4691 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
4692 (options.evaluate || reNoMatch).source + '|$'
4695 text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
4696 interpolateValue || (interpolateValue = esTemplateValue);
4698 // escape characters that cannot be included in string literals
4699 source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
4701 // replace delimiters with snippets
4703 source += "' +\n__e(" + escapeValue + ") +\n'";
4705 if (evaluateValue) {
4706 isEvaluating = true;
4707 source += "';\n" + evaluateValue + ";\n__p += '";
4709 if (interpolateValue) {
4710 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
4712 index = offset + match.length;
4714 // the JS engine embedded in Adobe products requires returning the `match`
4715 // string in order to produce the correct `offset` value
4721 // if `variable` is not specified and the template contains "evaluate"
4722 // delimiters, wrap a with-statement around the generated code to add the
4723 // data object to the top of the scope chain
4724 var variable = options.variable,
4725 hasVariable = variable;
4729 source = 'with (' + variable + ') {\n' + source + '\n}\n';
4731 // cleanup code by stripping empty strings
4732 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
4733 .replace(reEmptyStringMiddle, '$1')
4734 .replace(reEmptyStringTrailing, '$1;');
4736 // frame code as the function body
4737 source = 'function(' + variable + ') {\n' +
4738 (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
4739 "var __t, __p = '', __e = _.escape" +
4741 ? ', __j = Array.prototype.join;\n' +
4742 "function print() { __p += __j.call(arguments, '') }\n"
4748 // Use a sourceURL for easier debugging and wrap in a multi-line comment to
4749 // avoid issues with Narwhal, IE conditional compilation, and the JS engine
4750 // embedded in Adobe products.
4751 // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
4752 var sourceURL = '\n/*\n//@ sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
4755 var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
4761 return result(data);
4763 // provide the compiled function's source via its `toString` method, in
4764 // supported environments, or the `source` property as a convenience for
4765 // inlining compiled templates during the build process
4766 result.source = source;
4771 * Executes the `callback` function `n` times, returning an array of the results
4772 * of each `callback` execution. The `callback` is bound to `thisArg` and invoked
4773 * with one argument; (index).
4777 * @category Utilities
4778 * @param {Number} n The number of times to execute the callback.
4779 * @param {Function} callback The function called per iteration.
4780 * @param {Mixed} [thisArg] The `this` binding of `callback`.
4781 * @returns {Array} Returns a new array of the results of each `callback` execution.
4784 * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
4787 * _.times(3, function(n) { mage.castSpell(n); });
4788 * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
4790 * _.times(3, function(n) { this.cast(n); }, mage);
4791 * // => also calls `mage.castSpell(n)` three times
4793 function times(n, callback, thisArg) {
4798 while (++index < n) {
4799 result[index] = callback.call(thisArg, index);
4805 * The opposite of `_.escape`, this method converts the HTML entities
4806 * `&`, `<`, `>`, `"`, and `'` in `string` to their
4807 * corresponding characters.
4811 * @category Utilities
4812 * @param {String} string The string to unescape.
4813 * @returns {String} Returns the unescaped string.
4816 * _.unescape('Moe, Larry & Curly');
4817 * // => 'Moe, Larry & Curly'
4819 function unescape(string) {
4820 return string == null ? '' : (string + '').replace(reEscapedHtml, unescapeHtmlChar);
4824 * Generates a unique ID. If `prefix` is passed, the ID will be appended to it.
4828 * @category Utilities
4829 * @param {String} [prefix] The value to prefix the ID with.
4830 * @returns {String} Returns the unique ID.
4833 * _.uniqueId('contact_');
4834 * // => 'contact_104'
4839 function uniqueId(prefix) {
4840 var id = ++idCounter;
4841 return (prefix == null ? '' : prefix + '') + id;
4844 /*--------------------------------------------------------------------------*/
4847 * Invokes `interceptor` with the `value` as the first argument, and then
4848 * returns `value`. The purpose of this method is to "tap into" a method chain,
4849 * in order to perform operations on intermediate results within the chain.
4853 * @category Chaining
4854 * @param {Mixed} value The value to pass to `interceptor`.
4855 * @param {Function} interceptor The function to invoke.
4856 * @returns {Mixed} Returns `value`.
4860 * .filter(function(num) { return num % 2 == 0; })
4862 * .map(function(num) { return num * num; })
4864 * // => // [2, 4] (alerted)
4867 function tap(value, interceptor) {
4873 * Produces the `toString` result of the wrapped value.
4877 * @category Chaining
4878 * @returns {String} Returns the string result.
4881 * _([1, 2, 3]).toString();
4884 function wrapperToString() {
4885 return this.__wrapped__ + '';
4889 * Extracts the wrapped value.
4894 * @category Chaining
4895 * @returns {Mixed} Returns the wrapped value.
4898 * _([1, 2, 3]).valueOf();
4901 function wrapperValueOf() {
4902 return this.__wrapped__;
4905 /*--------------------------------------------------------------------------*/
4907 // add functions that return wrapped values when chaining
4908 lodash.after = after;
4909 lodash.assign = assign;
4912 lodash.bindAll = bindAll;
4913 lodash.bindKey = bindKey;
4914 lodash.compact = compact;
4915 lodash.compose = compose;
4916 lodash.countBy = countBy;
4917 lodash.debounce = debounce;
4918 lodash.defaults = defaults;
4919 lodash.defer = defer;
4920 lodash.delay = delay;
4921 lodash.difference = difference;
4922 lodash.filter = filter;
4923 lodash.flatten = flatten;
4924 lodash.forEach = forEach;
4925 lodash.forIn = forIn;
4926 lodash.forOwn = forOwn;
4927 lodash.functions = functions;
4928 lodash.groupBy = groupBy;
4929 lodash.initial = initial;
4930 lodash.intersection = intersection;
4931 lodash.invert = invert;
4932 lodash.invoke = invoke;
4936 lodash.memoize = memoize;
4937 lodash.merge = merge;
4939 lodash.object = object;
4942 lodash.pairs = pairs;
4943 lodash.partial = partial;
4944 lodash.partialRight = partialRight;
4946 lodash.pluck = pluck;
4947 lodash.range = range;
4948 lodash.reject = reject;
4950 lodash.shuffle = shuffle;
4951 lodash.sortBy = sortBy;
4953 lodash.throttle = throttle;
4954 lodash.times = times;
4955 lodash.toArray = toArray;
4956 lodash.union = union;
4958 lodash.values = values;
4959 lodash.where = where;
4960 lodash.without = without;
4965 lodash.collect = map;
4967 lodash.each = forEach;
4968 lodash.extend = assign;
4969 lodash.methods = functions;
4970 lodash.select = filter;
4972 lodash.unique = uniq;
4974 // add functions to `lodash.prototype`
4977 /*--------------------------------------------------------------------------*/
4979 // add functions that return unwrapped values when chaining
4980 lodash.clone = clone;
4981 lodash.cloneDeep = cloneDeep;
4982 lodash.contains = contains;
4983 lodash.escape = escape;
4984 lodash.every = every;
4987 lodash.identity = identity;
4988 lodash.indexOf = indexOf;
4989 lodash.isArguments = isArguments;
4990 lodash.isArray = isArray;
4991 lodash.isBoolean = isBoolean;
4992 lodash.isDate = isDate;
4993 lodash.isElement = isElement;
4994 lodash.isEmpty = isEmpty;
4995 lodash.isEqual = isEqual;
4996 lodash.isFinite = isFinite;
4997 lodash.isFunction = isFunction;
4998 lodash.isNaN = isNaN;
4999 lodash.isNull = isNull;
5000 lodash.isNumber = isNumber;
5001 lodash.isObject = isObject;
5002 lodash.isPlainObject = isPlainObject;
5003 lodash.isRegExp = isRegExp;
5004 lodash.isString = isString;
5005 lodash.isUndefined = isUndefined;
5006 lodash.lastIndexOf = lastIndexOf;
5007 lodash.mixin = mixin;
5008 lodash.noConflict = noConflict;
5009 lodash.random = random;
5010 lodash.reduce = reduce;
5011 lodash.reduceRight = reduceRight;
5012 lodash.result = result;
5015 lodash.sortedIndex = sortedIndex;
5016 lodash.template = template;
5017 lodash.unescape = unescape;
5018 lodash.uniqueId = uniqueId;
5023 lodash.detect = find;
5024 lodash.foldl = reduce;
5025 lodash.foldr = reduceRight;
5026 lodash.include = contains;
5027 lodash.inject = reduce;
5029 forOwn(lodash, function(func, methodName) {
5030 if (!lodash.prototype[methodName]) {
5031 lodash.prototype[methodName] = function() {
5032 var args = [this.__wrapped__];
5033 push.apply(args, arguments);
5034 return func.apply(lodash, args);
5039 /*--------------------------------------------------------------------------*/
5041 // add functions capable of returning wrapped and unwrapped values when chaining
5042 lodash.first = first;
5046 lodash.take = first;
5047 lodash.head = first;
5049 forOwn(lodash, function(func, methodName) {
5050 if (!lodash.prototype[methodName]) {
5051 lodash.prototype[methodName]= function(callback, thisArg) {
5052 var result = func(this.__wrapped__, callback, thisArg);
5053 return callback == null || (thisArg && typeof callback != 'function')
5055 : new lodash(result);
5060 /*--------------------------------------------------------------------------*/
5063 * The semantic version number.
5069 lodash.VERSION = '1.0.2';
5071 // add "Chaining" functions to the wrapper
5072 lodash.prototype.toString = wrapperToString;
5073 lodash.prototype.value = wrapperValueOf;
5074 lodash.prototype.valueOf = wrapperValueOf;
5076 // add `Array` functions that return unwrapped values
5077 each(['join', 'pop', 'shift'], function(methodName) {
5078 var func = arrayRef[methodName];
5079 lodash.prototype[methodName] = function() {
5080 return func.apply(this.__wrapped__, arguments);
5084 // add `Array` functions that return the wrapped value
5085 each(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
5086 var func = arrayRef[methodName];
5087 lodash.prototype[methodName] = function() {
5088 func.apply(this.__wrapped__, arguments);
5093 // add `Array` functions that return new wrapped values
5094 each(['concat', 'slice', 'splice'], function(methodName) {
5095 var func = arrayRef[methodName];
5096 lodash.prototype[methodName] = function() {
5097 return new lodash(func.apply(this.__wrapped__, arguments));
5101 // avoid array-like object bugs with `Array#shift` and `Array#splice`
5102 // in Firefox < 10 and IE < 9
5103 if (hasObjectSpliceBug) {
5104 each(['pop', 'shift', 'splice'], function(methodName) {
5105 var func = arrayRef[methodName],
5106 isSplice = methodName == 'splice';
5108 lodash.prototype[methodName] = function() {
5109 var value = this.__wrapped__,
5110 result = func.apply(value, arguments);
5112 if (value.length === 0) {
5115 return isSplice ? new lodash(result) : result;
5120 /*--------------------------------------------------------------------------*/
5123 // some AMD build optimizers, like r.js, check for specific condition patterns like the following:
5124 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
5125 // Expose Lo-Dash to the global object even when an AMD loader is present in
5126 // case Lo-Dash was injected by a third-party script and not intended to be
5127 // loaded as a module. The global assignment can be reverted in the Lo-Dash
5128 // module via its `noConflict()` method.
5131 // define as an anonymous module so, through path mapping, it can be
5132 // referenced as the "underscore" module
5137 // check for `exports` after `define` in case a build optimizer adds an `exports` object
5138 else if (freeExports) {
5139 // in Node.js or RingoJS v0.8.0+
5141 (freeModule.exports = lodash)._ = lodash;
5143 // in Narwhal or RingoJS v0.7.0-
5145 freeExports._ = lodash;
5149 // in a browser or Rhino