Built motion from commit fd239ea.|0.0.31
[motion.git] / public / bower_components / lodash / dist / lodash.js
1 /**
2  * @license
3  * lodash 4.0.0 (Custom Build) <https://lodash.com/>
4  * Build: `lodash -o ./dist/lodash.js`
5  * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
6  * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7  * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8  * Available under MIT license <https://lodash.com/license>
9  */
10 ;(function() {
11
12   /** Used as a safe reference for `undefined` in pre-ES5 environments. */
13   var undefined;
14
15   /** Used as the semantic version number. */
16   var VERSION = '4.0.0';
17
18   /** Used to compose bitmasks for wrapper metadata. */
19   var BIND_FLAG = 1,
20       BIND_KEY_FLAG = 2,
21       CURRY_BOUND_FLAG = 4,
22       CURRY_FLAG = 8,
23       CURRY_RIGHT_FLAG = 16,
24       PARTIAL_FLAG = 32,
25       PARTIAL_RIGHT_FLAG = 64,
26       ARY_FLAG = 128,
27       REARG_FLAG = 256,
28       FLIP_FLAG = 512;
29
30   /** Used to compose bitmasks for comparison styles. */
31   var UNORDERED_COMPARE_FLAG = 1,
32       PARTIAL_COMPARE_FLAG = 2;
33
34   /** Used as default options for `_.truncate`. */
35   var DEFAULT_TRUNC_LENGTH = 30,
36       DEFAULT_TRUNC_OMISSION = '...';
37
38   /** Used to detect hot functions by number of calls within a span of milliseconds. */
39   var HOT_COUNT = 150,
40       HOT_SPAN = 16;
41
42   /** Used as the size to enable large array optimizations. */
43   var LARGE_ARRAY_SIZE = 200;
44
45   /** Used to indicate the type of lazy iteratees. */
46   var LAZY_FILTER_FLAG = 1,
47       LAZY_MAP_FLAG = 2,
48       LAZY_WHILE_FLAG = 3;
49
50   /** Used as the `TypeError` message for "Functions" methods. */
51   var FUNC_ERROR_TEXT = 'Expected a function';
52
53   /** Used to stand-in for `undefined` hash values. */
54   var HASH_UNDEFINED = '__lodash_hash_undefined__';
55
56   /** Used as references for various `Number` constants. */
57   var INFINITY = 1 / 0,
58       MAX_SAFE_INTEGER = 9007199254740991,
59       MAX_INTEGER = 1.7976931348623157e+308,
60       NAN = 0 / 0;
61
62   /** Used as references for the maximum length and index of an array. */
63   var MAX_ARRAY_LENGTH = 4294967295,
64       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
65       HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
66
67   /** Used as the internal argument placeholder. */
68   var PLACEHOLDER = '__lodash_placeholder__';
69
70   /** `Object#toString` result references. */
71   var argsTag = '[object Arguments]',
72       arrayTag = '[object Array]',
73       boolTag = '[object Boolean]',
74       dateTag = '[object Date]',
75       errorTag = '[object Error]',
76       funcTag = '[object Function]',
77       genTag = '[object GeneratorFunction]',
78       mapTag = '[object Map]',
79       numberTag = '[object Number]',
80       objectTag = '[object Object]',
81       regexpTag = '[object RegExp]',
82       setTag = '[object Set]',
83       stringTag = '[object String]',
84       symbolTag = '[object Symbol]',
85       weakMapTag = '[object WeakMap]';
86
87   var arrayBufferTag = '[object ArrayBuffer]',
88       float32Tag = '[object Float32Array]',
89       float64Tag = '[object Float64Array]',
90       int8Tag = '[object Int8Array]',
91       int16Tag = '[object Int16Array]',
92       int32Tag = '[object Int32Array]',
93       uint8Tag = '[object Uint8Array]',
94       uint8ClampedTag = '[object Uint8ClampedArray]',
95       uint16Tag = '[object Uint16Array]',
96       uint32Tag = '[object Uint32Array]';
97
98   /** Used to match empty string literals in compiled template source. */
99   var reEmptyStringLeading = /\b__p \+= '';/g,
100       reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
101       reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
102
103   /** Used to match HTML entities and HTML characters. */
104   var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
105       reUnescapedHtml = /[&<>"'`]/g,
106       reHasEscapedHtml = RegExp(reEscapedHtml.source),
107       reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
108
109   /** Used to match template delimiters. */
110   var reEscape = /<%-([\s\S]+?)%>/g,
111       reEvaluate = /<%([\s\S]+?)%>/g,
112       reInterpolate = /<%=([\s\S]+?)%>/g;
113
114   /** Used to match property names within property paths. */
115   var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
116       reIsPlainProp = /^\w*$/,
117       rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
118
119   /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
120   var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
121       reHasRegExpChar = RegExp(reRegExpChar.source);
122
123   /** Used to match leading and trailing whitespace. */
124   var reTrim = /^\s+|\s+$/g,
125       reTrimStart = /^\s+/,
126       reTrimEnd = /\s+$/;
127
128   /** Used to match backslashes in property paths. */
129   var reEscapeChar = /\\(\\)?/g;
130
131   /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
132   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
133
134   /** Used to match `RegExp` flags from their coerced string values. */
135   var reFlags = /\w*$/;
136
137   /** Used to detect hexadecimal string values. */
138   var reHasHexPrefix = /^0x/i;
139
140   /** Used to detect bad signed hexadecimal string values. */
141   var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
142
143   /** Used to detect binary string values. */
144   var reIsBinary = /^0b[01]+$/i;
145
146   /** Used to detect host constructors (Safari > 5). */
147   var reIsHostCtor = /^\[object .+?Constructor\]$/;
148
149   /** Used to detect octal string values. */
150   var reIsOctal = /^0o[0-7]+$/i;
151
152   /** Used to detect unsigned integer values. */
153   var reIsUint = /^(?:0|[1-9]\d*)$/;
154
155   /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
156   var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
157
158   /** Used to ensure capturing order of template delimiters. */
159   var reNoMatch = /($^)/;
160
161   /** Used to match unescaped characters in compiled string literals. */
162   var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
163
164   /** Used to compose unicode character classes. */
165   var rsAstralRange = '\\ud800-\\udfff',
166       rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
167       rsDingbatRange = '\\u2700-\\u27bf',
168       rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
169       rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
170       rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
171       rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
172       rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
173       rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
174       rsVarRange = '\\ufe0e\\ufe0f',
175       rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
176
177   /** Used to compose unicode capture groups. */
178   var rsAstral = '[' + rsAstralRange + ']',
179       rsBreak = '[' + rsBreakRange + ']',
180       rsCombo = '[' + rsComboRange + ']',
181       rsDigits = '\\d+',
182       rsDingbat = '[' + rsDingbatRange + ']',
183       rsLower = '[' + rsLowerRange + ']',
184       rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
185       rsModifier = '(?:\\ud83c[\\udffb-\\udfff])',
186       rsNonAstral = '[^' + rsAstralRange + ']',
187       rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
188       rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
189       rsUpper = '[' + rsUpperRange + ']',
190       rsZWJ = '\\u200d';
191
192   /** Used to compose unicode regexes. */
193   var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
194       rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
195       reOptMod = rsModifier + '?',
196       rsOptVar = '[' + rsVarRange + ']?',
197       rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
198       rsSeq = rsOptVar + reOptMod + rsOptJoin,
199       rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
200       rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
201
202   /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
203   var reComboMark = RegExp(rsCombo, 'g');
204
205   /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
206   var reComplexSymbol = RegExp(rsSymbol + rsSeq, 'g');
207
208   /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
209   var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
210
211   /** Used to match non-compound words composed of alphanumeric characters. */
212   var reBasicWord = /[a-zA-Z0-9]+/g;
213
214   /** Used to match complex or compound words. */
215   var reComplexWord = RegExp([
216     rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
217     rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
218     rsUpper + '?' + rsLowerMisc + '+',
219     rsDigits + '(?:' + rsLowerMisc + '+)?',
220     rsEmoji
221   ].join('|'), 'g');
222
223   /** Used to detect strings that need a more robust regexp to match words. */
224   var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
225
226   /** Used to assign default `context` object properties. */
227   var contextProps = [
228     'Array', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function',
229     'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
230     'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
231     'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
232     'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
233   ];
234
235   /** Used to make template sourceURLs easier to identify. */
236   var templateCounter = -1;
237
238   /** Used to identify `toStringTag` values of typed arrays. */
239   var typedArrayTags = {};
240   typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
241   typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
242   typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
243   typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
244   typedArrayTags[uint32Tag] = true;
245   typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
246   typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
247   typedArrayTags[dateTag] = typedArrayTags[errorTag] =
248   typedArrayTags[funcTag] = typedArrayTags[mapTag] =
249   typedArrayTags[numberTag] = typedArrayTags[objectTag] =
250   typedArrayTags[regexpTag] = typedArrayTags[setTag] =
251   typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
252
253   /** Used to identify `toStringTag` values supported by `_.clone`. */
254   var cloneableTags = {};
255   cloneableTags[argsTag] = cloneableTags[arrayTag] =
256   cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
257   cloneableTags[dateTag] = cloneableTags[float32Tag] =
258   cloneableTags[float64Tag] = cloneableTags[int8Tag] =
259   cloneableTags[int16Tag] = cloneableTags[int32Tag] =
260   cloneableTags[mapTag] = cloneableTags[numberTag] =
261   cloneableTags[objectTag] = cloneableTags[regexpTag] =
262   cloneableTags[setTag] = cloneableTags[stringTag] =
263   cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
264   cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
265   cloneableTags[uint32Tag] = true;
266   cloneableTags[errorTag] = cloneableTags[funcTag] =
267   cloneableTags[weakMapTag] = false;
268
269   /** Used to map latin-1 supplementary letters to basic latin letters. */
270   var deburredLetters = {
271     '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
272     '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
273     '\xc7': 'C',  '\xe7': 'c',
274     '\xd0': 'D',  '\xf0': 'd',
275     '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
276     '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
277     '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
278     '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
279     '\xd1': 'N',  '\xf1': 'n',
280     '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
281     '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
282     '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
283     '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
284     '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
285     '\xc6': 'Ae', '\xe6': 'ae',
286     '\xde': 'Th', '\xfe': 'th',
287     '\xdf': 'ss'
288   };
289
290   /** Used to map characters to HTML entities. */
291   var htmlEscapes = {
292     '&': '&amp;',
293     '<': '&lt;',
294     '>': '&gt;',
295     '"': '&quot;',
296     "'": '&#39;',
297     '`': '&#96;'
298   };
299
300   /** Used to map HTML entities to characters. */
301   var htmlUnescapes = {
302     '&amp;': '&',
303     '&lt;': '<',
304     '&gt;': '>',
305     '&quot;': '"',
306     '&#39;': "'",
307     '&#96;': '`'
308   };
309
310   /** Used to determine if values are of the language type `Object`. */
311   var objectTypes = {
312     'function': true,
313     'object': true
314   };
315
316   /** Used to escape characters for inclusion in compiled string literals. */
317   var stringEscapes = {
318     '\\': '\\',
319     "'": "'",
320     '\n': 'n',
321     '\r': 'r',
322     '\u2028': 'u2028',
323     '\u2029': 'u2029'
324   };
325
326   /** Built-in method references without a dependency on `root`. */
327   var freeParseFloat = parseFloat,
328       freeParseInt = parseInt;
329
330   /** Detect free variable `exports`. */
331   var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
332
333   /** Detect free variable `module`. */
334   var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
335
336   /** Detect free variable `global` from Node.js. */
337   var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
338
339   /** Detect free variable `self`. */
340   var freeSelf = checkGlobal(objectTypes[typeof self] && self);
341
342   /** Detect free variable `window`. */
343   var freeWindow = checkGlobal(objectTypes[typeof window] && window);
344
345   /** Detect the popular CommonJS extension `module.exports`. */
346   var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
347
348   /** Detect `this` as the global object. */
349   var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
350
351   /**
352    * Used as a reference to the global object.
353    *
354    * The `this` value is used if it's the global object to avoid Greasemonkey's
355    * restricted `window` object, otherwise the `window` object is used.
356    */
357   var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
358
359   /*--------------------------------------------------------------------------*/
360
361   /**
362    * Adds the key-value `pair` to `map`.
363    *
364    * @private
365    * @param {Object} map The map to modify.
366    * @param {Array} pair The key-value pair to add.
367    * @returns {Object} Returns `map`.
368    */
369   function addMapEntry(map, pair) {
370     map.set(pair[0], pair[1]);
371     return map;
372   }
373
374   /**
375    * Adds `value` to `set`.
376    *
377    * @private
378    * @param {Object} set The set to modify.
379    * @param {*} value The value to add.
380    * @returns {Object} Returns `set`.
381    */
382   function addSetEntry(set, value) {
383     set.add(value);
384     return set;
385   }
386
387   /**
388    * A faster alternative to `Function#apply`, this function invokes `func`
389    * with the `this` binding of `thisArg` and the arguments of `args`.
390    *
391    * @private
392    * @param {Function} func The function to invoke.
393    * @param {*} thisArg The `this` binding of `func`.
394    * @param {...*} [args] The arguments to invoke `func` with.
395    * @returns {*} Returns the result of `func`.
396    */
397   function apply(func, thisArg, args) {
398     var length = args ? args.length : 0;
399     switch (length) {
400       case 0: return func.call(thisArg);
401       case 1: return func.call(thisArg, args[0]);
402       case 2: return func.call(thisArg, args[0], args[1]);
403       case 3: return func.call(thisArg, args[0], args[1], args[2]);
404     }
405     return func.apply(thisArg, args);
406   }
407
408   /**
409    * Creates a new array concatenating `array` with `other`.
410    *
411    * @private
412    * @param {Array} array The first array to concatenate.
413    * @param {Array} other The second array to concatenate.
414    * @returns {Array} Returns the new concatenated array.
415    */
416   function arrayConcat(array, other) {
417     var index = -1,
418         length = array.length,
419         othIndex = -1,
420         othLength = other.length,
421         result = Array(length + othLength);
422
423     while (++index < length) {
424       result[index] = array[index];
425     }
426     while (++othIndex < othLength) {
427       result[index++] = other[othIndex];
428     }
429     return result;
430   }
431
432   /**
433    * A specialized version of `_.forEach` for arrays without support for
434    * iteratee shorthands.
435    *
436    * @private
437    * @param {Array} array The array to iterate over.
438    * @param {Function} iteratee The function invoked per iteration.
439    * @returns {Array} Returns `array`.
440    */
441   function arrayEach(array, iteratee) {
442     var index = -1,
443         length = array.length;
444
445     while (++index < length) {
446       if (iteratee(array[index], index, array) === false) {
447         break;
448       }
449     }
450     return array;
451   }
452
453   /**
454    * A specialized version of `_.forEachRight` for arrays without support for
455    * iteratee shorthands.
456    *
457    * @private
458    * @param {Array} array The array to iterate over.
459    * @param {Function} iteratee The function invoked per iteration.
460    * @returns {Array} Returns `array`.
461    */
462   function arrayEachRight(array, iteratee) {
463     var length = array.length;
464
465     while (length--) {
466       if (iteratee(array[length], length, array) === false) {
467         break;
468       }
469     }
470     return array;
471   }
472
473   /**
474    * A specialized version of `_.every` for arrays without support for
475    * iteratee shorthands.
476    *
477    * @private
478    * @param {Array} array The array to iterate over.
479    * @param {Function} predicate The function invoked per iteration.
480    * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
481    */
482   function arrayEvery(array, predicate) {
483     var index = -1,
484         length = array.length;
485
486     while (++index < length) {
487       if (!predicate(array[index], index, array)) {
488         return false;
489       }
490     }
491     return true;
492   }
493
494   /**
495    * A specialized version of `_.filter` for arrays without support for
496    * iteratee shorthands.
497    *
498    * @private
499    * @param {Array} array The array to iterate over.
500    * @param {Function} predicate The function invoked per iteration.
501    * @returns {Array} Returns the new filtered array.
502    */
503   function arrayFilter(array, predicate) {
504     var index = -1,
505         length = array.length,
506         resIndex = -1,
507         result = [];
508
509     while (++index < length) {
510       var value = array[index];
511       if (predicate(value, index, array)) {
512         result[++resIndex] = value;
513       }
514     }
515     return result;
516   }
517
518   /**
519    * A specialized version of `_.includes` for arrays without support for
520    * specifying an index to search from.
521    *
522    * @private
523    * @param {Array} array The array to search.
524    * @param {*} target The value to search for.
525    * @returns {boolean} Returns `true` if `target` is found, else `false`.
526    */
527   function arrayIncludes(array, value) {
528     return !!array.length && baseIndexOf(array, value, 0) > -1;
529   }
530
531   /**
532    * A specialized version of `_.includesWith` for arrays without support for
533    * specifying an index to search from.
534    *
535    * @private
536    * @param {Array} array The array to search.
537    * @param {*} target The value to search for.
538    * @param {Function} comparator The comparator invoked per element.
539    * @returns {boolean} Returns `true` if `target` is found, else `false`.
540    */
541   function arrayIncludesWith(array, value, comparator) {
542     var index = -1,
543         length = array.length;
544
545     while (++index < length) {
546       if (comparator(value, array[index])) {
547         return true;
548       }
549     }
550     return false;
551   }
552
553   /**
554    * A specialized version of `_.map` for arrays without support for iteratee
555    * shorthands.
556    *
557    * @private
558    * @param {Array} array The array to iterate over.
559    * @param {Function} iteratee The function invoked per iteration.
560    * @returns {Array} Returns the new mapped array.
561    */
562   function arrayMap(array, iteratee) {
563     var index = -1,
564         length = array.length,
565         result = Array(length);
566
567     while (++index < length) {
568       result[index] = iteratee(array[index], index, array);
569     }
570     return result;
571   }
572
573   /**
574    * Appends the elements of `values` to `array`.
575    *
576    * @private
577    * @param {Array} array The array to modify.
578    * @param {Array} values The values to append.
579    * @returns {Array} Returns `array`.
580    */
581   function arrayPush(array, values) {
582     var index = -1,
583         length = values.length,
584         offset = array.length;
585
586     while (++index < length) {
587       array[offset + index] = values[index];
588     }
589     return array;
590   }
591
592   /**
593    * A specialized version of `_.reduce` for arrays without support for
594    * iteratee shorthands.
595    *
596    * @private
597    * @param {Array} array The array to iterate over.
598    * @param {Function} iteratee The function invoked per iteration.
599    * @param {*} [accumulator] The initial value.
600    * @param {boolean} [initFromArray] Specify using the first element of `array` as the initial value.
601    * @returns {*} Returns the accumulated value.
602    */
603   function arrayReduce(array, iteratee, accumulator, initFromArray) {
604     var index = -1,
605         length = array.length;
606
607     if (initFromArray && length) {
608       accumulator = array[++index];
609     }
610     while (++index < length) {
611       accumulator = iteratee(accumulator, array[index], index, array);
612     }
613     return accumulator;
614   }
615
616   /**
617    * A specialized version of `_.reduceRight` for arrays without support for
618    * iteratee shorthands.
619    *
620    * @private
621    * @param {Array} array The array to iterate over.
622    * @param {Function} iteratee The function invoked per iteration.
623    * @param {*} [accumulator] The initial value.
624    * @param {boolean} [initFromArray] Specify using the last element of `array` as the initial value.
625    * @returns {*} Returns the accumulated value.
626    */
627   function arrayReduceRight(array, iteratee, accumulator, initFromArray) {
628     var length = array.length;
629     if (initFromArray && length) {
630       accumulator = array[--length];
631     }
632     while (length--) {
633       accumulator = iteratee(accumulator, array[length], length, array);
634     }
635     return accumulator;
636   }
637
638   /**
639    * A specialized version of `_.some` for arrays without support for iteratee
640    * shorthands.
641    *
642    * @private
643    * @param {Array} array The array to iterate over.
644    * @param {Function} predicate The function invoked per iteration.
645    * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
646    */
647   function arraySome(array, predicate) {
648     var index = -1,
649         length = array.length;
650
651     while (++index < length) {
652       if (predicate(array[index], index, array)) {
653         return true;
654       }
655     }
656     return false;
657   }
658
659   /**
660    * The base implementation of methods like `_.max` and `_.min` which accepts a
661    * `comparator` to determine the extremum value.
662    *
663    * @private
664    * @param {Array} array The array to iterate over.
665    * @param {Function} iteratee The iteratee invoked per iteration.
666    * @param {Function} comparator The comparator used to compare values.
667    * @returns {*} Returns the extremum value.
668    */
669   function baseExtremum(array, iteratee, comparator) {
670     var index = -1,
671         length = array.length;
672
673     while (++index < length) {
674       var value = array[index],
675           current = iteratee(value);
676
677       if (current != null && (computed === undefined
678             ? current === current
679             : comparator(current, computed)
680           )) {
681         var computed = current,
682             result = value;
683       }
684     }
685     return result;
686   }
687
688   /**
689    * The base implementation of methods like `_.find` and `_.findKey`, without
690    * support for iteratee shorthands, which iterates over `collection` using
691    * the provided `eachFunc`.
692    *
693    * @private
694    * @param {Array|Object} collection The collection to search.
695    * @param {Function} predicate The function invoked per iteration.
696    * @param {Function} eachFunc The function to iterate over `collection`.
697    * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
698    * @returns {*} Returns the found element or its key, else `undefined`.
699    */
700   function baseFind(collection, predicate, eachFunc, retKey) {
701     var result;
702     eachFunc(collection, function(value, key, collection) {
703       if (predicate(value, key, collection)) {
704         result = retKey ? key : value;
705         return false;
706       }
707     });
708     return result;
709   }
710
711   /**
712    * The base implementation of `_.findIndex` and `_.findLastIndex` without
713    * support for iteratee shorthands.
714    *
715    * @private
716    * @param {Array} array The array to search.
717    * @param {Function} predicate The function invoked per iteration.
718    * @param {boolean} [fromRight] Specify iterating from right to left.
719    * @returns {number} Returns the index of the matched value, else `-1`.
720    */
721   function baseFindIndex(array, predicate, fromRight) {
722     var length = array.length,
723         index = fromRight ? length : -1;
724
725     while ((fromRight ? index-- : ++index < length)) {
726       if (predicate(array[index], index, array)) {
727         return index;
728       }
729     }
730     return -1;
731   }
732
733   /**
734    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
735    *
736    * @private
737    * @param {Array} array The array to search.
738    * @param {*} value The value to search for.
739    * @param {number} fromIndex The index to search from.
740    * @returns {number} Returns the index of the matched value, else `-1`.
741    */
742   function baseIndexOf(array, value, fromIndex) {
743     if (value !== value) {
744       return indexOfNaN(array, fromIndex);
745     }
746     var index = fromIndex - 1,
747         length = array.length;
748
749     while (++index < length) {
750       if (array[index] === value) {
751         return index;
752       }
753     }
754     return -1;
755   }
756
757   /**
758    * The base implementation of `_.reduce` and `_.reduceRight`, without support
759    * for iteratee shorthands, which iterates over `collection` using the provided
760    * `eachFunc`.
761    *
762    * @private
763    * @param {Array|Object} collection The collection to iterate over.
764    * @param {Function} iteratee The function invoked per iteration.
765    * @param {*} accumulator The initial value.
766    * @param {boolean} initFromCollection Specify using the first or last element of `collection` as the initial value.
767    * @param {Function} eachFunc The function to iterate over `collection`.
768    * @returns {*} Returns the accumulated value.
769    */
770   function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {
771     eachFunc(collection, function(value, index, collection) {
772       accumulator = initFromCollection
773         ? (initFromCollection = false, value)
774         : iteratee(accumulator, value, index, collection);
775     });
776     return accumulator;
777   }
778
779   /**
780    * The base implementation of `_.sortBy` which uses `comparer` to define
781    * the sort order of `array` and replaces criteria objects with their
782    * corresponding values.
783    *
784    * @private
785    * @param {Array} array The array to sort.
786    * @param {Function} comparer The function to define sort order.
787    * @returns {Array} Returns `array`.
788    */
789   function baseSortBy(array, comparer) {
790     var length = array.length;
791
792     array.sort(comparer);
793     while (length--) {
794       array[length] = array[length].value;
795     }
796     return array;
797   }
798
799   /**
800    * The base implementation of `_.sum` without support for iteratee shorthands.
801    *
802    * @private
803    * @param {Array} array The array to iterate over.
804    * @param {Function} iteratee The function invoked per iteration.
805    * @returns {number} Returns the sum.
806    */
807   function baseSum(array, iteratee) {
808     var result,
809         index = -1,
810         length = array.length;
811
812     while (++index < length) {
813       var current = iteratee(array[index]);
814       if (current !== undefined) {
815         result = result === undefined ? current : (result + current);
816       }
817     }
818     return result;
819   }
820
821   /**
822    * The base implementation of `_.times` without support for iteratee shorthands
823    * or max array length checks.
824    *
825    * @private
826    * @param {number} n The number of times to invoke `iteratee`.
827    * @param {Function} iteratee The function invoked per iteration.
828    * @returns {Array} Returns the array of results.
829    */
830   function baseTimes(n, iteratee) {
831     var index = -1,
832         result = Array(n);
833
834     while (++index < n) {
835       result[index] = iteratee(index);
836     }
837     return result;
838   }
839
840   /**
841    * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
842    * of key-value pairs for `object` corresponding to the property names of `props`.
843    *
844    * @private
845    * @param {Object} object The object to query.
846    * @param {Array} props The property names to get values for.
847    * @returns {Object} Returns the new array of key-value pairs.
848    */
849   function baseToPairs(object, props) {
850     return arrayMap(props, function(key) {
851       return [key, object[key]];
852     });
853   }
854
855   /**
856    * The base implementation of `_.unary` without support for storing wrapper metadata.
857    *
858    * @private
859    * @param {Function} func The function to cap arguments for.
860    * @returns {Function} Returns the new function.
861    */
862   function baseUnary(func) {
863     return function(value) {
864       return func(value);
865     };
866   }
867
868   /**
869    * The base implementation of `_.values` and `_.valuesIn` which creates an
870    * array of `object` property values corresponding to the property names
871    * of `props`.
872    *
873    * @private
874    * @param {Object} object The object to query.
875    * @param {Array} props The property names to get values for.
876    * @returns {Object} Returns the array of property values.
877    */
878   function baseValues(object, props) {
879     return arrayMap(props, function(key) {
880       return object[key];
881     });
882   }
883
884   /**
885    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
886    * that is not found in the character symbols.
887    *
888    * @private
889    * @param {Array} strSymbols The string symbols to inspect.
890    * @param {Array} chrSymbols The character symbols to find.
891    * @returns {number} Returns the index of the first unmatched string symbol.
892    */
893   function charsStartIndex(strSymbols, chrSymbols) {
894     var index = -1,
895         length = strSymbols.length;
896
897     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
898     return index;
899   }
900
901   /**
902    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
903    * that is not found in the character symbols.
904    *
905    * @private
906    * @param {Array} strSymbols The string symbols to inspect.
907    * @param {Array} chrSymbols The character symbols to find.
908    * @returns {number} Returns the index of the last unmatched string symbol.
909    */
910   function charsEndIndex(strSymbols, chrSymbols) {
911     var index = strSymbols.length;
912
913     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
914     return index;
915   }
916
917   /**
918    * Checks if `value` is a global object.
919    *
920    * @private
921    * @param {*} value The value to check.
922    * @returns {null|Object} Returns `value` if it's a global object, else `null`.
923    */
924   function checkGlobal(value) {
925     return (value && value.Object === Object) ? value : null;
926   }
927
928   /**
929    * Compares values to sort them in ascending order.
930    *
931    * @private
932    * @param {*} value The value to compare.
933    * @param {*} other The other value to compare.
934    * @returns {number} Returns the sort order indicator for `value`.
935    */
936   function compareAscending(value, other) {
937     if (value !== other) {
938       var valIsNull = value === null,
939           valIsUndef = value === undefined,
940           valIsReflexive = value === value;
941
942       var othIsNull = other === null,
943           othIsUndef = other === undefined,
944           othIsReflexive = other === other;
945
946       if ((value > other && !othIsNull) || !valIsReflexive ||
947           (valIsNull && !othIsUndef && othIsReflexive) ||
948           (valIsUndef && othIsReflexive)) {
949         return 1;
950       }
951       if ((value < other && !valIsNull) || !othIsReflexive ||
952           (othIsNull && !valIsUndef && valIsReflexive) ||
953           (othIsUndef && valIsReflexive)) {
954         return -1;
955       }
956     }
957     return 0;
958   }
959
960   /**
961    * Used by `_.orderBy` to compare multiple properties of a value to another
962    * and stable sort them.
963    *
964    * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
965    * specify an order of "desc" for descending or "asc" for ascending sort order
966    * of corresponding values.
967    *
968    * @private
969    * @param {Object} object The object to compare.
970    * @param {Object} other The other object to compare.
971    * @param {boolean[]|string[]} orders The order to sort by for each property.
972    * @returns {number} Returns the sort order indicator for `object`.
973    */
974   function compareMultiple(object, other, orders) {
975     var index = -1,
976         objCriteria = object.criteria,
977         othCriteria = other.criteria,
978         length = objCriteria.length,
979         ordersLength = orders.length;
980
981     while (++index < length) {
982       var result = compareAscending(objCriteria[index], othCriteria[index]);
983       if (result) {
984         if (index >= ordersLength) {
985           return result;
986         }
987         var order = orders[index];
988         return result * (order == 'desc' ? -1 : 1);
989       }
990     }
991     // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
992     // that causes it, under certain circumstances, to provide the same value for
993     // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
994     // for more details.
995     //
996     // This also ensures a stable sort in V8 and other engines.
997     // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
998     return object.index - other.index;
999   }
1000
1001   /**
1002    * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
1003    *
1004    * @private
1005    * @param {string} letter The matched letter to deburr.
1006    * @returns {string} Returns the deburred letter.
1007    */
1008   function deburrLetter(letter) {
1009     return deburredLetters[letter];
1010   }
1011
1012   /**
1013    * Used by `_.escape` to convert characters to HTML entities.
1014    *
1015    * @private
1016    * @param {string} chr The matched character to escape.
1017    * @returns {string} Returns the escaped character.
1018    */
1019   function escapeHtmlChar(chr) {
1020     return htmlEscapes[chr];
1021   }
1022
1023   /**
1024    * Used by `_.template` to escape characters for inclusion in compiled string literals.
1025    *
1026    * @private
1027    * @param {string} chr The matched character to escape.
1028    * @returns {string} Returns the escaped character.
1029    */
1030   function escapeStringChar(chr) {
1031     return '\\' + stringEscapes[chr];
1032   }
1033
1034   /**
1035    * Gets the index at which the first occurrence of `NaN` is found in `array`.
1036    *
1037    * @private
1038    * @param {Array} array The array to search.
1039    * @param {number} fromIndex The index to search from.
1040    * @param {boolean} [fromRight] Specify iterating from right to left.
1041    * @returns {number} Returns the index of the matched `NaN`, else `-1`.
1042    */
1043   function indexOfNaN(array, fromIndex, fromRight) {
1044     var length = array.length,
1045         index = fromIndex + (fromRight ? 0 : -1);
1046
1047     while ((fromRight ? index-- : ++index < length)) {
1048       var other = array[index];
1049       if (other !== other) {
1050         return index;
1051       }
1052     }
1053     return -1;
1054   }
1055
1056   /**
1057    * Checks if `value` is a host object in IE < 9.
1058    *
1059    * @private
1060    * @param {*} value The value to check.
1061    * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
1062    */
1063   function isHostObject(value) {
1064     // Many host objects are `Object` objects that can coerce to strings
1065     // despite having improperly defined `toString` methods.
1066     var result = false;
1067     if (value != null && typeof value.toString != 'function') {
1068       try {
1069         result = !!(value + '');
1070       } catch (e) {}
1071     }
1072     return result;
1073   }
1074
1075   /**
1076    * Checks if `value` is a valid array-like index.
1077    *
1078    * @private
1079    * @param {*} value The value to check.
1080    * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
1081    * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
1082    */
1083   function isIndex(value, length) {
1084     value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
1085     length = length == null ? MAX_SAFE_INTEGER : length;
1086     return value > -1 && value % 1 == 0 && value < length;
1087   }
1088
1089   /**
1090    * Converts `iterator` to an array.
1091    *
1092    * @private
1093    * @param {Object} iterator The iterator to convert.
1094    * @returns {Array} Returns the converted array.
1095    */
1096   function iteratorToArray(iterator) {
1097     var data,
1098         result = [];
1099
1100     while (!(data = iterator.next()).done) {
1101       result.push(data.value);
1102     }
1103     return result;
1104   }
1105
1106   /**
1107    * Converts `map` to an array.
1108    *
1109    * @private
1110    * @param {Object} map The map to convert.
1111    * @returns {Array} Returns the converted array.
1112    */
1113   function mapToArray(map) {
1114     var index = -1,
1115         result = Array(map.size);
1116
1117     map.forEach(function(value, key) {
1118       result[++index] = [key, value];
1119     });
1120     return result;
1121   }
1122
1123   /**
1124    * Replaces all `placeholder` elements in `array` with an internal placeholder
1125    * and returns an array of their indexes.
1126    *
1127    * @private
1128    * @param {Array} array The array to modify.
1129    * @param {*} placeholder The placeholder to replace.
1130    * @returns {Array} Returns the new array of placeholder indexes.
1131    */
1132   function replaceHolders(array, placeholder) {
1133     var index = -1,
1134         length = array.length,
1135         resIndex = -1,
1136         result = [];
1137
1138     while (++index < length) {
1139       if (array[index] === placeholder) {
1140         array[index] = PLACEHOLDER;
1141         result[++resIndex] = index;
1142       }
1143     }
1144     return result;
1145   }
1146
1147   /**
1148    * Converts `set` to an array.
1149    *
1150    * @private
1151    * @param {Object} set The set to convert.
1152    * @returns {Array} Returns the converted array.
1153    */
1154   function setToArray(set) {
1155     var index = -1,
1156         result = Array(set.size);
1157
1158     set.forEach(function(value) {
1159       result[++index] = value;
1160     });
1161     return result;
1162   }
1163
1164   /**
1165    * Gets the number of symbols in `string`.
1166    *
1167    * @param {string} string The string to inspect.
1168    * @returns {number} Returns the string size.
1169    */
1170   function stringSize(string) {
1171     if (!(string && reHasComplexSymbol.test(string))) {
1172       return string.length;
1173     }
1174     var result = reComplexSymbol.lastIndex = 0;
1175     while (reComplexSymbol.test(string)) {
1176       result++;
1177     }
1178     return result;
1179   }
1180
1181   /**
1182    * Converts `string` to an array.
1183    *
1184    * @private
1185    * @param {string} string The string to convert.
1186    * @returns {Array} Returns the converted array.
1187    */
1188   function stringToArray(string) {
1189     return string.match(reComplexSymbol);
1190   }
1191
1192   /**
1193    * Used by `_.unescape` to convert HTML entities to characters.
1194    *
1195    * @private
1196    * @param {string} chr The matched character to unescape.
1197    * @returns {string} Returns the unescaped character.
1198    */
1199   function unescapeHtmlChar(chr) {
1200     return htmlUnescapes[chr];
1201   }
1202
1203   /*--------------------------------------------------------------------------*/
1204
1205   /**
1206    * Create a new pristine `lodash` function using the `context` object.
1207    *
1208    * @static
1209    * @memberOf _
1210    * @category Util
1211    * @param {Object} [context=root] The context object.
1212    * @returns {Function} Returns a new `lodash` function.
1213    * @example
1214    *
1215    * _.mixin({ 'foo': _.constant('foo') });
1216    *
1217    * var lodash = _.runInContext();
1218    * lodash.mixin({ 'bar': lodash.constant('bar') });
1219    *
1220    * _.isFunction(_.foo);
1221    * // => true
1222    * _.isFunction(_.bar);
1223    * // => false
1224    *
1225    * lodash.isFunction(lodash.foo);
1226    * // => false
1227    * lodash.isFunction(lodash.bar);
1228    * // => true
1229    *
1230    * // using `context` to mock `Date#getTime` use in `_.now`
1231    * var mock = _.runInContext({
1232    *   'Date': function() {
1233    *     return { 'getTime': getTimeMock };
1234    *   }
1235    * });
1236    *
1237    * // or creating a suped-up `defer` in Node.js
1238    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1239    */
1240   function runInContext(context) {
1241     context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
1242
1243     /** Built-in constructor references. */
1244     var Date = context.Date,
1245         Error = context.Error,
1246         Math = context.Math,
1247         RegExp = context.RegExp,
1248         TypeError = context.TypeError;
1249
1250     /** Used for built-in method references. */
1251     var arrayProto = context.Array.prototype,
1252         objectProto = context.Object.prototype;
1253
1254     /** Used to resolve the decompiled source of functions. */
1255     var funcToString = context.Function.prototype.toString;
1256
1257     /** Used to check objects for own properties. */
1258     var hasOwnProperty = objectProto.hasOwnProperty;
1259
1260     /** Used to generate unique IDs. */
1261     var idCounter = 0;
1262
1263     /** Used to infer the `Object` constructor. */
1264     var objectCtorString = funcToString.call(Object);
1265
1266     /**
1267      * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1268      * of values.
1269      */
1270     var objectToString = objectProto.toString;
1271
1272     /** Used to restore the original `_` reference in `_.noConflict`. */
1273     var oldDash = root._;
1274
1275     /** Used to detect if a method is native. */
1276     var reIsNative = RegExp('^' +
1277       funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1278       .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1279     );
1280
1281     /** Built-in value references. */
1282     var _Symbol = context.Symbol,
1283         Reflect = context.Reflect,
1284         Uint8Array = context.Uint8Array,
1285         clearTimeout = context.clearTimeout,
1286         enumerate = Reflect ? Reflect.enumerate : undefined,
1287         getPrototypeOf = Object.getPrototypeOf,
1288         getOwnPropertySymbols = Object.getOwnPropertySymbols,
1289         iteratorSymbol = typeof (iteratorSymbol = _Symbol && _Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
1290         propertyIsEnumerable = objectProto.propertyIsEnumerable,
1291         setTimeout = context.setTimeout,
1292         splice = arrayProto.splice;
1293
1294     /* Built-in method references for those with the same name as other `lodash` methods. */
1295     var nativeCeil = Math.ceil,
1296         nativeFloor = Math.floor,
1297         nativeIsFinite = context.isFinite,
1298         nativeJoin = arrayProto.join,
1299         nativeKeys = Object.keys,
1300         nativeMax = Math.max,
1301         nativeMin = Math.min,
1302         nativeParseInt = context.parseInt,
1303         nativeRandom = Math.random,
1304         nativeReverse = arrayProto.reverse;
1305
1306     /* Built-in method references that are verified to be native. */
1307     var Map = getNative(context, 'Map'),
1308         Set = getNative(context, 'Set'),
1309         WeakMap = getNative(context, 'WeakMap'),
1310         nativeCreate = getNative(Object, 'create');
1311
1312     /** Used to store function metadata. */
1313     var metaMap = WeakMap && new WeakMap;
1314
1315     /** Used to detect maps and sets. */
1316     var mapCtorString = Map ? funcToString.call(Map) : '',
1317         setCtorString = Set ? funcToString.call(Set) : '';
1318
1319     /** Used to convert symbols to primitives and strings. */
1320     var symbolProto = _Symbol ? _Symbol.prototype : undefined,
1321         symbolValueOf = _Symbol ? symbolProto.valueOf : undefined,
1322         symbolToString = _Symbol ? symbolProto.toString : undefined;
1323
1324     /** Used to lookup unminified function names. */
1325     var realNames = {};
1326
1327     /*------------------------------------------------------------------------*/
1328
1329     /**
1330      * Creates a `lodash` object which wraps `value` to enable implicit method
1331      * chaining. Methods that operate on and return arrays, collections, and
1332      * functions can be chained together. Methods that retrieve a single value or
1333      * may return a primitive value will automatically end the chain sequence and
1334      * return the unwrapped value. Otherwise, the value must be unwrapped with
1335      * `_#value`.
1336      *
1337      * Explicit chaining, which must be unwrapped with `_#value` in all cases,
1338      * may be enabled using `_.chain`.
1339      *
1340      * The execution of chained methods is lazy, that is, it's deferred until
1341      * `_#value` is implicitly or explicitly called.
1342      *
1343      * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
1344      * fusion is an optimization to merge iteratee calls; this avoids the creation
1345      * of intermediate arrays and can greatly reduce the number of iteratee executions.
1346      * Sections of a chain sequence qualify for shortcut fusion if the section is
1347      * applied to an array of at least two hundred elements and any iteratees
1348      * accept only one argument. The heuristic for whether a section qualifies
1349      * for shortcut fusion is subject to change.
1350      *
1351      * Chaining is supported in custom builds as long as the `_#value` method is
1352      * directly or indirectly included in the build.
1353      *
1354      * In addition to lodash methods, wrappers have `Array` and `String` methods.
1355      *
1356      * The wrapper `Array` methods are:
1357      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1358      *
1359      * The wrapper `String` methods are:
1360      * `replace` and `split`
1361      *
1362      * The wrapper methods that support shortcut fusion are:
1363      * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1364      * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1365      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1366      *
1367      * The chainable wrapper methods are:
1368      * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
1369      * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
1370      * `compact`, `concat`, `conforms`,  `constant`, `countBy`, `create`, `curry`,
1371      * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
1372      * `differenceBy`, `differenceWith`,  `drop`, `dropRight`, `dropRightWhile`,
1373      * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
1374      * `flowRight`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
1375      * `forOwnRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
1376      * `intersection`, `intersectionBy`, `intersectionWith`, invert`, `invokeMap`,
1377      * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`,
1378      * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`,
1379      * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`,
1380      * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`,
1381      * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`,
1382      * `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`,
1383      * `reject`, `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`,
1384      * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`,
1385      * `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`,
1386      * `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`,
1387      * `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`,
1388      * `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `without`,
1389      * `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, and `zipWith`
1390      *
1391      * The wrapper methods that are **not** chainable by default are:
1392      * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1393      * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
1394      * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
1395      * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `get`, `gt`, `gte`,
1396      * `has`, `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`,
1397      * `invoke`, `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`,
1398      * `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`,
1399      * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`,
1400      * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
1401      * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
1402      * `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, `last`,
1403      * `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`,
1404      * `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, `padEnd`,
1405      * `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`,
1406      * `result`, `round`, `runInContext`, `sample`, `shift`, `size`, `snakeCase`,
1407      * `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`,
1408      * `startCase`, `startsWith`, `subtract`, `sum`, sumBy`, `template`, `times`,
1409      * `toLower`, `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, toString`,
1410      * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
1411      * `upperCase`, `upperFirst`, `value`, and `words`
1412      *
1413      * @name _
1414      * @constructor
1415      * @category Seq
1416      * @param {*} value The value to wrap in a `lodash` instance.
1417      * @returns {Object} Returns the new `lodash` wrapper instance.
1418      * @example
1419      *
1420      * function square(n) {
1421      *   return n * n;
1422      * }
1423      *
1424      * var wrapped = _([1, 2, 3]);
1425      *
1426      * // returns an unwrapped value
1427      * wrapped.reduce(_.add);
1428      * // => 6
1429      *
1430      * // returns a wrapped value
1431      * var squares = wrapped.map(square);
1432      *
1433      * _.isArray(squares);
1434      * // => false
1435      *
1436      * _.isArray(squares.value());
1437      * // => true
1438      */
1439     function lodash(value) {
1440       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1441         if (value instanceof LodashWrapper) {
1442           return value;
1443         }
1444         if (hasOwnProperty.call(value, '__wrapped__')) {
1445           return wrapperClone(value);
1446         }
1447       }
1448       return new LodashWrapper(value);
1449     }
1450
1451     /**
1452      * The function whose prototype all chaining wrappers inherit from.
1453      *
1454      * @private
1455      */
1456     function baseLodash() {
1457       // No operation performed.
1458     }
1459
1460     /**
1461      * The base constructor for creating `lodash` wrapper objects.
1462      *
1463      * @private
1464      * @param {*} value The value to wrap.
1465      * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
1466      */
1467     function LodashWrapper(value, chainAll) {
1468       this.__wrapped__ = value;
1469       this.__actions__ = [];
1470       this.__chain__ = !!chainAll;
1471       this.__index__ = 0;
1472       this.__values__ = undefined;
1473     }
1474
1475     /**
1476      * By default, the template delimiters used by lodash are like those in
1477      * embedded Ruby (ERB). Change the following template settings to use
1478      * alternative delimiters.
1479      *
1480      * @static
1481      * @memberOf _
1482      * @type Object
1483      */
1484     lodash.templateSettings = {
1485
1486       /**
1487        * Used to detect `data` property values to be HTML-escaped.
1488        *
1489        * @memberOf _.templateSettings
1490        * @type RegExp
1491        */
1492       'escape': reEscape,
1493
1494       /**
1495        * Used to detect code to be evaluated.
1496        *
1497        * @memberOf _.templateSettings
1498        * @type RegExp
1499        */
1500       'evaluate': reEvaluate,
1501
1502       /**
1503        * Used to detect `data` property values to inject.
1504        *
1505        * @memberOf _.templateSettings
1506        * @type RegExp
1507        */
1508       'interpolate': reInterpolate,
1509
1510       /**
1511        * Used to reference the data object in the template text.
1512        *
1513        * @memberOf _.templateSettings
1514        * @type string
1515        */
1516       'variable': '',
1517
1518       /**
1519        * Used to import variables into the compiled template.
1520        *
1521        * @memberOf _.templateSettings
1522        * @type Object
1523        */
1524       'imports': {
1525
1526         /**
1527          * A reference to the `lodash` function.
1528          *
1529          * @memberOf _.templateSettings.imports
1530          * @type Function
1531          */
1532         '_': lodash
1533       }
1534     };
1535
1536     /*------------------------------------------------------------------------*/
1537
1538     /**
1539      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1540      *
1541      * @private
1542      * @param {*} value The value to wrap.
1543      */
1544     function LazyWrapper(value) {
1545       this.__wrapped__ = value;
1546       this.__actions__ = [];
1547       this.__dir__ = 1;
1548       this.__filtered__ = false;
1549       this.__iteratees__ = [];
1550       this.__takeCount__ = MAX_ARRAY_LENGTH;
1551       this.__views__ = [];
1552     }
1553
1554     /**
1555      * Creates a clone of the lazy wrapper object.
1556      *
1557      * @private
1558      * @name clone
1559      * @memberOf LazyWrapper
1560      * @returns {Object} Returns the cloned `LazyWrapper` object.
1561      */
1562     function lazyClone() {
1563       var result = new LazyWrapper(this.__wrapped__);
1564       result.__actions__ = copyArray(this.__actions__);
1565       result.__dir__ = this.__dir__;
1566       result.__filtered__ = this.__filtered__;
1567       result.__iteratees__ = copyArray(this.__iteratees__);
1568       result.__takeCount__ = this.__takeCount__;
1569       result.__views__ = copyArray(this.__views__);
1570       return result;
1571     }
1572
1573     /**
1574      * Reverses the direction of lazy iteration.
1575      *
1576      * @private
1577      * @name reverse
1578      * @memberOf LazyWrapper
1579      * @returns {Object} Returns the new reversed `LazyWrapper` object.
1580      */
1581     function lazyReverse() {
1582       if (this.__filtered__) {
1583         var result = new LazyWrapper(this);
1584         result.__dir__ = -1;
1585         result.__filtered__ = true;
1586       } else {
1587         result = this.clone();
1588         result.__dir__ *= -1;
1589       }
1590       return result;
1591     }
1592
1593     /**
1594      * Extracts the unwrapped value from its lazy wrapper.
1595      *
1596      * @private
1597      * @name value
1598      * @memberOf LazyWrapper
1599      * @returns {*} Returns the unwrapped value.
1600      */
1601     function lazyValue() {
1602       var array = this.__wrapped__.value(),
1603           dir = this.__dir__,
1604           isArr = isArray(array),
1605           isRight = dir < 0,
1606           arrLength = isArr ? array.length : 0,
1607           view = getView(0, arrLength, this.__views__),
1608           start = view.start,
1609           end = view.end,
1610           length = end - start,
1611           index = isRight ? end : (start - 1),
1612           iteratees = this.__iteratees__,
1613           iterLength = iteratees.length,
1614           resIndex = 0,
1615           takeCount = nativeMin(length, this.__takeCount__);
1616
1617       if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
1618         return baseWrapperValue(array, this.__actions__);
1619       }
1620       var result = [];
1621
1622       outer:
1623       while (length-- && resIndex < takeCount) {
1624         index += dir;
1625
1626         var iterIndex = -1,
1627             value = array[index];
1628
1629         while (++iterIndex < iterLength) {
1630           var data = iteratees[iterIndex],
1631               iteratee = data.iteratee,
1632               type = data.type,
1633               computed = iteratee(value);
1634
1635           if (type == LAZY_MAP_FLAG) {
1636             value = computed;
1637           } else if (!computed) {
1638             if (type == LAZY_FILTER_FLAG) {
1639               continue outer;
1640             } else {
1641               break outer;
1642             }
1643           }
1644         }
1645         result[resIndex++] = value;
1646       }
1647       return result;
1648     }
1649
1650     /*------------------------------------------------------------------------*/
1651
1652     /**
1653      * Creates an hash object.
1654      *
1655      * @private
1656      * @returns {Object} Returns the new hash object.
1657      */
1658     function Hash() {}
1659
1660     /**
1661      * Removes `key` and its value from the hash.
1662      *
1663      * @private
1664      * @param {Object} hash The hash to modify.
1665      * @param {string} key The key of the value to remove.
1666      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1667      */
1668     function hashDelete(hash, key) {
1669       return hashHas(hash, key) && delete hash[key];
1670     }
1671
1672     /**
1673      * Gets the hash value for `key`.
1674      *
1675      * @private
1676      * @param {Object} hash The hash to query.
1677      * @param {string} key The key of the value to get.
1678      * @returns {*} Returns the entry value.
1679      */
1680     function hashGet(hash, key) {
1681       if (nativeCreate) {
1682         var result = hash[key];
1683         return result === HASH_UNDEFINED ? undefined : result;
1684       }
1685       return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
1686     }
1687
1688     /**
1689      * Checks if a hash value for `key` exists.
1690      *
1691      * @private
1692      * @param {Object} hash The hash to query.
1693      * @param {string} key The key of the entry to check.
1694      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1695      */
1696     function hashHas(hash, key) {
1697       return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
1698     }
1699
1700     /**
1701      * Sets the hash `key` to `value`.
1702      *
1703      * @private
1704      * @param {Object} hash The hash to modify.
1705      * @param {string} key The key of the value to set.
1706      * @param {*} value The value to set.
1707      */
1708     function hashSet(hash, key, value) {
1709       hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1710     }
1711
1712     /*------------------------------------------------------------------------*/
1713
1714     /**
1715      * Creates a map cache object to store key-value pairs.
1716      *
1717      * @private
1718      * @param {Array} [values] The values to cache.
1719      */
1720     function MapCache(values) {
1721       var index = -1,
1722           length = values ? values.length : 0;
1723
1724       this.clear();
1725       while (++index < length) {
1726         var entry = values[index];
1727         this.set(entry[0], entry[1]);
1728       }
1729     }
1730
1731     /**
1732      * Removes all key-value entries from the map.
1733      *
1734      * @private
1735      * @name clear
1736      * @memberOf MapCache
1737      */
1738     function mapClear() {
1739       this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], 'string': new Hash };
1740     }
1741
1742     /**
1743      * Removes `key` and its value from the map.
1744      *
1745      * @private
1746      * @name delete
1747      * @memberOf MapCache
1748      * @param {string} key The key of the value to remove.
1749      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1750      */
1751     function mapDelete(key) {
1752       var data = this.__data__;
1753       if (isKeyable(key)) {
1754         return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
1755       }
1756       return Map ? data.map['delete'](key) : assocDelete(data.map, key);
1757     }
1758
1759     /**
1760      * Gets the map value for `key`.
1761      *
1762      * @private
1763      * @name get
1764      * @memberOf MapCache
1765      * @param {string} key The key of the value to get.
1766      * @returns {*} Returns the entry value.
1767      */
1768     function mapGet(key) {
1769       var data = this.__data__;
1770       if (isKeyable(key)) {
1771         return hashGet(typeof key == 'string' ? data.string : data.hash, key);
1772       }
1773       return Map ? data.map.get(key) : assocGet(data.map, key);
1774     }
1775
1776     /**
1777      * Checks if a map value for `key` exists.
1778      *
1779      * @private
1780      * @name has
1781      * @memberOf MapCache
1782      * @param {string} key The key of the entry to check.
1783      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1784      */
1785     function mapHas(key) {
1786       var data = this.__data__;
1787       if (isKeyable(key)) {
1788         return hashHas(typeof key == 'string' ? data.string : data.hash, key);
1789       }
1790       return Map ? data.map.has(key) : assocHas(data.map, key);
1791     }
1792
1793     /**
1794      * Sets the map `key` to `value`.
1795      *
1796      * @private
1797      * @name set
1798      * @memberOf MapCache
1799      * @param {string} key The key of the value to set.
1800      * @param {*} value The value to set.
1801      * @returns {Object} Returns the map cache object.
1802      */
1803     function mapSet(key, value) {
1804       var data = this.__data__;
1805       if (isKeyable(key)) {
1806         hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
1807       } else if (Map) {
1808         data.map.set(key, value);
1809       } else {
1810         assocSet(data.map, key, value);
1811       }
1812       return this;
1813     }
1814
1815     /*------------------------------------------------------------------------*/
1816
1817     /**
1818      *
1819      * Creates a set cache object to store unique values.
1820      *
1821      * @private
1822      * @param {Array} [values] The values to cache.
1823      */
1824     function SetCache(values) {
1825       var index = -1,
1826           length = values ? values.length : 0;
1827
1828       this.__data__ = new MapCache;
1829       while (++index < length) {
1830         this.push(values[index]);
1831       }
1832     }
1833
1834     /**
1835      * Checks if `value` is in `cache`.
1836      *
1837      * @private
1838      * @param {Object} cache The set cache to search.
1839      * @param {*} value The value to search for.
1840      * @returns {number} Returns `true` if `value` is found, else `false`.
1841      */
1842     function cacheHas(cache, value) {
1843       var map = cache.__data__;
1844       if (isKeyable(value)) {
1845         var data = map.__data__,
1846             hash = typeof value == 'string' ? data.string : data.hash;
1847
1848         return hash[value] === HASH_UNDEFINED;
1849       }
1850       return map.has(value);
1851     }
1852
1853     /**
1854      * Adds `value` to the set cache.
1855      *
1856      * @private
1857      * @name push
1858      * @memberOf SetCache
1859      * @param {*} value The value to cache.
1860      */
1861     function cachePush(value) {
1862       var map = this.__data__;
1863       if (isKeyable(value)) {
1864         var data = map.__data__,
1865             hash = typeof value == 'string' ? data.string : data.hash;
1866
1867         hash[value] = HASH_UNDEFINED;
1868       }
1869       else {
1870         map.set(value, HASH_UNDEFINED);
1871       }
1872     }
1873
1874     /*------------------------------------------------------------------------*/
1875
1876     /**
1877      * Creates a stack cache object to store key-value pairs.
1878      *
1879      * @private
1880      * @param {Array} [values] The values to cache.
1881      */
1882     function Stack(values) {
1883       var index = -1,
1884           length = values ? values.length : 0;
1885
1886       this.clear();
1887       while (++index < length) {
1888         var entry = values[index];
1889         this.set(entry[0], entry[1]);
1890       }
1891     }
1892
1893     /**
1894      * Removes all key-value entries from the stack.
1895      *
1896      * @private
1897      * @name clear
1898      * @memberOf Stack
1899      */
1900     function stackClear() {
1901       this.__data__ = { 'array': [], 'map': null };
1902     }
1903
1904     /**
1905      * Removes `key` and its value from the stack.
1906      *
1907      * @private
1908      * @name delete
1909      * @memberOf Stack
1910      * @param {string} key The key of the value to remove.
1911      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1912      */
1913     function stackDelete(key) {
1914       var data = this.__data__,
1915           array = data.array;
1916
1917       return array ? assocDelete(array, key) : data.map['delete'](key);
1918     }
1919
1920     /**
1921      * Gets the stack value for `key`.
1922      *
1923      * @private
1924      * @name get
1925      * @memberOf Stack
1926      * @param {string} key The key of the value to get.
1927      * @returns {*} Returns the entry value.
1928      */
1929     function stackGet(key) {
1930       var data = this.__data__,
1931           array = data.array;
1932
1933       return array ? assocGet(array, key) : data.map.get(key);
1934     }
1935
1936     /**
1937      * Checks if a stack value for `key` exists.
1938      *
1939      * @private
1940      * @name has
1941      * @memberOf Stack
1942      * @param {string} key The key of the entry to check.
1943      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1944      */
1945     function stackHas(key) {
1946       var data = this.__data__,
1947           array = data.array;
1948
1949       return array ? assocHas(array, key) : data.map.has(key);
1950     }
1951
1952     /**
1953      * Sets the stack `key` to `value`.
1954      *
1955      * @private
1956      * @name set
1957      * @memberOf Stack
1958      * @param {string} key The key of the value to set.
1959      * @param {*} value The value to set.
1960      * @returns {Object} Returns the stack cache object.
1961      */
1962     function stackSet(key, value) {
1963       var data = this.__data__,
1964           array = data.array;
1965
1966       if (array) {
1967         if (array.length < (LARGE_ARRAY_SIZE - 1)) {
1968           assocSet(array, key, value);
1969         } else {
1970           data.array = null;
1971           data.map = new MapCache(array);
1972         }
1973       }
1974       var map = data.map;
1975       if (map) {
1976         map.set(key, value);
1977       }
1978       return this;
1979     }
1980
1981     /*------------------------------------------------------------------------*/
1982
1983     /**
1984      * Removes `key` and its value from the associative array.
1985      *
1986      * @private
1987      * @param {Array} array The array to query.
1988      * @param {string} key The key of the value to remove.
1989      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1990      */
1991     function assocDelete(array, key) {
1992       var index = assocIndexOf(array, key);
1993       if (index < 0) {
1994         return false;
1995       }
1996       var lastIndex = array.length - 1;
1997       if (index == lastIndex) {
1998         array.pop();
1999       } else {
2000         splice.call(array, index, 1);
2001       }
2002       return true;
2003     }
2004
2005     /**
2006      * Gets the associative array value for `key`.
2007      *
2008      * @private
2009      * @param {Array} array The array to query.
2010      * @param {string} key The key of the value to get.
2011      * @returns {*} Returns the entry value.
2012      */
2013     function assocGet(array, key) {
2014       var index = assocIndexOf(array, key);
2015       return index < 0 ? undefined : array[index][1];
2016     }
2017
2018     /**
2019      * Checks if an associative array value for `key` exists.
2020      *
2021      * @private
2022      * @param {Array} array The array to query.
2023      * @param {string} key The key of the entry to check.
2024      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2025      */
2026     function assocHas(array, key) {
2027       return assocIndexOf(array, key) > -1;
2028     }
2029
2030     /**
2031      * Gets the index at which the first occurrence of `key` is found in `array`
2032      * of key-value pairs.
2033      *
2034      * @private
2035      * @param {Array} array The array to search.
2036      * @param {*} key The key to search for.
2037      * @returns {number} Returns the index of the matched value, else `-1`.
2038      */
2039     function assocIndexOf(array, key) {
2040       var length = array.length;
2041       while (length--) {
2042         if (eq(array[length][0], key)) {
2043           return length;
2044         }
2045       }
2046       return -1;
2047     }
2048
2049     /**
2050      * Sets the associative array `key` to `value`.
2051      *
2052      * @private
2053      * @param {Array} array The array to modify.
2054      * @param {string} key The key of the value to set.
2055      * @param {*} value The value to set.
2056      */
2057     function assocSet(array, key, value) {
2058       var index = assocIndexOf(array, key);
2059       if (index < 0) {
2060         array.push([key, value]);
2061       } else {
2062         array[index][1] = value;
2063       }
2064     }
2065
2066     /*------------------------------------------------------------------------*/
2067
2068     /**
2069      * Used by `_.defaults` to customize its `_.assignIn` use.
2070      *
2071      * @private
2072      * @param {*} objValue The destination value.
2073      * @param {*} srcValue The source value.
2074      * @param {string} key The key of the property to assign.
2075      * @param {Object} object The parent object of `objValue`.
2076      * @returns {*} Returns the value to assign.
2077      */
2078     function assignInDefaults(objValue, srcValue, key, object) {
2079       if (objValue === undefined ||
2080           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2081         return srcValue;
2082       }
2083       return objValue;
2084     }
2085
2086     /**
2087      * This function is like `assignValue` except that it doesn't assign `undefined` values.
2088      *
2089      * @private
2090      * @param {Object} object The object to modify.
2091      * @param {string} key The key of the property to assign.
2092      * @param {*} value The value to assign.
2093      */
2094     function assignMergeValue(object, key, value) {
2095       if ((value !== undefined && !eq(object[key], value)) ||
2096           (typeof key == 'number' && value === undefined && !(key in object))) {
2097         object[key] = value;
2098       }
2099     }
2100
2101     /**
2102      * Assigns `value` to `key` of `object` if the existing value is not equivalent
2103      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
2104      * for equality comparisons.
2105      *
2106      * @private
2107      * @param {Object} object The object to modify.
2108      * @param {string} key The key of the property to assign.
2109      * @param {*} value The value to assign.
2110      */
2111     function assignValue(object, key, value) {
2112       var objValue = object[key];
2113       if ((!eq(objValue, value) ||
2114             (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
2115           (value === undefined && !(key in object))) {
2116         object[key] = value;
2117       }
2118     }
2119
2120     /**
2121      * The base implementation of `_.assign` without support for multiple sources
2122      * or `customizer` functions.
2123      *
2124      * @private
2125      * @param {Object} object The destination object.
2126      * @param {Object} source The source object.
2127      * @returns {Object} Returns `object`.
2128      */
2129     function baseAssign(object, source) {
2130       return object && copyObject(source, keys(source), object);
2131     }
2132
2133     /**
2134      * The base implementation of `_.at` without support for individual paths.
2135      *
2136      * @private
2137      * @param {Object} object The object to iterate over.
2138      * @param {string[]} paths The property paths of elements to pick.
2139      * @returns {Array} Returns the new array of picked elements.
2140      */
2141     function baseAt(object, paths) {
2142       var index = -1,
2143           isNil = object == null,
2144           length = paths.length,
2145           result = Array(length);
2146
2147       while (++index < length) {
2148         result[index] = isNil ? undefined : get(object, paths[index]);
2149       }
2150       return result;
2151     }
2152
2153     /**
2154      * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
2155      *
2156      * @private
2157      * @param {number} number The number to clamp.
2158      * @param {number} [lower] The lower bound.
2159      * @param {number} upper The upper bound.
2160      * @returns {number} Returns the clamped number.
2161      */
2162     function baseClamp(number, lower, upper) {
2163       if (number === number) {
2164         if (upper !== undefined) {
2165           number = number <= upper ? number : upper;
2166         }
2167         if (lower !== undefined) {
2168           number = number >= lower ? number : lower;
2169         }
2170       }
2171       return number;
2172     }
2173
2174     /**
2175      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2176      * traversed objects.
2177      *
2178      * @private
2179      * @param {*} value The value to clone.
2180      * @param {boolean} [isDeep] Specify a deep clone.
2181      * @param {Function} [customizer] The function to customize cloning.
2182      * @param {string} [key] The key of `value`.
2183      * @param {Object} [object] The parent object of `value`.
2184      * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2185      * @returns {*} Returns the cloned value.
2186      */
2187     function baseClone(value, isDeep, customizer, key, object, stack) {
2188       var result;
2189       if (customizer) {
2190         result = object ? customizer(value, key, object, stack) : customizer(value);
2191       }
2192       if (result !== undefined) {
2193         return result;
2194       }
2195       if (!isObject(value)) {
2196         return value;
2197       }
2198       var isArr = isArray(value);
2199       if (isArr) {
2200         result = initCloneArray(value);
2201         if (!isDeep) {
2202           return copyArray(value, result);
2203         }
2204       } else {
2205         var tag = getTag(value),
2206             isFunc = tag == funcTag || tag == genTag;
2207
2208         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2209           if (isHostObject(value)) {
2210             return object ? value : {};
2211           }
2212           result = initCloneObject(isFunc ? {} : value);
2213           if (!isDeep) {
2214             return copySymbols(value, baseAssign(result, value));
2215           }
2216         } else {
2217           return cloneableTags[tag]
2218             ? initCloneByTag(value, tag, isDeep)
2219             : (object ? value : {});
2220         }
2221       }
2222       // Check for circular references and return its corresponding clone.
2223       stack || (stack = new Stack);
2224       var stacked = stack.get(value);
2225       if (stacked) {
2226         return stacked;
2227       }
2228       stack.set(value, result);
2229
2230       // Recursively populate clone (susceptible to call stack limits).
2231       (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
2232         assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
2233       });
2234       return isArr ? result : copySymbols(value, result);
2235     }
2236
2237     /**
2238      * The base implementation of `_.conforms` which doesn't clone `source`.
2239      *
2240      * @private
2241      * @param {Object} source The object of property predicates to conform to.
2242      * @returns {Function} Returns the new function.
2243      */
2244     function baseConforms(source) {
2245       var props = keys(source),
2246           length = props.length;
2247
2248       return function(object) {
2249         if (object == null) {
2250           return !length;
2251         }
2252         var index = length;
2253         while (index--) {
2254           var key = props[index],
2255               predicate = source[key],
2256               value = object[key];
2257
2258           if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
2259             return false;
2260           }
2261         }
2262         return true;
2263       };
2264     }
2265
2266     /**
2267      * The base implementation of `_.create` without support for assigning
2268      * properties to the created object.
2269      *
2270      * @private
2271      * @param {Object} prototype The object to inherit from.
2272      * @returns {Object} Returns the new object.
2273      */
2274     var baseCreate = (function() {
2275       function object() {}
2276       return function(prototype) {
2277         if (isObject(prototype)) {
2278           object.prototype = prototype;
2279           var result = new object;
2280           object.prototype = undefined;
2281         }
2282         return result || {};
2283       };
2284     }());
2285
2286     /**
2287      * The base implementation of `_.delay` and `_.defer` which accepts an array
2288      * of `func` arguments.
2289      *
2290      * @private
2291      * @param {Function} func The function to delay.
2292      * @param {number} wait The number of milliseconds to delay invocation.
2293      * @param {Object} args The arguments provide to `func`.
2294      * @returns {number} Returns the timer id.
2295      */
2296     function baseDelay(func, wait, args) {
2297       if (typeof func != 'function') {
2298         throw new TypeError(FUNC_ERROR_TEXT);
2299       }
2300       return setTimeout(function() { func.apply(undefined, args); }, wait);
2301     }
2302
2303     /**
2304      * The base implementation of methods like `_.difference` without support for
2305      * excluding multiple arrays or iteratee shorthands.
2306      *
2307      * @private
2308      * @param {Array} array The array to inspect.
2309      * @param {Array} values The values to exclude.
2310      * @param {Function} [iteratee] The iteratee invoked per element.
2311      * @param {Function} [comparator] The comparator invoked per element.
2312      * @returns {Array} Returns the new array of filtered values.
2313      */
2314     function baseDifference(array, values, iteratee, comparator) {
2315       var index = -1,
2316           includes = arrayIncludes,
2317           isCommon = true,
2318           length = array.length,
2319           result = [],
2320           valuesLength = values.length;
2321
2322       if (!length) {
2323         return result;
2324       }
2325       if (iteratee) {
2326         values = arrayMap(values, baseUnary(iteratee));
2327       }
2328       if (comparator) {
2329         includes = arrayIncludesWith;
2330         isCommon = false;
2331       }
2332       else if (values.length >= LARGE_ARRAY_SIZE) {
2333         includes = cacheHas;
2334         isCommon = false;
2335         values = new SetCache(values);
2336       }
2337       outer:
2338       while (++index < length) {
2339         var value = array[index],
2340             computed = iteratee ? iteratee(value) : value;
2341
2342         if (isCommon && computed === computed) {
2343           var valuesIndex = valuesLength;
2344           while (valuesIndex--) {
2345             if (values[valuesIndex] === computed) {
2346               continue outer;
2347             }
2348           }
2349           result.push(value);
2350         }
2351         else if (!includes(values, computed, comparator)) {
2352           result.push(value);
2353         }
2354       }
2355       return result;
2356     }
2357
2358     /**
2359      * The base implementation of `_.forEach` without support for iteratee shorthands.
2360      *
2361      * @private
2362      * @param {Array|Object} collection The collection to iterate over.
2363      * @param {Function} iteratee The function invoked per iteration.
2364      * @returns {Array|Object} Returns `collection`.
2365      */
2366     var baseEach = createBaseEach(baseForOwn);
2367
2368     /**
2369      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2370      *
2371      * @private
2372      * @param {Array|Object} collection The collection to iterate over.
2373      * @param {Function} iteratee The function invoked per iteration.
2374      * @returns {Array|Object} Returns `collection`.
2375      */
2376     var baseEachRight = createBaseEach(baseForOwnRight, true);
2377
2378     /**
2379      * The base implementation of `_.every` without support for iteratee shorthands.
2380      *
2381      * @private
2382      * @param {Array|Object} collection The collection to iterate over.
2383      * @param {Function} predicate The function invoked per iteration.
2384      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
2385      */
2386     function baseEvery(collection, predicate) {
2387       var result = true;
2388       baseEach(collection, function(value, index, collection) {
2389         result = !!predicate(value, index, collection);
2390         return result;
2391       });
2392       return result;
2393     }
2394
2395     /**
2396      * The base implementation of `_.fill` without an iteratee call guard.
2397      *
2398      * @private
2399      * @param {Array} array The array to fill.
2400      * @param {*} value The value to fill `array` with.
2401      * @param {number} [start=0] The start position.
2402      * @param {number} [end=array.length] The end position.
2403      * @returns {Array} Returns `array`.
2404      */
2405     function baseFill(array, value, start, end) {
2406       var length = array.length;
2407
2408       start = toInteger(start);
2409       if (start < 0) {
2410         start = -start > length ? 0 : (length + start);
2411       }
2412       end = (end === undefined || end > length) ? length : toInteger(end);
2413       if (end < 0) {
2414         end += length;
2415       }
2416       end = start > end ? 0 : toLength(end);
2417       while (start < end) {
2418         array[start++] = value;
2419       }
2420       return array;
2421     }
2422
2423     /**
2424      * The base implementation of `_.filter` without support for iteratee shorthands.
2425      *
2426      * @private
2427      * @param {Array|Object} collection The collection to iterate over.
2428      * @param {Function} predicate The function invoked per iteration.
2429      * @returns {Array} Returns the new filtered array.
2430      */
2431     function baseFilter(collection, predicate) {
2432       var result = [];
2433       baseEach(collection, function(value, index, collection) {
2434         if (predicate(value, index, collection)) {
2435           result.push(value);
2436         }
2437       });
2438       return result;
2439     }
2440
2441     /**
2442      * The base implementation of `_.flatten` with support for restricting flattening.
2443      *
2444      * @private
2445      * @param {Array} array The array to flatten.
2446      * @param {boolean} [isDeep] Specify a deep flatten.
2447      * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
2448      * @param {Array} [result=[]] The initial result value.
2449      * @returns {Array} Returns the new flattened array.
2450      */
2451     function baseFlatten(array, isDeep, isStrict, result) {
2452       result || (result = []);
2453
2454       var index = -1,
2455           length = array.length;
2456
2457       while (++index < length) {
2458         var value = array[index];
2459         if (isArrayLikeObject(value) &&
2460             (isStrict || isArray(value) || isArguments(value))) {
2461           if (isDeep) {
2462             // Recursively flatten arrays (susceptible to call stack limits).
2463             baseFlatten(value, isDeep, isStrict, result);
2464           } else {
2465             arrayPush(result, value);
2466           }
2467         } else if (!isStrict) {
2468           result[result.length] = value;
2469         }
2470       }
2471       return result;
2472     }
2473
2474     /**
2475      * The base implementation of `baseForIn` and `baseForOwn` which iterates
2476      * over `object` properties returned by `keysFunc` invoking `iteratee` for
2477      * each property. Iteratee functions may exit iteration early by explicitly
2478      * returning `false`.
2479      *
2480      * @private
2481      * @param {Object} object The object to iterate over.
2482      * @param {Function} iteratee The function invoked per iteration.
2483      * @param {Function} keysFunc The function to get the keys of `object`.
2484      * @returns {Object} Returns `object`.
2485      */
2486     var baseFor = createBaseFor();
2487
2488     /**
2489      * This function is like `baseFor` except that it iterates over properties
2490      * in the opposite order.
2491      *
2492      * @private
2493      * @param {Object} object The object to iterate over.
2494      * @param {Function} iteratee The function invoked per iteration.
2495      * @param {Function} keysFunc The function to get the keys of `object`.
2496      * @returns {Object} Returns `object`.
2497      */
2498     var baseForRight = createBaseFor(true);
2499
2500     /**
2501      * The base implementation of `_.forIn` without support for iteratee shorthands.
2502      *
2503      * @private
2504      * @param {Object} object The object to iterate over.
2505      * @param {Function} iteratee The function invoked per iteration.
2506      * @returns {Object} Returns `object`.
2507      */
2508     function baseForIn(object, iteratee) {
2509       return object == null ? object : baseFor(object, iteratee, keysIn);
2510     }
2511
2512     /**
2513      * The base implementation of `_.forOwn` without support for iteratee shorthands.
2514      *
2515      * @private
2516      * @param {Object} object The object to iterate over.
2517      * @param {Function} iteratee The function invoked per iteration.
2518      * @returns {Object} Returns `object`.
2519      */
2520     function baseForOwn(object, iteratee) {
2521       return object && baseFor(object, iteratee, keys);
2522     }
2523
2524     /**
2525      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2526      *
2527      * @private
2528      * @param {Object} object The object to iterate over.
2529      * @param {Function} iteratee The function invoked per iteration.
2530      * @returns {Object} Returns `object`.
2531      */
2532     function baseForOwnRight(object, iteratee) {
2533       return object && baseForRight(object, iteratee, keys);
2534     }
2535
2536     /**
2537      * The base implementation of `_.functions` which creates an array of
2538      * `object` function property names filtered from those provided.
2539      *
2540      * @private
2541      * @param {Object} object The object to inspect.
2542      * @param {Array} props The property names to filter.
2543      * @returns {Array} Returns the new array of filtered property names.
2544      */
2545     function baseFunctions(object, props) {
2546       return arrayFilter(props, function(key) {
2547         return isFunction(object[key]);
2548       });
2549     }
2550
2551     /**
2552      * The base implementation of `_.get` without support for default values.
2553      *
2554      * @private
2555      * @param {Object} object The object to query.
2556      * @param {Array|string} path The path of the property to get.
2557      * @returns {*} Returns the resolved value.
2558      */
2559     function baseGet(object, path) {
2560       path = isKey(path, object) ? [path + ''] : baseToPath(path);
2561
2562       var index = 0,
2563           length = path.length;
2564
2565       while (object != null && index < length) {
2566         object = object[path[index++]];
2567       }
2568       return (index && index == length) ? object : undefined;
2569     }
2570
2571     /**
2572      * The base implementation of `_.has` without support for deep paths.
2573      *
2574      * @private
2575      * @param {Object} object The object to query.
2576      * @param {Array|string} key The key to check.
2577      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2578      */
2579     function baseHas(object, key) {
2580       // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
2581       // that are composed entirely of index properties, return `false` for
2582       // `hasOwnProperty` checks of them.
2583       return hasOwnProperty.call(object, key) ||
2584         (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
2585     }
2586
2587     /**
2588      * The base implementation of `_.hasIn` without support for deep paths.
2589      *
2590      * @private
2591      * @param {Object} object The object to query.
2592      * @param {Array|string} key The key to check.
2593      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2594      */
2595     function baseHasIn(object, key) {
2596       return key in Object(object);
2597     }
2598
2599     /**
2600      * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
2601      *
2602      * @private
2603      * @param {number} number The number to check.
2604      * @param {number} start The start of the range.
2605      * @param {number} end The end of the range.
2606      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
2607      */
2608     function baseInRange(number, start, end) {
2609       return number >= nativeMin(start, end) && number < nativeMax(start, end);
2610     }
2611
2612     /**
2613      * The base implementation of methods like `_.intersection`, without support
2614      * for iteratee shorthands, that accepts an array of arrays to inspect.
2615      *
2616      * @private
2617      * @param {Array} arrays The arrays to inspect.
2618      * @param {Function} [iteratee] The iteratee invoked per element.
2619      * @param {Function} [comparator] The comparator invoked per element.
2620      * @returns {Array} Returns the new array of shared values.
2621      */
2622     function baseIntersection(arrays, iteratee, comparator) {
2623       var includes = comparator ? arrayIncludesWith : arrayIncludes,
2624           othLength = arrays.length,
2625           othIndex = othLength,
2626           caches = Array(othLength),
2627           result = [];
2628
2629       while (othIndex--) {
2630         var array = arrays[othIndex];
2631         if (othIndex && iteratee) {
2632           array = arrayMap(array, baseUnary(iteratee));
2633         }
2634         caches[othIndex] = !comparator && (iteratee || array.length >= 120)
2635           ? new SetCache(othIndex && array)
2636           : undefined;
2637       }
2638       array = arrays[0];
2639
2640       var index = -1,
2641           length = array.length,
2642           seen = caches[0];
2643
2644       outer:
2645       while (++index < length) {
2646         var value = array[index],
2647             computed = iteratee ? iteratee(value) : value;
2648
2649         if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) {
2650           var othIndex = othLength;
2651           while (--othIndex) {
2652             var cache = caches[othIndex];
2653             if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) {
2654               continue outer;
2655             }
2656           }
2657           if (seen) {
2658             seen.push(computed);
2659           }
2660           result.push(value);
2661         }
2662       }
2663       return result;
2664     }
2665
2666     /**
2667      * The base implementation of `_.invoke` without support for individual
2668      * method arguments.
2669      *
2670      *
2671      * @private
2672      * @param {Object} object The object to query.
2673      * @param {Array|string} path The path of the method to invoke.
2674      * @param {Array} args The arguments to invoke the method with.
2675      * @returns {*} Returns the result of the invoked method.
2676      */
2677     function baseInvoke(object, path, args) {
2678       if (!isKey(path, object)) {
2679         path = baseToPath(path);
2680         object = parent(object, path);
2681         path = last(path);
2682       }
2683       var func = object == null ? object : object[path];
2684       return func == null ? undefined : apply(func, object, args);
2685     }
2686
2687     /**
2688      * The base implementation of `_.isEqual` which supports partial comparisons
2689      * and tracks traversed objects.
2690      *
2691      * @private
2692      * @param {*} value The value to compare.
2693      * @param {*} other The other value to compare.
2694      * @param {Function} [customizer] The function to customize comparisons.
2695      * @param {boolean} [bitmask] The bitmask of comparison flags.
2696      *  The bitmask may be composed of the following flags:
2697      *     1 - Unordered comparison
2698      *     2 - Partial comparison
2699      * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2700      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2701      */
2702     function baseIsEqual(value, other, customizer, bitmask, stack) {
2703       if (value === other) {
2704         return true;
2705       }
2706       if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
2707         return value !== value && other !== other;
2708       }
2709       return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
2710     }
2711
2712     /**
2713      * A specialized version of `baseIsEqual` for arrays and objects which performs
2714      * deep comparisons and tracks traversed objects enabling objects with circular
2715      * references to be compared.
2716      *
2717      * @private
2718      * @param {Object} object The object to compare.
2719      * @param {Object} other The other object to compare.
2720      * @param {Function} equalFunc The function to determine equivalents of values.
2721      * @param {Function} [customizer] The function to customize comparisons.
2722      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
2723      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2724      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2725      */
2726     function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
2727       var objIsArr = isArray(object),
2728           othIsArr = isArray(other),
2729           objTag = arrayTag,
2730           othTag = arrayTag;
2731
2732       if (!objIsArr) {
2733         objTag = getTag(object);
2734         if (objTag == argsTag) {
2735           objTag = objectTag;
2736         } else if (objTag != objectTag) {
2737           objIsArr = isTypedArray(object);
2738         }
2739       }
2740       if (!othIsArr) {
2741         othTag = getTag(other);
2742         if (othTag == argsTag) {
2743           othTag = objectTag;
2744         } else if (othTag != objectTag) {
2745           othIsArr = isTypedArray(other);
2746         }
2747       }
2748       var objIsObj = objTag == objectTag && !isHostObject(object),
2749           othIsObj = othTag == objectTag && !isHostObject(other),
2750           isSameTag = objTag == othTag;
2751
2752       if (isSameTag && !(objIsArr || objIsObj)) {
2753         return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
2754       }
2755       var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
2756       if (!isPartial) {
2757         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2758             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2759
2760         if (objIsWrapped || othIsWrapped) {
2761           return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
2762         }
2763       }
2764       if (!isSameTag) {
2765         return false;
2766       }
2767       stack || (stack = new Stack);
2768       return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
2769     }
2770
2771     /**
2772      * The base implementation of `_.isMatch` without support for iteratee shorthands.
2773      *
2774      * @private
2775      * @param {Object} object The object to inspect.
2776      * @param {Object} source The object of property values to match.
2777      * @param {Array} matchData The property names, values, and compare flags to match.
2778      * @param {Function} [customizer] The function to customize comparisons.
2779      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
2780      */
2781     function baseIsMatch(object, source, matchData, customizer) {
2782       var index = matchData.length,
2783           length = index,
2784           noCustomizer = !customizer;
2785
2786       if (object == null) {
2787         return !length;
2788       }
2789       object = Object(object);
2790       while (index--) {
2791         var data = matchData[index];
2792         if ((noCustomizer && data[2])
2793               ? data[1] !== object[data[0]]
2794               : !(data[0] in object)
2795             ) {
2796           return false;
2797         }
2798       }
2799       while (++index < length) {
2800         data = matchData[index];
2801         var key = data[0],
2802             objValue = object[key],
2803             srcValue = data[1];
2804
2805         if (noCustomizer && data[2]) {
2806           if (objValue === undefined && !(key in object)) {
2807             return false;
2808           }
2809         } else {
2810           var stack = new Stack,
2811               result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
2812
2813           if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) : result)) {
2814             return false;
2815           }
2816         }
2817       }
2818       return true;
2819     }
2820
2821     /**
2822      * The base implementation of `_.iteratee`.
2823      *
2824      * @private
2825      * @param {*} [value=_.identity] The value to convert to an iteratee.
2826      * @returns {Function} Returns the iteratee.
2827      */
2828     function baseIteratee(value) {
2829       var type = typeof value;
2830       if (type == 'function') {
2831         return value;
2832       }
2833       if (value == null) {
2834         return identity;
2835       }
2836       if (type == 'object') {
2837         return isArray(value)
2838           ? baseMatchesProperty(value[0], value[1])
2839           : baseMatches(value);
2840       }
2841       return property(value);
2842     }
2843
2844     /**
2845      * The base implementation of `_.keys` which doesn't skip the constructor
2846      * property of prototypes or treat sparse arrays as dense.
2847      *
2848      * @private
2849      * @type Function
2850      * @param {Object} object The object to query.
2851      * @returns {Array} Returns the array of property names.
2852      */
2853     function baseKeys(object) {
2854       return nativeKeys(Object(object));
2855     }
2856
2857     /**
2858      * The base implementation of `_.keysIn` which doesn't skip the constructor
2859      * property of prototypes or treat sparse arrays as dense.
2860      *
2861      * @private
2862      * @param {Object} object The object to query.
2863      * @returns {Array} Returns the array of property names.
2864      */
2865     function baseKeysIn(object) {
2866       object = object == null ? object : Object(object);
2867
2868       var result = [];
2869       for (var key in object) {
2870         result.push(key);
2871       }
2872       return result;
2873     }
2874
2875     // Fallback for IE < 9 with es6-shim.
2876     if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
2877       baseKeysIn = function(object) {
2878         return iteratorToArray(enumerate(object));
2879       };
2880     }
2881
2882     /**
2883      * The base implementation of `_.map` without support for iteratee shorthands.
2884      *
2885      * @private
2886      * @param {Array|Object} collection The collection to iterate over.
2887      * @param {Function} iteratee The function invoked per iteration.
2888      * @returns {Array} Returns the new mapped array.
2889      */
2890     function baseMap(collection, iteratee) {
2891       var index = -1,
2892           result = isArrayLike(collection) ? Array(collection.length) : [];
2893
2894       baseEach(collection, function(value, key, collection) {
2895         result[++index] = iteratee(value, key, collection);
2896       });
2897       return result;
2898     }
2899
2900     /**
2901      * The base implementation of `_.matches` which doesn't clone `source`.
2902      *
2903      * @private
2904      * @param {Object} source The object of property values to match.
2905      * @returns {Function} Returns the new function.
2906      */
2907     function baseMatches(source) {
2908       var matchData = getMatchData(source);
2909       if (matchData.length == 1 && matchData[0][2]) {
2910         var key = matchData[0][0],
2911             value = matchData[0][1];
2912
2913         return function(object) {
2914           if (object == null) {
2915             return false;
2916           }
2917           return object[key] === value &&
2918             (value !== undefined || (key in Object(object)));
2919         };
2920       }
2921       return function(object) {
2922         return object === source || baseIsMatch(object, source, matchData);
2923       };
2924     }
2925
2926     /**
2927      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
2928      *
2929      * @private
2930      * @param {string} path The path of the property to get.
2931      * @param {*} srcValue The value to match.
2932      * @returns {Function} Returns the new function.
2933      */
2934     function baseMatchesProperty(path, srcValue) {
2935       return function(object) {
2936         var objValue = get(object, path);
2937         return (objValue === undefined && objValue === srcValue)
2938           ? hasIn(object, path)
2939           : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
2940       };
2941     }
2942
2943     /**
2944      * The base implementation of `_.merge` without support for multiple sources.
2945      *
2946      * @private
2947      * @param {Object} object The destination object.
2948      * @param {Object} source The source object.
2949      * @param {Function} [customizer] The function to customize merged values.
2950      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
2951      */
2952     function baseMerge(object, source, customizer, stack) {
2953       if (object === source) {
2954         return;
2955       }
2956       var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source);
2957       arrayEach(props || source, function(srcValue, key) {
2958         if (props) {
2959           key = srcValue;
2960           srcValue = source[key];
2961         }
2962         if (isObject(srcValue)) {
2963           stack || (stack = new Stack);
2964           baseMergeDeep(object, source, key, baseMerge, customizer, stack);
2965         }
2966         else {
2967           var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined;
2968           if (newValue === undefined) {
2969             newValue = srcValue;
2970           }
2971           assignMergeValue(object, key, newValue);
2972         }
2973       });
2974     }
2975
2976     /**
2977      * A specialized version of `baseMerge` for arrays and objects which performs
2978      * deep merges and tracks traversed objects enabling objects with circular
2979      * references to be merged.
2980      *
2981      * @private
2982      * @param {Object} object The destination object.
2983      * @param {Object} source The source object.
2984      * @param {string} key The key of the value to merge.
2985      * @param {Function} mergeFunc The function to merge values.
2986      * @param {Function} [customizer] The function to customize assigned values.
2987      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
2988      */
2989     function baseMergeDeep(object, source, key, mergeFunc, customizer, stack) {
2990       var objValue = object[key],
2991           srcValue = source[key],
2992           stacked = stack.get(srcValue) || stack.get(objValue);
2993
2994       if (stacked) {
2995         assignMergeValue(object, key, stacked);
2996         return;
2997       }
2998       var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined,
2999           isCommon = newValue === undefined;
3000
3001       if (isCommon) {
3002         newValue = srcValue;
3003         if (isArray(srcValue) || isTypedArray(srcValue)) {
3004           newValue = isArray(objValue)
3005             ? objValue
3006             : ((isArrayLikeObject(objValue)) ? copyArray(objValue) : baseClone(srcValue));
3007         }
3008         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3009           newValue = isArguments(objValue)
3010             ? toPlainObject(objValue)
3011             : (isObject(objValue) ? objValue : baseClone(srcValue));
3012         }
3013         else {
3014           isCommon = isFunction(srcValue);
3015         }
3016       }
3017       stack.set(srcValue, newValue);
3018
3019       if (isCommon) {
3020         // Recursively merge objects and arrays (susceptible to call stack limits).
3021         mergeFunc(newValue, srcValue, customizer, stack);
3022       }
3023       assignMergeValue(object, key, newValue);
3024     }
3025
3026     /**
3027      * The base implementation of `_.orderBy` without param guards.
3028      *
3029      * @private
3030      * @param {Array|Object} collection The collection to iterate over.
3031      * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3032      * @param {string[]} orders The sort orders of `iteratees`.
3033      * @returns {Array} Returns the new sorted array.
3034      */
3035     function baseOrderBy(collection, iteratees, orders) {
3036       var index = -1,
3037           toIteratee = getIteratee();
3038
3039       iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
3040         return toIteratee(iteratee);
3041       });
3042
3043       var result = baseMap(collection, function(value, key, collection) {
3044         var criteria = arrayMap(iteratees, function(iteratee) {
3045           return iteratee(value);
3046         });
3047         return { 'criteria': criteria, 'index': ++index, 'value': value };
3048       });
3049
3050       return baseSortBy(result, function(object, other) {
3051         return compareMultiple(object, other, orders);
3052       });
3053     }
3054
3055     /**
3056      * The base implementation of `_.pick` without support for individual
3057      * property names.
3058      *
3059      * @private
3060      * @param {Object} object The source object.
3061      * @param {string[]} props The property names to pick.
3062      * @returns {Object} Returns the new object.
3063      */
3064     function basePick(object, props) {
3065       object = Object(object);
3066       return arrayReduce(props, function(result, key) {
3067         if (key in object) {
3068           result[key] = object[key];
3069         }
3070         return result;
3071       }, {});
3072     }
3073
3074     /**
3075      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3076      *
3077      * @private
3078      * @param {Object} object The source object.
3079      * @param {Function} predicate The function invoked per property.
3080      * @returns {Object} Returns the new object.
3081      */
3082     function basePickBy(object, predicate) {
3083       var result = {};
3084       baseForIn(object, function(value, key) {
3085         if (predicate(value)) {
3086           result[key] = value;
3087         }
3088       });
3089       return result;
3090     }
3091
3092     /**
3093      * The base implementation of `_.property` without support for deep paths.
3094      *
3095      * @private
3096      * @param {string} key The key of the property to get.
3097      * @returns {Function} Returns the new function.
3098      */
3099     function baseProperty(key) {
3100       return function(object) {
3101         return object == null ? undefined : object[key];
3102       };
3103     }
3104
3105     /**
3106      * A specialized version of `baseProperty` which supports deep paths.
3107      *
3108      * @private
3109      * @param {Array|string} path The path of the property to get.
3110      * @returns {Function} Returns the new function.
3111      */
3112     function basePropertyDeep(path) {
3113       return function(object) {
3114         return baseGet(object, path);
3115       };
3116     }
3117
3118     /**
3119      * The base implementation of `_.pullAll`.
3120      *
3121      * @private
3122      * @param {Array} array The array to modify.
3123      * @param {Array} values The values to remove.
3124      * @returns {Array} Returns `array`.
3125      */
3126     function basePullAll(array, values) {
3127       return basePullAllBy(array, values);
3128     }
3129
3130     /**
3131      * The base implementation of `_.pullAllBy` without support for iteratee
3132      * shorthands.
3133      *
3134      * @private
3135      * @param {Array} array The array to modify.
3136      * @param {Array} values The values to remove.
3137      * @param {Function} [iteratee] The iteratee invoked per element.
3138      * @returns {Array} Returns `array`.
3139      */
3140     function basePullAllBy(array, values, iteratee) {
3141       var index = -1,
3142           length = values.length,
3143           seen = array;
3144
3145       if (iteratee) {
3146         seen = arrayMap(array, function(value) { return iteratee(value); });
3147       }
3148       while (++index < length) {
3149         var fromIndex = 0,
3150             value = values[index],
3151             computed = iteratee ? iteratee(value) : value;
3152
3153         while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
3154           if (seen !== array) {
3155             splice.call(seen, fromIndex, 1);
3156           }
3157           splice.call(array, fromIndex, 1);
3158         }
3159       }
3160       return array;
3161     }
3162
3163     /**
3164      * The base implementation of `_.pullAt` without support for individual
3165      * indexes or capturing the removed elements.
3166      *
3167      * @private
3168      * @param {Array} array The array to modify.
3169      * @param {number[]} indexes The indexes of elements to remove.
3170      * @returns {Array} Returns `array`.
3171      */
3172     function basePullAt(array, indexes) {
3173       var length = array ? indexes.length : 0,
3174           lastIndex = length - 1;
3175
3176       while (length--) {
3177         var index = indexes[length];
3178         if (lastIndex == length || index != previous) {
3179           var previous = index;
3180           if (isIndex(index)) {
3181             splice.call(array, index, 1);
3182           }
3183           else if (!isKey(index, array)) {
3184             var path = baseToPath(index),
3185                 object = parent(array, path);
3186
3187             if (object != null) {
3188               delete object[last(path)];
3189             }
3190           }
3191           else {
3192             delete array[index];
3193           }
3194         }
3195       }
3196       return array;
3197     }
3198
3199     /**
3200      * The base implementation of `_.random` without support for returning
3201      * floating-point numbers.
3202      *
3203      * @private
3204      * @param {number} lower The lower bound.
3205      * @param {number} upper The upper bound.
3206      * @returns {number} Returns the random number.
3207      */
3208     function baseRandom(lower, upper) {
3209       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3210     }
3211
3212     /**
3213      * The base implementation of `_.range` and `_.rangeRight` which doesn't
3214      * coerce arguments to numbers.
3215      *
3216      * @private
3217      * @param {number} start The start of the range.
3218      * @param {number} end The end of the range.
3219      * @param {number} step The value to increment or decrement by.
3220      * @param {boolean} [fromRight] Specify iterating from right to left.
3221      * @returns {Array} Returns the new array of numbers.
3222      */
3223     function baseRange(start, end, step, fromRight) {
3224       var index = -1,
3225           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3226           result = Array(length);
3227
3228       while (length--) {
3229         result[fromRight ? length : ++index] = start;
3230         start += step;
3231       }
3232       return result;
3233     }
3234
3235     /**
3236      * The base implementation of `_.set`.
3237      *
3238      * @private
3239      * @param {Object} object The object to query.
3240      * @param {Array|string} path The path of the property to set.
3241      * @param {*} value The value to set.
3242      * @param {Function} [customizer] The function to customize path creation.
3243      * @returns {Object} Returns `object`.
3244      */
3245     function baseSet(object, path, value, customizer) {
3246       path = isKey(path, object) ? [path + ''] : baseToPath(path);
3247
3248       var index = -1,
3249           length = path.length,
3250           lastIndex = length - 1,
3251           nested = object;
3252
3253       while (nested != null && ++index < length) {
3254         var key = path[index];
3255         if (isObject(nested)) {
3256           var newValue = value;
3257           if (index != lastIndex) {
3258             var objValue = nested[key];
3259             newValue = customizer ? customizer(objValue, key, nested) : undefined;
3260             if (newValue === undefined) {
3261               newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue;
3262             }
3263           }
3264           assignValue(nested, key, newValue);
3265         }
3266         nested = nested[key];
3267       }
3268       return object;
3269     }
3270
3271     /**
3272      * The base implementation of `setData` without support for hot loop detection.
3273      *
3274      * @private
3275      * @param {Function} func The function to associate metadata with.
3276      * @param {*} data The metadata.
3277      * @returns {Function} Returns `func`.
3278      */
3279     var baseSetData = !metaMap ? identity : function(func, data) {
3280       metaMap.set(func, data);
3281       return func;
3282     };
3283
3284     /**
3285      * The base implementation of `_.slice` without an iteratee call guard.
3286      *
3287      * @private
3288      * @param {Array} array The array to slice.
3289      * @param {number} [start=0] The start position.
3290      * @param {number} [end=array.length] The end position.
3291      * @returns {Array} Returns the slice of `array`.
3292      */
3293     function baseSlice(array, start, end) {
3294       var index = -1,
3295           length = array.length;
3296
3297       if (start < 0) {
3298         start = -start > length ? 0 : (length + start);
3299       }
3300       end = end > length ? length : end;
3301       if (end < 0) {
3302         end += length;
3303       }
3304       length = start > end ? 0 : ((end - start) >>> 0);
3305       start >>>= 0;
3306
3307       var result = Array(length);
3308       while (++index < length) {
3309         result[index] = array[index + start];
3310       }
3311       return result;
3312     }
3313
3314     /**
3315      * The base implementation of `_.some` without support for iteratee shorthands.
3316      *
3317      * @private
3318      * @param {Array|Object} collection The collection to iterate over.
3319      * @param {Function} predicate The function invoked per iteration.
3320      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
3321      */
3322     function baseSome(collection, predicate) {
3323       var result;
3324
3325       baseEach(collection, function(value, index, collection) {
3326         result = predicate(value, index, collection);
3327         return !result;
3328       });
3329       return !!result;
3330     }
3331
3332     /**
3333      * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
3334      * performs a binary search of `array` to determine the index at which `value`
3335      * should be inserted into `array` in order to maintain its sort order.
3336      *
3337      * @private
3338      * @param {Array} array The sorted array to inspect.
3339      * @param {*} value The value to evaluate.
3340      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3341      * @returns {number} Returns the index at which `value` should be inserted
3342      *  into `array`.
3343      */
3344     function baseSortedIndex(array, value, retHighest) {
3345       var low = 0,
3346           high = array ? array.length : low;
3347
3348       if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
3349         while (low < high) {
3350           var mid = (low + high) >>> 1,
3351               computed = array[mid];
3352
3353           if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
3354             low = mid + 1;
3355           } else {
3356             high = mid;
3357           }
3358         }
3359         return high;
3360       }
3361       return baseSortedIndexBy(array, value, identity, retHighest);
3362     }
3363
3364     /**
3365      * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
3366      * which invokes `iteratee` for `value` and each element of `array` to compute
3367      * their sort ranking. The iteratee is invoked with one argument; (value).
3368      *
3369      * @private
3370      * @param {Array} array The sorted array to inspect.
3371      * @param {*} value The value to evaluate.
3372      * @param {Function} iteratee The iteratee invoked per element.
3373      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3374      * @returns {number} Returns the index at which `value` should be inserted into `array`.
3375      */
3376     function baseSortedIndexBy(array, value, iteratee, retHighest) {
3377       value = iteratee(value);
3378
3379       var low = 0,
3380           high = array ? array.length : 0,
3381           valIsNaN = value !== value,
3382           valIsNull = value === null,
3383           valIsUndef = value === undefined;
3384
3385       while (low < high) {
3386         var mid = nativeFloor((low + high) / 2),
3387             computed = iteratee(array[mid]),
3388             isDef = computed !== undefined,
3389             isReflexive = computed === computed;
3390
3391         if (valIsNaN) {
3392           var setLow = isReflexive || retHighest;
3393         } else if (valIsNull) {
3394           setLow = isReflexive && isDef && (retHighest || computed != null);
3395         } else if (valIsUndef) {
3396           setLow = isReflexive && (retHighest || isDef);
3397         } else if (computed == null) {
3398           setLow = false;
3399         } else {
3400           setLow = retHighest ? (computed <= value) : (computed < value);
3401         }
3402         if (setLow) {
3403           low = mid + 1;
3404         } else {
3405           high = mid;
3406         }
3407       }
3408       return nativeMin(high, MAX_ARRAY_INDEX);
3409     }
3410
3411     /**
3412      * The base implementation of `_.sortedUniq`.
3413      *
3414      * @private
3415      * @param {Array} array The array to inspect.
3416      * @returns {Array} Returns the new duplicate free array.
3417      */
3418     function baseSortedUniq(array) {
3419       return baseSortedUniqBy(array);
3420     }
3421
3422     /**
3423      * The base implementation of `_.sortedUniqBy` without support for iteratee
3424      * shorthands.
3425      *
3426      * @private
3427      * @param {Array} array The array to inspect.
3428      * @param {Function} [iteratee] The iteratee invoked per element.
3429      * @returns {Array} Returns the new duplicate free array.
3430      */
3431     function baseSortedUniqBy(array, iteratee) {
3432       var index = 0,
3433           length = array.length,
3434           value = array[0],
3435           computed = iteratee ? iteratee(value) : value,
3436           seen = computed,
3437           resIndex = 0,
3438           result = [value];
3439
3440       while (++index < length) {
3441         value = array[index],
3442         computed = iteratee ? iteratee(value) : value;
3443
3444         if (!eq(computed, seen)) {
3445           seen = computed;
3446           result[++resIndex] = value;
3447         }
3448       }
3449       return result;
3450     }
3451
3452     /**
3453      * The base implementation of `_.toPath` which only converts `value` to a
3454      * path if it's not one.
3455      *
3456      * @private
3457      * @param {*} value The value to process.
3458      * @returns {Array} Returns the property path array.
3459      */
3460     function baseToPath(value) {
3461       return isArray(value) ? value : stringToPath(value);
3462     }
3463
3464     /**
3465      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
3466      *
3467      * @private
3468      * @param {Array} array The array to inspect.
3469      * @param {Function} [iteratee] The iteratee invoked per element.
3470      * @param {Function} [comparator] The comparator invoked per element.
3471      * @returns {Array} Returns the new duplicate free array.
3472      */
3473     function baseUniq(array, iteratee, comparator) {
3474       var index = -1,
3475           includes = arrayIncludes,
3476           length = array.length,
3477           isCommon = true,
3478           result = [],
3479           seen = result;
3480
3481       if (comparator) {
3482         isCommon = false;
3483         includes = arrayIncludesWith;
3484       }
3485       else if (length >= LARGE_ARRAY_SIZE) {
3486         var set = iteratee ? null : createSet(array);
3487         if (set) {
3488           return setToArray(set);
3489         }
3490         isCommon = false;
3491         includes = cacheHas;
3492         seen = new SetCache;
3493       }
3494       else {
3495         seen = iteratee ? [] : result;
3496       }
3497       outer:
3498       while (++index < length) {
3499         var value = array[index],
3500             computed = iteratee ? iteratee(value) : value;
3501
3502         if (isCommon && computed === computed) {
3503           var seenIndex = seen.length;
3504           while (seenIndex--) {
3505             if (seen[seenIndex] === computed) {
3506               continue outer;
3507             }
3508           }
3509           if (iteratee) {
3510             seen.push(computed);
3511           }
3512           result.push(value);
3513         }
3514         else if (!includes(seen, computed, comparator)) {
3515           if (seen !== result) {
3516             seen.push(computed);
3517           }
3518           result.push(value);
3519         }
3520       }
3521       return result;
3522     }
3523
3524     /**
3525      * The base implementation of `_.unset`.
3526      *
3527      * @private
3528      * @param {Object} object The object to modify.
3529      * @param {Array|string} path The path of the property to unset.
3530      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
3531      */
3532     function baseUnset(object, path) {
3533       path = isKey(path, object) ? [path + ''] : baseToPath(path);
3534       object = parent(object, path);
3535       var key = last(path);
3536       return (object != null && has(object, key)) ? delete object[key] : true;
3537     }
3538
3539     /**
3540      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
3541      * without support for iteratee shorthands.
3542      *
3543      * @private
3544      * @param {Array} array The array to query.
3545      * @param {Function} predicate The function invoked per iteration.
3546      * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
3547      * @param {boolean} [fromRight] Specify iterating from right to left.
3548      * @returns {Array} Returns the slice of `array`.
3549      */
3550     function baseWhile(array, predicate, isDrop, fromRight) {
3551       var length = array.length,
3552           index = fromRight ? length : -1;
3553
3554       while ((fromRight ? index-- : ++index < length) &&
3555         predicate(array[index], index, array)) {}
3556
3557       return isDrop
3558         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
3559         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
3560     }
3561
3562     /**
3563      * The base implementation of `wrapperValue` which returns the result of
3564      * performing a sequence of actions on the unwrapped `value`, where each
3565      * successive action is supplied the return value of the previous.
3566      *
3567      * @private
3568      * @param {*} value The unwrapped value.
3569      * @param {Array} actions Actions to perform to resolve the unwrapped value.
3570      * @returns {*} Returns the resolved value.
3571      */
3572     function baseWrapperValue(value, actions) {
3573       var result = value;
3574       if (result instanceof LazyWrapper) {
3575         result = result.value();
3576       }
3577       return arrayReduce(actions, function(result, action) {
3578         return action.func.apply(action.thisArg, arrayPush([result], action.args));
3579       }, result);
3580     }
3581
3582     /**
3583      * The base implementation of methods like `_.xor`, without support for
3584      * iteratee shorthands, that accepts an array of arrays to inspect.
3585      *
3586      * @private
3587      * @param {Array} arrays The arrays to inspect.
3588      * @param {Function} [iteratee] The iteratee invoked per element.
3589      * @param {Function} [comparator] The comparator invoked per element.
3590      * @returns {Array} Returns the new array of values.
3591      */
3592     function baseXor(arrays, iteratee, comparator) {
3593       var index = -1,
3594           length = arrays.length;
3595
3596       while (++index < length) {
3597         var result = result
3598           ? arrayPush(
3599               baseDifference(result, arrays[index], iteratee, comparator),
3600               baseDifference(arrays[index], result, iteratee, comparator)
3601             )
3602           : arrays[index];
3603       }
3604       return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
3605     }
3606
3607     /**
3608      * Creates a clone of `buffer`.
3609      *
3610      * @private
3611      * @param {ArrayBuffer} buffer The array buffer to clone.
3612      * @returns {ArrayBuffer} Returns the cloned array buffer.
3613      */
3614     function cloneBuffer(buffer) {
3615       var Ctor = buffer.constructor,
3616           result = new Ctor(buffer.byteLength),
3617           view = new Uint8Array(result);
3618
3619       view.set(new Uint8Array(buffer));
3620       return result;
3621     }
3622
3623     /**
3624      * Creates a clone of `map`.
3625      *
3626      * @private
3627      * @param {Object} map The map to clone.
3628      * @returns {Object} Returns the cloned map.
3629      */
3630     function cloneMap(map) {
3631       var Ctor = map.constructor;
3632       return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
3633     }
3634
3635     /**
3636      * Creates a clone of `regexp`.
3637      *
3638      * @private
3639      * @param {Object} regexp The regexp to clone.
3640      * @returns {Object} Returns the cloned regexp.
3641      */
3642     function cloneRegExp(regexp) {
3643       var Ctor = regexp.constructor,
3644           result = new Ctor(regexp.source, reFlags.exec(regexp));
3645
3646       result.lastIndex = regexp.lastIndex;
3647       return result;
3648     }
3649
3650     /**
3651      * Creates a clone of `set`.
3652      *
3653      * @private
3654      * @param {Object} set The set to clone.
3655      * @returns {Object} Returns the cloned set.
3656      */
3657     function cloneSet(set) {
3658       var Ctor = set.constructor;
3659       return arrayReduce(setToArray(set), addSetEntry, new Ctor);
3660     }
3661
3662     /**
3663      * Creates a clone of the `symbol` object.
3664      *
3665      * @private
3666      * @param {Object} symbol The symbol object to clone.
3667      * @returns {Object} Returns the cloned symbol object.
3668      */
3669     function cloneSymbol(symbol) {
3670       return _Symbol ? Object(symbolValueOf.call(symbol)) : {};
3671     }
3672
3673     /**
3674      * Creates a clone of `typedArray`.
3675      *
3676      * @private
3677      * @param {Object} typedArray The typed array to clone.
3678      * @param {boolean} [isDeep] Specify a deep clone.
3679      * @returns {Object} Returns the cloned typed array.
3680      */
3681     function cloneTypedArray(typedArray, isDeep) {
3682       var buffer = typedArray.buffer,
3683           Ctor = typedArray.constructor;
3684
3685       return new Ctor(isDeep ? cloneBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
3686     }
3687
3688     /**
3689      * Creates an array that is the composition of partially applied arguments,
3690      * placeholders, and provided arguments into a single array of arguments.
3691      *
3692      * @private
3693      * @param {Array|Object} args The provided arguments.
3694      * @param {Array} partials The arguments to prepend to those provided.
3695      * @param {Array} holders The `partials` placeholder indexes.
3696      * @returns {Array} Returns the new array of composed arguments.
3697      */
3698     function composeArgs(args, partials, holders) {
3699       var holdersLength = holders.length,
3700           argsIndex = -1,
3701           argsLength = nativeMax(args.length - holdersLength, 0),
3702           leftIndex = -1,
3703           leftLength = partials.length,
3704           result = Array(leftLength + argsLength);
3705
3706       while (++leftIndex < leftLength) {
3707         result[leftIndex] = partials[leftIndex];
3708       }
3709       while (++argsIndex < holdersLength) {
3710         result[holders[argsIndex]] = args[argsIndex];
3711       }
3712       while (argsLength--) {
3713         result[leftIndex++] = args[argsIndex++];
3714       }
3715       return result;
3716     }
3717
3718     /**
3719      * This function is like `composeArgs` except that the arguments composition
3720      * is tailored for `_.partialRight`.
3721      *
3722      * @private
3723      * @param {Array|Object} args The provided arguments.
3724      * @param {Array} partials The arguments to append to those provided.
3725      * @param {Array} holders The `partials` placeholder indexes.
3726      * @returns {Array} Returns the new array of composed arguments.
3727      */
3728     function composeArgsRight(args, partials, holders) {
3729       var holdersIndex = -1,
3730           holdersLength = holders.length,
3731           argsIndex = -1,
3732           argsLength = nativeMax(args.length - holdersLength, 0),
3733           rightIndex = -1,
3734           rightLength = partials.length,
3735           result = Array(argsLength + rightLength);
3736
3737       while (++argsIndex < argsLength) {
3738         result[argsIndex] = args[argsIndex];
3739       }
3740       var offset = argsIndex;
3741       while (++rightIndex < rightLength) {
3742         result[offset + rightIndex] = partials[rightIndex];
3743       }
3744       while (++holdersIndex < holdersLength) {
3745         result[offset + holders[holdersIndex]] = args[argsIndex++];
3746       }
3747       return result;
3748     }
3749
3750     /**
3751      * Copies the values of `source` to `array`.
3752      *
3753      * @private
3754      * @param {Array} source The array to copy values from.
3755      * @param {Array} [array=[]] The array to copy values to.
3756      * @returns {Array} Returns `array`.
3757      */
3758     function copyArray(source, array) {
3759       var index = -1,
3760           length = source.length;
3761
3762       array || (array = Array(length));
3763       while (++index < length) {
3764         array[index] = source[index];
3765       }
3766       return array;
3767     }
3768
3769     /**
3770      * Copies properties of `source` to `object`.
3771      *
3772      * @private
3773      * @param {Object} source The object to copy properties from.
3774      * @param {Array} props The property names to copy.
3775      * @param {Object} [object={}] The object to copy properties to.
3776      * @returns {Object} Returns `object`.
3777      */
3778     function copyObject(source, props, object) {
3779       return copyObjectWith(source, props, object);
3780     }
3781
3782     /**
3783      * This function is like `copyObject` except that it accepts a function to
3784      * customize copied values.
3785      *
3786      * @private
3787      * @param {Object} source The object to copy properties from.
3788      * @param {Array} props The property names to copy.
3789      * @param {Object} [object={}] The object to copy properties to.
3790      * @param {Function} [customizer] The function to customize copied values.
3791      * @returns {Object} Returns `object`.
3792      */
3793     function copyObjectWith(source, props, object, customizer) {
3794       object || (object = {});
3795
3796       var index = -1,
3797           length = props.length;
3798
3799       while (++index < length) {
3800         var key = props[index],
3801             newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
3802
3803         assignValue(object, key, newValue);
3804       }
3805       return object;
3806     }
3807
3808     /**
3809      * Copies own symbol properties of `source` to `object`.
3810      *
3811      * @private
3812      * @param {Object} source The object to copy symbols from.
3813      * @param {Object} [object={}] The object to copy symbols to.
3814      * @returns {Object} Returns `object`.
3815      */
3816     function copySymbols(source, object) {
3817       return copyObject(source, getSymbols(source), object);
3818     }
3819
3820     /**
3821      * Creates a function like `_.groupBy`.
3822      *
3823      * @private
3824      * @param {Function} setter The function to set keys and values of the accumulator object.
3825      * @param {Function} [initializer] The function to initialize the accumulator object.
3826      * @returns {Function} Returns the new aggregator function.
3827      */
3828     function createAggregator(setter, initializer) {
3829       return function(collection, iteratee) {
3830         var result = initializer ? initializer() : {};
3831         iteratee = getIteratee(iteratee);
3832
3833         if (isArray(collection)) {
3834           var index = -1,
3835               length = collection.length;
3836
3837           while (++index < length) {
3838             var value = collection[index];
3839             setter(result, value, iteratee(value), collection);
3840           }
3841         } else {
3842           baseEach(collection, function(value, key, collection) {
3843             setter(result, value, iteratee(value), collection);
3844           });
3845         }
3846         return result;
3847       };
3848     }
3849
3850     /**
3851      * Creates a function like `_.assign`.
3852      *
3853      * @private
3854      * @param {Function} assigner The function to assign values.
3855      * @returns {Function} Returns the new assigner function.
3856      */
3857     function createAssigner(assigner) {
3858       return rest(function(object, sources) {
3859         var index = -1,
3860             length = sources.length,
3861             customizer = length > 1 ? sources[length - 1] : undefined,
3862             guard = length > 2 ? sources[2] : undefined;
3863
3864         customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
3865         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
3866           customizer = length < 3 ? undefined : customizer;
3867           length = 1;
3868         }
3869         object = Object(object);
3870         while (++index < length) {
3871           var source = sources[index];
3872           if (source) {
3873             assigner(object, source, customizer);
3874           }
3875         }
3876         return object;
3877       });
3878     }
3879
3880     /**
3881      * Creates a `baseEach` or `baseEachRight` function.
3882      *
3883      * @private
3884      * @param {Function} eachFunc The function to iterate over a collection.
3885      * @param {boolean} [fromRight] Specify iterating from right to left.
3886      * @returns {Function} Returns the new base function.
3887      */
3888     function createBaseEach(eachFunc, fromRight) {
3889       return function(collection, iteratee) {
3890         if (collection == null) {
3891           return collection;
3892         }
3893         if (!isArrayLike(collection)) {
3894           return eachFunc(collection, iteratee);
3895         }
3896         var length = collection.length,
3897             index = fromRight ? length : -1,
3898             iterable = Object(collection);
3899
3900         while ((fromRight ? index-- : ++index < length)) {
3901           if (iteratee(iterable[index], index, iterable) === false) {
3902             break;
3903           }
3904         }
3905         return collection;
3906       };
3907     }
3908
3909     /**
3910      * Creates a base function for methods like `_.forIn`.
3911      *
3912      * @private
3913      * @param {boolean} [fromRight] Specify iterating from right to left.
3914      * @returns {Function} Returns the new base function.
3915      */
3916     function createBaseFor(fromRight) {
3917       return function(object, iteratee, keysFunc) {
3918         var index = -1,
3919             iterable = Object(object),
3920             props = keysFunc(object),
3921             length = props.length;
3922
3923         while (length--) {
3924           var key = props[fromRight ? length : ++index];
3925           if (iteratee(iterable[key], key, iterable) === false) {
3926             break;
3927           }
3928         }
3929         return object;
3930       };
3931     }
3932
3933     /**
3934      * Creates a function that wraps `func` to invoke it with the optional `this`
3935      * binding of `thisArg`.
3936      *
3937      * @private
3938      * @param {Function} func The function to wrap.
3939      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
3940      * @param {*} [thisArg] The `this` binding of `func`.
3941      * @returns {Function} Returns the new wrapped function.
3942      */
3943     function createBaseWrapper(func, bitmask, thisArg) {
3944       var isBind = bitmask & BIND_FLAG,
3945           Ctor = createCtorWrapper(func);
3946
3947       function wrapper() {
3948         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
3949         return fn.apply(isBind ? thisArg : this, arguments);
3950       }
3951       return wrapper;
3952     }
3953
3954     /**
3955      * Creates a function like `_.lowerFirst`.
3956      *
3957      * @private
3958      * @param {string} methodName The name of the `String` case method to use.
3959      * @returns {Function} Returns the new function.
3960      */
3961     function createCaseFirst(methodName) {
3962       return function(string) {
3963         string = toString(string);
3964
3965         var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined,
3966             chr = strSymbols ? strSymbols[0] : string.charAt(0),
3967             trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
3968
3969         return chr[methodName]() + trailing;
3970       };
3971     }
3972
3973     /**
3974      * Creates a function like `_.camelCase`.
3975      *
3976      * @private
3977      * @param {Function} callback The function to combine each word.
3978      * @returns {Function} Returns the new compounder function.
3979      */
3980     function createCompounder(callback) {
3981       return function(string) {
3982         return arrayReduce(words(deburr(string)), callback, '');
3983       };
3984     }
3985
3986     /**
3987      * Creates a function that produces an instance of `Ctor` regardless of
3988      * whether it was invoked as part of a `new` expression or by `call` or `apply`.
3989      *
3990      * @private
3991      * @param {Function} Ctor The constructor to wrap.
3992      * @returns {Function} Returns the new wrapped function.
3993      */
3994     function createCtorWrapper(Ctor) {
3995       return function() {
3996         // Use a `switch` statement to work with class constructors.
3997         // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
3998         // for more details.
3999         var args = arguments;
4000         switch (args.length) {
4001           case 0: return new Ctor;
4002           case 1: return new Ctor(args[0]);
4003           case 2: return new Ctor(args[0], args[1]);
4004           case 3: return new Ctor(args[0], args[1], args[2]);
4005           case 4: return new Ctor(args[0], args[1], args[2], args[3]);
4006           case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
4007           case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
4008           case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
4009         }
4010         var thisBinding = baseCreate(Ctor.prototype),
4011             result = Ctor.apply(thisBinding, args);
4012
4013         // Mimic the constructor's `return` behavior.
4014         // See https://es5.github.io/#x13.2.2 for more details.
4015         return isObject(result) ? result : thisBinding;
4016       };
4017     }
4018
4019     /**
4020      * Creates a function that wraps `func` to enable currying.
4021      *
4022      * @private
4023      * @param {Function} func The function to wrap.
4024      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4025      * @param {number} arity The arity of `func`.
4026      * @returns {Function} Returns the new wrapped function.
4027      */
4028     function createCurryWrapper(func, bitmask, arity) {
4029       var Ctor = createCtorWrapper(func);
4030
4031       function wrapper() {
4032         var length = arguments.length,
4033             index = length,
4034             args = Array(length),
4035             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func,
4036             placeholder = wrapper.placeholder;
4037
4038         while (index--) {
4039           args[index] = arguments[index];
4040         }
4041         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
4042           ? []
4043           : replaceHolders(args, placeholder);
4044
4045         length -= holders.length;
4046         return length < arity
4047           ? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length)
4048           : apply(fn, this, args);
4049       }
4050       return wrapper;
4051     }
4052
4053     /**
4054      * Creates a `_.flow` or `_.flowRight` function.
4055      *
4056      * @private
4057      * @param {boolean} [fromRight] Specify iterating from right to left.
4058      * @returns {Function} Returns the new flow function.
4059      */
4060     function createFlow(fromRight) {
4061       return rest(function(funcs) {
4062         funcs = baseFlatten(funcs);
4063
4064         var length = funcs.length,
4065             index = length,
4066             prereq = LodashWrapper.prototype.thru;
4067
4068         if (fromRight) {
4069           funcs.reverse();
4070         }
4071         while (index--) {
4072           var func = funcs[index];
4073           if (typeof func != 'function') {
4074             throw new TypeError(FUNC_ERROR_TEXT);
4075           }
4076           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
4077             var wrapper = new LodashWrapper([], true);
4078           }
4079         }
4080         index = wrapper ? index : length;
4081         while (++index < length) {
4082           func = funcs[index];
4083
4084           var funcName = getFuncName(func),
4085               data = funcName == 'wrapper' ? getData(func) : undefined;
4086
4087           if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
4088             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
4089           } else {
4090             wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
4091           }
4092         }
4093         return function() {
4094           var args = arguments,
4095               value = args[0];
4096
4097           if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
4098             return wrapper.plant(value).value();
4099           }
4100           var index = 0,
4101               result = length ? funcs[index].apply(this, args) : value;
4102
4103           while (++index < length) {
4104             result = funcs[index].call(this, result);
4105           }
4106           return result;
4107         };
4108       });
4109     }
4110
4111     /**
4112      * Creates a function that wraps `func` to invoke it with optional `this`
4113      * binding of `thisArg`, partial application, and currying.
4114      *
4115      * @private
4116      * @param {Function|string} func The function or method name to wrap.
4117      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4118      * @param {*} [thisArg] The `this` binding of `func`.
4119      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4120      * @param {Array} [holders] The `partials` placeholder indexes.
4121      * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
4122      * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
4123      * @param {Array} [argPos] The argument positions of the new function.
4124      * @param {number} [ary] The arity cap of `func`.
4125      * @param {number} [arity] The arity of `func`.
4126      * @returns {Function} Returns the new wrapped function.
4127      */
4128     function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
4129       var isAry = bitmask & ARY_FLAG,
4130           isBind = bitmask & BIND_FLAG,
4131           isBindKey = bitmask & BIND_KEY_FLAG,
4132           isCurry = bitmask & CURRY_FLAG,
4133           isCurryRight = bitmask & CURRY_RIGHT_FLAG,
4134           isFlip = bitmask & FLIP_FLAG,
4135           Ctor = isBindKey ? undefined : createCtorWrapper(func);
4136
4137       function wrapper() {
4138         var length = arguments.length,
4139             index = length,
4140             args = Array(length);
4141
4142         while (index--) {
4143           args[index] = arguments[index];
4144         }
4145         if (partials) {
4146           args = composeArgs(args, partials, holders);
4147         }
4148         if (partialsRight) {
4149           args = composeArgsRight(args, partialsRight, holdersRight);
4150         }
4151         if (isCurry || isCurryRight) {
4152           var placeholder = wrapper.placeholder,
4153               argsHolders = replaceHolders(args, placeholder);
4154
4155           length -= argsHolders.length;
4156           if (length < arity) {
4157             return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length);
4158           }
4159         }
4160         var thisBinding = isBind ? thisArg : this,
4161             fn = isBindKey ? thisBinding[func] : func;
4162
4163         if (argPos) {
4164           args = reorder(args, argPos);
4165         } else if (isFlip && args.length > 1) {
4166           args.reverse();
4167         }
4168         if (isAry && ary < args.length) {
4169           args.length = ary;
4170         }
4171         if (this && this !== root && this instanceof wrapper) {
4172           fn = Ctor || createCtorWrapper(fn);
4173         }
4174         return fn.apply(thisBinding, args);
4175       }
4176       return wrapper;
4177     }
4178
4179     /**
4180      * Creates a function like `_.over`.
4181      *
4182      * @private
4183      * @param {Function} arrayFunc The function to iterate over iteratees.
4184      * @returns {Function} Returns the new invoker function.
4185      */
4186     function createOver(arrayFunc) {
4187       return rest(function(iteratees) {
4188         iteratees = arrayMap(baseFlatten(iteratees), getIteratee());
4189         return rest(function(args) {
4190           var thisArg = this;
4191           return arrayFunc(iteratees, function(iteratee) {
4192             return apply(iteratee, thisArg, args);
4193           });
4194         });
4195       });
4196     }
4197
4198     /**
4199      * Creates the padding for `string` based on `length`. The `chars` string
4200      * is truncated if the number of characters exceeds `length`.
4201      *
4202      * @private
4203      * @param {string} string The string to create padding for.
4204      * @param {number} [length=0] The padding length.
4205      * @param {string} [chars=' '] The string used as padding.
4206      * @returns {string} Returns the padding for `string`.
4207      */
4208     function createPadding(string, length, chars) {
4209       length = toInteger(length);
4210
4211       var strLength = stringSize(string);
4212       if (!length || strLength >= length) {
4213         return '';
4214       }
4215       var padLength = length - strLength;
4216       chars = chars === undefined ? ' ' : (chars + '');
4217
4218       var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
4219       return reHasComplexSymbol.test(chars)
4220         ? stringToArray(result).slice(0, padLength).join('')
4221         : result.slice(0, padLength);
4222     }
4223
4224     /**
4225      * Creates a function that wraps `func` to invoke it with the optional `this`
4226      * binding of `thisArg` and the `partials` prepended to those provided to
4227      * the wrapper.
4228      *
4229      * @private
4230      * @param {Function} func The function to wrap.
4231      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4232      * @param {*} thisArg The `this` binding of `func`.
4233      * @param {Array} partials The arguments to prepend to those provided to the new function.
4234      * @returns {Function} Returns the new wrapped function.
4235      */
4236     function createPartialWrapper(func, bitmask, thisArg, partials) {
4237       var isBind = bitmask & BIND_FLAG,
4238           Ctor = createCtorWrapper(func);
4239
4240       function wrapper() {
4241         var argsIndex = -1,
4242             argsLength = arguments.length,
4243             leftIndex = -1,
4244             leftLength = partials.length,
4245             args = Array(leftLength + argsLength),
4246             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4247
4248         while (++leftIndex < leftLength) {
4249           args[leftIndex] = partials[leftIndex];
4250         }
4251         while (argsLength--) {
4252           args[leftIndex++] = arguments[++argsIndex];
4253         }
4254         return apply(fn, isBind ? thisArg : this, args);
4255       }
4256       return wrapper;
4257     }
4258
4259     /**
4260      * Creates a `_.range` or `_.rangeRight` function.
4261      *
4262      * @private
4263      * @param {boolean} [fromRight] Specify iterating from right to left.
4264      * @returns {Function} Returns the new range function.
4265      */
4266     function createRange(fromRight) {
4267       return function(start, end, step) {
4268         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
4269           end = step = undefined;
4270         }
4271         // Ensure the sign of `-0` is preserved.
4272         start = toNumber(start);
4273         start = start === start ? start : 0;
4274         if (end === undefined) {
4275           end = start;
4276           start = 0;
4277         } else {
4278           end = toNumber(end) || 0;
4279         }
4280         step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
4281         return baseRange(start, end, step, fromRight);
4282       };
4283     }
4284
4285     /**
4286      * Creates a function that wraps `func` to continue currying.
4287      *
4288      * @private
4289      * @param {Function} func The function to wrap.
4290      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4291      * @param {Function} wrapFunc The function to create the `func` wrapper.
4292      * @param {*} placeholder The placeholder to replace.
4293      * @param {*} [thisArg] The `this` binding of `func`.
4294      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4295      * @param {Array} [holders] The `partials` placeholder indexes.
4296      * @param {Array} [argPos] The argument positions of the new function.
4297      * @param {number} [ary] The arity cap of `func`.
4298      * @param {number} [arity] The arity of `func`.
4299      * @returns {Function} Returns the new wrapped function.
4300      */
4301     function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
4302       var isCurry = bitmask & CURRY_FLAG,
4303           newArgPos = argPos ? copyArray(argPos) : undefined,
4304           newsHolders = isCurry ? holders : undefined,
4305           newHoldersRight = isCurry ? undefined : holders,
4306           newPartials = isCurry ? partials : undefined,
4307           newPartialsRight = isCurry ? undefined : partials;
4308
4309       bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
4310       bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
4311
4312       if (!(bitmask & CURRY_BOUND_FLAG)) {
4313         bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
4314       }
4315       var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity],
4316           result = wrapFunc.apply(undefined, newData);
4317
4318       if (isLaziable(func)) {
4319         setData(result, newData);
4320       }
4321       result.placeholder = placeholder;
4322       return result;
4323     }
4324
4325     /**
4326      * Creates a function like `_.round`.
4327      *
4328      * @private
4329      * @param {string} methodName The name of the `Math` method to use when rounding.
4330      * @returns {Function} Returns the new round function.
4331      */
4332     function createRound(methodName) {
4333       var func = Math[methodName];
4334       return function(number, precision) {
4335         number = toNumber(number);
4336         precision = toInteger(precision);
4337         if (precision) {
4338           // Shift with exponential notation to avoid floating-point issues.
4339           // See [MDN](https://mdn.io/round#Examples) for more details.
4340           var pair = (toString(number) + 'e').split('e'),
4341               value = func(pair[0] + 'e' + (+pair[1] + precision));
4342
4343           pair = (toString(value) + 'e').split('e');
4344           return +(pair[0] + 'e' + (+pair[1] - precision));
4345         }
4346         return func(number);
4347       };
4348     }
4349
4350     /**
4351      * Creates a set of `values`.
4352      *
4353      * @private
4354      * @param {Array} values The values to add to the set.
4355      * @returns {Object} Returns the new set.
4356      */
4357     var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
4358       return new Set(values);
4359     };
4360
4361     /**
4362      * Creates a function that either curries or invokes `func` with optional
4363      * `this` binding and partially applied arguments.
4364      *
4365      * @private
4366      * @param {Function|string} func The function or method name to wrap.
4367      * @param {number} bitmask The bitmask of wrapper flags.
4368      *  The bitmask may be composed of the following flags:
4369      *     1 - `_.bind`
4370      *     2 - `_.bindKey`
4371      *     4 - `_.curry` or `_.curryRight` of a bound function
4372      *     8 - `_.curry`
4373      *    16 - `_.curryRight`
4374      *    32 - `_.partial`
4375      *    64 - `_.partialRight`
4376      *   128 - `_.rearg`
4377      *   256 - `_.ary`
4378      * @param {*} [thisArg] The `this` binding of `func`.
4379      * @param {Array} [partials] The arguments to be partially applied.
4380      * @param {Array} [holders] The `partials` placeholder indexes.
4381      * @param {Array} [argPos] The argument positions of the new function.
4382      * @param {number} [ary] The arity cap of `func`.
4383      * @param {number} [arity] The arity of `func`.
4384      * @returns {Function} Returns the new wrapped function.
4385      */
4386     function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
4387       var isBindKey = bitmask & BIND_KEY_FLAG;
4388       if (!isBindKey && typeof func != 'function') {
4389         throw new TypeError(FUNC_ERROR_TEXT);
4390       }
4391       var length = partials ? partials.length : 0;
4392       if (!length) {
4393         bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
4394         partials = holders = undefined;
4395       }
4396       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
4397       arity = arity === undefined ? arity : toInteger(arity);
4398       length -= holders ? holders.length : 0;
4399
4400       if (bitmask & PARTIAL_RIGHT_FLAG) {
4401         var partialsRight = partials,
4402             holdersRight = holders;
4403
4404         partials = holders = undefined;
4405       }
4406       var data = isBindKey ? undefined : getData(func),
4407           newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
4408
4409       if (data) {
4410         mergeData(newData, data);
4411       }
4412       func = newData[0];
4413       bitmask = newData[1];
4414       thisArg = newData[2];
4415       partials = newData[3];
4416       holders = newData[4];
4417       arity = newData[9] = newData[9] == null
4418         ? (isBindKey ? 0 : func.length)
4419         : nativeMax(newData[9] - length, 0);
4420
4421       if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
4422         bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
4423       }
4424       if (!bitmask || bitmask == BIND_FLAG) {
4425         var result = createBaseWrapper(func, bitmask, thisArg);
4426       } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
4427         result = createCurryWrapper(func, bitmask, arity);
4428       } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
4429         result = createPartialWrapper(func, bitmask, thisArg, partials);
4430       } else {
4431         result = createHybridWrapper.apply(undefined, newData);
4432       }
4433       var setter = data ? baseSetData : setData;
4434       return setter(result, newData);
4435     }
4436
4437     /**
4438      * A specialized version of `baseIsEqualDeep` for arrays with support for
4439      * partial deep comparisons.
4440      *
4441      * @private
4442      * @param {Array} array The array to compare.
4443      * @param {Array} other The other array to compare.
4444      * @param {Function} equalFunc The function to determine equivalents of values.
4445      * @param {Function} [customizer] The function to customize comparisons.
4446      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4447      * @param {Object} [stack] Tracks traversed `array` and `other` objects.
4448      * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
4449      */
4450     function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
4451       var index = -1,
4452           isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4453           isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
4454           arrLength = array.length,
4455           othLength = other.length;
4456
4457       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
4458         return false;
4459       }
4460       // Assume cyclic values are equal.
4461       var stacked = stack.get(array);
4462       if (stacked) {
4463         return stacked == other;
4464       }
4465       var result = true;
4466       stack.set(array, other);
4467
4468       // Ignore non-index properties.
4469       while (++index < arrLength) {
4470         var arrValue = array[index],
4471             othValue = other[index];
4472
4473         if (customizer) {
4474           var compared = isPartial
4475             ? customizer(othValue, arrValue, index, other, array, stack)
4476             : customizer(arrValue, othValue, index, array, other, stack);
4477         }
4478         if (compared !== undefined) {
4479           if (compared) {
4480             continue;
4481           }
4482           result = false;
4483           break;
4484         }
4485         // Recursively compare arrays (susceptible to call stack limits).
4486         if (isUnordered) {
4487           if (!arraySome(other, function(othValue) {
4488                 return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
4489               })) {
4490             result = false;
4491             break;
4492           }
4493         } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
4494           result = false;
4495           break;
4496         }
4497       }
4498       stack['delete'](array);
4499       return result;
4500     }
4501
4502     /**
4503      * A specialized version of `baseIsEqualDeep` for comparing objects of
4504      * the same `toStringTag`.
4505      *
4506      * **Note:** This function only supports comparing values with tags of
4507      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4508      *
4509      * @private
4510      * @param {Object} object The object to compare.
4511      * @param {Object} other The other object to compare.
4512      * @param {string} tag The `toStringTag` of the objects to compare.
4513      * @param {Function} equalFunc The function to determine equivalents of values.
4514      * @param {Function} [customizer] The function to customize comparisons.
4515      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4516      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4517      */
4518     function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
4519       switch (tag) {
4520         case arrayBufferTag:
4521           if ((object.byteLength != other.byteLength) ||
4522               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
4523             return false;
4524           }
4525           return true;
4526
4527         case boolTag:
4528         case dateTag:
4529           // Coerce dates and booleans to numbers, dates to milliseconds and booleans
4530           // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
4531           return +object == +other;
4532
4533         case errorTag:
4534           return object.name == other.name && object.message == other.message;
4535
4536         case numberTag:
4537           // Treat `NaN` vs. `NaN` as equal.
4538           return (object != +object) ? other != +other : object == +other;
4539
4540         case regexpTag:
4541         case stringTag:
4542           // Coerce regexes to strings and treat strings primitives and string
4543           // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
4544           return object == (other + '');
4545
4546         case mapTag:
4547           var convert = mapToArray;
4548
4549         case setTag:
4550           var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
4551           convert || (convert = setToArray);
4552
4553           // Recursively compare objects (susceptible to call stack limits).
4554           return (isPartial || object.size == other.size) &&
4555             equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
4556
4557         case symbolTag:
4558           return !!_Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
4559       }
4560       return false;
4561     }
4562
4563     /**
4564      * A specialized version of `baseIsEqualDeep` for objects with support for
4565      * partial deep comparisons.
4566      *
4567      * @private
4568      * @param {Object} object The object to compare.
4569      * @param {Object} other The other object to compare.
4570      * @param {Function} equalFunc The function to determine equivalents of values.
4571      * @param {Function} [customizer] The function to customize comparisons.
4572      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4573      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
4574      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4575      */
4576     function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
4577       var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4578           isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
4579           objProps = keys(object),
4580           objLength = objProps.length,
4581           othProps = keys(other),
4582           othLength = othProps.length;
4583
4584       if (objLength != othLength && !isPartial) {
4585         return false;
4586       }
4587       var index = objLength;
4588       while (index--) {
4589         var key = objProps[index];
4590         if (!(isPartial ? key in other : baseHas(other, key)) ||
4591             !(isUnordered || key == othProps[index])) {
4592           return false;
4593         }
4594       }
4595       // Assume cyclic values are equal.
4596       var stacked = stack.get(object);
4597       if (stacked) {
4598         return stacked == other;
4599       }
4600       var result = true;
4601       stack.set(object, other);
4602
4603       var skipCtor = isPartial;
4604       while (++index < objLength) {
4605         key = objProps[index];
4606         var objValue = object[key],
4607             othValue = other[key];
4608
4609         if (customizer) {
4610           var compared = isPartial
4611             ? customizer(othValue, objValue, key, other, object, stack)
4612             : customizer(objValue, othValue, key, object, other, stack);
4613         }
4614         // Recursively compare objects (susceptible to call stack limits).
4615         if (!(compared === undefined
4616               ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
4617               : compared
4618             )) {
4619           result = false;
4620           break;
4621         }
4622         skipCtor || (skipCtor = key == 'constructor');
4623       }
4624       if (result && !skipCtor) {
4625         var objCtor = object.constructor,
4626             othCtor = other.constructor;
4627
4628         // Non `Object` object instances with different constructors are not equal.
4629         if (objCtor != othCtor &&
4630             ('constructor' in object && 'constructor' in other) &&
4631             !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
4632               typeof othCtor == 'function' && othCtor instanceof othCtor)) {
4633           result = false;
4634         }
4635       }
4636       stack['delete'](object);
4637       return result;
4638     }
4639
4640     /**
4641      * Gets metadata for `func`.
4642      *
4643      * @private
4644      * @param {Function} func The function to query.
4645      * @returns {*} Returns the metadata for `func`.
4646      */
4647     var getData = !metaMap ? noop : function(func) {
4648       return metaMap.get(func);
4649     };
4650
4651     /**
4652      * Gets the name of `func`.
4653      *
4654      * @private
4655      * @param {Function} func The function to query.
4656      * @returns {string} Returns the function name.
4657      */
4658     function getFuncName(func) {
4659       var result = (func.name + ''),
4660           array = realNames[result],
4661           length = array ? array.length : 0;
4662
4663       while (length--) {
4664         var data = array[length],
4665             otherFunc = data.func;
4666         if (otherFunc == null || otherFunc == func) {
4667           return data.name;
4668         }
4669       }
4670       return result;
4671     }
4672
4673     /**
4674      * Gets the appropriate "iteratee" function. If the `_.iteratee` method is
4675      * customized this function returns the custom method, otherwise it returns
4676      * `baseIteratee`. If arguments are provided the chosen function is invoked
4677      * with them and its result is returned.
4678      *
4679      * @private
4680      * @param {*} [value] The value to convert to an iteratee.
4681      * @param {number} [arity] The arity of the created iteratee.
4682      * @returns {Function} Returns the chosen function or its result.
4683      */
4684     function getIteratee() {
4685       var result = lodash.iteratee || iteratee;
4686       result = result === iteratee ? baseIteratee : result;
4687       return arguments.length ? result(arguments[0], arguments[1]) : result;
4688     }
4689
4690     /**
4691      * Gets the "length" property value of `object`.
4692      *
4693      * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
4694      * that affects Safari on at least iOS 8.1-8.3 ARM64.
4695      *
4696      * @private
4697      * @param {Object} object The object to query.
4698      * @returns {*} Returns the "length" value.
4699      */
4700     var getLength = baseProperty('length');
4701
4702     /**
4703      * Gets the property names, values, and compare flags of `object`.
4704      *
4705      * @private
4706      * @param {Object} object The object to query.
4707      * @returns {Array} Returns the match data of `object`.
4708      */
4709     function getMatchData(object) {
4710       var result = toPairs(object),
4711           length = result.length;
4712
4713       while (length--) {
4714         result[length][2] = isStrictComparable(result[length][1]);
4715       }
4716       return result;
4717     }
4718
4719     /**
4720      * Gets the native function at `key` of `object`.
4721      *
4722      * @private
4723      * @param {Object} object The object to query.
4724      * @param {string} key The key of the method to get.
4725      * @returns {*} Returns the function if it's native, else `undefined`.
4726      */
4727     function getNative(object, key) {
4728       var value = object == null ? undefined : object[key];
4729       return isNative(value) ? value : undefined;
4730     }
4731
4732     /**
4733      * Creates an array of the own symbol properties of `object`.
4734      *
4735      * @private
4736      * @param {Object} object The object to query.
4737      * @returns {Array} Returns the array of symbols.
4738      */
4739     var getSymbols = getOwnPropertySymbols || function() {
4740       return [];
4741     };
4742
4743     /**
4744      * Gets the `toStringTag` of `value`.
4745      *
4746      * @private
4747      * @param {*} value The value to query.
4748      * @returns {string} Returns the `toStringTag`.
4749      */
4750     function getTag(value) {
4751       return objectToString.call(value);
4752     }
4753
4754     // Fallback for IE 11 providing `toStringTag` values for maps and sets.
4755     if ((Map && getTag(new Map) != mapTag) || (Set && getTag(new Set) != setTag)) {
4756       getTag = function(value) {
4757         var result = objectToString.call(value),
4758             Ctor = result == objectTag ? value.constructor : null,
4759             ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
4760
4761         if (ctorString) {
4762           if (ctorString == mapCtorString) {
4763             return mapTag;
4764           }
4765           if (ctorString == setCtorString) {
4766             return setTag;
4767           }
4768         }
4769         return result;
4770       };
4771     }
4772
4773     /**
4774      * Gets the view, applying any `transforms` to the `start` and `end` positions.
4775      *
4776      * @private
4777      * @param {number} start The start of the view.
4778      * @param {number} end The end of the view.
4779      * @param {Array} transforms The transformations to apply to the view.
4780      * @returns {Object} Returns an object containing the `start` and `end`
4781      *  positions of the view.
4782      */
4783     function getView(start, end, transforms) {
4784       var index = -1,
4785           length = transforms.length;
4786
4787       while (++index < length) {
4788         var data = transforms[index],
4789             size = data.size;
4790
4791         switch (data.type) {
4792           case 'drop':      start += size; break;
4793           case 'dropRight': end -= size; break;
4794           case 'take':      end = nativeMin(end, start + size); break;
4795           case 'takeRight': start = nativeMax(start, end - size); break;
4796         }
4797       }
4798       return { 'start': start, 'end': end };
4799     }
4800
4801     /**
4802      * Checks if `path` exists on `object`.
4803      *
4804      * @private
4805      * @param {Object} object The object to query.
4806      * @param {Array|string} path The path to check.
4807      * @param {Function} hasFunc The function to check properties.
4808      * @returns {boolean} Returns `true` if `path` exists, else `false`.
4809      */
4810     function hasPath(object, path, hasFunc) {
4811       if (object == null) {
4812         return false;
4813       }
4814       var result = hasFunc(object, path);
4815       if (!result && !isKey(path)) {
4816         path = baseToPath(path);
4817         object = parent(object, path);
4818         if (object != null) {
4819           path = last(path);
4820           result = hasFunc(object, path);
4821         }
4822       }
4823       return result || (isLength(object && object.length) && isIndex(path, object.length) &&
4824         (isArray(object) || isString(object) || isArguments(object)));
4825     }
4826
4827     /**
4828      * Initializes an array clone.
4829      *
4830      * @private
4831      * @param {Array} array The array to clone.
4832      * @returns {Array} Returns the initialized clone.
4833      */
4834     function initCloneArray(array) {
4835       var length = array.length,
4836           result = array.constructor(length);
4837
4838       // Add properties assigned by `RegExp#exec`.
4839       if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
4840         result.index = array.index;
4841         result.input = array.input;
4842       }
4843       return result;
4844     }
4845
4846     /**
4847      * Initializes an object clone.
4848      *
4849      * @private
4850      * @param {Object} object The object to clone.
4851      * @returns {Object} Returns the initialized clone.
4852      */
4853     function initCloneObject(object) {
4854       var Ctor = object.constructor;
4855       return baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
4856     }
4857
4858     /**
4859      * Initializes an object clone based on its `toStringTag`.
4860      *
4861      * **Note:** This function only supports cloning values with tags of
4862      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4863      *
4864      * @private
4865      * @param {Object} object The object to clone.
4866      * @param {string} tag The `toStringTag` of the object to clone.
4867      * @param {boolean} [isDeep] Specify a deep clone.
4868      * @returns {Object} Returns the initialized clone.
4869      */
4870     function initCloneByTag(object, tag, isDeep) {
4871       var Ctor = object.constructor;
4872       switch (tag) {
4873         case arrayBufferTag:
4874           return cloneBuffer(object);
4875
4876         case boolTag:
4877         case dateTag:
4878           return new Ctor(+object);
4879
4880         case float32Tag: case float64Tag:
4881         case int8Tag: case int16Tag: case int32Tag:
4882         case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
4883           return cloneTypedArray(object, isDeep);
4884
4885         case mapTag:
4886           return cloneMap(object);
4887
4888         case numberTag:
4889         case stringTag:
4890           return new Ctor(object);
4891
4892         case regexpTag:
4893           return cloneRegExp(object);
4894
4895         case setTag:
4896           return cloneSet(object);
4897
4898         case symbolTag:
4899           return cloneSymbol(object);
4900       }
4901     }
4902
4903     /**
4904      * Creates an array of index keys for `object` values of arrays,
4905      * `arguments` objects, and strings, otherwise `null` is returned.
4906      *
4907      * @private
4908      * @param {Object} object The object to query.
4909      * @returns {Array|null} Returns index keys, else `null`.
4910      */
4911     function indexKeys(object) {
4912       var length = object ? object.length : undefined;
4913       return (isLength(length) && (isArray(object) || isString(object) || isArguments(object)))
4914         ? baseTimes(length, String)
4915         : null;
4916     }
4917
4918     /**
4919      * Checks if the provided arguments are from an iteratee call.
4920      *
4921      * @private
4922      * @param {*} value The potential iteratee value argument.
4923      * @param {*} index The potential iteratee index or key argument.
4924      * @param {*} object The potential iteratee object argument.
4925      * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
4926      */
4927     function isIterateeCall(value, index, object) {
4928       if (!isObject(object)) {
4929         return false;
4930       }
4931       var type = typeof index;
4932       if (type == 'number'
4933           ? (isArrayLike(object) && isIndex(index, object.length))
4934           : (type == 'string' && index in object)) {
4935         return eq(object[index], value);
4936       }
4937       return false;
4938     }
4939
4940     /**
4941      * Checks if `value` is a property name and not a property path.
4942      *
4943      * @private
4944      * @param {*} value The value to check.
4945      * @param {Object} [object] The object to query keys on.
4946      * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
4947      */
4948     function isKey(value, object) {
4949       if (typeof value == 'number') {
4950         return true;
4951       }
4952       return !isArray(value) &&
4953         (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
4954           (object != null && value in Object(object)));
4955     }
4956
4957     /**
4958      * Checks if `value` is suitable for use as unique object key.
4959      *
4960      * @private
4961      * @param {*} value The value to check.
4962      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
4963      */
4964     function isKeyable(value) {
4965       var type = typeof value;
4966       return type == 'number' || type == 'boolean' ||
4967         (type == 'string' && value !== '__proto__') || value == null;
4968     }
4969
4970     /**
4971      * Checks if `func` has a lazy counterpart.
4972      *
4973      * @private
4974      * @param {Function} func The function to check.
4975      * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
4976      */
4977     function isLaziable(func) {
4978       var funcName = getFuncName(func),
4979           other = lodash[funcName];
4980
4981       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
4982         return false;
4983       }
4984       if (func === other) {
4985         return true;
4986       }
4987       var data = getData(other);
4988       return !!data && func === data[0];
4989     }
4990
4991     /**
4992      * Checks if `value` is likely a prototype object.
4993      *
4994      * @private
4995      * @param {*} value The value to check.
4996      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
4997      */
4998     function isPrototype(value) {
4999       var Ctor = value && value.constructor,
5000           proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
5001
5002       return value === proto;
5003     }
5004
5005     /**
5006      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
5007      *
5008      * @private
5009      * @param {*} value The value to check.
5010      * @returns {boolean} Returns `true` if `value` if suitable for strict
5011      *  equality comparisons, else `false`.
5012      */
5013     function isStrictComparable(value) {
5014       return value === value && !isObject(value);
5015     }
5016
5017     /**
5018      * Merges the function metadata of `source` into `data`.
5019      *
5020      * Merging metadata reduces the number of wrappers used to invoke a function.
5021      * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
5022      * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
5023      * modify function arguments, making the order in which they are executed important,
5024      * preventing the merging of metadata. However, we make an exception for a safe
5025      * combined case where curried functions have `_.ary` and or `_.rearg` applied.
5026      *
5027      * @private
5028      * @param {Array} data The destination metadata.
5029      * @param {Array} source The source metadata.
5030      * @returns {Array} Returns `data`.
5031      */
5032     function mergeData(data, source) {
5033       var bitmask = data[1],
5034           srcBitmask = source[1],
5035           newBitmask = bitmask | srcBitmask,
5036           isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
5037
5038       var isCombo =
5039         (srcBitmask == ARY_FLAG && (bitmask == CURRY_FLAG)) ||
5040         (srcBitmask == ARY_FLAG && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
5041         (srcBitmask == (ARY_FLAG | REARG_FLAG) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
5042
5043       // Exit early if metadata can't be merged.
5044       if (!(isCommon || isCombo)) {
5045         return data;
5046       }
5047       // Use source `thisArg` if available.
5048       if (srcBitmask & BIND_FLAG) {
5049         data[2] = source[2];
5050         // Set when currying a bound function.
5051         newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
5052       }
5053       // Compose partial arguments.
5054       var value = source[3];
5055       if (value) {
5056         var partials = data[3];
5057         data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
5058         data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
5059       }
5060       // Compose partial right arguments.
5061       value = source[5];
5062       if (value) {
5063         partials = data[5];
5064         data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
5065         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
5066       }
5067       // Use source `argPos` if available.
5068       value = source[7];
5069       if (value) {
5070         data[7] = copyArray(value);
5071       }
5072       // Use source `ary` if it's smaller.
5073       if (srcBitmask & ARY_FLAG) {
5074         data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
5075       }
5076       // Use source `arity` if one is not provided.
5077       if (data[9] == null) {
5078         data[9] = source[9];
5079       }
5080       // Use source `func` and merge bitmasks.
5081       data[0] = source[0];
5082       data[1] = newBitmask;
5083
5084       return data;
5085     }
5086
5087     /**
5088      * Used by `_.defaultsDeep` to customize its `_.merge` use.
5089      *
5090      * @private
5091      * @param {*} objValue The destination value.
5092      * @param {*} srcValue The source value.
5093      * @param {string} key The key of the property to merge.
5094      * @param {Object} object The parent object of `objValue`.
5095      * @param {Object} source The parent object of `srcValue`.
5096      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
5097      * @returns {*} Returns the value to assign.
5098      */
5099     function mergeDefaults(objValue, srcValue, key, object, source, stack) {
5100       if (isObject(objValue) && isObject(srcValue)) {
5101         stack.set(srcValue, objValue);
5102         baseMerge(objValue, srcValue, mergeDefaults, stack);
5103       }
5104       return objValue === undefined ? baseClone(srcValue) : objValue;
5105     }
5106
5107     /**
5108      * Gets the parent value at `path` of `object`.
5109      *
5110      * @private
5111      * @param {Object} object The object to query.
5112      * @param {Array} path The path to get the parent value of.
5113      * @returns {*} Returns the parent value.
5114      */
5115     function parent(object, path) {
5116       return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
5117     }
5118
5119     /**
5120      * Reorder `array` according to the specified indexes where the element at
5121      * the first index is assigned as the first element, the element at
5122      * the second index is assigned as the second element, and so on.
5123      *
5124      * @private
5125      * @param {Array} array The array to reorder.
5126      * @param {Array} indexes The arranged array indexes.
5127      * @returns {Array} Returns `array`.
5128      */
5129     function reorder(array, indexes) {
5130       var arrLength = array.length,
5131           length = nativeMin(indexes.length, arrLength),
5132           oldArray = copyArray(array);
5133
5134       while (length--) {
5135         var index = indexes[length];
5136         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5137       }
5138       return array;
5139     }
5140
5141     /**
5142      * Sets metadata for `func`.
5143      *
5144      * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
5145      * period of time, it will trip its breaker and transition to an identity function
5146      * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
5147      * for more details.
5148      *
5149      * @private
5150      * @param {Function} func The function to associate metadata with.
5151      * @param {*} data The metadata.
5152      * @returns {Function} Returns `func`.
5153      */
5154     var setData = (function() {
5155       var count = 0,
5156           lastCalled = 0;
5157
5158       return function(key, value) {
5159         var stamp = now(),
5160             remaining = HOT_SPAN - (stamp - lastCalled);
5161
5162         lastCalled = stamp;
5163         if (remaining > 0) {
5164           if (++count >= HOT_COUNT) {
5165             return key;
5166           }
5167         } else {
5168           count = 0;
5169         }
5170         return baseSetData(key, value);
5171       };
5172     }());
5173
5174     /**
5175      * Converts `string` to a property path array.
5176      *
5177      * @private
5178      * @param {string} string The string to convert.
5179      * @returns {Array} Returns the property path array.
5180      */
5181     function stringToPath(string) {
5182       var result = [];
5183       toString(string).replace(rePropName, function(match, number, quote, string) {
5184         result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
5185       });
5186       return result;
5187     }
5188
5189     /**
5190      * Converts `value` to an array-like object if it's not one.
5191      *
5192      * @private
5193      * @param {*} value The value to process.
5194      * @returns {Array} Returns the array-like object.
5195      */
5196     function toArrayLikeObject(value) {
5197       return isArrayLikeObject(value) ? value : [];
5198     }
5199
5200     /**
5201      * Converts `value` to a function if it's not one.
5202      *
5203      * @private
5204      * @param {*} value The value to process.
5205      * @returns {Function} Returns the function.
5206      */
5207     function toFunction(value) {
5208       return typeof value == 'function' ? value : identity;
5209     }
5210
5211     /**
5212      * Creates a clone of `wrapper`.
5213      *
5214      * @private
5215      * @param {Object} wrapper The wrapper to clone.
5216      * @returns {Object} Returns the cloned wrapper.
5217      */
5218     function wrapperClone(wrapper) {
5219       if (wrapper instanceof LazyWrapper) {
5220         return wrapper.clone();
5221       }
5222       var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
5223       result.__actions__ = copyArray(wrapper.__actions__);
5224       result.__index__  = wrapper.__index__;
5225       result.__values__ = wrapper.__values__;
5226       return result;
5227     }
5228
5229     /*------------------------------------------------------------------------*/
5230
5231     /**
5232      * Creates an array of elements split into groups the length of `size`.
5233      * If `array` can't be split evenly, the final chunk will be the remaining
5234      * elements.
5235      *
5236      * @static
5237      * @memberOf _
5238      * @category Array
5239      * @param {Array} array The array to process.
5240      * @param {number} [size=0] The length of each chunk.
5241      * @returns {Array} Returns the new array containing chunks.
5242      * @example
5243      *
5244      * _.chunk(['a', 'b', 'c', 'd'], 2);
5245      * // => [['a', 'b'], ['c', 'd']]
5246      *
5247      * _.chunk(['a', 'b', 'c', 'd'], 3);
5248      * // => [['a', 'b', 'c'], ['d']]
5249      */
5250     function chunk(array, size) {
5251       size = nativeMax(toInteger(size), 0);
5252
5253       var length = array ? array.length : 0;
5254       if (!length || size < 1) {
5255         return [];
5256       }
5257       var index = 0,
5258           resIndex = -1,
5259           result = Array(nativeCeil(length / size));
5260
5261       while (index < length) {
5262         result[++resIndex] = baseSlice(array, index, (index += size));
5263       }
5264       return result;
5265     }
5266
5267     /**
5268      * Creates an array with all falsey values removed. The values `false`, `null`,
5269      * `0`, `""`, `undefined`, and `NaN` are falsey.
5270      *
5271      * @static
5272      * @memberOf _
5273      * @category Array
5274      * @param {Array} array The array to compact.
5275      * @returns {Array} Returns the new array of filtered values.
5276      * @example
5277      *
5278      * _.compact([0, 1, false, 2, '', 3]);
5279      * // => [1, 2, 3]
5280      */
5281     function compact(array) {
5282       var index = -1,
5283           length = array ? array.length : 0,
5284           resIndex = -1,
5285           result = [];
5286
5287       while (++index < length) {
5288         var value = array[index];
5289         if (value) {
5290           result[++resIndex] = value;
5291         }
5292       }
5293       return result;
5294     }
5295
5296     /**
5297      * Creates a new array concatenating `array` with any additional arrays
5298      * and/or values.
5299      *
5300      * @static
5301      * @memberOf _
5302      * @category Array
5303      * @param {Array} array The array to concatenate.
5304      * @param {...*} [values] The values to concatenate.
5305      * @returns {Array} Returns the new concatenated array.
5306      * @example
5307      *
5308      * var array = [1];
5309      * var other = _.concat(array, 2, [3], [[4]]);
5310      *
5311      * console.log(other);
5312      * // => [1, 2, 3, [4]]
5313      *
5314      * console.log(array);
5315      * // => [1]
5316      */
5317     var concat = rest(function(array, values) {
5318       values = baseFlatten(values);
5319       return arrayConcat(isArray(array) ? array : [Object(array)], values);
5320     });
5321
5322     /**
5323      * Creates an array of unique `array` values not included in the other
5324      * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5325      * for equality comparisons.
5326      *
5327      * @static
5328      * @memberOf _
5329      * @category Array
5330      * @param {Array} array The array to inspect.
5331      * @param {...Array} [values] The values to exclude.
5332      * @returns {Array} Returns the new array of filtered values.
5333      * @example
5334      *
5335      * _.difference([3, 2, 1], [4, 2]);
5336      * // => [3, 1]
5337      */
5338     var difference = rest(function(array, values) {
5339       return isArrayLikeObject(array)
5340         ? baseDifference(array, baseFlatten(values, false, true))
5341         : [];
5342     });
5343
5344     /**
5345      * This method is like `_.difference` except that it accepts `iteratee` which
5346      * is invoked for each element of `array` and `values` to generate the criterion
5347      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5348      *
5349      * @static
5350      * @memberOf _
5351      * @category Array
5352      * @param {Array} array The array to inspect.
5353      * @param {...Array} [values] The values to exclude.
5354      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5355      * @returns {Array} Returns the new array of filtered values.
5356      * @example
5357      *
5358      * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
5359      * // => [3.1, 1.3]
5360      *
5361      * // using the `_.property` iteratee shorthand
5362      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
5363      * // => [{ 'x': 2 }]
5364      */
5365     var differenceBy = rest(function(array, values) {
5366       var iteratee = last(values);
5367       if (isArrayLikeObject(iteratee)) {
5368         iteratee = undefined;
5369       }
5370       return isArrayLikeObject(array)
5371         ? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee))
5372         : [];
5373     });
5374
5375     /**
5376      * This method is like `_.difference` except that it accepts `comparator`
5377      * which is invoked to compare elements of `array` to `values`. The comparator
5378      * is invoked with two arguments: (arrVal, othVal).
5379      *
5380      * @static
5381      * @memberOf _
5382      * @category Array
5383      * @param {Array} array The array to inspect.
5384      * @param {...Array} [values] The values to exclude.
5385      * @param {Function} [comparator] The comparator invoked per element.
5386      * @returns {Array} Returns the new array of filtered values.
5387      * @example
5388      *
5389      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5390      *
5391      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
5392      * // => [{ 'x': 2, 'y': 1 }]
5393      */
5394     var differenceWith = rest(function(array, values) {
5395       var comparator = last(values);
5396       if (isArrayLikeObject(comparator)) {
5397         comparator = undefined;
5398       }
5399       return isArrayLikeObject(array)
5400         ? baseDifference(array, baseFlatten(values, false, true), undefined, comparator)
5401         : [];
5402     });
5403
5404     /**
5405      * Creates a slice of `array` with `n` elements dropped from the beginning.
5406      *
5407      * @static
5408      * @memberOf _
5409      * @category Array
5410      * @param {Array} array The array to query.
5411      * @param {number} [n=1] The number of elements to drop.
5412      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5413      * @returns {Array} Returns the slice of `array`.
5414      * @example
5415      *
5416      * _.drop([1, 2, 3]);
5417      * // => [2, 3]
5418      *
5419      * _.drop([1, 2, 3], 2);
5420      * // => [3]
5421      *
5422      * _.drop([1, 2, 3], 5);
5423      * // => []
5424      *
5425      * _.drop([1, 2, 3], 0);
5426      * // => [1, 2, 3]
5427      */
5428     function drop(array, n, guard) {
5429       var length = array ? array.length : 0;
5430       if (!length) {
5431         return [];
5432       }
5433       n = (guard || n === undefined) ? 1 : toInteger(n);
5434       return baseSlice(array, n < 0 ? 0 : n, length);
5435     }
5436
5437     /**
5438      * Creates a slice of `array` with `n` elements dropped from the end.
5439      *
5440      * @static
5441      * @memberOf _
5442      * @category Array
5443      * @param {Array} array The array to query.
5444      * @param {number} [n=1] The number of elements to drop.
5445      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5446      * @returns {Array} Returns the slice of `array`.
5447      * @example
5448      *
5449      * _.dropRight([1, 2, 3]);
5450      * // => [1, 2]
5451      *
5452      * _.dropRight([1, 2, 3], 2);
5453      * // => [1]
5454      *
5455      * _.dropRight([1, 2, 3], 5);
5456      * // => []
5457      *
5458      * _.dropRight([1, 2, 3], 0);
5459      * // => [1, 2, 3]
5460      */
5461     function dropRight(array, n, guard) {
5462       var length = array ? array.length : 0;
5463       if (!length) {
5464         return [];
5465       }
5466       n = (guard || n === undefined) ? 1 : toInteger(n);
5467       n = length - n;
5468       return baseSlice(array, 0, n < 0 ? 0 : n);
5469     }
5470
5471     /**
5472      * Creates a slice of `array` excluding elements dropped from the end.
5473      * Elements are dropped until `predicate` returns falsey. The predicate is
5474      * invoked with three arguments: (value, index, array).
5475      *
5476      * @static
5477      * @memberOf _
5478      * @category Array
5479      * @param {Array} array The array to query.
5480      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5481      * @returns {Array} Returns the slice of `array`.
5482      * @example
5483      *
5484      * var users = [
5485      *   { 'user': 'barney',  'active': true },
5486      *   { 'user': 'fred',    'active': false },
5487      *   { 'user': 'pebbles', 'active': false }
5488      * ];
5489      *
5490      * _.dropRightWhile(users, function(o) { return !o.active; });
5491      * // => objects for ['barney']
5492      *
5493      * // using the `_.matches` iteratee shorthand
5494      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
5495      * // => objects for ['barney', 'fred']
5496      *
5497      * // using the `_.matchesProperty` iteratee shorthand
5498      * _.dropRightWhile(users, ['active', false]);
5499      * // => objects for ['barney']
5500      *
5501      * // using the `_.property` iteratee shorthand
5502      * _.dropRightWhile(users, 'active');
5503      * // => objects for ['barney', 'fred', 'pebbles']
5504      */
5505     function dropRightWhile(array, predicate) {
5506       return (array && array.length)
5507         ? baseWhile(array, getIteratee(predicate, 3), true, true)
5508         : [];
5509     }
5510
5511     /**
5512      * Creates a slice of `array` excluding elements dropped from the beginning.
5513      * Elements are dropped until `predicate` returns falsey. The predicate is
5514      * invoked with three arguments: (value, index, array).
5515      *
5516      * @static
5517      * @memberOf _
5518      * @category Array
5519      * @param {Array} array The array to query.
5520      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5521      * @returns {Array} Returns the slice of `array`.
5522      * @example
5523      *
5524      * var users = [
5525      *   { 'user': 'barney',  'active': false },
5526      *   { 'user': 'fred',    'active': false },
5527      *   { 'user': 'pebbles', 'active': true }
5528      * ];
5529      *
5530      * _.dropWhile(users, function(o) { return !o.active; });
5531      * // => objects for ['pebbles']
5532      *
5533      * // using the `_.matches` iteratee shorthand
5534      * _.dropWhile(users, { 'user': 'barney', 'active': false });
5535      * // => objects for ['fred', 'pebbles']
5536      *
5537      * // using the `_.matchesProperty` iteratee shorthand
5538      * _.dropWhile(users, ['active', false]);
5539      * // => objects for ['pebbles']
5540      *
5541      * // using the `_.property` iteratee shorthand
5542      * _.dropWhile(users, 'active');
5543      * // => objects for ['barney', 'fred', 'pebbles']
5544      */
5545     function dropWhile(array, predicate) {
5546       return (array && array.length)
5547         ? baseWhile(array, getIteratee(predicate, 3), true)
5548         : [];
5549     }
5550
5551     /**
5552      * Fills elements of `array` with `value` from `start` up to, but not
5553      * including, `end`.
5554      *
5555      * **Note:** This method mutates `array`.
5556      *
5557      * @static
5558      * @memberOf _
5559      * @category Array
5560      * @param {Array} array The array to fill.
5561      * @param {*} value The value to fill `array` with.
5562      * @param {number} [start=0] The start position.
5563      * @param {number} [end=array.length] The end position.
5564      * @returns {Array} Returns `array`.
5565      * @example
5566      *
5567      * var array = [1, 2, 3];
5568      *
5569      * _.fill(array, 'a');
5570      * console.log(array);
5571      * // => ['a', 'a', 'a']
5572      *
5573      * _.fill(Array(3), 2);
5574      * // => [2, 2, 2]
5575      *
5576      * _.fill([4, 6, 8, 10], '*', 1, 3);
5577      * // => [4, '*', '*', 10]
5578      */
5579     function fill(array, value, start, end) {
5580       var length = array ? array.length : 0;
5581       if (!length) {
5582         return [];
5583       }
5584       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
5585         start = 0;
5586         end = length;
5587       }
5588       return baseFill(array, value, start, end);
5589     }
5590
5591     /**
5592      * This method is like `_.find` except that it returns the index of the first
5593      * element `predicate` returns truthy for instead of the element itself.
5594      *
5595      * @static
5596      * @memberOf _
5597      * @category Array
5598      * @param {Array} array The array to search.
5599      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5600      * @returns {number} Returns the index of the found element, else `-1`.
5601      * @example
5602      *
5603      * var users = [
5604      *   { 'user': 'barney',  'active': false },
5605      *   { 'user': 'fred',    'active': false },
5606      *   { 'user': 'pebbles', 'active': true }
5607      * ];
5608      *
5609      * _.findIndex(users, function(o) { return o.user == 'barney'; });
5610      * // => 0
5611      *
5612      * // using the `_.matches` iteratee shorthand
5613      * _.findIndex(users, { 'user': 'fred', 'active': false });
5614      * // => 1
5615      *
5616      * // using the `_.matchesProperty` iteratee shorthand
5617      * _.findIndex(users, ['active', false]);
5618      * // => 0
5619      *
5620      * // using the `_.property` iteratee shorthand
5621      * _.findIndex(users, 'active');
5622      * // => 2
5623      */
5624     function findIndex(array, predicate) {
5625       return (array && array.length)
5626         ? baseFindIndex(array, getIteratee(predicate, 3))
5627         : -1;
5628     }
5629
5630     /**
5631      * This method is like `_.findIndex` except that it iterates over elements
5632      * of `collection` from right to left.
5633      *
5634      * @static
5635      * @memberOf _
5636      * @category Array
5637      * @param {Array} array The array to search.
5638      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5639      * @returns {number} Returns the index of the found element, else `-1`.
5640      * @example
5641      *
5642      * var users = [
5643      *   { 'user': 'barney',  'active': true },
5644      *   { 'user': 'fred',    'active': false },
5645      *   { 'user': 'pebbles', 'active': false }
5646      * ];
5647      *
5648      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
5649      * // => 2
5650      *
5651      * // using the `_.matches` iteratee shorthand
5652      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
5653      * // => 0
5654      *
5655      * // using the `_.matchesProperty` iteratee shorthand
5656      * _.findLastIndex(users, ['active', false]);
5657      * // => 2
5658      *
5659      * // using the `_.property` iteratee shorthand
5660      * _.findLastIndex(users, 'active');
5661      * // => 0
5662      */
5663     function findLastIndex(array, predicate) {
5664       return (array && array.length)
5665         ? baseFindIndex(array, getIteratee(predicate, 3), true)
5666         : -1;
5667     }
5668
5669     /**
5670      * Creates an array of flattened values by running each element in `array`
5671      * through `iteratee` and concating its result to the other mapped values.
5672      * The iteratee is invoked with three arguments: (value, index|key, array).
5673      *
5674      * @static
5675      * @memberOf _
5676      * @category Array
5677      * @param {Array} array The array to iterate over.
5678      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
5679      * @returns {Array} Returns the new array.
5680      * @example
5681      *
5682      * function duplicate(n) {
5683      *   return [n, n];
5684      * }
5685      *
5686      * _.flatMap([1, 2], duplicate);
5687      * // => [1, 1, 2, 2]
5688      */
5689     function flatMap(array, iteratee) {
5690       var length = array ? array.length : 0;
5691       return length ? baseFlatten(arrayMap(array, getIteratee(iteratee, 3))) : [];
5692     }
5693
5694     /**
5695      * Flattens `array` a single level.
5696      *
5697      * @static
5698      * @memberOf _
5699      * @category Array
5700      * @param {Array} array The array to flatten.
5701      * @returns {Array} Returns the new flattened array.
5702      * @example
5703      *
5704      * _.flatten([1, [2, 3, [4]]]);
5705      * // => [1, 2, 3, [4]]
5706      */
5707     function flatten(array) {
5708       var length = array ? array.length : 0;
5709       return length ? baseFlatten(array) : [];
5710     }
5711
5712     /**
5713      * This method is like `_.flatten` except that it recursively flattens `array`.
5714      *
5715      * @static
5716      * @memberOf _
5717      * @category Array
5718      * @param {Array} array The array to recursively flatten.
5719      * @returns {Array} Returns the new flattened array.
5720      * @example
5721      *
5722      * _.flattenDeep([1, [2, 3, [4]]]);
5723      * // => [1, 2, 3, 4]
5724      */
5725     function flattenDeep(array) {
5726       var length = array ? array.length : 0;
5727       return length ? baseFlatten(array, true) : [];
5728     }
5729
5730     /**
5731      * The inverse of `_.toPairs`; this method returns an object composed
5732      * from key-value `pairs`.
5733      *
5734      * @static
5735      * @memberOf _
5736      * @category Array
5737      * @param {Array} pairs The key-value pairs.
5738      * @returns {Object} Returns the new object.
5739      * @example
5740      *
5741      * _.fromPairs([['fred', 30], ['barney', 40]]);
5742      * // => { 'fred': 30, 'barney': 40 }
5743      */
5744     function fromPairs(pairs) {
5745       var index = -1,
5746           length = pairs ? pairs.length : 0,
5747           result = {};
5748
5749       while (++index < length) {
5750         var pair = pairs[index];
5751         baseSet(result, pair[0], pair[1]);
5752       }
5753       return result;
5754     }
5755
5756     /**
5757      * Gets the first element of `array`.
5758      *
5759      * @static
5760      * @memberOf _
5761      * @alias first
5762      * @category Array
5763      * @param {Array} array The array to query.
5764      * @returns {*} Returns the first element of `array`.
5765      * @example
5766      *
5767      * _.head([1, 2, 3]);
5768      * // => 1
5769      *
5770      * _.head([]);
5771      * // => undefined
5772      */
5773     function head(array) {
5774       return array ? array[0] : undefined;
5775     }
5776
5777     /**
5778      * Gets the index at which the first occurrence of `value` is found in `array`
5779      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5780      * for equality comparisons. If `fromIndex` is negative, it's used as the offset
5781      * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
5782      * performs a faster binary search.
5783      *
5784      * @static
5785      * @memberOf _
5786      * @category Array
5787      * @param {Array} array The array to search.
5788      * @param {*} value The value to search for.
5789      * @param {number} [fromIndex=0] The index to search from.
5790      * @returns {number} Returns the index of the matched value, else `-1`.
5791      * @example
5792      *
5793      * _.indexOf([1, 2, 1, 2], 2);
5794      * // => 1
5795      *
5796      * // using `fromIndex`
5797      * _.indexOf([1, 2, 1, 2], 2, 2);
5798      * // => 3
5799      */
5800     function indexOf(array, value, fromIndex) {
5801       var length = array ? array.length : 0;
5802       if (!length) {
5803         return -1;
5804       }
5805       fromIndex = toInteger(fromIndex);
5806       if (fromIndex < 0) {
5807         fromIndex = nativeMax(length + fromIndex, 0);
5808       }
5809       return baseIndexOf(array, value, fromIndex);
5810     }
5811
5812     /**
5813      * Gets all but the last element of `array`.
5814      *
5815      * @static
5816      * @memberOf _
5817      * @category Array
5818      * @param {Array} array The array to query.
5819      * @returns {Array} Returns the slice of `array`.
5820      * @example
5821      *
5822      * _.initial([1, 2, 3]);
5823      * // => [1, 2]
5824      */
5825     function initial(array) {
5826       return dropRight(array, 1);
5827     }
5828
5829     /**
5830      * Creates an array of unique values that are included in all of the provided
5831      * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5832      * for equality comparisons.
5833      *
5834      * @static
5835      * @memberOf _
5836      * @category Array
5837      * @param {...Array} [arrays] The arrays to inspect.
5838      * @returns {Array} Returns the new array of shared values.
5839      * @example
5840      * _.intersection([2, 1], [4, 2], [1, 2]);
5841      * // => [2]
5842      */
5843     var intersection = rest(function(arrays) {
5844       var mapped = arrayMap(arrays, toArrayLikeObject);
5845       return (mapped.length && mapped[0] === arrays[0])
5846         ? baseIntersection(mapped)
5847         : [];
5848     });
5849
5850     /**
5851      * This method is like `_.intersection` except that it accepts `iteratee`
5852      * which is invoked for each element of each `arrays` to generate the criterion
5853      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5854      *
5855      * @static
5856      * @memberOf _
5857      * @category Array
5858      * @param {...Array} [arrays] The arrays to inspect.
5859      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5860      * @returns {Array} Returns the new array of shared values.
5861      * @example
5862      *
5863      * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
5864      * // => [2.1]
5865      *
5866      * // using the `_.property` iteratee shorthand
5867      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
5868      * // => [{ 'x': 1 }]
5869      */
5870     var intersectionBy = rest(function(arrays) {
5871       var iteratee = last(arrays),
5872           mapped = arrayMap(arrays, toArrayLikeObject);
5873
5874       if (iteratee === last(mapped)) {
5875         iteratee = undefined;
5876       } else {
5877         mapped.pop();
5878       }
5879       return (mapped.length && mapped[0] === arrays[0])
5880         ? baseIntersection(mapped, getIteratee(iteratee))
5881         : [];
5882     });
5883
5884     /**
5885      * This method is like `_.intersection` except that it accepts `comparator`
5886      * which is invoked to compare elements of `arrays`. The comparator is invoked
5887      * with two arguments: (arrVal, othVal).
5888      *
5889      * @static
5890      * @memberOf _
5891      * @category Array
5892      * @param {...Array} [arrays] The arrays to inspect.
5893      * @param {Function} [comparator] The comparator invoked per element.
5894      * @returns {Array} Returns the new array of shared values.
5895      * @example
5896      *
5897      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5898      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
5899      *
5900      * _.intersectionWith(objects, others, _.isEqual);
5901      * // => [{ 'x': 1, 'y': 2 }]
5902      */
5903     var intersectionWith = rest(function(arrays) {
5904       var comparator = last(arrays),
5905           mapped = arrayMap(arrays, toArrayLikeObject);
5906
5907       if (comparator === last(mapped)) {
5908         comparator = undefined;
5909       } else {
5910         mapped.pop();
5911       }
5912       return (mapped.length && mapped[0] === arrays[0])
5913         ? baseIntersection(mapped, undefined, comparator)
5914         : [];
5915     });
5916
5917     /**
5918      * Converts all elements in `array` into a string separated by `separator`.
5919      *
5920      * @static
5921      * @memberOf _
5922      * @category Array
5923      * @param {Array} array The array to convert.
5924      * @param {string} [separator=','] The element separator.
5925      * @returns {string} Returns the joined string.
5926      * @example
5927      *
5928      * _.join(['a', 'b', 'c'], '~');
5929      * // => 'a~b~c'
5930      */
5931     function join(array, separator) {
5932       return array ? nativeJoin.call(array, separator) : '';
5933     }
5934
5935     /**
5936      * Gets the last element of `array`.
5937      *
5938      * @static
5939      * @memberOf _
5940      * @category Array
5941      * @param {Array} array The array to query.
5942      * @returns {*} Returns the last element of `array`.
5943      * @example
5944      *
5945      * _.last([1, 2, 3]);
5946      * // => 3
5947      */
5948     function last(array) {
5949       var length = array ? array.length : 0;
5950       return length ? array[length - 1] : undefined;
5951     }
5952
5953     /**
5954      * This method is like `_.indexOf` except that it iterates over elements of
5955      * `array` from right to left.
5956      *
5957      * @static
5958      * @memberOf _
5959      * @category Array
5960      * @param {Array} array The array to search.
5961      * @param {*} value The value to search for.
5962      * @param {number} [fromIndex=array.length-1] The index to search from.
5963      * @returns {number} Returns the index of the matched value, else `-1`.
5964      * @example
5965      *
5966      * _.lastIndexOf([1, 2, 1, 2], 2);
5967      * // => 3
5968      *
5969      * // using `fromIndex`
5970      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
5971      * // => 1
5972      */
5973     function lastIndexOf(array, value, fromIndex) {
5974       var length = array ? array.length : 0;
5975       if (!length) {
5976         return -1;
5977       }
5978       var index = length;
5979       if (fromIndex !== undefined) {
5980         index = toInteger(fromIndex);
5981         index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
5982       }
5983       if (value !== value) {
5984         return indexOfNaN(array, index, true);
5985       }
5986       while (index--) {
5987         if (array[index] === value) {
5988           return index;
5989         }
5990       }
5991       return -1;
5992     }
5993
5994     /**
5995      * Removes all provided values from `array` using
5996      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5997      * for equality comparisons.
5998      *
5999      * **Note:** Unlike `_.without`, this method mutates `array`.
6000      *
6001      * @static
6002      * @memberOf _
6003      * @category Array
6004      * @param {Array} array The array to modify.
6005      * @param {...*} [values] The values to remove.
6006      * @returns {Array} Returns `array`.
6007      * @example
6008      *
6009      * var array = [1, 2, 3, 1, 2, 3];
6010      *
6011      * _.pull(array, 2, 3);
6012      * console.log(array);
6013      * // => [1, 1]
6014      */
6015     var pull = rest(pullAll);
6016
6017     /**
6018      * This method is like `_.pull` except that it accepts an array of values to remove.
6019      *
6020      * **Note:** Unlike `_.difference`, this method mutates `array`.
6021      *
6022      * @static
6023      * @memberOf _
6024      * @category Array
6025      * @param {Array} array The array to modify.
6026      * @param {Array} values The values to remove.
6027      * @returns {Array} Returns `array`.
6028      * @example
6029      *
6030      * var array = [1, 2, 3, 1, 2, 3];
6031      *
6032      * _.pull(array, [2, 3]);
6033      * console.log(array);
6034      * // => [1, 1]
6035      */
6036     function pullAll(array, values) {
6037       return (array && array.length && values && values.length)
6038         ? basePullAll(array, values)
6039         : array;
6040     }
6041
6042     /**
6043      * This method is like `_.pullAll` except that it accepts `iteratee` which is
6044      * invoked for each element of `array` and `values` to to generate the criterion
6045      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
6046      *
6047      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
6048      *
6049      * @static
6050      * @memberOf _
6051      * @category Array
6052      * @param {Array} array The array to modify.
6053      * @param {Array} values The values to remove.
6054      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6055      * @returns {Array} Returns `array`.
6056      * @example
6057      *
6058      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
6059      *
6060      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
6061      * console.log(array);
6062      * // => [{ 'x': 2 }]
6063      */
6064     function pullAllBy(array, values, iteratee) {
6065       return (array && array.length && values && values.length)
6066         ? basePullAllBy(array, values, getIteratee(iteratee))
6067         : array;
6068     }
6069
6070     /**
6071      * Removes elements from `array` corresponding to `indexes` and returns an
6072      * array of removed elements.
6073      *
6074      * **Note:** Unlike `_.at`, this method mutates `array`.
6075      *
6076      * @static
6077      * @memberOf _
6078      * @category Array
6079      * @param {Array} array The array to modify.
6080      * @param {...(number|number[])} [indexes] The indexes of elements to remove,
6081      *  specified individually or in arrays.
6082      * @returns {Array} Returns the new array of removed elements.
6083      * @example
6084      *
6085      * var array = [5, 10, 15, 20];
6086      * var evens = _.pullAt(array, 1, 3);
6087      *
6088      * console.log(array);
6089      * // => [5, 15]
6090      *
6091      * console.log(evens);
6092      * // => [10, 20]
6093      */
6094     var pullAt = rest(function(array, indexes) {
6095       indexes = arrayMap(baseFlatten(indexes), String);
6096
6097       var result = baseAt(array, indexes);
6098       basePullAt(array, indexes.sort(compareAscending));
6099       return result;
6100     });
6101
6102     /**
6103      * Removes all elements from `array` that `predicate` returns truthy for
6104      * and returns an array of the removed elements. The predicate is invoked with
6105      * three arguments: (value, index, array).
6106      *
6107      * **Note:** Unlike `_.filter`, this method mutates `array`.
6108      *
6109      * @static
6110      * @memberOf _
6111      * @category Array
6112      * @param {Array} array The array to modify.
6113      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6114      * @returns {Array} Returns the new array of removed elements.
6115      * @example
6116      *
6117      * var array = [1, 2, 3, 4];
6118      * var evens = _.remove(array, function(n) {
6119      *   return n % 2 == 0;
6120      * });
6121      *
6122      * console.log(array);
6123      * // => [1, 3]
6124      *
6125      * console.log(evens);
6126      * // => [2, 4]
6127      */
6128     function remove(array, predicate) {
6129       var result = [];
6130       if (!(array && array.length)) {
6131         return result;
6132       }
6133       var index = -1,
6134           indexes = [],
6135           length = array.length;
6136
6137       predicate = getIteratee(predicate, 3);
6138       while (++index < length) {
6139         var value = array[index];
6140         if (predicate(value, index, array)) {
6141           result.push(value);
6142           indexes.push(index);
6143         }
6144       }
6145       basePullAt(array, indexes);
6146       return result;
6147     }
6148
6149     /**
6150      * Reverses `array` so that the first element becomes the last, the second
6151      * element becomes the second to last, and so on.
6152      *
6153      * **Note:** This method mutates `array` and is based on
6154      * [`Array#reverse`](https://mdn.io/Array/reverse).
6155      *
6156      * @memberOf _
6157      * @category Array
6158      * @returns {Array} Returns `array`.
6159      * @example
6160      *
6161      * var array = [1, 2, 3];
6162      *
6163      * _.reverse(array);
6164      * // => [3, 2, 1]
6165      *
6166      * console.log(array);
6167      * // => [3, 2, 1]
6168      */
6169     function reverse(array) {
6170       return array ? nativeReverse.call(array) : array;
6171     }
6172
6173     /**
6174      * Creates a slice of `array` from `start` up to, but not including, `end`.
6175      *
6176      * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
6177      * to ensure dense arrays are returned.
6178      *
6179      * @static
6180      * @memberOf _
6181      * @category Array
6182      * @param {Array} array The array to slice.
6183      * @param {number} [start=0] The start position.
6184      * @param {number} [end=array.length] The end position.
6185      * @returns {Array} Returns the slice of `array`.
6186      */
6187     function slice(array, start, end) {
6188       var length = array ? array.length : 0;
6189       if (!length) {
6190         return [];
6191       }
6192       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
6193         start = 0;
6194         end = length;
6195       }
6196       else {
6197         start = start == null ? 0 : toInteger(start);
6198         end = end === undefined ? length : toInteger(end);
6199       }
6200       return baseSlice(array, start, end);
6201     }
6202
6203     /**
6204      * Uses a binary search to determine the lowest index at which `value` should
6205      * be inserted into `array` in order to maintain its sort order.
6206      *
6207      * @static
6208      * @memberOf _
6209      * @category Array
6210      * @param {Array} array The sorted array to inspect.
6211      * @param {*} value The value to evaluate.
6212      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6213      * @example
6214      *
6215      * _.sortedIndex([30, 50], 40);
6216      * // => 1
6217      *
6218      * _.sortedIndex([4, 5], 4);
6219      * // => 0
6220      */
6221     function sortedIndex(array, value) {
6222       return baseSortedIndex(array, value);
6223     }
6224
6225     /**
6226      * This method is like `_.sortedIndex` except that it accepts `iteratee`
6227      * which is invoked for `value` and each element of `array` to compute their
6228      * sort ranking. The iteratee is invoked with one argument: (value).
6229      *
6230      * @static
6231      * @memberOf _
6232      * @category Array
6233      * @param {Array} array The sorted array to inspect.
6234      * @param {*} value The value to evaluate.
6235      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6236      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6237      * @example
6238      *
6239      * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
6240      *
6241      * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
6242      * // => 1
6243      *
6244      * // using the `_.property` iteratee shorthand
6245      * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6246      * // => 0
6247      */
6248     function sortedIndexBy(array, value, iteratee) {
6249       return baseSortedIndexBy(array, value, getIteratee(iteratee));
6250     }
6251
6252     /**
6253      * This method is like `_.indexOf` except that it performs a binary
6254      * search on a sorted `array`.
6255      *
6256      * @static
6257      * @memberOf _
6258      * @category Array
6259      * @param {Array} array The array to search.
6260      * @param {*} value The value to search for.
6261      * @returns {number} Returns the index of the matched value, else `-1`.
6262      * @example
6263      *
6264      * _.sortedIndexOf([1, 1, 2, 2], 2);
6265      * // => 2
6266      */
6267     function sortedIndexOf(array, value) {
6268       var length = array ? array.length : 0;
6269       if (length) {
6270         var index = baseSortedIndex(array, value);
6271         if (index < length && eq(array[index], value)) {
6272           return index;
6273         }
6274       }
6275       return -1;
6276     }
6277
6278     /**
6279      * This method is like `_.sortedIndex` except that it returns the highest
6280      * index at which `value` should be inserted into `array` in order to
6281      * maintain its sort order.
6282      *
6283      * @static
6284      * @memberOf _
6285      * @category Array
6286      * @param {Array} array The sorted array to inspect.
6287      * @param {*} value The value to evaluate.
6288      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6289      * @example
6290      *
6291      * _.sortedLastIndex([4, 5], 4);
6292      * // => 1
6293      */
6294     function sortedLastIndex(array, value) {
6295       return baseSortedIndex(array, value, true);
6296     }
6297
6298     /**
6299      * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
6300      * which is invoked for `value` and each element of `array` to compute their
6301      * sort ranking. The iteratee is invoked with one argument: (value).
6302      *
6303      * @static
6304      * @memberOf _
6305      * @category Array
6306      * @param {Array} array The sorted array to inspect.
6307      * @param {*} value The value to evaluate.
6308      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6309      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6310      * @example
6311      *
6312      * // using the `_.property` iteratee shorthand
6313      * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6314      * // => 1
6315      */
6316     function sortedLastIndexBy(array, value, iteratee) {
6317       return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
6318     }
6319
6320     /**
6321      * This method is like `_.lastIndexOf` except that it performs a binary
6322      * search on a sorted `array`.
6323      *
6324      * @static
6325      * @memberOf _
6326      * @category Array
6327      * @param {Array} array The array to search.
6328      * @param {*} value The value to search for.
6329      * @returns {number} Returns the index of the matched value, else `-1`.
6330      * @example
6331      *
6332      * _.sortedLastIndexOf([1, 1, 2, 2], 2);
6333      * // => 3
6334      */
6335     function sortedLastIndexOf(array, value) {
6336       var length = array ? array.length : 0;
6337       if (length) {
6338         var index = baseSortedIndex(array, value, true) - 1;
6339         if (eq(array[index], value)) {
6340           return index;
6341         }
6342       }
6343       return -1;
6344     }
6345
6346     /**
6347      * This method is like `_.uniq` except that it's designed and optimized
6348      * for sorted arrays.
6349      *
6350      * @static
6351      * @memberOf _
6352      * @category Array
6353      * @param {Array} array The array to inspect.
6354      * @returns {Array} Returns the new duplicate free array.
6355      * @example
6356      *
6357      * _.sortedUniq([1, 1, 2]);
6358      * // => [1, 2]
6359      */
6360     function sortedUniq(array) {
6361       return (array && array.length)
6362         ? baseSortedUniq(array)
6363         : [];
6364     }
6365
6366     /**
6367      * This method is like `_.uniqBy` except that it's designed and optimized
6368      * for sorted arrays.
6369      *
6370      * @static
6371      * @memberOf _
6372      * @category Array
6373      * @param {Array} array The array to inspect.
6374      * @param {Function} [iteratee] The iteratee invoked per element.
6375      * @returns {Array} Returns the new duplicate free array.
6376      * @example
6377      *
6378      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
6379      * // => [1.1, 2.2]
6380      */
6381     function sortedUniqBy(array, iteratee) {
6382       return (array && array.length)
6383         ? baseSortedUniqBy(array, getIteratee(iteratee))
6384         : [];
6385     }
6386
6387     /**
6388      * Gets all but the first element of `array`.
6389      *
6390      * @static
6391      * @memberOf _
6392      * @category Array
6393      * @param {Array} array The array to query.
6394      * @returns {Array} Returns the slice of `array`.
6395      * @example
6396      *
6397      * _.tail([1, 2, 3]);
6398      * // => [2, 3]
6399      */
6400     function tail(array) {
6401       return drop(array, 1);
6402     }
6403
6404     /**
6405      * Creates a slice of `array` with `n` elements taken from the beginning.
6406      *
6407      * @static
6408      * @memberOf _
6409      * @category Array
6410      * @param {Array} array The array to query.
6411      * @param {number} [n=1] The number of elements to take.
6412      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6413      * @returns {Array} Returns the slice of `array`.
6414      * @example
6415      *
6416      * _.take([1, 2, 3]);
6417      * // => [1]
6418      *
6419      * _.take([1, 2, 3], 2);
6420      * // => [1, 2]
6421      *
6422      * _.take([1, 2, 3], 5);
6423      * // => [1, 2, 3]
6424      *
6425      * _.take([1, 2, 3], 0);
6426      * // => []
6427      */
6428     function take(array, n, guard) {
6429       if (!(array && array.length)) {
6430         return [];
6431       }
6432       n = (guard || n === undefined) ? 1 : toInteger(n);
6433       return baseSlice(array, 0, n < 0 ? 0 : n);
6434     }
6435
6436     /**
6437      * Creates a slice of `array` with `n` elements taken from the end.
6438      *
6439      * @static
6440      * @memberOf _
6441      * @category Array
6442      * @param {Array} array The array to query.
6443      * @param {number} [n=1] The number of elements to take.
6444      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6445      * @returns {Array} Returns the slice of `array`.
6446      * @example
6447      *
6448      * _.takeRight([1, 2, 3]);
6449      * // => [3]
6450      *
6451      * _.takeRight([1, 2, 3], 2);
6452      * // => [2, 3]
6453      *
6454      * _.takeRight([1, 2, 3], 5);
6455      * // => [1, 2, 3]
6456      *
6457      * _.takeRight([1, 2, 3], 0);
6458      * // => []
6459      */
6460     function takeRight(array, n, guard) {
6461       var length = array ? array.length : 0;
6462       if (!length) {
6463         return [];
6464       }
6465       n = (guard || n === undefined) ? 1 : toInteger(n);
6466       n = length - n;
6467       return baseSlice(array, n < 0 ? 0 : n, length);
6468     }
6469
6470     /**
6471      * Creates a slice of `array` with elements taken from the end. Elements are
6472      * taken until `predicate` returns falsey. The predicate is invoked with three
6473      * arguments: (value, index, array).
6474      *
6475      * @static
6476      * @memberOf _
6477      * @category Array
6478      * @param {Array} array The array to query.
6479      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6480      * @returns {Array} Returns the slice of `array`.
6481      * @example
6482      *
6483      * var users = [
6484      *   { 'user': 'barney',  'active': true },
6485      *   { 'user': 'fred',    'active': false },
6486      *   { 'user': 'pebbles', 'active': false }
6487      * ];
6488      *
6489      * _.takeRightWhile(users, function(o) { return !o.active; });
6490      * // => objects for ['fred', 'pebbles']
6491      *
6492      * // using the `_.matches` iteratee shorthand
6493      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
6494      * // => objects for ['pebbles']
6495      *
6496      * // using the `_.matchesProperty` iteratee shorthand
6497      * _.takeRightWhile(users, ['active', false]);
6498      * // => objects for ['fred', 'pebbles']
6499      *
6500      * // using the `_.property` iteratee shorthand
6501      * _.takeRightWhile(users, 'active');
6502      * // => []
6503      */
6504     function takeRightWhile(array, predicate) {
6505       return (array && array.length)
6506         ? baseWhile(array, getIteratee(predicate, 3), false, true)
6507         : [];
6508     }
6509
6510     /**
6511      * Creates a slice of `array` with elements taken from the beginning. Elements
6512      * are taken until `predicate` returns falsey. The predicate is invoked with
6513      * three arguments: (value, index, array).
6514      *
6515      * @static
6516      * @memberOf _
6517      * @category Array
6518      * @param {Array} array The array to query.
6519      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6520      * @returns {Array} Returns the slice of `array`.
6521      * @example
6522      *
6523      * var users = [
6524      *   { 'user': 'barney',  'active': false },
6525      *   { 'user': 'fred',    'active': false},
6526      *   { 'user': 'pebbles', 'active': true }
6527      * ];
6528      *
6529      * _.takeWhile(users, function(o) { return !o.active; });
6530      * // => objects for ['barney', 'fred']
6531      *
6532      * // using the `_.matches` iteratee shorthand
6533      * _.takeWhile(users, { 'user': 'barney', 'active': false });
6534      * // => objects for ['barney']
6535      *
6536      * // using the `_.matchesProperty` iteratee shorthand
6537      * _.takeWhile(users, ['active', false]);
6538      * // => objects for ['barney', 'fred']
6539      *
6540      * // using the `_.property` iteratee shorthand
6541      * _.takeWhile(users, 'active');
6542      * // => []
6543      */
6544     function takeWhile(array, predicate) {
6545       return (array && array.length)
6546         ? baseWhile(array, getIteratee(predicate, 3))
6547         : [];
6548     }
6549
6550     /**
6551      * Creates an array of unique values, in order, from all of the provided arrays
6552      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6553      * for equality comparisons.
6554      *
6555      * @static
6556      * @memberOf _
6557      * @category Array
6558      * @param {...Array} [arrays] The arrays to inspect.
6559      * @returns {Array} Returns the new array of combined values.
6560      * @example
6561      *
6562      * _.union([2, 1], [4, 2], [1, 2]);
6563      * // => [2, 1, 4]
6564      */
6565     var union = rest(function(arrays) {
6566       return baseUniq(baseFlatten(arrays, false, true));
6567     });
6568
6569     /**
6570      * This method is like `_.union` except that it accepts `iteratee` which is
6571      * invoked for each element of each `arrays` to generate the criterion by which
6572      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6573      *
6574      * @static
6575      * @memberOf _
6576      * @category Array
6577      * @param {...Array} [arrays] The arrays to inspect.
6578      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6579      * @returns {Array} Returns the new array of combined values.
6580      * @example
6581      *
6582      * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6583      * // => [2.1, 1.2, 4.3]
6584      *
6585      * // using the `_.property` iteratee shorthand
6586      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6587      * // => [{ 'x': 1 }, { 'x': 2 }]
6588      */
6589     var unionBy = rest(function(arrays) {
6590       var iteratee = last(arrays);
6591       if (isArrayLikeObject(iteratee)) {
6592         iteratee = undefined;
6593       }
6594       return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee));
6595     });
6596
6597     /**
6598      * This method is like `_.union` except that it accepts `comparator` which
6599      * is invoked to compare elements of `arrays`. The comparator is invoked
6600      * with two arguments: (arrVal, othVal).
6601      *
6602      * @static
6603      * @memberOf _
6604      * @category Array
6605      * @param {...Array} [arrays] The arrays to inspect.
6606      * @param {Function} [comparator] The comparator invoked per element.
6607      * @returns {Array} Returns the new array of combined values.
6608      * @example
6609      *
6610      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6611      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6612      *
6613      * _.unionWith(objects, others, _.isEqual);
6614      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6615      */
6616     var unionWith = rest(function(arrays) {
6617       var comparator = last(arrays);
6618       if (isArrayLikeObject(comparator)) {
6619         comparator = undefined;
6620       }
6621       return baseUniq(baseFlatten(arrays, false, true), undefined, comparator);
6622     });
6623
6624     /**
6625      * Creates a duplicate-free version of an array, using
6626      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6627      * for equality comparisons, in which only the first occurrence of each element
6628      * is kept.
6629      *
6630      * @static
6631      * @memberOf _
6632      * @category Array
6633      * @param {Array} array The array to inspect.
6634      * @returns {Array} Returns the new duplicate free array.
6635      * @example
6636      *
6637      * _.uniq([2, 1, 2]);
6638      * // => [2, 1]
6639      */
6640     function uniq(array) {
6641       return (array && array.length)
6642         ? baseUniq(array)
6643         : [];
6644     }
6645
6646     /**
6647      * This method is like `_.uniq` except that it accepts `iteratee` which is
6648      * invoked for each element in `array` to generate the criterion by which
6649      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6650      *
6651      * @static
6652      * @memberOf _
6653      * @category Array
6654      * @param {Array} array The array to inspect.
6655      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6656      * @returns {Array} Returns the new duplicate free array.
6657      * @example
6658      *
6659      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
6660      * // => [2.1, 1.2]
6661      *
6662      * // using the `_.property` iteratee shorthand
6663      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
6664      * // => [{ 'x': 1 }, { 'x': 2 }]
6665      */
6666     function uniqBy(array, iteratee) {
6667       return (array && array.length)
6668         ? baseUniq(array, getIteratee(iteratee))
6669         : [];
6670     }
6671
6672     /**
6673      * This method is like `_.uniq` except that it accepts `comparator` which
6674      * is invoked to compare elements of `array`. The comparator is invoked with
6675      * two arguments: (arrVal, othVal).
6676      *
6677      * @static
6678      * @memberOf _
6679      * @category Array
6680      * @param {Array} array The array to inspect.
6681      * @param {Function} [comparator] The comparator invoked per element.
6682      * @returns {Array} Returns the new duplicate free array.
6683      * @example
6684      *
6685      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
6686      *
6687      * _.uniqWith(objects, _.isEqual);
6688      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
6689      */
6690     function uniqWith(array, comparator) {
6691       return (array && array.length)
6692         ? baseUniq(array, undefined, comparator)
6693         : [];
6694     }
6695
6696     /**
6697      * This method is like `_.zip` except that it accepts an array of grouped
6698      * elements and creates an array regrouping the elements to their pre-zip
6699      * configuration.
6700      *
6701      * @static
6702      * @memberOf _
6703      * @category Array
6704      * @param {Array} array The array of grouped elements to process.
6705      * @returns {Array} Returns the new array of regrouped elements.
6706      * @example
6707      *
6708      * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
6709      * // => [['fred', 30, true], ['barney', 40, false]]
6710      *
6711      * _.unzip(zipped);
6712      * // => [['fred', 'barney'], [30, 40], [true, false]]
6713      */
6714     function unzip(array) {
6715       if (!(array && array.length)) {
6716         return [];
6717       }
6718       var length = 0;
6719       array = arrayFilter(array, function(group) {
6720         if (isArrayLikeObject(group)) {
6721           length = nativeMax(group.length, length);
6722           return true;
6723         }
6724       });
6725       return baseTimes(length, function(index) {
6726         return arrayMap(array, baseProperty(index));
6727       });
6728     }
6729
6730     /**
6731      * This method is like `_.unzip` except that it accepts `iteratee` to specify
6732      * how regrouped values should be combined. The iteratee is invoked with the
6733      * elements of each group: (...group).
6734      *
6735      * @static
6736      * @memberOf _
6737      * @category Array
6738      * @param {Array} array The array of grouped elements to process.
6739      * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
6740      * @returns {Array} Returns the new array of regrouped elements.
6741      * @example
6742      *
6743      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
6744      * // => [[1, 10, 100], [2, 20, 200]]
6745      *
6746      * _.unzipWith(zipped, _.add);
6747      * // => [3, 30, 300]
6748      */
6749     function unzipWith(array, iteratee) {
6750       if (!(array && array.length)) {
6751         return [];
6752       }
6753       var result = unzip(array);
6754       if (iteratee == null) {
6755         return result;
6756       }
6757       return arrayMap(result, function(group) {
6758         return apply(iteratee, undefined, group);
6759       });
6760     }
6761
6762     /**
6763      * Creates an array excluding all provided values using
6764      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6765      * for equality comparisons.
6766      *
6767      * @static
6768      * @memberOf _
6769      * @category Array
6770      * @param {Array} array The array to filter.
6771      * @param {...*} [values] The values to exclude.
6772      * @returns {Array} Returns the new array of filtered values.
6773      * @example
6774      *
6775      * _.without([1, 2, 1, 3], 1, 2);
6776      * // => [3]
6777      */
6778     var without = rest(function(array, values) {
6779       return isArrayLikeObject(array)
6780         ? baseDifference(array, values)
6781         : [];
6782     });
6783
6784     /**
6785      * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
6786      * of the provided arrays.
6787      *
6788      * @static
6789      * @memberOf _
6790      * @category Array
6791      * @param {...Array} [arrays] The arrays to inspect.
6792      * @returns {Array} Returns the new array of values.
6793      * @example
6794      *
6795      * _.xor([2, 1], [4, 2]);
6796      * // => [1, 4]
6797      */
6798     var xor = rest(function(arrays) {
6799       return baseXor(arrayFilter(arrays, isArrayLikeObject));
6800     });
6801
6802     /**
6803      * This method is like `_.xor` except that it accepts `iteratee` which is
6804      * invoked for each element of each `arrays` to generate the criterion by which
6805      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6806      *
6807      * @static
6808      * @memberOf _
6809      * @category Array
6810      * @param {...Array} [arrays] The arrays to inspect.
6811      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6812      * @returns {Array} Returns the new array of values.
6813      * @example
6814      *
6815      * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6816      * // => [1.2, 4.3]
6817      *
6818      * // using the `_.property` iteratee shorthand
6819      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6820      * // => [{ 'x': 2 }]
6821      */
6822     var xorBy = rest(function(arrays) {
6823       var iteratee = last(arrays);
6824       if (isArrayLikeObject(iteratee)) {
6825         iteratee = undefined;
6826       }
6827       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
6828     });
6829
6830     /**
6831      * This method is like `_.xor` except that it accepts `comparator` which is
6832      * invoked to compare elements of `arrays`. The comparator is invoked with
6833      * two arguments: (arrVal, othVal).
6834      *
6835      * @static
6836      * @memberOf _
6837      * @category Array
6838      * @param {...Array} [arrays] The arrays to inspect.
6839      * @param {Function} [comparator] The comparator invoked per element.
6840      * @returns {Array} Returns the new array of values.
6841      * @example
6842      *
6843      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6844      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6845      *
6846      * _.xorWith(objects, others, _.isEqual);
6847      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6848      */
6849     var xorWith = rest(function(arrays) {
6850       var comparator = last(arrays);
6851       if (isArrayLikeObject(comparator)) {
6852         comparator = undefined;
6853       }
6854       return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
6855     });
6856
6857     /**
6858      * Creates an array of grouped elements, the first of which contains the first
6859      * elements of the given arrays, the second of which contains the second elements
6860      * of the given arrays, and so on.
6861      *
6862      * @static
6863      * @memberOf _
6864      * @category Array
6865      * @param {...Array} [arrays] The arrays to process.
6866      * @returns {Array} Returns the new array of grouped elements.
6867      * @example
6868      *
6869      * _.zip(['fred', 'barney'], [30, 40], [true, false]);
6870      * // => [['fred', 30, true], ['barney', 40, false]]
6871      */
6872     var zip = rest(unzip);
6873
6874     /**
6875      * This method is like `_.fromPairs` except that it accepts two arrays,
6876      * one of property names and one of corresponding values.
6877      *
6878      * @static
6879      * @memberOf _
6880      * @category Array
6881      * @param {Array} [props=[]] The property names.
6882      * @param {Array} [values=[]] The property values.
6883      * @returns {Object} Returns the new object.
6884      * @example
6885      *
6886      * _.zipObject(['fred', 'barney'], [30, 40]);
6887      * // => { 'fred': 30, 'barney': 40 }
6888      */
6889     function zipObject(props, values) {
6890       var index = -1,
6891           length = props ? props.length : 0,
6892           valsLength = values ? values.length : 0,
6893           result = {};
6894
6895       while (++index < length) {
6896         baseSet(result, props[index], index < valsLength ? values[index] : undefined);
6897       }
6898       return result;
6899     }
6900
6901     /**
6902      * This method is like `_.zip` except that it accepts `iteratee` to specify
6903      * how grouped values should be combined. The iteratee is invoked with the
6904      * elements of each group: (...group).
6905      *
6906      * @static
6907      * @memberOf _
6908      * @category Array
6909      * @param {...Array} [arrays] The arrays to process.
6910      * @param {Function} [iteratee=_.identity] The function to combine grouped values.
6911      * @returns {Array} Returns the new array of grouped elements.
6912      * @example
6913      *
6914      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
6915      *   return a + b + c;
6916      * });
6917      * // => [111, 222]
6918      */
6919     var zipWith = rest(function(arrays) {
6920       var length = arrays.length,
6921           iteratee = length > 1 ? arrays[length - 1] : undefined;
6922
6923       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
6924       return unzipWith(arrays, iteratee);
6925     });
6926
6927     /*------------------------------------------------------------------------*/
6928
6929     /**
6930      * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
6931      * The result of such method chaining must be unwrapped with `_#value`.
6932      *
6933      * @static
6934      * @memberOf _
6935      * @category Seq
6936      * @param {*} value The value to wrap.
6937      * @returns {Object} Returns the new `lodash` wrapper instance.
6938      * @example
6939      *
6940      * var users = [
6941      *   { 'user': 'barney',  'age': 36 },
6942      *   { 'user': 'fred',    'age': 40 },
6943      *   { 'user': 'pebbles', 'age': 1 }
6944      * ];
6945      *
6946      * var youngest = _
6947      *   .chain(users)
6948      *   .sortBy('age')
6949      *   .map(function(o) {
6950      *     return o.user + ' is ' + o.age;
6951      *   })
6952      *   .head()
6953      *   .value();
6954      * // => 'pebbles is 1'
6955      */
6956     function chain(value) {
6957       var result = lodash(value);
6958       result.__chain__ = true;
6959       return result;
6960     }
6961
6962     /**
6963      * This method invokes `interceptor` and returns `value`. The interceptor is
6964      * invoked with one argument; (value). The purpose of this method is to "tap into"
6965      * a method chain in order to perform operations on intermediate results within
6966      * the chain.
6967      *
6968      * @static
6969      * @memberOf _
6970      * @category Seq
6971      * @param {*} value The value to provide to `interceptor`.
6972      * @param {Function} interceptor The function to invoke.
6973      * @returns {*} Returns `value`.
6974      * @example
6975      *
6976      * _([1, 2, 3])
6977      *  .tap(function(array) {
6978      *    array.pop();
6979      *  })
6980      *  .reverse()
6981      *  .value();
6982      * // => [2, 1]
6983      */
6984     function tap(value, interceptor) {
6985       interceptor(value);
6986       return value;
6987     }
6988
6989     /**
6990      * This method is like `_.tap` except that it returns the result of `interceptor`.
6991      *
6992      * @static
6993      * @memberOf _
6994      * @category Seq
6995      * @param {*} value The value to provide to `interceptor`.
6996      * @param {Function} interceptor The function to invoke.
6997      * @returns {*} Returns the result of `interceptor`.
6998      * @example
6999      *
7000      * _('  abc  ')
7001      *  .chain()
7002      *  .trim()
7003      *  .thru(function(value) {
7004      *    return [value];
7005      *  })
7006      *  .value();
7007      * // => ['abc']
7008      */
7009     function thru(value, interceptor) {
7010       return interceptor(value);
7011     }
7012
7013     /**
7014      * This method is the wrapper version of `_.at`.
7015      *
7016      * @name at
7017      * @memberOf _
7018      * @category Seq
7019      * @param {...(string|string[])} [paths] The property paths of elements to pick,
7020      *  specified individually or in arrays.
7021      * @returns {Object} Returns the new `lodash` wrapper instance.
7022      * @example
7023      *
7024      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
7025      *
7026      * _(object).at(['a[0].b.c', 'a[1]']).value();
7027      * // => [3, 4]
7028      *
7029      * _(['a', 'b', 'c']).at(0, 2).value();
7030      * // => ['a', 'c']
7031      */
7032     var wrapperAt = rest(function(paths) {
7033       paths = baseFlatten(paths);
7034       var length = paths.length,
7035           start = length ? paths[0] : 0,
7036           value = this.__wrapped__,
7037           interceptor = function(object) { return baseAt(object, paths); };
7038
7039       if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) {
7040         return this.thru(interceptor);
7041       }
7042       value = value.slice(start, +start + (length ? 1 : 0));
7043       value.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
7044       return new LodashWrapper(value, this.__chain__).thru(function(array) {
7045         if (length && !array.length) {
7046           array.push(undefined);
7047         }
7048         return array;
7049       });
7050     });
7051
7052     /**
7053      * Enables explicit method chaining on the wrapper object.
7054      *
7055      * @name chain
7056      * @memberOf _
7057      * @category Seq
7058      * @returns {Object} Returns the new `lodash` wrapper instance.
7059      * @example
7060      *
7061      * var users = [
7062      *   { 'user': 'barney', 'age': 36 },
7063      *   { 'user': 'fred',   'age': 40 }
7064      * ];
7065      *
7066      * // without explicit chaining
7067      * _(users).head();
7068      * // => { 'user': 'barney', 'age': 36 }
7069      *
7070      * // with explicit chaining
7071      * _(users)
7072      *   .chain()
7073      *   .head()
7074      *   .pick('user')
7075      *   .value();
7076      * // => { 'user': 'barney' }
7077      */
7078     function wrapperChain() {
7079       return chain(this);
7080     }
7081
7082     /**
7083      * Executes the chained sequence and returns the wrapped result.
7084      *
7085      * @name commit
7086      * @memberOf _
7087      * @category Seq
7088      * @returns {Object} Returns the new `lodash` wrapper instance.
7089      * @example
7090      *
7091      * var array = [1, 2];
7092      * var wrapped = _(array).push(3);
7093      *
7094      * console.log(array);
7095      * // => [1, 2]
7096      *
7097      * wrapped = wrapped.commit();
7098      * console.log(array);
7099      * // => [1, 2, 3]
7100      *
7101      * wrapped.last();
7102      * // => 3
7103      *
7104      * console.log(array);
7105      * // => [1, 2, 3]
7106      */
7107     function wrapperCommit() {
7108       return new LodashWrapper(this.value(), this.__chain__);
7109     }
7110
7111     /**
7112      * This method is the wrapper version of `_.flatMap`.
7113      *
7114      * @static
7115      * @memberOf _
7116      * @category Seq
7117      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7118      * @returns {Object} Returns the new `lodash` wrapper instance.
7119      * @example
7120      *
7121      * function duplicate(n) {
7122      *   return [n, n];
7123      * }
7124      *
7125      * _([1, 2]).flatMap(duplicate).value();
7126      * // => [1, 1, 2, 2]
7127      */
7128     function wrapperFlatMap(iteratee) {
7129       return this.map(iteratee).flatten();
7130     }
7131
7132     /**
7133      * Gets the next value on a wrapped object following the
7134      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
7135      *
7136      * @name next
7137      * @memberOf _
7138      * @category Seq
7139      * @returns {Object} Returns the next iterator value.
7140      * @example
7141      *
7142      * var wrapped = _([1, 2]);
7143      *
7144      * wrapped.next();
7145      * // => { 'done': false, 'value': 1 }
7146      *
7147      * wrapped.next();
7148      * // => { 'done': false, 'value': 2 }
7149      *
7150      * wrapped.next();
7151      * // => { 'done': true, 'value': undefined }
7152      */
7153     function wrapperNext() {
7154       if (this.__values__ === undefined) {
7155         this.__values__ = toArray(this.value());
7156       }
7157       var done = this.__index__ >= this.__values__.length,
7158           value = done ? undefined : this.__values__[this.__index__++];
7159
7160       return { 'done': done, 'value': value };
7161     }
7162
7163     /**
7164      * Enables the wrapper to be iterable.
7165      *
7166      * @name Symbol.iterator
7167      * @memberOf _
7168      * @category Seq
7169      * @returns {Object} Returns the wrapper object.
7170      * @example
7171      *
7172      * var wrapped = _([1, 2]);
7173      *
7174      * wrapped[Symbol.iterator]() === wrapped;
7175      * // => true
7176      *
7177      * Array.from(wrapped);
7178      * // => [1, 2]
7179      */
7180     function wrapperToIterator() {
7181       return this;
7182     }
7183
7184     /**
7185      * Creates a clone of the chained sequence planting `value` as the wrapped value.
7186      *
7187      * @name plant
7188      * @memberOf _
7189      * @category Seq
7190      * @param {*} value The value to plant.
7191      * @returns {Object} Returns the new `lodash` wrapper instance.
7192      * @example
7193      *
7194      * function square(n) {
7195      *   return n * n;
7196      * }
7197      *
7198      * var wrapped = _([1, 2]).map(square);
7199      * var other = wrapped.plant([3, 4]);
7200      *
7201      * other.value();
7202      * // => [9, 16]
7203      *
7204      * wrapped.value();
7205      * // => [1, 4]
7206      */
7207     function wrapperPlant(value) {
7208       var result,
7209           parent = this;
7210
7211       while (parent instanceof baseLodash) {
7212         var clone = wrapperClone(parent);
7213         clone.__index__ = 0;
7214         clone.__values__ = undefined;
7215         if (result) {
7216           previous.__wrapped__ = clone;
7217         } else {
7218           result = clone;
7219         }
7220         var previous = clone;
7221         parent = parent.__wrapped__;
7222       }
7223       previous.__wrapped__ = value;
7224       return result;
7225     }
7226
7227     /**
7228      * This method is the wrapper version of `_.reverse`.
7229      *
7230      * **Note:** This method mutates the wrapped array.
7231      *
7232      * @name reverse
7233      * @memberOf _
7234      * @category Seq
7235      * @returns {Object} Returns the new `lodash` wrapper instance.
7236      * @example
7237      *
7238      * var array = [1, 2, 3];
7239      *
7240      * _(array).reverse().value()
7241      * // => [3, 2, 1]
7242      *
7243      * console.log(array);
7244      * // => [3, 2, 1]
7245      */
7246     function wrapperReverse() {
7247       var value = this.__wrapped__;
7248       if (value instanceof LazyWrapper) {
7249         var wrapped = value;
7250         if (this.__actions__.length) {
7251           wrapped = new LazyWrapper(this);
7252         }
7253         wrapped = wrapped.reverse();
7254         wrapped.__actions__.push({ 'func': thru, 'args': [reverse], 'thisArg': undefined });
7255         return new LodashWrapper(wrapped, this.__chain__);
7256       }
7257       return this.thru(reverse);
7258     }
7259
7260     /**
7261      * Executes the chained sequence to extract the unwrapped value.
7262      *
7263      * @name value
7264      * @memberOf _
7265      * @alias run, toJSON, valueOf
7266      * @category Seq
7267      * @returns {*} Returns the resolved unwrapped value.
7268      * @example
7269      *
7270      * _([1, 2, 3]).value();
7271      * // => [1, 2, 3]
7272      */
7273     function wrapperValue() {
7274       return baseWrapperValue(this.__wrapped__, this.__actions__);
7275     }
7276
7277     /*------------------------------------------------------------------------*/
7278
7279     /**
7280      * Creates an object composed of keys generated from the results of running
7281      * each element of `collection` through `iteratee`. The corresponding value
7282      * of each key is the number of times the key was returned by `iteratee`.
7283      * The iteratee is invoked with one argument: (value).
7284      *
7285      * @static
7286      * @memberOf _
7287      * @category Collection
7288      * @param {Array|Object} collection The collection to iterate over.
7289      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
7290      * @returns {Object} Returns the composed aggregate object.
7291      * @example
7292      *
7293      * _.countBy([6.1, 4.2, 6.3], Math.floor);
7294      * // => { '4': 1, '6': 2 }
7295      *
7296      * _.countBy(['one', 'two', 'three'], 'length');
7297      * // => { '3': 2, '5': 1 }
7298      */
7299     var countBy = createAggregator(function(result, value, key) {
7300       hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
7301     });
7302
7303     /**
7304      * Checks if `predicate` returns truthy for **all** elements of `collection`.
7305      * Iteration is stopped once `predicate` returns falsey. The predicate is
7306      * invoked with three arguments: (value, index|key, collection).
7307      *
7308      * @static
7309      * @memberOf _
7310      * @category Collection
7311      * @param {Array|Object} collection The collection to iterate over.
7312      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7313      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
7314      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
7315      * @example
7316      *
7317      * _.every([true, 1, null, 'yes'], Boolean);
7318      * // => false
7319      *
7320      * var users = [
7321      *   { 'user': 'barney', 'active': false },
7322      *   { 'user': 'fred',   'active': false }
7323      * ];
7324      *
7325      * // using the `_.matches` iteratee shorthand
7326      * _.every(users, { 'user': 'barney', 'active': false });
7327      * // => false
7328      *
7329      * // using the `_.matchesProperty` iteratee shorthand
7330      * _.every(users, ['active', false]);
7331      * // => true
7332      *
7333      * // using the `_.property` iteratee shorthand
7334      * _.every(users, 'active');
7335      * // => false
7336      */
7337     function every(collection, predicate, guard) {
7338       var func = isArray(collection) ? arrayEvery : baseEvery;
7339       if (guard && isIterateeCall(collection, predicate, guard)) {
7340         predicate = undefined;
7341       }
7342       return func(collection, getIteratee(predicate, 3));
7343     }
7344
7345     /**
7346      * Iterates over elements of `collection`, returning an array of all elements
7347      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7348      * (value, index|key, collection).
7349      *
7350      * @static
7351      * @memberOf _
7352      * @category Collection
7353      * @param {Array|Object} collection The collection to iterate over.
7354      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7355      * @returns {Array} Returns the new filtered array.
7356      * @example
7357      *
7358      * var users = [
7359      *   { 'user': 'barney', 'age': 36, 'active': true },
7360      *   { 'user': 'fred',   'age': 40, 'active': false }
7361      * ];
7362      *
7363      * _.filter(users, function(o) { return !o.active; });
7364      * // => objects for ['fred']
7365      *
7366      * // using the `_.matches` iteratee shorthand
7367      * _.filter(users, { 'age': 36, 'active': true });
7368      * // => objects for ['barney']
7369      *
7370      * // using the `_.matchesProperty` iteratee shorthand
7371      * _.filter(users, ['active', false]);
7372      * // => objects for ['fred']
7373      *
7374      * // using the `_.property` iteratee shorthand
7375      * _.filter(users, 'active');
7376      * // => objects for ['barney']
7377      */
7378     function filter(collection, predicate) {
7379       var func = isArray(collection) ? arrayFilter : baseFilter;
7380       return func(collection, getIteratee(predicate, 3));
7381     }
7382
7383     /**
7384      * Iterates over elements of `collection`, returning the first element
7385      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7386      * (value, index|key, collection).
7387      *
7388      * @static
7389      * @memberOf _
7390      * @category Collection
7391      * @param {Array|Object} collection The collection to search.
7392      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7393      * @returns {*} Returns the matched element, else `undefined`.
7394      * @example
7395      *
7396      * var users = [
7397      *   { 'user': 'barney',  'age': 36, 'active': true },
7398      *   { 'user': 'fred',    'age': 40, 'active': false },
7399      *   { 'user': 'pebbles', 'age': 1,  'active': true }
7400      * ];
7401      *
7402      * _.find(users, function(o) { return o.age < 40; });
7403      * // => object for 'barney'
7404      *
7405      * // using the `_.matches` iteratee shorthand
7406      * _.find(users, { 'age': 1, 'active': true });
7407      * // => object for 'pebbles'
7408      *
7409      * // using the `_.matchesProperty` iteratee shorthand
7410      * _.find(users, ['active', false]);
7411      * // => object for 'fred'
7412      *
7413      * // using the `_.property` iteratee shorthand
7414      * _.find(users, 'active');
7415      * // => object for 'barney'
7416      */
7417     function find(collection, predicate) {
7418       predicate = getIteratee(predicate, 3);
7419       if (isArray(collection)) {
7420         var index = baseFindIndex(collection, predicate);
7421         return index > -1 ? collection[index] : undefined;
7422       }
7423       return baseFind(collection, predicate, baseEach);
7424     }
7425
7426     /**
7427      * This method is like `_.find` except that it iterates over elements of
7428      * `collection` from right to left.
7429      *
7430      * @static
7431      * @memberOf _
7432      * @category Collection
7433      * @param {Array|Object} collection The collection to search.
7434      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7435      * @returns {*} Returns the matched element, else `undefined`.
7436      * @example
7437      *
7438      * _.findLast([1, 2, 3, 4], function(n) {
7439      *   return n % 2 == 1;
7440      * });
7441      * // => 3
7442      */
7443     function findLast(collection, predicate) {
7444       predicate = getIteratee(predicate, 3);
7445       if (isArray(collection)) {
7446         var index = baseFindIndex(collection, predicate, true);
7447         return index > -1 ? collection[index] : undefined;
7448       }
7449       return baseFind(collection, predicate, baseEachRight);
7450     }
7451
7452     /**
7453      * Iterates over elements of `collection` invoking `iteratee` for each element.
7454      * The iteratee is invoked with three arguments: (value, index|key, collection).
7455      * Iteratee functions may exit iteration early by explicitly returning `false`.
7456      *
7457      * **Note:** As with other "Collections" methods, objects with a "length" property
7458      * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
7459      * for object iteration.
7460      *
7461      * @static
7462      * @memberOf _
7463      * @alias each
7464      * @category Collection
7465      * @param {Array|Object} collection The collection to iterate over.
7466      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7467      * @returns {Array|Object} Returns `collection`.
7468      * @example
7469      *
7470      * _([1, 2]).forEach(function(value) {
7471      *   console.log(value);
7472      * });
7473      * // => logs `1` then `2`
7474      *
7475      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
7476      *   console.log(key);
7477      * });
7478      * // => logs 'a' then 'b' (iteration order is not guaranteed)
7479      */
7480     function forEach(collection, iteratee) {
7481       return (typeof iteratee == 'function' && isArray(collection))
7482         ? arrayEach(collection, iteratee)
7483         : baseEach(collection, toFunction(iteratee));
7484     }
7485
7486     /**
7487      * This method is like `_.forEach` except that it iterates over elements of
7488      * `collection` from right to left.
7489      *
7490      * @static
7491      * @memberOf _
7492      * @alias eachRight
7493      * @category Collection
7494      * @param {Array|Object} collection The collection to iterate over.
7495      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7496      * @returns {Array|Object} Returns `collection`.
7497      * @example
7498      *
7499      * _.forEachRight([1, 2], function(value) {
7500      *   console.log(value);
7501      * });
7502      * // => logs `2` then `1`
7503      */
7504     function forEachRight(collection, iteratee) {
7505       return (typeof iteratee == 'function' && isArray(collection))
7506         ? arrayEachRight(collection, iteratee)
7507         : baseEachRight(collection, toFunction(iteratee));
7508     }
7509
7510     /**
7511      * Creates an object composed of keys generated from the results of running
7512      * each element of `collection` through `iteratee`. The corresponding value
7513      * of each key is an array of the elements responsible for generating the key.
7514      * The iteratee is invoked with one argument: (value).
7515      *
7516      * @static
7517      * @memberOf _
7518      * @category Collection
7519      * @param {Array|Object} collection The collection to iterate over.
7520      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
7521      * @returns {Object} Returns the composed aggregate object.
7522      * @example
7523      *
7524      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
7525      * // => { '4': [4.2], '6': [6.1, 6.3] }
7526      *
7527      * // using the `_.property` iteratee shorthand
7528      * _.groupBy(['one', 'two', 'three'], 'length');
7529      * // => { '3': ['one', 'two'], '5': ['three'] }
7530      */
7531     var groupBy = createAggregator(function(result, value, key) {
7532       if (hasOwnProperty.call(result, key)) {
7533         result[key].push(value);
7534       } else {
7535         result[key] = [value];
7536       }
7537     });
7538
7539     /**
7540      * Checks if `value` is in `collection`. If `collection` is a string it's checked
7541      * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7542      * is used for equality comparisons. If `fromIndex` is negative, it's used as
7543      * the offset from the end of `collection`.
7544      *
7545      * @static
7546      * @memberOf _
7547      * @category Collection
7548      * @param {Array|Object|string} collection The collection to search.
7549      * @param {*} value The value to search for.
7550      * @param {number} [fromIndex=0] The index to search from.
7551      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7552      * @returns {boolean} Returns `true` if `value` is found, else `false`.
7553      * @example
7554      *
7555      * _.includes([1, 2, 3], 1);
7556      * // => true
7557      *
7558      * _.includes([1, 2, 3], 1, 2);
7559      * // => false
7560      *
7561      * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
7562      * // => true
7563      *
7564      * _.includes('pebbles', 'eb');
7565      * // => true
7566      */
7567     function includes(collection, value, fromIndex, guard) {
7568       collection = isArrayLike(collection) ? collection : values(collection);
7569       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
7570
7571       var length = collection.length;
7572       if (fromIndex < 0) {
7573         fromIndex = nativeMax(length + fromIndex, 0);
7574       }
7575       return isString(collection)
7576         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
7577         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
7578     }
7579
7580     /**
7581      * Invokes the method at `path` of each element in `collection`, returning
7582      * an array of the results of each invoked method. Any additional arguments
7583      * are provided to each invoked method. If `methodName` is a function it's
7584      * invoked for, and `this` bound to, each element in `collection`.
7585      *
7586      * @static
7587      * @memberOf _
7588      * @category Collection
7589      * @param {Array|Object} collection The collection to iterate over.
7590      * @param {Array|Function|string} path The path of the method to invoke or
7591      *  the function invoked per iteration.
7592      * @param {...*} [args] The arguments to invoke each method with.
7593      * @returns {Array} Returns the array of results.
7594      * @example
7595      *
7596      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
7597      * // => [[1, 5, 7], [1, 2, 3]]
7598      *
7599      * _.invokeMap([123, 456], String.prototype.split, '');
7600      * // => [['1', '2', '3'], ['4', '5', '6']]
7601      */
7602     var invokeMap = rest(function(collection, path, args) {
7603       var index = -1,
7604           isFunc = typeof path == 'function',
7605           isProp = isKey(path),
7606           result = isArrayLike(collection) ? Array(collection.length) : [];
7607
7608       baseEach(collection, function(value) {
7609         var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
7610         result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
7611       });
7612       return result;
7613     });
7614
7615     /**
7616      * Creates an object composed of keys generated from the results of running
7617      * each element of `collection` through `iteratee`. The corresponding value
7618      * of each key is the last element responsible for generating the key. The
7619      * iteratee is invoked with one argument: (value).
7620      *
7621      * @static
7622      * @memberOf _
7623      * @category Collection
7624      * @param {Array|Object} collection The collection to iterate over.
7625      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
7626      * @returns {Object} Returns the composed aggregate object.
7627      * @example
7628      *
7629      * var keyData = [
7630      *   { 'dir': 'left', 'code': 97 },
7631      *   { 'dir': 'right', 'code': 100 }
7632      * ];
7633      *
7634      * _.keyBy(keyData, 'dir');
7635      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
7636      *
7637      * _.keyBy(keyData, function(o) {
7638      *   return String.fromCharCode(o.code);
7639      * });
7640      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
7641      */
7642     var keyBy = createAggregator(function(result, value, key) {
7643       result[key] = value;
7644     });
7645
7646     /**
7647      * Creates an array of values by running each element in `collection` through
7648      * `iteratee`. The iteratee is invoked with three arguments:
7649      * (value, index|key, collection).
7650      *
7651      * Many lodash methods are guarded to work as iteratees for methods like
7652      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
7653      *
7654      * The guarded methods are:
7655      * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
7656      * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
7657      * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
7658      * and `words`
7659      *
7660      * @static
7661      * @memberOf _
7662      * @category Collection
7663      * @param {Array|Object} collection The collection to iterate over.
7664      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7665      * @returns {Array} Returns the new mapped array.
7666      * @example
7667      *
7668      * function square(n) {
7669      *   return n * n;
7670      * }
7671      *
7672      * _.map([1, 2], square);
7673      * // => [3, 6]
7674      *
7675      * _.map({ 'a': 1, 'b': 2 }, square);
7676      * // => [3, 6] (iteration order is not guaranteed)
7677      *
7678      * var users = [
7679      *   { 'user': 'barney' },
7680      *   { 'user': 'fred' }
7681      * ];
7682      *
7683      * // using the `_.property` iteratee shorthand
7684      * _.map(users, 'user');
7685      * // => ['barney', 'fred']
7686      */
7687     function map(collection, iteratee) {
7688       var func = isArray(collection) ? arrayMap : baseMap;
7689       return func(collection, getIteratee(iteratee, 3));
7690     }
7691
7692     /**
7693      * This method is like `_.sortBy` except that it allows specifying the sort
7694      * orders of the iteratees to sort by. If `orders` is unspecified, all values
7695      * are sorted in ascending order. Otherwise, specify an order of "desc" for
7696      * descending or "asc" for ascending sort order of corresponding values.
7697      *
7698      * @static
7699      * @memberOf _
7700      * @category Collection
7701      * @param {Array|Object} collection The collection to iterate over.
7702      * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
7703      * @param {string[]} [orders] The sort orders of `iteratees`.
7704      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7705      * @returns {Array} Returns the new sorted array.
7706      * @example
7707      *
7708      * var users = [
7709      *   { 'user': 'fred',   'age': 48 },
7710      *   { 'user': 'barney', 'age': 34 },
7711      *   { 'user': 'fred',   'age': 42 },
7712      *   { 'user': 'barney', 'age': 36 }
7713      * ];
7714      *
7715      * // sort by `user` in ascending order and by `age` in descending order
7716      * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
7717      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
7718      */
7719     function orderBy(collection, iteratees, orders, guard) {
7720       if (collection == null) {
7721         return [];
7722       }
7723       if (!isArray(iteratees)) {
7724         iteratees = iteratees == null ? [] : [iteratees];
7725       }
7726       orders = guard ? undefined : orders;
7727       if (!isArray(orders)) {
7728         orders = orders == null ? [] : [orders];
7729       }
7730       return baseOrderBy(collection, iteratees, orders);
7731     }
7732
7733     /**
7734      * Creates an array of elements split into two groups, the first of which
7735      * contains elements `predicate` returns truthy for, while the second of which
7736      * contains elements `predicate` returns falsey for. The predicate is invoked
7737      * with three arguments: (value, index|key, collection).
7738      *
7739      * @static
7740      * @memberOf _
7741      * @category Collection
7742      * @param {Array|Object} collection The collection to iterate over.
7743      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7744      * @returns {Array} Returns the array of grouped elements.
7745      * @example
7746      *
7747      * var users = [
7748      *   { 'user': 'barney',  'age': 36, 'active': false },
7749      *   { 'user': 'fred',    'age': 40, 'active': true },
7750      *   { 'user': 'pebbles', 'age': 1,  'active': false }
7751      * ];
7752      *
7753      * _.partition(users, function(o) { return o.active; });
7754      * // => objects for [['fred'], ['barney', 'pebbles']]
7755      *
7756      * // using the `_.matches` iteratee shorthand
7757      * _.partition(users, { 'age': 1, 'active': false });
7758      * // => objects for [['pebbles'], ['barney', 'fred']]
7759      *
7760      * // using the `_.matchesProperty` iteratee shorthand
7761      * _.partition(users, ['active', false]);
7762      * // => objects for [['barney', 'pebbles'], ['fred']]
7763      *
7764      * // using the `_.property` iteratee shorthand
7765      * _.partition(users, 'active');
7766      * // => objects for [['fred'], ['barney', 'pebbles']]
7767      */
7768     var partition = createAggregator(function(result, value, key) {
7769       result[key ? 0 : 1].push(value);
7770     }, function() { return [[], []]; });
7771
7772     /**
7773      * Reduces `collection` to a value which is the accumulated result of running
7774      * each element in `collection` through `iteratee`, where each successive
7775      * invocation is supplied the return value of the previous. If `accumulator`
7776      * is not provided the first element of `collection` is used as the initial
7777      * value. The iteratee is invoked with four arguments:
7778      * (accumulator, value, index|key, collection).
7779      *
7780      * Many lodash methods are guarded to work as iteratees for methods like
7781      * `_.reduce`, `_.reduceRight`, and `_.transform`.
7782      *
7783      * The guarded methods are:
7784      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
7785      * and `sortBy`
7786      *
7787      * @static
7788      * @memberOf _
7789      * @category Collection
7790      * @param {Array|Object} collection The collection to iterate over.
7791      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7792      * @param {*} [accumulator] The initial value.
7793      * @returns {*} Returns the accumulated value.
7794      * @example
7795      *
7796      * _.reduce([1, 2], function(sum, n) {
7797      *   return sum + n;
7798      * });
7799      * // => 3
7800      *
7801      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
7802      *   (result[value] || (result[value] = [])).push(key);
7803      *   return result;
7804      * }, {});
7805      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
7806      */
7807     function reduce(collection, iteratee, accumulator) {
7808       var func = isArray(collection) ? arrayReduce : baseReduce,
7809           initFromCollection = arguments.length < 3;
7810
7811       return func(collection, getIteratee(iteratee, 4), accumulator, initFromCollection, baseEach);
7812     }
7813
7814     /**
7815      * This method is like `_.reduce` except that it iterates over elements of
7816      * `collection` from right to left.
7817      *
7818      * @static
7819      * @memberOf _
7820      * @category Collection
7821      * @param {Array|Object} collection The collection to iterate over.
7822      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7823      * @param {*} [accumulator] The initial value.
7824      * @returns {*} Returns the accumulated value.
7825      * @example
7826      *
7827      * var array = [[0, 1], [2, 3], [4, 5]];
7828      *
7829      * _.reduceRight(array, function(flattened, other) {
7830      *   return flattened.concat(other);
7831      * }, []);
7832      * // => [4, 5, 2, 3, 0, 1]
7833      */
7834     function reduceRight(collection, iteratee, accumulator) {
7835       var func = isArray(collection) ? arrayReduceRight : baseReduce,
7836           initFromCollection = arguments.length < 3;
7837
7838       return func(collection, getIteratee(iteratee, 4), accumulator, initFromCollection, baseEachRight);
7839     }
7840
7841     /**
7842      * The opposite of `_.filter`; this method returns the elements of `collection`
7843      * that `predicate` does **not** return truthy for.
7844      *
7845      * @static
7846      * @memberOf _
7847      * @category Collection
7848      * @param {Array|Object} collection The collection to iterate over.
7849      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7850      * @returns {Array} Returns the new filtered array.
7851      * @example
7852      *
7853      * var users = [
7854      *   { 'user': 'barney', 'age': 36, 'active': false },
7855      *   { 'user': 'fred',   'age': 40, 'active': true }
7856      * ];
7857      *
7858      * _.reject(users, function(o) { return !o.active; });
7859      * // => objects for ['fred']
7860      *
7861      * // using the `_.matches` iteratee shorthand
7862      * _.reject(users, { 'age': 40, 'active': true });
7863      * // => objects for ['barney']
7864      *
7865      * // using the `_.matchesProperty` iteratee shorthand
7866      * _.reject(users, ['active', false]);
7867      * // => objects for ['fred']
7868      *
7869      * // using the `_.property` iteratee shorthand
7870      * _.reject(users, 'active');
7871      * // => objects for ['barney']
7872      */
7873     function reject(collection, predicate) {
7874       var func = isArray(collection) ? arrayFilter : baseFilter;
7875       predicate = getIteratee(predicate, 3);
7876       return func(collection, function(value, index, collection) {
7877         return !predicate(value, index, collection);
7878       });
7879     }
7880
7881     /**
7882      * Gets a random element from `collection`.
7883      *
7884      * @static
7885      * @memberOf _
7886      * @category Collection
7887      * @param {Array|Object} collection The collection to sample.
7888      * @returns {*} Returns the random element.
7889      * @example
7890      *
7891      * _.sample([1, 2, 3, 4]);
7892      * // => 2
7893      */
7894     function sample(collection) {
7895       var array = isArrayLike(collection) ? collection : values(collection),
7896           length = array.length;
7897
7898       return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
7899     }
7900
7901     /**
7902      * Gets `n` random elements from `collection`.
7903      *
7904      * @static
7905      * @memberOf _
7906      * @category Collection
7907      * @param {Array|Object} collection The collection to sample.
7908      * @param {number} [n=0] The number of elements to sample.
7909      * @returns {Array} Returns the random elements.
7910      * @example
7911      *
7912      * _.sampleSize([1, 2, 3, 4], 2);
7913      * // => [3, 1]
7914      */
7915     function sampleSize(collection, n) {
7916       var index = -1,
7917           result = toArray(collection),
7918           length = result.length,
7919           lastIndex = length - 1;
7920
7921       n = baseClamp(toInteger(n), 0, length);
7922       while (++index < n) {
7923         var rand = baseRandom(index, lastIndex),
7924             value = result[rand];
7925
7926         result[rand] = result[index];
7927         result[index] = value;
7928       }
7929       result.length = n;
7930       return result;
7931     }
7932
7933     /**
7934      * Creates an array of shuffled values, using a version of the
7935      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
7936      *
7937      * @static
7938      * @memberOf _
7939      * @category Collection
7940      * @param {Array|Object} collection The collection to shuffle.
7941      * @returns {Array} Returns the new shuffled array.
7942      * @example
7943      *
7944      * _.shuffle([1, 2, 3, 4]);
7945      * // => [4, 1, 3, 2]
7946      */
7947     function shuffle(collection) {
7948       return sampleSize(collection, MAX_ARRAY_LENGTH);
7949     }
7950
7951     /**
7952      * Gets the size of `collection` by returning its length for array-like
7953      * values or the number of own enumerable properties for objects.
7954      *
7955      * @static
7956      * @memberOf _
7957      * @category Collection
7958      * @param {Array|Object} collection The collection to inspect.
7959      * @returns {number} Returns the collection size.
7960      * @example
7961      *
7962      * _.size([1, 2, 3]);
7963      * // => 3
7964      *
7965      * _.size({ 'a': 1, 'b': 2 });
7966      * // => 2
7967      *
7968      * _.size('pebbles');
7969      * // => 7
7970      */
7971     function size(collection) {
7972       if (collection == null) {
7973         return 0;
7974       }
7975       if (isArrayLike(collection)) {
7976         var result = collection.length;
7977         return (result && isString(collection)) ? stringSize(collection) : result;
7978       }
7979       return keys(collection).length;
7980     }
7981
7982     /**
7983      * Checks if `predicate` returns truthy for **any** element of `collection`.
7984      * Iteration is stopped once `predicate` returns truthy. The predicate is
7985      * invoked with three arguments: (value, index|key, collection).
7986      *
7987      * @static
7988      * @memberOf _
7989      * @category Collection
7990      * @param {Array|Object} collection The collection to iterate over.
7991      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7992      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
7993      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
7994      * @example
7995      *
7996      * _.some([null, 0, 'yes', false], Boolean);
7997      * // => true
7998      *
7999      * var users = [
8000      *   { 'user': 'barney', 'active': true },
8001      *   { 'user': 'fred',   'active': false }
8002      * ];
8003      *
8004      * // using the `_.matches` iteratee shorthand
8005      * _.some(users, { 'user': 'barney', 'active': false });
8006      * // => false
8007      *
8008      * // using the `_.matchesProperty` iteratee shorthand
8009      * _.some(users, ['active', false]);
8010      * // => true
8011      *
8012      * // using the `_.property` iteratee shorthand
8013      * _.some(users, 'active');
8014      * // => true
8015      */
8016     function some(collection, predicate, guard) {
8017       var func = isArray(collection) ? arraySome : baseSome;
8018       if (guard && isIterateeCall(collection, predicate, guard)) {
8019         predicate = undefined;
8020       }
8021       return func(collection, getIteratee(predicate, 3));
8022     }
8023
8024     /**
8025      * Creates an array of elements, sorted in ascending order by the results of
8026      * running each element in a collection through each iteratee. This method
8027      * performs a stable sort, that is, it preserves the original sort order of
8028      * equal elements. The iteratees are invoked with one argument: (value).
8029      *
8030      * @static
8031      * @memberOf _
8032      * @category Collection
8033      * @param {Array|Object} collection The collection to iterate over.
8034      * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
8035      *  The iteratees to sort by, specified individually or in arrays.
8036      * @returns {Array} Returns the new sorted array.
8037      * @example
8038      *
8039      * var users = [
8040      *   { 'user': 'fred',   'age': 48 },
8041      *   { 'user': 'barney', 'age': 36 },
8042      *   { 'user': 'fred',   'age': 42 },
8043      *   { 'user': 'barney', 'age': 34 }
8044      * ];
8045      *
8046      * _.sortBy(users, function(o) { return o.user; });
8047      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8048      *
8049      * _.sortBy(users, ['user', 'age']);
8050      * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
8051      *
8052      * _.sortBy(users, 'user', function(o) {
8053      *   return Math.floor(o.age / 10);
8054      * });
8055      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8056      */
8057     var sortBy = rest(function(collection, iteratees) {
8058       if (collection == null) {
8059         return [];
8060       }
8061       var length = iteratees.length;
8062       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
8063         iteratees = [];
8064       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
8065         iteratees.length = 1;
8066       }
8067       return baseOrderBy(collection, baseFlatten(iteratees), []);
8068     });
8069
8070     /*------------------------------------------------------------------------*/
8071
8072     /**
8073      * Gets the timestamp of the number of milliseconds that have elapsed since
8074      * the Unix epoch (1 January 1970 00:00:00 UTC).
8075      *
8076      * @static
8077      * @memberOf _
8078      * @type Function
8079      * @category Date
8080      * @returns {number} Returns the timestamp.
8081      * @example
8082      *
8083      * _.defer(function(stamp) {
8084      *   console.log(_.now() - stamp);
8085      * }, _.now());
8086      * // => logs the number of milliseconds it took for the deferred function to be invoked
8087      */
8088     var now = Date.now;
8089
8090     /*------------------------------------------------------------------------*/
8091
8092     /**
8093      * The opposite of `_.before`; this method creates a function that invokes
8094      * `func` once it's called `n` or more times.
8095      *
8096      * @static
8097      * @memberOf _
8098      * @category Function
8099      * @param {number} n The number of calls before `func` is invoked.
8100      * @param {Function} func The function to restrict.
8101      * @returns {Function} Returns the new restricted function.
8102      * @example
8103      *
8104      * var saves = ['profile', 'settings'];
8105      *
8106      * var done = _.after(saves.length, function() {
8107      *   console.log('done saving!');
8108      * });
8109      *
8110      * _.forEach(saves, function(type) {
8111      *   asyncSave({ 'type': type, 'complete': done });
8112      * });
8113      * // => logs 'done saving!' after the two async saves have completed
8114      */
8115     function after(n, func) {
8116       if (typeof func != 'function') {
8117         throw new TypeError(FUNC_ERROR_TEXT);
8118       }
8119       n = toInteger(n);
8120       return function() {
8121         if (--n < 1) {
8122           return func.apply(this, arguments);
8123         }
8124       };
8125     }
8126
8127     /**
8128      * Creates a function that accepts up to `n` arguments, ignoring any
8129      * additional arguments.
8130      *
8131      * @static
8132      * @memberOf _
8133      * @category Function
8134      * @param {Function} func The function to cap arguments for.
8135      * @param {number} [n=func.length] The arity cap.
8136      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8137      * @returns {Function} Returns the new function.
8138      * @example
8139      *
8140      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
8141      * // => [6, 8, 10]
8142      */
8143     function ary(func, n, guard) {
8144       n = guard ? undefined : n;
8145       n = (func && n == null) ? func.length : n;
8146       return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
8147     }
8148
8149     /**
8150      * Creates a function that invokes `func`, with the `this` binding and arguments
8151      * of the created function, while it's called less than `n` times. Subsequent
8152      * calls to the created function return the result of the last `func` invocation.
8153      *
8154      * @static
8155      * @memberOf _
8156      * @category Function
8157      * @param {number} n The number of calls at which `func` is no longer invoked.
8158      * @param {Function} func The function to restrict.
8159      * @returns {Function} Returns the new restricted function.
8160      * @example
8161      *
8162      * jQuery(element).on('click', _.before(5, addContactToList));
8163      * // => allows adding up to 4 contacts to the list
8164      */
8165     function before(n, func) {
8166       var result;
8167       if (typeof func != 'function') {
8168         throw new TypeError(FUNC_ERROR_TEXT);
8169       }
8170       n = toInteger(n);
8171       return function() {
8172         if (--n > 0) {
8173           result = func.apply(this, arguments);
8174         }
8175         if (n <= 1) {
8176           func = undefined;
8177         }
8178         return result;
8179       };
8180     }
8181
8182     /**
8183      * Creates a function that invokes `func` with the `this` binding of `thisArg`
8184      * and prepends any additional `_.bind` arguments to those provided to the
8185      * bound function.
8186      *
8187      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
8188      * may be used as a placeholder for partially applied arguments.
8189      *
8190      * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
8191      * property of bound functions.
8192      *
8193      * @static
8194      * @memberOf _
8195      * @category Function
8196      * @param {Function} func The function to bind.
8197      * @param {*} thisArg The `this` binding of `func`.
8198      * @param {...*} [partials] The arguments to be partially applied.
8199      * @returns {Function} Returns the new bound function.
8200      * @example
8201      *
8202      * var greet = function(greeting, punctuation) {
8203      *   return greeting + ' ' + this.user + punctuation;
8204      * };
8205      *
8206      * var object = { 'user': 'fred' };
8207      *
8208      * var bound = _.bind(greet, object, 'hi');
8209      * bound('!');
8210      * // => 'hi fred!'
8211      *
8212      * // using placeholders
8213      * var bound = _.bind(greet, object, _, '!');
8214      * bound('hi');
8215      * // => 'hi fred!'
8216      */
8217     var bind = rest(function(func, thisArg, partials) {
8218       var bitmask = BIND_FLAG;
8219       if (partials.length) {
8220         var holders = replaceHolders(partials, bind.placeholder);
8221         bitmask |= PARTIAL_FLAG;
8222       }
8223       return createWrapper(func, bitmask, thisArg, partials, holders);
8224     });
8225
8226     /**
8227      * Creates a function that invokes the method at `object[key]` and prepends
8228      * any additional `_.bindKey` arguments to those provided to the bound function.
8229      *
8230      * This method differs from `_.bind` by allowing bound functions to reference
8231      * methods that may be redefined or don't yet exist.
8232      * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
8233      * for more details.
8234      *
8235      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
8236      * builds, may be used as a placeholder for partially applied arguments.
8237      *
8238      * @static
8239      * @memberOf _
8240      * @category Function
8241      * @param {Object} object The object to invoke the method on.
8242      * @param {string} key The key of the method.
8243      * @param {...*} [partials] The arguments to be partially applied.
8244      * @returns {Function} Returns the new bound function.
8245      * @example
8246      *
8247      * var object = {
8248      *   'user': 'fred',
8249      *   'greet': function(greeting, punctuation) {
8250      *     return greeting + ' ' + this.user + punctuation;
8251      *   }
8252      * };
8253      *
8254      * var bound = _.bindKey(object, 'greet', 'hi');
8255      * bound('!');
8256      * // => 'hi fred!'
8257      *
8258      * object.greet = function(greeting, punctuation) {
8259      *   return greeting + 'ya ' + this.user + punctuation;
8260      * };
8261      *
8262      * bound('!');
8263      * // => 'hiya fred!'
8264      *
8265      * // using placeholders
8266      * var bound = _.bindKey(object, 'greet', _, '!');
8267      * bound('hi');
8268      * // => 'hiya fred!'
8269      */
8270     var bindKey = rest(function(object, key, partials) {
8271       var bitmask = BIND_FLAG | BIND_KEY_FLAG;
8272       if (partials.length) {
8273         var holders = replaceHolders(partials, bindKey.placeholder);
8274         bitmask |= PARTIAL_FLAG;
8275       }
8276       return createWrapper(key, bitmask, object, partials, holders);
8277     });
8278
8279     /**
8280      * Creates a function that accepts arguments of `func` and either invokes
8281      * `func` returning its result, if at least `arity` number of arguments have
8282      * been provided, or returns a function that accepts the remaining `func`
8283      * arguments, and so on. The arity of `func` may be specified if `func.length`
8284      * is not sufficient.
8285      *
8286      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
8287      * may be used as a placeholder for provided arguments.
8288      *
8289      * **Note:** This method doesn't set the "length" property of curried functions.
8290      *
8291      * @static
8292      * @memberOf _
8293      * @category Function
8294      * @param {Function} func The function to curry.
8295      * @param {number} [arity=func.length] The arity of `func`.
8296      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8297      * @returns {Function} Returns the new curried function.
8298      * @example
8299      *
8300      * var abc = function(a, b, c) {
8301      *   return [a, b, c];
8302      * };
8303      *
8304      * var curried = _.curry(abc);
8305      *
8306      * curried(1)(2)(3);
8307      * // => [1, 2, 3]
8308      *
8309      * curried(1, 2)(3);
8310      * // => [1, 2, 3]
8311      *
8312      * curried(1, 2, 3);
8313      * // => [1, 2, 3]
8314      *
8315      * // using placeholders
8316      * curried(1)(_, 3)(2);
8317      * // => [1, 2, 3]
8318      */
8319     function curry(func, arity, guard) {
8320       arity = guard ? undefined : arity;
8321       var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8322       result.placeholder = curry.placeholder;
8323       return result;
8324     }
8325
8326     /**
8327      * This method is like `_.curry` except that arguments are applied to `func`
8328      * in the manner of `_.partialRight` instead of `_.partial`.
8329      *
8330      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
8331      * builds, may be used as a placeholder for provided arguments.
8332      *
8333      * **Note:** This method doesn't set the "length" property of curried functions.
8334      *
8335      * @static
8336      * @memberOf _
8337      * @category Function
8338      * @param {Function} func The function to curry.
8339      * @param {number} [arity=func.length] The arity of `func`.
8340      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8341      * @returns {Function} Returns the new curried function.
8342      * @example
8343      *
8344      * var abc = function(a, b, c) {
8345      *   return [a, b, c];
8346      * };
8347      *
8348      * var curried = _.curryRight(abc);
8349      *
8350      * curried(3)(2)(1);
8351      * // => [1, 2, 3]
8352      *
8353      * curried(2, 3)(1);
8354      * // => [1, 2, 3]
8355      *
8356      * curried(1, 2, 3);
8357      * // => [1, 2, 3]
8358      *
8359      * // using placeholders
8360      * curried(3)(1, _)(2);
8361      * // => [1, 2, 3]
8362      */
8363     function curryRight(func, arity, guard) {
8364       arity = guard ? undefined : arity;
8365       var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8366       result.placeholder = curryRight.placeholder;
8367       return result;
8368     }
8369
8370     /**
8371      * Creates a debounced function that delays invoking `func` until after `wait`
8372      * milliseconds have elapsed since the last time the debounced function was
8373      * invoked. The debounced function comes with a `cancel` method to cancel
8374      * delayed `func` invocations and a `flush` method to immediately invoke them.
8375      * Provide an options object to indicate whether `func` should be invoked on
8376      * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
8377      * with the last arguments provided to the debounced function. Subsequent calls
8378      * to the debounced function return the result of the last `func` invocation.
8379      *
8380      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8381      * on the trailing edge of the timeout only if the the debounced function is
8382      * invoked more than once during the `wait` timeout.
8383      *
8384      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8385      * for details over the differences between `_.debounce` and `_.throttle`.
8386      *
8387      * @static
8388      * @memberOf _
8389      * @category Function
8390      * @param {Function} func The function to debounce.
8391      * @param {number} [wait=0] The number of milliseconds to delay.
8392      * @param {Object} [options] The options object.
8393      * @param {boolean} [options.leading=false] Specify invoking on the leading
8394      *  edge of the timeout.
8395      * @param {number} [options.maxWait] The maximum time `func` is allowed to be
8396      *  delayed before it's invoked.
8397      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
8398      *  edge of the timeout.
8399      * @returns {Function} Returns the new debounced function.
8400      * @example
8401      *
8402      * // avoid costly calculations while the window size is in flux
8403      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
8404      *
8405      * // invoke `sendMail` when clicked, debouncing subsequent calls
8406      * jQuery(element).on('click', _.debounce(sendMail, 300, {
8407      *   'leading': true,
8408      *   'trailing': false
8409      * }));
8410      *
8411      * // ensure `batchLog` is invoked once after 1 second of debounced calls
8412      * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
8413      * var source = new EventSource('/stream');
8414      * jQuery(source).on('message', debounced);
8415      *
8416      * // cancel a trailing debounced invocation
8417      * jQuery(window).on('popstate', debounced.cancel);
8418      */
8419     function debounce(func, wait, options) {
8420       var args,
8421           maxTimeoutId,
8422           result,
8423           stamp,
8424           thisArg,
8425           timeoutId,
8426           trailingCall,
8427           lastCalled = 0,
8428           leading = false,
8429           maxWait = false,
8430           trailing = true;
8431
8432       if (typeof func != 'function') {
8433         throw new TypeError(FUNC_ERROR_TEXT);
8434       }
8435       wait = toNumber(wait) || 0;
8436       if (isObject(options)) {
8437         leading = !!options.leading;
8438         maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
8439         trailing = 'trailing' in options ? !!options.trailing : trailing;
8440       }
8441
8442       function cancel() {
8443         if (timeoutId) {
8444           clearTimeout(timeoutId);
8445         }
8446         if (maxTimeoutId) {
8447           clearTimeout(maxTimeoutId);
8448         }
8449         lastCalled = 0;
8450         args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
8451       }
8452
8453       function complete(isCalled, id) {
8454         if (id) {
8455           clearTimeout(id);
8456         }
8457         maxTimeoutId = timeoutId = trailingCall = undefined;
8458         if (isCalled) {
8459           lastCalled = now();
8460           result = func.apply(thisArg, args);
8461           if (!timeoutId && !maxTimeoutId) {
8462             args = thisArg = undefined;
8463           }
8464         }
8465       }
8466
8467       function delayed() {
8468         var remaining = wait - (now() - stamp);
8469         if (remaining <= 0 || remaining > wait) {
8470           complete(trailingCall, maxTimeoutId);
8471         } else {
8472           timeoutId = setTimeout(delayed, remaining);
8473         }
8474       }
8475
8476       function flush() {
8477         if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
8478           result = func.apply(thisArg, args);
8479         }
8480         cancel();
8481         return result;
8482       }
8483
8484       function maxDelayed() {
8485         complete(trailing, timeoutId);
8486       }
8487
8488       function debounced() {
8489         args = arguments;
8490         stamp = now();
8491         thisArg = this;
8492         trailingCall = trailing && (timeoutId || !leading);
8493
8494         if (maxWait === false) {
8495           var leadingCall = leading && !timeoutId;
8496         } else {
8497           if (!maxTimeoutId && !leading) {
8498             lastCalled = stamp;
8499           }
8500           var remaining = maxWait - (stamp - lastCalled),
8501               isCalled = remaining <= 0 || remaining > maxWait;
8502
8503           if (isCalled) {
8504             if (maxTimeoutId) {
8505               maxTimeoutId = clearTimeout(maxTimeoutId);
8506             }
8507             lastCalled = stamp;
8508             result = func.apply(thisArg, args);
8509           }
8510           else if (!maxTimeoutId) {
8511             maxTimeoutId = setTimeout(maxDelayed, remaining);
8512           }
8513         }
8514         if (isCalled && timeoutId) {
8515           timeoutId = clearTimeout(timeoutId);
8516         }
8517         else if (!timeoutId && wait !== maxWait) {
8518           timeoutId = setTimeout(delayed, wait);
8519         }
8520         if (leadingCall) {
8521           isCalled = true;
8522           result = func.apply(thisArg, args);
8523         }
8524         if (isCalled && !timeoutId && !maxTimeoutId) {
8525           args = thisArg = undefined;
8526         }
8527         return result;
8528       }
8529       debounced.cancel = cancel;
8530       debounced.flush = flush;
8531       return debounced;
8532     }
8533
8534     /**
8535      * Defers invoking the `func` until the current call stack has cleared. Any
8536      * additional arguments are provided to `func` when it's invoked.
8537      *
8538      * @static
8539      * @memberOf _
8540      * @category Function
8541      * @param {Function} func The function to defer.
8542      * @param {...*} [args] The arguments to invoke `func` with.
8543      * @returns {number} Returns the timer id.
8544      * @example
8545      *
8546      * _.defer(function(text) {
8547      *   console.log(text);
8548      * }, 'deferred');
8549      * // logs 'deferred' after one or more milliseconds
8550      */
8551     var defer = rest(function(func, args) {
8552       return baseDelay(func, 1, args);
8553     });
8554
8555     /**
8556      * Invokes `func` after `wait` milliseconds. Any additional arguments are
8557      * provided to `func` when it's invoked.
8558      *
8559      * @static
8560      * @memberOf _
8561      * @category Function
8562      * @param {Function} func The function to delay.
8563      * @param {number} wait The number of milliseconds to delay invocation.
8564      * @param {...*} [args] The arguments to invoke `func` with.
8565      * @returns {number} Returns the timer id.
8566      * @example
8567      *
8568      * _.delay(function(text) {
8569      *   console.log(text);
8570      * }, 1000, 'later');
8571      * // => logs 'later' after one second
8572      */
8573     var delay = rest(function(func, wait, args) {
8574       return baseDelay(func, toNumber(wait) || 0, args);
8575     });
8576
8577     /**
8578      * Creates a function that invokes `func` with arguments reversed.
8579      *
8580      * @static
8581      * @memberOf _
8582      * @category Function
8583      * @param {Function} func The function to flip arguments for.
8584      * @returns {Function} Returns the new function.
8585      * @example
8586      *
8587      * var flipped = _.flip(function() {
8588      *   return _.toArray(arguments);
8589      * });
8590      *
8591      * flipped('a', 'b', 'c', 'd');
8592      * // => ['d', 'c', 'b', 'a']
8593      */
8594     function flip(func) {
8595       return createWrapper(func, FLIP_FLAG);
8596     }
8597
8598     /**
8599      * Creates a function that memoizes the result of `func`. If `resolver` is
8600      * provided it determines the cache key for storing the result based on the
8601      * arguments provided to the memoized function. By default, the first argument
8602      * provided to the memoized function is used as the map cache key. The `func`
8603      * is invoked with the `this` binding of the memoized function.
8604      *
8605      * **Note:** The cache is exposed as the `cache` property on the memoized
8606      * function. Its creation may be customized by replacing the `_.memoize.Cache`
8607      * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
8608      * method interface of `delete`, `get`, `has`, and `set`.
8609      *
8610      * @static
8611      * @memberOf _
8612      * @category Function
8613      * @param {Function} func The function to have its output memoized.
8614      * @param {Function} [resolver] The function to resolve the cache key.
8615      * @returns {Function} Returns the new memoizing function.
8616      * @example
8617      *
8618      * var object = { 'a': 1, 'b': 2 };
8619      * var other = { 'c': 3, 'd': 4 };
8620      *
8621      * var values = _.memoize(_.values);
8622      * values(object);
8623      * // => [1, 2]
8624      *
8625      * values(other);
8626      * // => [3, 4]
8627      *
8628      * object.a = 2;
8629      * values(object);
8630      * // => [1, 2]
8631      *
8632      * // modifying the result cache
8633      * values.cache.set(object, ['a', 'b']);
8634      * values(object);
8635      * // => ['a', 'b']
8636      *
8637      * // replacing `_.memoize.Cache`
8638      * _.memoize.Cache = WeakMap;
8639      */
8640     function memoize(func, resolver) {
8641       if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
8642         throw new TypeError(FUNC_ERROR_TEXT);
8643       }
8644       var memoized = function() {
8645         var args = arguments,
8646             key = resolver ? resolver.apply(this, args) : args[0],
8647             cache = memoized.cache;
8648
8649         if (cache.has(key)) {
8650           return cache.get(key);
8651         }
8652         var result = func.apply(this, args);
8653         memoized.cache = cache.set(key, result);
8654         return result;
8655       };
8656       memoized.cache = new memoize.Cache;
8657       return memoized;
8658     }
8659
8660     /**
8661      * Creates a function that negates the result of the predicate `func`. The
8662      * `func` predicate is invoked with the `this` binding and arguments of the
8663      * created function.
8664      *
8665      * @static
8666      * @memberOf _
8667      * @category Function
8668      * @param {Function} predicate The predicate to negate.
8669      * @returns {Function} Returns the new function.
8670      * @example
8671      *
8672      * function isEven(n) {
8673      *   return n % 2 == 0;
8674      * }
8675      *
8676      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
8677      * // => [1, 3, 5]
8678      */
8679     function negate(predicate) {
8680       if (typeof predicate != 'function') {
8681         throw new TypeError(FUNC_ERROR_TEXT);
8682       }
8683       return function() {
8684         return !predicate.apply(this, arguments);
8685       };
8686     }
8687
8688     /**
8689      * Creates a function that is restricted to invoking `func` once. Repeat calls
8690      * to the function return the value of the first invocation. The `func` is
8691      * invoked with the `this` binding and arguments of the created function.
8692      *
8693      * @static
8694      * @memberOf _
8695      * @category Function
8696      * @param {Function} func The function to restrict.
8697      * @returns {Function} Returns the new restricted function.
8698      * @example
8699      *
8700      * var initialize = _.once(createApplication);
8701      * initialize();
8702      * initialize();
8703      * // `initialize` invokes `createApplication` once
8704      */
8705     function once(func) {
8706       return before(2, func);
8707     }
8708
8709     /**
8710      * Creates a function that invokes `func` with arguments transformed by
8711      * corresponding `transforms`.
8712      *
8713      * @static
8714      * @memberOf _
8715      * @category Function
8716      * @param {Function} func The function to wrap.
8717      * @param {...(Function|Function[])} [transforms] The functions to transform
8718      * arguments, specified individually or in arrays.
8719      * @returns {Function} Returns the new function.
8720      * @example
8721      *
8722      * function doubled(n) {
8723      *   return n * 2;
8724      * }
8725      *
8726      * function square(n) {
8727      *   return n * n;
8728      * }
8729      *
8730      * var func = _.overArgs(function(x, y) {
8731      *   return [x, y];
8732      * }, square, doubled);
8733      *
8734      * func(9, 3);
8735      * // => [81, 6]
8736      *
8737      * func(10, 5);
8738      * // => [100, 10]
8739      */
8740     var overArgs = rest(function(func, transforms) {
8741       transforms = arrayMap(baseFlatten(transforms), getIteratee());
8742
8743       var funcsLength = transforms.length;
8744       return rest(function(args) {
8745         var index = -1,
8746             length = nativeMin(args.length, funcsLength);
8747
8748         while (++index < length) {
8749           args[index] = transforms[index].call(this, args[index]);
8750         }
8751         return apply(func, this, args);
8752       });
8753     });
8754
8755     /**
8756      * Creates a function that invokes `func` with `partial` arguments prepended
8757      * to those provided to the new function. This method is like `_.bind` except
8758      * it does **not** alter the `this` binding.
8759      *
8760      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
8761      * builds, may be used as a placeholder for partially applied arguments.
8762      *
8763      * **Note:** This method doesn't set the "length" property of partially
8764      * applied functions.
8765      *
8766      * @static
8767      * @memberOf _
8768      * @category Function
8769      * @param {Function} func The function to partially apply arguments to.
8770      * @param {...*} [partials] The arguments to be partially applied.
8771      * @returns {Function} Returns the new partially applied function.
8772      * @example
8773      *
8774      * var greet = function(greeting, name) {
8775      *   return greeting + ' ' + name;
8776      * };
8777      *
8778      * var sayHelloTo = _.partial(greet, 'hello');
8779      * sayHelloTo('fred');
8780      * // => 'hello fred'
8781      *
8782      * // using placeholders
8783      * var greetFred = _.partial(greet, _, 'fred');
8784      * greetFred('hi');
8785      * // => 'hi fred'
8786      */
8787     var partial = rest(function(func, partials) {
8788       var holders = replaceHolders(partials, partial.placeholder);
8789       return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
8790     });
8791
8792     /**
8793      * This method is like `_.partial` except that partially applied arguments
8794      * are appended to those provided to the new function.
8795      *
8796      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
8797      * builds, may be used as a placeholder for partially applied arguments.
8798      *
8799      * **Note:** This method doesn't set the "length" property of partially
8800      * applied functions.
8801      *
8802      * @static
8803      * @memberOf _
8804      * @category Function
8805      * @param {Function} func The function to partially apply arguments to.
8806      * @param {...*} [partials] The arguments to be partially applied.
8807      * @returns {Function} Returns the new partially applied function.
8808      * @example
8809      *
8810      * var greet = function(greeting, name) {
8811      *   return greeting + ' ' + name;
8812      * };
8813      *
8814      * var greetFred = _.partialRight(greet, 'fred');
8815      * greetFred('hi');
8816      * // => 'hi fred'
8817      *
8818      * // using placeholders
8819      * var sayHelloTo = _.partialRight(greet, 'hello', _);
8820      * sayHelloTo('fred');
8821      * // => 'hello fred'
8822      */
8823     var partialRight = rest(function(func, partials) {
8824       var holders = replaceHolders(partials, partialRight.placeholder);
8825       return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
8826     });
8827
8828     /**
8829      * Creates a function that invokes `func` with arguments arranged according
8830      * to the specified indexes where the argument value at the first index is
8831      * provided as the first argument, the argument value at the second index is
8832      * provided as the second argument, and so on.
8833      *
8834      * @static
8835      * @memberOf _
8836      * @category Function
8837      * @param {Function} func The function to rearrange arguments for.
8838      * @param {...(number|number[])} indexes The arranged argument indexes,
8839      *  specified individually or in arrays.
8840      * @returns {Function} Returns the new function.
8841      * @example
8842      *
8843      * var rearged = _.rearg(function(a, b, c) {
8844      *   return [a, b, c];
8845      * }, 2, 0, 1);
8846      *
8847      * rearged('b', 'c', 'a')
8848      * // => ['a', 'b', 'c']
8849      */
8850     var rearg = rest(function(func, indexes) {
8851       return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
8852     });
8853
8854     /**
8855      * Creates a function that invokes `func` with the `this` binding of the
8856      * created function and arguments from `start` and beyond provided as an array.
8857      *
8858      * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
8859      *
8860      * @static
8861      * @memberOf _
8862      * @category Function
8863      * @param {Function} func The function to apply a rest parameter to.
8864      * @param {number} [start=func.length-1] The start position of the rest parameter.
8865      * @returns {Function} Returns the new function.
8866      * @example
8867      *
8868      * var say = _.rest(function(what, names) {
8869      *   return what + ' ' + _.initial(names).join(', ') +
8870      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
8871      * });
8872      *
8873      * say('hello', 'fred', 'barney', 'pebbles');
8874      * // => 'hello fred, barney, & pebbles'
8875      */
8876     function rest(func, start) {
8877       if (typeof func != 'function') {
8878         throw new TypeError(FUNC_ERROR_TEXT);
8879       }
8880       start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
8881       return function() {
8882         var args = arguments,
8883             index = -1,
8884             length = nativeMax(args.length - start, 0),
8885             array = Array(length);
8886
8887         while (++index < length) {
8888           array[index] = args[start + index];
8889         }
8890         switch (start) {
8891           case 0: return func.call(this, array);
8892           case 1: return func.call(this, args[0], array);
8893           case 2: return func.call(this, args[0], args[1], array);
8894         }
8895         var otherArgs = Array(start + 1);
8896         index = -1;
8897         while (++index < start) {
8898           otherArgs[index] = args[index];
8899         }
8900         otherArgs[start] = array;
8901         return apply(func, this, otherArgs);
8902       };
8903     }
8904
8905     /**
8906      * Creates a function that invokes `func` with the `this` binding of the created
8907      * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
8908      *
8909      * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
8910      *
8911      * @static
8912      * @memberOf _
8913      * @category Function
8914      * @param {Function} func The function to spread arguments over.
8915      * @returns {Function} Returns the new function.
8916      * @example
8917      *
8918      * var say = _.spread(function(who, what) {
8919      *   return who + ' says ' + what;
8920      * });
8921      *
8922      * say(['fred', 'hello']);
8923      * // => 'fred says hello'
8924      *
8925      * // with a Promise
8926      * var numbers = Promise.all([
8927      *   Promise.resolve(40),
8928      *   Promise.resolve(36)
8929      * ]);
8930      *
8931      * numbers.then(_.spread(function(x, y) {
8932      *   return x + y;
8933      * }));
8934      * // => a Promise of 76
8935      */
8936     function spread(func) {
8937       if (typeof func != 'function') {
8938         throw new TypeError(FUNC_ERROR_TEXT);
8939       }
8940       return function(array) {
8941         return apply(func, this, array);
8942       };
8943     }
8944
8945     /**
8946      * Creates a throttled function that only invokes `func` at most once per
8947      * every `wait` milliseconds. The throttled function comes with a `cancel`
8948      * method to cancel delayed `func` invocations and a `flush` method to
8949      * immediately invoke them. Provide an options object to indicate whether
8950      * `func` should be invoked on the leading and/or trailing edge of the `wait`
8951      * timeout. The `func` is invoked with the last arguments provided to the
8952      * throttled function. Subsequent calls to the throttled function return the
8953      * result of the last `func` invocation.
8954      *
8955      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8956      * on the trailing edge of the timeout only if the the throttled function is
8957      * invoked more than once during the `wait` timeout.
8958      *
8959      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8960      * for details over the differences between `_.throttle` and `_.debounce`.
8961      *
8962      * @static
8963      * @memberOf _
8964      * @category Function
8965      * @param {Function} func The function to throttle.
8966      * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
8967      * @param {Object} [options] The options object.
8968      * @param {boolean} [options.leading=true] Specify invoking on the leading
8969      *  edge of the timeout.
8970      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
8971      *  edge of the timeout.
8972      * @returns {Function} Returns the new throttled function.
8973      * @example
8974      *
8975      * // avoid excessively updating the position while scrolling
8976      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
8977      *
8978      * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
8979      * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
8980      * jQuery(element).on('click', throttled);
8981      *
8982      * // cancel a trailing throttled invocation
8983      * jQuery(window).on('popstate', throttled.cancel);
8984      */
8985     function throttle(func, wait, options) {
8986       var leading = true,
8987           trailing = true;
8988
8989       if (typeof func != 'function') {
8990         throw new TypeError(FUNC_ERROR_TEXT);
8991       }
8992       if (isObject(options)) {
8993         leading = 'leading' in options ? !!options.leading : leading;
8994         trailing = 'trailing' in options ? !!options.trailing : trailing;
8995       }
8996       return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing });
8997     }
8998
8999     /**
9000      * Creates a function that accepts up to one argument, ignoring any
9001      * additional arguments.
9002      *
9003      * @static
9004      * @memberOf _
9005      * @category Function
9006      * @param {Function} func The function to cap arguments for.
9007      * @returns {Function} Returns the new function.
9008      * @example
9009      *
9010      * _.map(['6', '8', '10'], _.unary(parseInt));
9011      * // => [6, 8, 10]
9012      */
9013     function unary(func) {
9014       return ary(func, 1);
9015     }
9016
9017     /**
9018      * Creates a function that provides `value` to the wrapper function as its
9019      * first argument. Any additional arguments provided to the function are
9020      * appended to those provided to the wrapper function. The wrapper is invoked
9021      * with the `this` binding of the created function.
9022      *
9023      * @static
9024      * @memberOf _
9025      * @category Function
9026      * @param {*} value The value to wrap.
9027      * @param {Function} wrapper The wrapper function.
9028      * @returns {Function} Returns the new function.
9029      * @example
9030      *
9031      * var p = _.wrap(_.escape, function(func, text) {
9032      *   return '<p>' + func(text) + '</p>';
9033      * });
9034      *
9035      * p('fred, barney, & pebbles');
9036      * // => '<p>fred, barney, &amp; pebbles</p>'
9037      */
9038     function wrap(value, wrapper) {
9039       wrapper = wrapper == null ? identity : wrapper;
9040       return partial(wrapper, value);
9041     }
9042
9043     /*------------------------------------------------------------------------*/
9044
9045     /**
9046      * Creates a shallow clone of `value`.
9047      *
9048      * **Note:** This method is loosely based on the
9049      * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
9050      * and supports cloning arrays, array buffers, booleans, date objects, maps,
9051      * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
9052      * arrays. The own enumerable properties of `arguments` objects are cloned
9053      * as plain objects. An empty object is returned for uncloneable values such
9054      * as error objects, functions, DOM nodes, and WeakMaps.
9055      *
9056      * @static
9057      * @memberOf _
9058      * @category Lang
9059      * @param {*} value The value to clone.
9060      * @returns {*} Returns the cloned value.
9061      * @example
9062      *
9063      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9064      *
9065      * var shallow = _.clone(objects);
9066      * console.log(shallow[0] === objects[0]);
9067      * // => true
9068      */
9069     function clone(value) {
9070       return baseClone(value);
9071     }
9072
9073     /**
9074      * This method is like `_.clone` except that it accepts `customizer` which
9075      * is invoked to produce the cloned value. If `customizer` returns `undefined`
9076      * cloning is handled by the method instead. The `customizer` is invoked with
9077      * up to five arguments; (value [, index|key, object, stack]).
9078      *
9079      * @static
9080      * @memberOf _
9081      * @category Lang
9082      * @param {*} value The value to clone.
9083      * @param {Function} [customizer] The function to customize cloning.
9084      * @returns {*} Returns the cloned value.
9085      * @example
9086      *
9087      * function customizer(value) {
9088      *   if (_.isElement(value)) {
9089      *     return value.cloneNode(false);
9090      *   }
9091      * }
9092      *
9093      * var el = _.clone(document.body, customizer);
9094      *
9095      * console.log(el === document.body);
9096      * // => false
9097      * console.log(el.nodeName);
9098      * // => 'BODY'
9099      * console.log(el.childNodes.length);
9100      * // => 0
9101      */
9102     function cloneWith(value, customizer) {
9103       return baseClone(value, false, customizer);
9104     }
9105
9106     /**
9107      * This method is like `_.clone` except that it recursively clones `value`.
9108      *
9109      * @static
9110      * @memberOf _
9111      * @category Lang
9112      * @param {*} value The value to recursively clone.
9113      * @returns {*} Returns the deep cloned value.
9114      * @example
9115      *
9116      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9117      *
9118      * var deep = _.cloneDeep(objects);
9119      * console.log(deep[0] === objects[0]);
9120      * // => false
9121      */
9122     function cloneDeep(value) {
9123       return baseClone(value, true);
9124     }
9125
9126     /**
9127      * This method is like `_.cloneWith` except that it recursively clones `value`.
9128      *
9129      * @static
9130      * @memberOf _
9131      * @category Lang
9132      * @param {*} value The value to recursively clone.
9133      * @param {Function} [customizer] The function to customize cloning.
9134      * @returns {*} Returns the deep cloned value.
9135      * @example
9136      *
9137      * function customizer(value) {
9138      *   if (_.isElement(value)) {
9139      *     return value.cloneNode(true);
9140      *   }
9141      * }
9142      *
9143      * var el = _.cloneDeep(document.body, customizer);
9144      *
9145      * console.log(el === document.body);
9146      * // => false
9147      * console.log(el.nodeName);
9148      * // => 'BODY'
9149      * console.log(el.childNodes.length);
9150      * // => 20
9151      */
9152     function cloneDeepWith(value, customizer) {
9153       return baseClone(value, true, customizer);
9154     }
9155
9156     /**
9157      * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
9158      * comparison between two values to determine if they are equivalent.
9159      *
9160      * @static
9161      * @memberOf _
9162      * @category Lang
9163      * @param {*} value The value to compare.
9164      * @param {*} other The other value to compare.
9165      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9166      * @example
9167      *
9168      * var object = { 'user': 'fred' };
9169      * var other = { 'user': 'fred' };
9170      *
9171      * _.eq(object, object);
9172      * // => true
9173      *
9174      * _.eq(object, other);
9175      * // => false
9176      *
9177      * _.eq('a', 'a');
9178      * // => true
9179      *
9180      * _.eq('a', Object('a'));
9181      * // => false
9182      *
9183      * _.eq(NaN, NaN);
9184      * // => true
9185      */
9186     function eq(value, other) {
9187       return value === other || (value !== value && other !== other);
9188     }
9189
9190     /**
9191      * Checks if `value` is greater than `other`.
9192      *
9193      * @static
9194      * @memberOf _
9195      * @category Lang
9196      * @param {*} value The value to compare.
9197      * @param {*} other The other value to compare.
9198      * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
9199      * @example
9200      *
9201      * _.gt(3, 1);
9202      * // => true
9203      *
9204      * _.gt(3, 3);
9205      * // => false
9206      *
9207      * _.gt(1, 3);
9208      * // => false
9209      */
9210     function gt(value, other) {
9211       return value > other;
9212     }
9213
9214     /**
9215      * Checks if `value` is greater than or equal to `other`.
9216      *
9217      * @static
9218      * @memberOf _
9219      * @category Lang
9220      * @param {*} value The value to compare.
9221      * @param {*} other The other value to compare.
9222      * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
9223      * @example
9224      *
9225      * _.gte(3, 1);
9226      * // => true
9227      *
9228      * _.gte(3, 3);
9229      * // => true
9230      *
9231      * _.gte(1, 3);
9232      * // => false
9233      */
9234     function gte(value, other) {
9235       return value >= other;
9236     }
9237
9238     /**
9239      * Checks if `value` is likely an `arguments` object.
9240      *
9241      * @static
9242      * @memberOf _
9243      * @category Lang
9244      * @param {*} value The value to check.
9245      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9246      * @example
9247      *
9248      * _.isArguments(function() { return arguments; }());
9249      * // => true
9250      *
9251      * _.isArguments([1, 2, 3]);
9252      * // => false
9253      */
9254     function isArguments(value) {
9255       // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
9256       return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
9257         (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
9258     }
9259
9260     /**
9261      * Checks if `value` is classified as an `Array` object.
9262      *
9263      * @static
9264      * @memberOf _
9265      * @type Function
9266      * @category Lang
9267      * @param {*} value The value to check.
9268      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9269      * @example
9270      *
9271      * _.isArray([1, 2, 3]);
9272      * // => true
9273      *
9274      * _.isArray(document.body.children);
9275      * // => false
9276      *
9277      * _.isArray('abc');
9278      * // => false
9279      *
9280      * _.isArray(_.noop);
9281      * // => false
9282      */
9283     var isArray = Array.isArray;
9284
9285     /**
9286      * Checks if `value` is array-like. A value is considered array-like if it's
9287      * not a function and has a `value.length` that's an integer greater than or
9288      * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
9289      *
9290      * @static
9291      * @memberOf _
9292      * @type Function
9293      * @category Lang
9294      * @param {*} value The value to check.
9295      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
9296      * @example
9297      *
9298      * _.isArrayLike([1, 2, 3]);
9299      * // => true
9300      *
9301      * _.isArrayLike(document.body.children);
9302      * // => true
9303      *
9304      * _.isArrayLike('abc');
9305      * // => true
9306      *
9307      * _.isArrayLike(_.noop);
9308      * // => false
9309      */
9310     function isArrayLike(value) {
9311       return value != null &&
9312         !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
9313     }
9314
9315     /**
9316      * This method is like `_.isArrayLike` except that it also checks if `value`
9317      * is an object.
9318      *
9319      * @static
9320      * @memberOf _
9321      * @type Function
9322      * @category Lang
9323      * @param {*} value The value to check.
9324      * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
9325      * @example
9326      *
9327      * _.isArrayLikeObject([1, 2, 3]);
9328      * // => true
9329      *
9330      * _.isArrayLikeObject(document.body.children);
9331      * // => true
9332      *
9333      * _.isArrayLikeObject('abc');
9334      * // => false
9335      *
9336      * _.isArrayLikeObject(_.noop);
9337      * // => false
9338      */
9339     function isArrayLikeObject(value) {
9340       return isObjectLike(value) && isArrayLike(value);
9341     }
9342
9343     /**
9344      * Checks if `value` is classified as a boolean primitive or object.
9345      *
9346      * @static
9347      * @memberOf _
9348      * @category Lang
9349      * @param {*} value The value to check.
9350      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9351      * @example
9352      *
9353      * _.isBoolean(false);
9354      * // => true
9355      *
9356      * _.isBoolean(null);
9357      * // => false
9358      */
9359     function isBoolean(value) {
9360       return value === true || value === false ||
9361         (isObjectLike(value) && objectToString.call(value) == boolTag);
9362     }
9363
9364     /**
9365      * Checks if `value` is classified as a `Date` object.
9366      *
9367      * @static
9368      * @memberOf _
9369      * @category Lang
9370      * @param {*} value The value to check.
9371      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9372      * @example
9373      *
9374      * _.isDate(new Date);
9375      * // => true
9376      *
9377      * _.isDate('Mon April 23 2012');
9378      * // => false
9379      */
9380     function isDate(value) {
9381       return isObjectLike(value) && objectToString.call(value) == dateTag;
9382     }
9383
9384     /**
9385      * Checks if `value` is likely a DOM element.
9386      *
9387      * @static
9388      * @memberOf _
9389      * @category Lang
9390      * @param {*} value The value to check.
9391      * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
9392      * @example
9393      *
9394      * _.isElement(document.body);
9395      * // => true
9396      *
9397      * _.isElement('<body>');
9398      * // => false
9399      */
9400     function isElement(value) {
9401       return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
9402     }
9403
9404     /**
9405      * Checks if `value` is empty. A value is considered empty unless it's an
9406      * `arguments` object, array, string, or jQuery-like collection with a length
9407      * greater than `0` or an object with own enumerable properties.
9408      *
9409      * @static
9410      * @memberOf _
9411      * @category Lang
9412      * @param {Array|Object|string} value The value to inspect.
9413      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
9414      * @example
9415      *
9416      * _.isEmpty(null);
9417      * // => true
9418      *
9419      * _.isEmpty(true);
9420      * // => true
9421      *
9422      * _.isEmpty(1);
9423      * // => true
9424      *
9425      * _.isEmpty([1, 2, 3]);
9426      * // => false
9427      *
9428      * _.isEmpty({ 'a': 1 });
9429      * // => false
9430      */
9431     function isEmpty(value) {
9432       return (!isObjectLike(value) || isFunction(value.splice))
9433         ? !size(value)
9434         : !keys(value).length;
9435     }
9436
9437     /**
9438      * Performs a deep comparison between two values to determine if they are
9439      * equivalent.
9440      *
9441      * **Note:** This method supports comparing arrays, array buffers, booleans,
9442      * date objects, error objects, maps, numbers, `Object` objects, regexes,
9443      * sets, strings, symbols, and typed arrays. `Object` objects are compared
9444      * by their own, not inherited, enumerable properties. Functions and DOM
9445      * nodes are **not** supported.
9446      *
9447      * @static
9448      * @memberOf _
9449      * @category Lang
9450      * @param {*} value The value to compare.
9451      * @param {*} other The other value to compare.
9452      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9453      * @example
9454      *
9455      * var object = { 'user': 'fred' };
9456      * var other = { 'user': 'fred' };
9457      *
9458      * _.isEqual(object, other);
9459      * // => true
9460      *
9461      * object === other;
9462      * // => false
9463      */
9464     function isEqual(value, other) {
9465       return baseIsEqual(value, other);
9466     }
9467
9468     /**
9469      * This method is like `_.isEqual` except that it accepts `customizer` which is
9470      * invoked to compare values. If `customizer` returns `undefined` comparisons are
9471      * handled by the method instead. The `customizer` is invoked with up to seven arguments:
9472      * (objValue, othValue [, index|key, object, other, stack]).
9473      *
9474      * @static
9475      * @memberOf _
9476      * @category Lang
9477      * @param {*} value The value to compare.
9478      * @param {*} other The other value to compare.
9479      * @param {Function} [customizer] The function to customize comparisons.
9480      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9481      * @example
9482      *
9483      * function isGreeting(value) {
9484      *   return /^h(?:i|ello)$/.test(value);
9485      * }
9486      *
9487      * function customizer(objValue, othValue) {
9488      *   if (isGreeting(objValue) && isGreeting(othValue)) {
9489      *     return true;
9490      *   }
9491      * }
9492      *
9493      * var array = ['hello', 'goodbye'];
9494      * var other = ['hi', 'goodbye'];
9495      *
9496      * _.isEqualWith(array, other, customizer);
9497      * // => true
9498      */
9499     function isEqualWith(value, other, customizer) {
9500       customizer = typeof customizer == 'function' ? customizer : undefined;
9501       var result = customizer ? customizer(value, other) : undefined;
9502       return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
9503     }
9504
9505     /**
9506      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
9507      * `SyntaxError`, `TypeError`, or `URIError` object.
9508      *
9509      * @static
9510      * @memberOf _
9511      * @category Lang
9512      * @param {*} value The value to check.
9513      * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
9514      * @example
9515      *
9516      * _.isError(new Error);
9517      * // => true
9518      *
9519      * _.isError(Error);
9520      * // => false
9521      */
9522     function isError(value) {
9523       return isObjectLike(value) &&
9524         typeof value.message == 'string' && objectToString.call(value) == errorTag;
9525     }
9526
9527     /**
9528      * Checks if `value` is a finite primitive number.
9529      *
9530      * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
9531      *
9532      * @static
9533      * @memberOf _
9534      * @category Lang
9535      * @param {*} value The value to check.
9536      * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
9537      * @example
9538      *
9539      * _.isFinite(3);
9540      * // => true
9541      *
9542      * _.isFinite(Number.MAX_VALUE);
9543      * // => true
9544      *
9545      * _.isFinite(3.14);
9546      * // => true
9547      *
9548      * _.isFinite(Infinity);
9549      * // => false
9550      */
9551     function isFinite(value) {
9552       return typeof value == 'number' && nativeIsFinite(value);
9553     }
9554
9555     /**
9556      * Checks if `value` is classified as a `Function` object.
9557      *
9558      * @static
9559      * @memberOf _
9560      * @category Lang
9561      * @param {*} value The value to check.
9562      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9563      * @example
9564      *
9565      * _.isFunction(_);
9566      * // => true
9567      *
9568      * _.isFunction(/abc/);
9569      * // => false
9570      */
9571     function isFunction(value) {
9572       // The use of `Object#toString` avoids issues with the `typeof` operator
9573       // in Safari 8 which returns 'object' for typed array constructors, and
9574       // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
9575       var tag = isObject(value) ? objectToString.call(value) : '';
9576       return tag == funcTag || tag == genTag;
9577     }
9578
9579     /**
9580      * Checks if `value` is an integer.
9581      *
9582      * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
9583      *
9584      * @static
9585      * @memberOf _
9586      * @category Lang
9587      * @param {*} value The value to check.
9588      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
9589      * @example
9590      *
9591      * _.isInteger(3);
9592      * // => true
9593      *
9594      * _.isInteger(Number.MIN_VALUE);
9595      * // => false
9596      *
9597      * _.isInteger(Infinity);
9598      * // => false
9599      *
9600      * _.isInteger('3');
9601      * // => false
9602      */
9603     function isInteger(value) {
9604       return typeof value == 'number' && value == toInteger(value);
9605     }
9606
9607     /**
9608      * Checks if `value` is a valid array-like length.
9609      *
9610      * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
9611      *
9612      * @static
9613      * @memberOf _
9614      * @category Lang
9615      * @param {*} value The value to check.
9616      * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
9617      * @example
9618      *
9619      * _.isLength(3);
9620      * // => true
9621      *
9622      * _.isLength(Number.MIN_VALUE);
9623      * // => false
9624      *
9625      * _.isLength(Infinity);
9626      * // => false
9627      *
9628      * _.isLength('3');
9629      * // => false
9630      */
9631     function isLength(value) {
9632       return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
9633     }
9634
9635     /**
9636      * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
9637      * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
9638      *
9639      * @static
9640      * @memberOf _
9641      * @category Lang
9642      * @param {*} value The value to check.
9643      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
9644      * @example
9645      *
9646      * _.isObject({});
9647      * // => true
9648      *
9649      * _.isObject([1, 2, 3]);
9650      * // => true
9651      *
9652      * _.isObject(_.noop);
9653      * // => true
9654      *
9655      * _.isObject(null);
9656      * // => false
9657      */
9658     function isObject(value) {
9659       // Avoid a V8 JIT bug in Chrome 19-20.
9660       // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
9661       var type = typeof value;
9662       return !!value && (type == 'object' || type == 'function');
9663     }
9664
9665     /**
9666      * Checks if `value` is object-like. A value is object-like if it's not `null`
9667      * and has a `typeof` result of "object".
9668      *
9669      * @static
9670      * @memberOf _
9671      * @category Lang
9672      * @param {*} value The value to check.
9673      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
9674      * @example
9675      *
9676      * _.isObjectLike({});
9677      * // => true
9678      *
9679      * _.isObjectLike([1, 2, 3]);
9680      * // => true
9681      *
9682      * _.isObjectLike(_.noop);
9683      * // => false
9684      *
9685      * _.isObjectLike(null);
9686      * // => false
9687      */
9688     function isObjectLike(value) {
9689       return !!value && typeof value == 'object';
9690     }
9691
9692     /**
9693      * Performs a deep comparison between `object` and `source` to determine if
9694      * `object` contains equivalent property values.
9695      *
9696      * **Note:** This method supports comparing the same values as `_.isEqual`.
9697      *
9698      * @static
9699      * @memberOf _
9700      * @category Lang
9701      * @param {Object} object The object to inspect.
9702      * @param {Object} source The object of property values to match.
9703      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9704      * @example
9705      *
9706      * var object = { 'user': 'fred', 'age': 40 };
9707      *
9708      * _.isMatch(object, { 'age': 40 });
9709      * // => true
9710      *
9711      * _.isMatch(object, { 'age': 36 });
9712      * // => false
9713      */
9714     function isMatch(object, source) {
9715       return object === source || baseIsMatch(object, source, getMatchData(source));
9716     }
9717
9718     /**
9719      * This method is like `_.isMatch` except that it accepts `customizer` which
9720      * is invoked to compare values. If `customizer` returns `undefined` comparisons
9721      * are handled by the method instead. The `customizer` is invoked with three
9722      * arguments: (objValue, srcValue, index|key, object, source).
9723      *
9724      * @static
9725      * @memberOf _
9726      * @category Lang
9727      * @param {Object} object The object to inspect.
9728      * @param {Object} source The object of property values to match.
9729      * @param {Function} [customizer] The function to customize comparisons.
9730      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9731      * @example
9732      *
9733      * function isGreeting(value) {
9734      *   return /^h(?:i|ello)$/.test(value);
9735      * }
9736      *
9737      * function customizer(objValue, srcValue) {
9738      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
9739      *     return true;
9740      *   }
9741      * }
9742      *
9743      * var object = { 'greeting': 'hello' };
9744      * var source = { 'greeting': 'hi' };
9745      *
9746      * _.isMatchWith(object, source, customizer);
9747      * // => true
9748      */
9749     function isMatchWith(object, source, customizer) {
9750       customizer = typeof customizer == 'function' ? customizer : undefined;
9751       return baseIsMatch(object, source, getMatchData(source), customizer);
9752     }
9753
9754     /**
9755      * Checks if `value` is `NaN`.
9756      *
9757      * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
9758      * which returns `true` for `undefined` and other non-numeric values.
9759      *
9760      * @static
9761      * @memberOf _
9762      * @category Lang
9763      * @param {*} value The value to check.
9764      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
9765      * @example
9766      *
9767      * _.isNaN(NaN);
9768      * // => true
9769      *
9770      * _.isNaN(new Number(NaN));
9771      * // => true
9772      *
9773      * isNaN(undefined);
9774      * // => true
9775      *
9776      * _.isNaN(undefined);
9777      * // => false
9778      */
9779     function isNaN(value) {
9780       // An `NaN` primitive is the only value that is not equal to itself.
9781       // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
9782       return isNumber(value) && value != +value;
9783     }
9784
9785     /**
9786      * Checks if `value` is a native function.
9787      *
9788      * @static
9789      * @memberOf _
9790      * @category Lang
9791      * @param {*} value The value to check.
9792      * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
9793      * @example
9794      *
9795      * _.isNative(Array.prototype.push);
9796      * // => true
9797      *
9798      * _.isNative(_);
9799      * // => false
9800      */
9801     function isNative(value) {
9802       if (value == null) {
9803         return false;
9804       }
9805       if (isFunction(value)) {
9806         return reIsNative.test(funcToString.call(value));
9807       }
9808       return isObjectLike(value) &&
9809         (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
9810     }
9811
9812     /**
9813      * Checks if `value` is `null`.
9814      *
9815      * @static
9816      * @memberOf _
9817      * @category Lang
9818      * @param {*} value The value to check.
9819      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
9820      * @example
9821      *
9822      * _.isNull(null);
9823      * // => true
9824      *
9825      * _.isNull(void 0);
9826      * // => false
9827      */
9828     function isNull(value) {
9829       return value === null;
9830     }
9831
9832     /**
9833      * Checks if `value` is `null` or `undefined`.
9834      *
9835      * @static
9836      * @memberOf _
9837      * @category Lang
9838      * @param {*} value The value to check.
9839      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
9840      * @example
9841      *
9842      * _.isNil(null);
9843      * // => true
9844      *
9845      * _.isNil(void 0);
9846      * // => true
9847      *
9848      * _.isNil(NaN);
9849      * // => false
9850      */
9851     function isNil(value) {
9852       return value == null;
9853     }
9854
9855     /**
9856      * Checks if `value` is classified as a `Number` primitive or object.
9857      *
9858      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
9859      * as numbers, use the `_.isFinite` method.
9860      *
9861      * @static
9862      * @memberOf _
9863      * @category Lang
9864      * @param {*} value The value to check.
9865      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9866      * @example
9867      *
9868      * _.isNumber(3);
9869      * // => true
9870      *
9871      * _.isNumber(Number.MIN_VALUE);
9872      * // => true
9873      *
9874      * _.isNumber(Infinity);
9875      * // => true
9876      *
9877      * _.isNumber('3');
9878      * // => false
9879      */
9880     function isNumber(value) {
9881       return typeof value == 'number' ||
9882         (isObjectLike(value) && objectToString.call(value) == numberTag);
9883     }
9884
9885     /**
9886      * Checks if `value` is a plain object, that is, an object created by the
9887      * `Object` constructor or one with a `[[Prototype]]` of `null`.
9888      *
9889      * @static
9890      * @memberOf _
9891      * @category Lang
9892      * @param {*} value The value to check.
9893      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
9894      * @example
9895      *
9896      * function Foo() {
9897      *   this.a = 1;
9898      * }
9899      *
9900      * _.isPlainObject(new Foo);
9901      * // => false
9902      *
9903      * _.isPlainObject([1, 2, 3]);
9904      * // => false
9905      *
9906      * _.isPlainObject({ 'x': 0, 'y': 0 });
9907      * // => true
9908      *
9909      * _.isPlainObject(Object.create(null));
9910      * // => true
9911      */
9912     function isPlainObject(value) {
9913       if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
9914         return false;
9915       }
9916       var proto = objectProto;
9917       if (typeof value.constructor == 'function') {
9918         proto = getPrototypeOf(value);
9919       }
9920       if (proto === null) {
9921         return true;
9922       }
9923       var Ctor = proto.constructor;
9924       return (typeof Ctor == 'function' &&
9925         Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
9926     }
9927
9928     /**
9929      * Checks if `value` is classified as a `RegExp` object.
9930      *
9931      * @static
9932      * @memberOf _
9933      * @category Lang
9934      * @param {*} value The value to check.
9935      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9936      * @example
9937      *
9938      * _.isRegExp(/abc/);
9939      * // => true
9940      *
9941      * _.isRegExp('/abc/');
9942      * // => false
9943      */
9944     function isRegExp(value) {
9945       return isObject(value) && objectToString.call(value) == regexpTag;
9946     }
9947
9948     /**
9949      * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
9950      * double precision number which isn't the result of a rounded unsafe integer.
9951      *
9952      * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
9953      *
9954      * @static
9955      * @memberOf _
9956      * @category Lang
9957      * @param {*} value The value to check.
9958      * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
9959      * @example
9960      *
9961      * _.isSafeInteger(3);
9962      * // => true
9963      *
9964      * _.isSafeInteger(Number.MIN_VALUE);
9965      * // => false
9966      *
9967      * _.isSafeInteger(Infinity);
9968      * // => false
9969      *
9970      * _.isSafeInteger('3');
9971      * // => false
9972      */
9973     function isSafeInteger(value) {
9974       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
9975     }
9976
9977     /**
9978      * Checks if `value` is classified as a `String` primitive or object.
9979      *
9980      * @static
9981      * @memberOf _
9982      * @category Lang
9983      * @param {*} value The value to check.
9984      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9985      * @example
9986      *
9987      * _.isString('abc');
9988      * // => true
9989      *
9990      * _.isString(1);
9991      * // => false
9992      */
9993     function isString(value) {
9994       return typeof value == 'string' ||
9995         (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
9996     }
9997
9998     /**
9999      * Checks if `value` is classified as a `Symbol` primitive or object.
10000      *
10001      * @static
10002      * @memberOf _
10003      * @category Lang
10004      * @param {*} value The value to check.
10005      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10006      * @example
10007      *
10008      * _.isSymbol(Symbol.iterator);
10009      * // => true
10010      *
10011      * _.isSymbol('abc');
10012      * // => false
10013      */
10014     function isSymbol(value) {
10015       return typeof value == 'symbol' ||
10016         (isObjectLike(value) && objectToString.call(value) == symbolTag);
10017     }
10018
10019     /**
10020      * Checks if `value` is classified as a typed array.
10021      *
10022      * @static
10023      * @memberOf _
10024      * @category Lang
10025      * @param {*} value The value to check.
10026      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10027      * @example
10028      *
10029      * _.isTypedArray(new Uint8Array);
10030      * // => true
10031      *
10032      * _.isTypedArray([]);
10033      * // => false
10034      */
10035     function isTypedArray(value) {
10036       return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
10037     }
10038
10039     /**
10040      * Checks if `value` is `undefined`.
10041      *
10042      * @static
10043      * @memberOf _
10044      * @category Lang
10045      * @param {*} value The value to check.
10046      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
10047      * @example
10048      *
10049      * _.isUndefined(void 0);
10050      * // => true
10051      *
10052      * _.isUndefined(null);
10053      * // => false
10054      */
10055     function isUndefined(value) {
10056       return value === undefined;
10057     }
10058
10059     /**
10060      * Checks if `value` is less than `other`.
10061      *
10062      * @static
10063      * @memberOf _
10064      * @category Lang
10065      * @param {*} value The value to compare.
10066      * @param {*} other The other value to compare.
10067      * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
10068      * @example
10069      *
10070      * _.lt(1, 3);
10071      * // => true
10072      *
10073      * _.lt(3, 3);
10074      * // => false
10075      *
10076      * _.lt(3, 1);
10077      * // => false
10078      */
10079     function lt(value, other) {
10080       return value < other;
10081     }
10082
10083     /**
10084      * Checks if `value` is less than or equal to `other`.
10085      *
10086      * @static
10087      * @memberOf _
10088      * @category Lang
10089      * @param {*} value The value to compare.
10090      * @param {*} other The other value to compare.
10091      * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
10092      * @example
10093      *
10094      * _.lte(1, 3);
10095      * // => true
10096      *
10097      * _.lte(3, 3);
10098      * // => true
10099      *
10100      * _.lte(3, 1);
10101      * // => false
10102      */
10103     function lte(value, other) {
10104       return value <= other;
10105     }
10106
10107     /**
10108      * Converts `value` to an array.
10109      *
10110      * @static
10111      * @memberOf _
10112      * @category Lang
10113      * @param {*} value The value to convert.
10114      * @returns {Array} Returns the converted array.
10115      * @example
10116      *
10117      * _.toArray({ 'a': 1, 'b': 2 });
10118      * // => [1, 2]
10119      *
10120      * _.toArray('abc');
10121      * // => ['a', 'b', 'c']
10122      *
10123      * _.toArray(1);
10124      * // => []
10125      *
10126      * _.toArray(null);
10127      * // => []
10128      */
10129     function toArray(value) {
10130       if (!value) {
10131         return [];
10132       }
10133       if (isArrayLike(value)) {
10134         return isString(value) ? stringToArray(value) : copyArray(value);
10135       }
10136       if (iteratorSymbol && value[iteratorSymbol]) {
10137         return iteratorToArray(value[iteratorSymbol]());
10138       }
10139       var tag = getTag(value),
10140           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
10141
10142       return func(value);
10143     }
10144
10145     /**
10146      * Converts `value` to an integer.
10147      *
10148      * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
10149      *
10150      * @static
10151      * @memberOf _
10152      * @category Lang
10153      * @param {*} value The value to convert.
10154      * @returns {number} Returns the converted integer.
10155      * @example
10156      *
10157      * _.toInteger(3);
10158      * // => 3
10159      *
10160      * _.toInteger(Number.MIN_VALUE);
10161      * // => 0
10162      *
10163      * _.toInteger(Infinity);
10164      * // => 1.7976931348623157e+308
10165      *
10166      * _.toInteger('3');
10167      * // => 3
10168      */
10169     function toInteger(value) {
10170       if (!value) {
10171         return value === 0 ? value : 0;
10172       }
10173       value = toNumber(value);
10174       if (value === INFINITY || value === -INFINITY) {
10175         var sign = (value < 0 ? -1 : 1);
10176         return sign * MAX_INTEGER;
10177       }
10178       var remainder = value % 1;
10179       return value === value ? (remainder ? value - remainder : value) : 0;
10180     }
10181
10182     /**
10183      * Converts `value` to an integer suitable for use as the length of an
10184      * array-like object.
10185      *
10186      * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10187      *
10188      * @static
10189      * @memberOf _
10190      * @category Lang
10191      * @param {*} value The value to convert.
10192      * @return {number} Returns the converted integer.
10193      * @example
10194      *
10195      * _.toLength(3);
10196      * // => 3
10197      *
10198      * _.toLength(Number.MIN_VALUE);
10199      * // => 0
10200      *
10201      * _.toLength(Infinity);
10202      * // => 4294967295
10203      *
10204      * _.toLength('3');
10205      * // => 3
10206      */
10207     function toLength(value) {
10208       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
10209     }
10210
10211     /**
10212      * Converts `value` to a number.
10213      *
10214      * @static
10215      * @memberOf _
10216      * @category Lang
10217      * @param {*} value The value to process.
10218      * @returns {number} Returns the number.
10219      * @example
10220      *
10221      * _.toNumber(3);
10222      * // => 3
10223      *
10224      * _.toNumber(Number.MIN_VALUE);
10225      * // => 5e-324
10226      *
10227      * _.toNumber(Infinity);
10228      * // => Infinity
10229      *
10230      * _.toNumber('3');
10231      * // => 3
10232      */
10233     function toNumber(value) {
10234       if (isObject(value)) {
10235         var other = isFunction(value.valueOf) ? value.valueOf() : value;
10236         value = isObject(other) ? (other + '') : other;
10237       }
10238       if (typeof value != 'string') {
10239         return value === 0 ? value : +value;
10240       }
10241       value = value.replace(reTrim, '');
10242       var isBinary = reIsBinary.test(value);
10243       return (isBinary || reIsOctal.test(value))
10244         ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
10245         : (reIsBadHex.test(value) ? NAN : +value);
10246     }
10247
10248     /**
10249      * Converts `value` to a plain object flattening inherited enumerable
10250      * properties of `value` to own properties of the plain object.
10251      *
10252      * @static
10253      * @memberOf _
10254      * @category Lang
10255      * @param {*} value The value to convert.
10256      * @returns {Object} Returns the converted plain object.
10257      * @example
10258      *
10259      * function Foo() {
10260      *   this.b = 2;
10261      * }
10262      *
10263      * Foo.prototype.c = 3;
10264      *
10265      * _.assign({ 'a': 1 }, new Foo);
10266      * // => { 'a': 1, 'b': 2 }
10267      *
10268      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
10269      * // => { 'a': 1, 'b': 2, 'c': 3 }
10270      */
10271     function toPlainObject(value) {
10272       return copyObject(value, keysIn(value));
10273     }
10274
10275     /**
10276      * Converts `value` to a safe integer. A safe integer can be compared and
10277      * represented correctly.
10278      *
10279      * @static
10280      * @memberOf _
10281      * @category Lang
10282      * @param {*} value The value to convert.
10283      * @returns {number} Returns the converted integer.
10284      * @example
10285      *
10286      * _.toSafeInteger(3);
10287      * // => 3
10288      *
10289      * _.toSafeInteger(Number.MIN_VALUE);
10290      * // => 0
10291      *
10292      * _.toSafeInteger(Infinity);
10293      * // => 9007199254740991
10294      *
10295      * _.toSafeInteger('3');
10296      * // => 3
10297      */
10298     function toSafeInteger(value) {
10299       return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
10300     }
10301
10302     /**
10303      * Converts `value` to a string if it's not one. An empty string is returned
10304      * for `null` and `undefined` values. The sign of `-0` is preserved.
10305      *
10306      * @static
10307      * @memberOf _
10308      * @category Lang
10309      * @param {*} value The value to process.
10310      * @returns {string} Returns the string.
10311      * @example
10312      *
10313      * _.toString(null);
10314      * // => ''
10315      *
10316      * _.toString(-0);
10317      * // => '-0'
10318      *
10319      * _.toString([1, 2, 3]);
10320      * // => '1,2,3'
10321      */
10322     function toString(value) {
10323       // Exit early for strings to avoid a performance hit in some environments.
10324       if (typeof value == 'string') {
10325         return value;
10326       }
10327       if (value == null) {
10328         return '';
10329       }
10330       if (isSymbol(value)) {
10331         return _Symbol ? symbolToString.call(value) : '';
10332       }
10333       var result = (value + '');
10334       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
10335     }
10336
10337     /*------------------------------------------------------------------------*/
10338
10339     /**
10340      * Assigns own enumerable properties of source objects to the destination
10341      * object. Source objects are applied from left to right. Subsequent sources
10342      * overwrite property assignments of previous sources.
10343      *
10344      * **Note:** This method mutates `object` and is loosely based on
10345      * [`Object.assign`](https://mdn.io/Object/assign).
10346      *
10347      * @static
10348      * @memberOf _
10349      * @category Object
10350      * @param {Object} object The destination object.
10351      * @param {...Object} [sources] The source objects.
10352      * @returns {Object} Returns `object`.
10353      * @example
10354      *
10355      * function Foo() {
10356      *   this.c = 3;
10357      * }
10358      *
10359      * function Bar() {
10360      *   this.e = 5;
10361      * }
10362      *
10363      * Foo.prototype.d = 4;
10364      * Bar.prototype.f = 6;
10365      *
10366      * _.assign({ 'a': 1 }, new Foo, new Bar);
10367      * // => { 'a': 1, 'c': 3, 'e': 5 }
10368      */
10369     var assign = createAssigner(function(object, source) {
10370       copyObject(source, keys(source), object);
10371     });
10372
10373     /**
10374      * This method is like `_.assign` except that it iterates over own and
10375      * inherited source properties.
10376      *
10377      * **Note:** This method mutates `object`.
10378      *
10379      * @static
10380      * @memberOf _
10381      * @alias extend
10382      * @category Object
10383      * @param {Object} object The destination object.
10384      * @param {...Object} [sources] The source objects.
10385      * @returns {Object} Returns `object`.
10386      * @example
10387      *
10388      * function Foo() {
10389      *   this.b = 2;
10390      * }
10391      *
10392      * function Bar() {
10393      *   this.d = 4;
10394      * }
10395      *
10396      * Foo.prototype.c = 3;
10397      * Bar.prototype.e = 5;
10398      *
10399      * _.assignIn({ 'a': 1 }, new Foo, new Bar);
10400      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
10401      */
10402     var assignIn = createAssigner(function(object, source) {
10403       copyObject(source, keysIn(source), object);
10404     });
10405
10406     /**
10407      * This method is like `_.assignIn` except that it accepts `customizer` which
10408      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10409      * assignment is handled by the method instead. The `customizer` is invoked
10410      * with five arguments: (objValue, srcValue, key, object, source).
10411      *
10412      * **Note:** This method mutates `object`.
10413      *
10414      * @static
10415      * @memberOf _
10416      * @alias extendWith
10417      * @category Object
10418      * @param {Object} object The destination object.
10419      * @param {...Object} sources The source objects.
10420      * @param {Function} [customizer] The function to customize assigned values.
10421      * @returns {Object} Returns `object`.
10422      * @example
10423      *
10424      * function customizer(objValue, srcValue) {
10425      *   return _.isUndefined(objValue) ? srcValue : objValue;
10426      * }
10427      *
10428      * var defaults = _.partialRight(_.assignInWith, customizer);
10429      *
10430      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10431      * // => { 'a': 1, 'b': 2 }
10432      */
10433     var assignInWith = createAssigner(function(object, source, customizer) {
10434       copyObjectWith(source, keysIn(source), object, customizer);
10435     });
10436
10437     /**
10438      * This method is like `_.assign` except that it accepts `customizer` which
10439      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10440      * assignment is handled by the method instead. The `customizer` is invoked
10441      * with five arguments: (objValue, srcValue, key, object, source).
10442      *
10443      * **Note:** This method mutates `object`.
10444      *
10445      * @static
10446      * @memberOf _
10447      * @category Object
10448      * @param {Object} object The destination object.
10449      * @param {...Object} sources The source objects.
10450      * @param {Function} [customizer] The function to customize assigned values.
10451      * @returns {Object} Returns `object`.
10452      * @example
10453      *
10454      * function customizer(objValue, srcValue) {
10455      *   return _.isUndefined(objValue) ? srcValue : objValue;
10456      * }
10457      *
10458      * var defaults = _.partialRight(_.assignWith, customizer);
10459      *
10460      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10461      * // => { 'a': 1, 'b': 2 }
10462      */
10463     var assignWith = createAssigner(function(object, source, customizer) {
10464       copyObjectWith(source, keys(source), object, customizer);
10465     });
10466
10467     /**
10468      * Creates an array of values corresponding to `paths` of `object`.
10469      *
10470      * @static
10471      * @memberOf _
10472      * @category Object
10473      * @param {Object} object The object to iterate over.
10474      * @param {...(string|string[])} [paths] The property paths of elements to pick,
10475      *  specified individually or in arrays.
10476      * @returns {Array} Returns the new array of picked elements.
10477      * @example
10478      *
10479      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
10480      *
10481      * _.at(object, ['a[0].b.c', 'a[1]']);
10482      * // => [3, 4]
10483      *
10484      * _.at(['a', 'b', 'c'], 0, 2);
10485      * // => ['a', 'c']
10486      */
10487     var at = rest(function(object, paths) {
10488       return baseAt(object, baseFlatten(paths));
10489     });
10490
10491     /**
10492      * Creates an object that inherits from the `prototype` object. If a `properties`
10493      * object is provided its own enumerable properties are assigned to the created object.
10494      *
10495      * @static
10496      * @memberOf _
10497      * @category Object
10498      * @param {Object} prototype The object to inherit from.
10499      * @param {Object} [properties] The properties to assign to the object.
10500      * @returns {Object} Returns the new object.
10501      * @example
10502      *
10503      * function Shape() {
10504      *   this.x = 0;
10505      *   this.y = 0;
10506      * }
10507      *
10508      * function Circle() {
10509      *   Shape.call(this);
10510      * }
10511      *
10512      * Circle.prototype = _.create(Shape.prototype, {
10513      *   'constructor': Circle
10514      * });
10515      *
10516      * var circle = new Circle;
10517      * circle instanceof Circle;
10518      * // => true
10519      *
10520      * circle instanceof Shape;
10521      * // => true
10522      */
10523     function create(prototype, properties) {
10524       var result = baseCreate(prototype);
10525       return properties ? baseAssign(result, properties) : result;
10526     }
10527
10528     /**
10529      * Assigns own and inherited enumerable properties of source objects to the
10530      * destination object for all destination properties that resolve to `undefined`.
10531      * Source objects are applied from left to right. Once a property is set,
10532      * additional values of the same property are ignored.
10533      *
10534      * **Note:** This method mutates `object`.
10535      *
10536      * @static
10537      * @memberOf _
10538      * @category Object
10539      * @param {Object} object The destination object.
10540      * @param {...Object} [sources] The source objects.
10541      * @returns {Object} Returns `object`.
10542      * @example
10543      *
10544      * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
10545      * // => { 'user': 'barney', 'age': 36 }
10546      */
10547     var defaults = rest(function(args) {
10548       args.push(undefined, assignInDefaults);
10549       return apply(assignInWith, undefined, args);
10550     });
10551
10552     /**
10553      * This method is like `_.defaults` except that it recursively assigns
10554      * default properties.
10555      *
10556      * **Note:** This method mutates `object`.
10557      *
10558      * @static
10559      * @memberOf _
10560      * @category Object
10561      * @param {Object} object The destination object.
10562      * @param {...Object} [sources] The source objects.
10563      * @returns {Object} Returns `object`.
10564      * @example
10565      *
10566      * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
10567      * // => { 'user': { 'name': 'barney', 'age': 36 } }
10568      *
10569      */
10570     var defaultsDeep = rest(function(args) {
10571       args.push(undefined, mergeDefaults);
10572       return apply(mergeWith, undefined, args);
10573     });
10574
10575     /**
10576      * This method is like `_.find` except that it returns the key of the first
10577      * element `predicate` returns truthy for instead of the element itself.
10578      *
10579      * @static
10580      * @memberOf _
10581      * @category Object
10582      * @param {Object} object The object to search.
10583      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10584      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10585      * @example
10586      *
10587      * var users = {
10588      *   'barney':  { 'age': 36, 'active': true },
10589      *   'fred':    { 'age': 40, 'active': false },
10590      *   'pebbles': { 'age': 1,  'active': true }
10591      * };
10592      *
10593      * _.findKey(users, function(o) { return o.age < 40; });
10594      * // => 'barney' (iteration order is not guaranteed)
10595      *
10596      * // using the `_.matches` iteratee shorthand
10597      * _.findKey(users, { 'age': 1, 'active': true });
10598      * // => 'pebbles'
10599      *
10600      * // using the `_.matchesProperty` iteratee shorthand
10601      * _.findKey(users, ['active', false]);
10602      * // => 'fred'
10603      *
10604      * // using the `_.property` iteratee shorthand
10605      * _.findKey(users, 'active');
10606      * // => 'barney'
10607      */
10608     function findKey(object, predicate) {
10609       return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
10610     }
10611
10612     /**
10613      * This method is like `_.findKey` except that it iterates over elements of
10614      * a collection in the opposite order.
10615      *
10616      * @static
10617      * @memberOf _
10618      * @category Object
10619      * @param {Object} object The object to search.
10620      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10621      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10622      * @example
10623      *
10624      * var users = {
10625      *   'barney':  { 'age': 36, 'active': true },
10626      *   'fred':    { 'age': 40, 'active': false },
10627      *   'pebbles': { 'age': 1,  'active': true }
10628      * };
10629      *
10630      * _.findLastKey(users, function(o) { return o.age < 40; });
10631      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
10632      *
10633      * // using the `_.matches` iteratee shorthand
10634      * _.findLastKey(users, { 'age': 36, 'active': true });
10635      * // => 'barney'
10636      *
10637      * // using the `_.matchesProperty` iteratee shorthand
10638      * _.findLastKey(users, ['active', false]);
10639      * // => 'fred'
10640      *
10641      * // using the `_.property` iteratee shorthand
10642      * _.findLastKey(users, 'active');
10643      * // => 'pebbles'
10644      */
10645     function findLastKey(object, predicate) {
10646       return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
10647     }
10648
10649     /**
10650      * Iterates over own and inherited enumerable properties of an object invoking
10651      * `iteratee` for each property. The iteratee is invoked with three arguments:
10652      * (value, key, object). Iteratee functions may exit iteration early by explicitly
10653      * returning `false`.
10654      *
10655      * @static
10656      * @memberOf _
10657      * @category Object
10658      * @param {Object} object The object to iterate over.
10659      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10660      * @returns {Object} Returns `object`.
10661      * @example
10662      *
10663      * function Foo() {
10664      *   this.a = 1;
10665      *   this.b = 2;
10666      * }
10667      *
10668      * Foo.prototype.c = 3;
10669      *
10670      * _.forIn(new Foo, function(value, key) {
10671      *   console.log(key);
10672      * });
10673      * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
10674      */
10675     function forIn(object, iteratee) {
10676       return object == null ? object : baseFor(object, toFunction(iteratee), keysIn);
10677     }
10678
10679     /**
10680      * This method is like `_.forIn` except that it iterates over properties of
10681      * `object` in the opposite order.
10682      *
10683      * @static
10684      * @memberOf _
10685      * @category Object
10686      * @param {Object} object The object to iterate over.
10687      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10688      * @returns {Object} Returns `object`.
10689      * @example
10690      *
10691      * function Foo() {
10692      *   this.a = 1;
10693      *   this.b = 2;
10694      * }
10695      *
10696      * Foo.prototype.c = 3;
10697      *
10698      * _.forInRight(new Foo, function(value, key) {
10699      *   console.log(key);
10700      * });
10701      * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
10702      */
10703     function forInRight(object, iteratee) {
10704       return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn);
10705     }
10706
10707     /**
10708      * Iterates over own enumerable properties of an object invoking `iteratee`
10709      * for each property. The iteratee is invoked with three arguments:
10710      * (value, key, object). Iteratee functions may exit iteration early by
10711      * explicitly returning `false`.
10712      *
10713      * @static
10714      * @memberOf _
10715      * @category Object
10716      * @param {Object} object The object to iterate over.
10717      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10718      * @returns {Object} Returns `object`.
10719      * @example
10720      *
10721      * function Foo() {
10722      *   this.a = 1;
10723      *   this.b = 2;
10724      * }
10725      *
10726      * Foo.prototype.c = 3;
10727      *
10728      * _.forOwn(new Foo, function(value, key) {
10729      *   console.log(key);
10730      * });
10731      * // => logs 'a' then 'b' (iteration order is not guaranteed)
10732      */
10733     function forOwn(object, iteratee) {
10734       return object && baseForOwn(object, toFunction(iteratee));
10735     }
10736
10737     /**
10738      * This method is like `_.forOwn` except that it iterates over properties of
10739      * `object` in the opposite order.
10740      *
10741      * @static
10742      * @memberOf _
10743      * @category Object
10744      * @param {Object} object The object to iterate over.
10745      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10746      * @returns {Object} Returns `object`.
10747      * @example
10748      *
10749      * function Foo() {
10750      *   this.a = 1;
10751      *   this.b = 2;
10752      * }
10753      *
10754      * Foo.prototype.c = 3;
10755      *
10756      * _.forOwnRight(new Foo, function(value, key) {
10757      *   console.log(key);
10758      * });
10759      * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
10760      */
10761     function forOwnRight(object, iteratee) {
10762       return object && baseForOwnRight(object, toFunction(iteratee));
10763     }
10764
10765     /**
10766      * Creates an array of function property names from own enumerable properties
10767      * of `object`.
10768      *
10769      * @static
10770      * @memberOf _
10771      * @category Object
10772      * @param {Object} object The object to inspect.
10773      * @returns {Array} Returns the new array of property names.
10774      * @example
10775      *
10776      * function Foo() {
10777      *   this.a = _.constant('a');
10778      *   this.b = _.constant('b');
10779      * }
10780      *
10781      * Foo.prototype.c = _.constant('c');
10782      *
10783      * _.functions(new Foo);
10784      * // => ['a', 'b']
10785      */
10786     function functions(object) {
10787       return object == null ? [] : baseFunctions(object, keys(object));
10788     }
10789
10790     /**
10791      * Creates an array of function property names from own and inherited
10792      * enumerable properties of `object`.
10793      *
10794      * @static
10795      * @memberOf _
10796      * @category Object
10797      * @param {Object} object The object to inspect.
10798      * @returns {Array} Returns the new array of property names.
10799      * @example
10800      *
10801      * function Foo() {
10802      *   this.a = _.constant('a');
10803      *   this.b = _.constant('b');
10804      * }
10805      *
10806      * Foo.prototype.c = _.constant('c');
10807      *
10808      * _.functionsIn(new Foo);
10809      * // => ['a', 'b', 'c']
10810      */
10811     function functionsIn(object) {
10812       return object == null ? [] : baseFunctions(object, keysIn(object));
10813     }
10814
10815     /**
10816      * Gets the value at `path` of `object`. If the resolved value is
10817      * `undefined` the `defaultValue` is used in its place.
10818      *
10819      * @static
10820      * @memberOf _
10821      * @category Object
10822      * @param {Object} object The object to query.
10823      * @param {Array|string} path The path of the property to get.
10824      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
10825      * @returns {*} Returns the resolved value.
10826      * @example
10827      *
10828      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
10829      *
10830      * _.get(object, 'a[0].b.c');
10831      * // => 3
10832      *
10833      * _.get(object, ['a', '0', 'b', 'c']);
10834      * // => 3
10835      *
10836      * _.get(object, 'a.b.c', 'default');
10837      * // => 'default'
10838      */
10839     function get(object, path, defaultValue) {
10840       var result = object == null ? undefined : baseGet(object, path);
10841       return result === undefined ? defaultValue : result;
10842     }
10843
10844     /**
10845      * Checks if `path` is a direct property of `object`.
10846      *
10847      * @static
10848      * @memberOf _
10849      * @category Object
10850      * @param {Object} object The object to query.
10851      * @param {Array|string} path The path to check.
10852      * @returns {boolean} Returns `true` if `path` exists, else `false`.
10853      * @example
10854      *
10855      * var object = { 'a': { 'b': { 'c': 3 } } };
10856      * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
10857      *
10858      * _.has(object, 'a');
10859      * // => true
10860      *
10861      * _.has(object, 'a.b.c');
10862      * // => true
10863      *
10864      * _.has(object, ['a', 'b', 'c']);
10865      * // => true
10866      *
10867      * _.has(other, 'a');
10868      * // => false
10869      */
10870     function has(object, path) {
10871       return hasPath(object, path, baseHas);
10872     }
10873
10874     /**
10875      * Checks if `path` is a direct or inherited property of `object`.
10876      *
10877      * @static
10878      * @memberOf _
10879      * @category Object
10880      * @param {Object} object The object to query.
10881      * @param {Array|string} path The path to check.
10882      * @returns {boolean} Returns `true` if `path` exists, else `false`.
10883      * @example
10884      *
10885      * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
10886      *
10887      * _.hasIn(object, 'a');
10888      * // => true
10889      *
10890      * _.hasIn(object, 'a.b.c');
10891      * // => true
10892      *
10893      * _.hasIn(object, ['a', 'b', 'c']);
10894      * // => true
10895      *
10896      * _.hasIn(object, 'b');
10897      * // => false
10898      */
10899     function hasIn(object, path) {
10900       return hasPath(object, path, baseHasIn);
10901     }
10902
10903     /**
10904      * Creates an object composed of the inverted keys and values of `object`.
10905      * If `object` contains duplicate values, subsequent values overwrite property
10906      * assignments of previous values unless `multiVal` is `true`.
10907      *
10908      * @static
10909      * @memberOf _
10910      * @category Object
10911      * @param {Object} object The object to invert.
10912      * @param {boolean} [multiVal] Allow multiple values per key.
10913      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
10914      * @returns {Object} Returns the new inverted object.
10915      * @example
10916      *
10917      * var object = { 'a': 1, 'b': 2, 'c': 1 };
10918      *
10919      * _.invert(object);
10920      * // => { '1': 'c', '2': 'b' }
10921      *
10922      * // with `multiVal`
10923      * _.invert(object, true);
10924      * // => { '1': ['a', 'c'], '2': ['b'] }
10925      */
10926     function invert(object, multiVal, guard) {
10927       return arrayReduce(keys(object), function(result, key) {
10928         var value = object[key];
10929         if (multiVal && !guard) {
10930           if (hasOwnProperty.call(result, value)) {
10931             result[value].push(key);
10932           } else {
10933             result[value] = [key];
10934           }
10935         }
10936         else {
10937           result[value] = key;
10938         }
10939         return result;
10940       }, {});
10941     }
10942
10943     /**
10944      * Invokes the method at `path` of `object`.
10945      *
10946      * @static
10947      * @memberOf _
10948      * @category Object
10949      * @param {Object} object The object to query.
10950      * @param {Array|string} path The path of the method to invoke.
10951      * @param {...*} [args] The arguments to invoke the method with.
10952      * @returns {*} Returns the result of the invoked method.
10953      * @example
10954      *
10955      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
10956      *
10957      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
10958      * // => [2, 3]
10959      */
10960     var invoke = rest(baseInvoke);
10961
10962     /**
10963      * Creates an array of the own enumerable property names of `object`.
10964      *
10965      * **Note:** Non-object values are coerced to objects. See the
10966      * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
10967      * for more details.
10968      *
10969      * @static
10970      * @memberOf _
10971      * @category Object
10972      * @param {Object} object The object to query.
10973      * @returns {Array} Returns the array of property names.
10974      * @example
10975      *
10976      * function Foo() {
10977      *   this.a = 1;
10978      *   this.b = 2;
10979      * }
10980      *
10981      * Foo.prototype.c = 3;
10982      *
10983      * _.keys(new Foo);
10984      * // => ['a', 'b'] (iteration order is not guaranteed)
10985      *
10986      * _.keys('hi');
10987      * // => ['0', '1']
10988      */
10989     function keys(object) {
10990       var isProto = isPrototype(object);
10991       if (!(isProto || isArrayLike(object))) {
10992         return baseKeys(object);
10993       }
10994       var indexes = indexKeys(object),
10995           skipIndexes = !!indexes,
10996           result = indexes || [],
10997           length = result.length;
10998
10999       for (var key in object) {
11000         if (baseHas(object, key) &&
11001             !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11002             !(isProto && key == 'constructor')) {
11003           result.push(key);
11004         }
11005       }
11006       return result;
11007     }
11008
11009     /**
11010      * Creates an array of the own and inherited enumerable property names of `object`.
11011      *
11012      * **Note:** Non-object values are coerced to objects.
11013      *
11014      * @static
11015      * @memberOf _
11016      * @category Object
11017      * @param {Object} object The object to query.
11018      * @returns {Array} Returns the array of property names.
11019      * @example
11020      *
11021      * function Foo() {
11022      *   this.a = 1;
11023      *   this.b = 2;
11024      * }
11025      *
11026      * Foo.prototype.c = 3;
11027      *
11028      * _.keysIn(new Foo);
11029      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
11030      */
11031     function keysIn(object) {
11032       var index = -1,
11033           isProto = isPrototype(object),
11034           props = baseKeysIn(object),
11035           propsLength = props.length,
11036           indexes = indexKeys(object),
11037           skipIndexes = !!indexes,
11038           result = indexes || [],
11039           length = result.length;
11040
11041       while (++index < propsLength) {
11042         var key = props[index];
11043         if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11044             !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
11045           result.push(key);
11046         }
11047       }
11048       return result;
11049     }
11050
11051     /**
11052      * The opposite of `_.mapValues`; this method creates an object with the
11053      * same values as `object` and keys generated by running each own enumerable
11054      * property of `object` through `iteratee`.
11055      *
11056      * @static
11057      * @memberOf _
11058      * @category Object
11059      * @param {Object} object The object to iterate over.
11060      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11061      * @returns {Object} Returns the new mapped object.
11062      * @example
11063      *
11064      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
11065      *   return key + value;
11066      * });
11067      * // => { 'a1': 1, 'b2': 2 }
11068      */
11069     function mapKeys(object, iteratee) {
11070       var result = {};
11071       iteratee = getIteratee(iteratee, 3);
11072
11073       baseForOwn(object, function(value, key, object) {
11074         result[iteratee(value, key, object)] = value;
11075       });
11076       return result;
11077     }
11078
11079     /**
11080      * Creates an object with the same keys as `object` and values generated by
11081      * running each own enumerable property of `object` through `iteratee`. The
11082      * iteratee function is invoked with three arguments: (value, key, object).
11083      *
11084      * @static
11085      * @memberOf _
11086      * @category Object
11087      * @param {Object} object The object to iterate over.
11088      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11089      * @returns {Object} Returns the new mapped object.
11090      * @example
11091      *
11092      * var users = {
11093      *   'fred':    { 'user': 'fred',    'age': 40 },
11094      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
11095      * };
11096      *
11097      * _.mapValues(users, function(o) { return o.age; });
11098      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11099      *
11100      * // using the `_.property` iteratee shorthand
11101      * _.mapValues(users, 'age');
11102      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11103      */
11104     function mapValues(object, iteratee) {
11105       var result = {};
11106       iteratee = getIteratee(iteratee, 3);
11107
11108       baseForOwn(object, function(value, key, object) {
11109         result[key] = iteratee(value, key, object);
11110       });
11111       return result;
11112     }
11113
11114     /**
11115      * Recursively merges own and inherited enumerable properties of source
11116      * objects into the destination object, skipping source properties that resolve
11117      * to `undefined`. Array and plain object properties are merged recursively.
11118      * Other objects and value types are overridden by assignment. Source objects
11119      * are applied from left to right. Subsequent sources overwrite property
11120      * assignments of previous sources.
11121      *
11122      * **Note:** This method mutates `object`.
11123      *
11124      * @static
11125      * @memberOf _
11126      * @category Object
11127      * @param {Object} object The destination object.
11128      * @param {...Object} [sources] The source objects.
11129      * @returns {Object} Returns `object`.
11130      * @example
11131      *
11132      * var users = {
11133      *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
11134      * };
11135      *
11136      * var ages = {
11137      *   'data': [{ 'age': 36 }, { 'age': 40 }]
11138      * };
11139      *
11140      * _.merge(users, ages);
11141      * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
11142      */
11143     var merge = createAssigner(function(object, source) {
11144       baseMerge(object, source);
11145     });
11146
11147     /**
11148      * This method is like `_.merge` except that it accepts `customizer` which
11149      * is invoked to produce the merged values of the destination and source
11150      * properties. If `customizer` returns `undefined` merging is handled by the
11151      * method instead. The `customizer` is invoked with seven arguments:
11152      * (objValue, srcValue, key, object, source, stack).
11153      *
11154      * @static
11155      * @memberOf _
11156      * @category Object
11157      * @param {Object} object The destination object.
11158      * @param {...Object} sources The source objects.
11159      * @param {Function} customizer The function to customize assigned values.
11160      * @returns {Object} Returns `object`.
11161      * @example
11162      *
11163      * function customizer(objValue, srcValue) {
11164      *   if (_.isArray(objValue)) {
11165      *     return objValue.concat(srcValue);
11166      *   }
11167      * }
11168      *
11169      * var object = {
11170      *   'fruits': ['apple'],
11171      *   'vegetables': ['beet']
11172      * };
11173      *
11174      * var other = {
11175      *   'fruits': ['banana'],
11176      *   'vegetables': ['carrot']
11177      * };
11178      *
11179      * _.mergeWith(object, other, customizer);
11180      * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
11181      */
11182     var mergeWith = createAssigner(function(object, source, customizer) {
11183       baseMerge(object, source, customizer);
11184     });
11185
11186     /**
11187      * The opposite of `_.pick`; this method creates an object composed of the
11188      * own and inherited enumerable properties of `object` that are not omitted.
11189      *
11190      * @static
11191      * @memberOf _
11192      * @category Object
11193      * @param {Object} object The source object.
11194      * @param {...(string|string[])} [props] The property names to omit, specified
11195      *  individually or in arrays..
11196      * @returns {Object} Returns the new object.
11197      * @example
11198      *
11199      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11200      *
11201      * _.omit(object, ['a', 'c']);
11202      * // => { 'b': '2' }
11203      */
11204     var omit = rest(function(object, props) {
11205       if (object == null) {
11206         return {};
11207       }
11208       props = arrayMap(baseFlatten(props), String);
11209       return basePick(object, baseDifference(keysIn(object), props));
11210     });
11211
11212     /**
11213      * The opposite of `_.pickBy`; this method creates an object composed of the
11214      * own and inherited enumerable properties of `object` that `predicate`
11215      * doesn't return truthy for.
11216      *
11217      * @static
11218      * @memberOf _
11219      * @category Object
11220      * @param {Object} object The source object.
11221      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11222      * @returns {Object} Returns the new object.
11223      * @example
11224      *
11225      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11226      *
11227      * _.omitBy(object, _.isNumber);
11228      * // => { 'b': '2' }
11229      */
11230     function omitBy(object, predicate) {
11231       predicate = getIteratee(predicate);
11232       return basePickBy(object, function(value) {
11233         return !predicate(value);
11234       });
11235     }
11236
11237     /**
11238      * Creates an object composed of the picked `object` properties.
11239      *
11240      * @static
11241      * @memberOf _
11242      * @category Object
11243      * @param {Object} object The source object.
11244      * @param {...(string|string[])} [props] The property names to pick, specified
11245      *  individually or in arrays.
11246      * @returns {Object} Returns the new object.
11247      * @example
11248      *
11249      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11250      *
11251      * _.pick(object, ['a', 'c']);
11252      * // => { 'a': 1, 'c': 3 }
11253      */
11254     var pick = rest(function(object, props) {
11255       return object == null ? {} : basePick(object, baseFlatten(props));
11256     });
11257
11258     /**
11259      * Creates an object composed of the `object` properties `predicate` returns
11260      * truthy for. The predicate is invoked with one argument: (value).
11261      *
11262      * @static
11263      * @memberOf _
11264      * @category Object
11265      * @param {Object} object The source object.
11266      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11267      * @returns {Object} Returns the new object.
11268      * @example
11269      *
11270      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11271      *
11272      * _.pickBy(object, _.isNumber);
11273      * // => { 'a': 1, 'c': 3 }
11274      */
11275     function pickBy(object, predicate) {
11276       return object == null ? {} : basePickBy(object, getIteratee(predicate));
11277     }
11278
11279     /**
11280      * This method is like `_.get` except that if the resolved value is a function
11281      * it's invoked with the `this` binding of its parent object and its result
11282      * is returned.
11283      *
11284      * @static
11285      * @memberOf _
11286      * @category Object
11287      * @param {Object} object The object to query.
11288      * @param {Array|string} path The path of the property to resolve.
11289      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11290      * @returns {*} Returns the resolved value.
11291      * @example
11292      *
11293      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
11294      *
11295      * _.result(object, 'a[0].b.c1');
11296      * // => 3
11297      *
11298      * _.result(object, 'a[0].b.c2');
11299      * // => 4
11300      *
11301      * _.result(object, 'a[0].b.c3', 'default');
11302      * // => 'default'
11303      *
11304      * _.result(object, 'a[0].b.c3', _.constant('default'));
11305      * // => 'default'
11306      */
11307     function result(object, path, defaultValue) {
11308       if (!isKey(path, object)) {
11309         path = baseToPath(path);
11310         var result = get(object, path);
11311         object = parent(object, path);
11312       } else {
11313         result = object == null ? undefined : object[path];
11314       }
11315       if (result === undefined) {
11316         result = defaultValue;
11317       }
11318       return isFunction(result) ? result.call(object) : result;
11319     }
11320
11321     /**
11322      * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
11323      * it's created. Arrays are created for missing index properties while objects
11324      * are created for all other missing properties. Use `_.setWith` to customize
11325      * `path` creation.
11326      *
11327      * @static
11328      * @memberOf _
11329      * @category Object
11330      * @param {Object} object The object to modify.
11331      * @param {Array|string} path The path of the property to set.
11332      * @param {*} value The value to set.
11333      * @returns {Object} Returns `object`.
11334      * @example
11335      *
11336      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11337      *
11338      * _.set(object, 'a[0].b.c', 4);
11339      * console.log(object.a[0].b.c);
11340      * // => 4
11341      *
11342      * _.set(object, 'x[0].y.z', 5);
11343      * console.log(object.x[0].y.z);
11344      * // => 5
11345      */
11346     function set(object, path, value) {
11347       return object == null ? object : baseSet(object, path, value);
11348     }
11349
11350     /**
11351      * This method is like `_.set` except that it accepts `customizer` which is
11352      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
11353      * path creation is handled by the method instead. The `customizer` is invoked
11354      * with three arguments: (nsValue, key, nsObject).
11355      *
11356      * @static
11357      * @memberOf _
11358      * @category Object
11359      * @param {Object} object The object to modify.
11360      * @param {Array|string} path The path of the property to set.
11361      * @param {*} value The value to set.
11362      * @param {Function} [customizer] The function to customize assigned values.
11363      * @returns {Object} Returns `object`.
11364      * @example
11365      *
11366      * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
11367      * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
11368      */
11369     function setWith(object, path, value, customizer) {
11370       customizer = typeof customizer == 'function' ? customizer : undefined;
11371       return object == null ? object : baseSet(object, path, value, customizer);
11372     }
11373
11374     /**
11375      * Creates an array of own enumerable key-value pairs for `object`.
11376      *
11377      * @static
11378      * @memberOf _
11379      * @category Object
11380      * @param {Object} object The object to query.
11381      * @returns {Array} Returns the new array of key-value pairs.
11382      * @example
11383      *
11384      * function Foo() {
11385      *   this.a = 1;
11386      *   this.b = 2;
11387      * }
11388      *
11389      * Foo.prototype.c = 3;
11390      *
11391      * _.toPairs(new Foo);
11392      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
11393      */
11394     function toPairs(object) {
11395       return baseToPairs(object, keys(object));
11396     }
11397
11398     /**
11399      * Creates an array of own and inherited enumerable key-value pairs for `object`.
11400      *
11401      * @static
11402      * @memberOf _
11403      * @category Object
11404      * @param {Object} object The object to query.
11405      * @returns {Array} Returns the new array of key-value pairs.
11406      * @example
11407      *
11408      * function Foo() {
11409      *   this.a = 1;
11410      *   this.b = 2;
11411      * }
11412      *
11413      * Foo.prototype.c = 3;
11414      *
11415      * _.toPairsIn(new Foo);
11416      * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
11417      */
11418     function toPairsIn(object) {
11419       return baseToPairs(object, keysIn(object));
11420     }
11421
11422     /**
11423      * An alternative to `_.reduce`; this method transforms `object` to a new
11424      * `accumulator` object which is the result of running each of its own enumerable
11425      * properties through `iteratee`, with each invocation potentially mutating
11426      * the `accumulator` object. The iteratee is invoked with four arguments:
11427      * (accumulator, value, key, object). Iteratee functions may exit iteration
11428      * early by explicitly returning `false`.
11429      *
11430      * @static
11431      * @memberOf _
11432      * @category Object
11433      * @param {Array|Object} object The object to iterate over.
11434      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11435      * @param {*} [accumulator] The custom accumulator value.
11436      * @returns {*} Returns the accumulated value.
11437      * @example
11438      *
11439      * _.transform([2, 3, 4], function(result, n) {
11440      *   result.push(n *= n);
11441      *   return n % 2 == 0;
11442      * });
11443      * // => [4, 9]
11444      *
11445      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
11446      *   (result[value] || (result[value] = [])).push(key);
11447      * });
11448      * // => { '1': ['a', 'c'], '2': ['b'] }
11449      */
11450     function transform(object, iteratee, accumulator) {
11451       var isArr = isArray(object) || isTypedArray(object);
11452       iteratee = getIteratee(iteratee, 4);
11453
11454       if (accumulator == null) {
11455         if (isArr || isObject(object)) {
11456           var Ctor = object.constructor;
11457           if (isArr) {
11458             accumulator = isArray(object) ? new Ctor : [];
11459           } else {
11460             accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
11461           }
11462         } else {
11463           accumulator = {};
11464         }
11465       }
11466       (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
11467         return iteratee(accumulator, value, index, object);
11468       });
11469       return accumulator;
11470     }
11471
11472     /**
11473      * Removes the property at `path` of `object`.
11474      *
11475      * @static
11476      * @memberOf _
11477      * @category Object
11478      * @param {Object} object The object to modify.
11479      * @param {Array|string} path The path of the property to unset.
11480      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
11481      * @example
11482      *
11483      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
11484      * _.unset(object, 'a[0].b.c');
11485      * // => true
11486      *
11487      * console.log(object);
11488      * // => { 'a': [{ 'b': {} }] };
11489      *
11490      * _.unset(object, 'a[0].b.c');
11491      * // => true
11492      *
11493      * console.log(object);
11494      * // => { 'a': [{ 'b': {} }] };
11495      */
11496     function unset(object, path) {
11497       return object == null ? true : baseUnset(object, path);
11498     }
11499
11500     /**
11501      * Creates an array of the own enumerable property values of `object`.
11502      *
11503      * **Note:** Non-object values are coerced to objects.
11504      *
11505      * @static
11506      * @memberOf _
11507      * @category Object
11508      * @param {Object} object The object to query.
11509      * @returns {Array} Returns the array of property values.
11510      * @example
11511      *
11512      * function Foo() {
11513      *   this.a = 1;
11514      *   this.b = 2;
11515      * }
11516      *
11517      * Foo.prototype.c = 3;
11518      *
11519      * _.values(new Foo);
11520      * // => [1, 2] (iteration order is not guaranteed)
11521      *
11522      * _.values('hi');
11523      * // => ['h', 'i']
11524      */
11525     function values(object) {
11526       return object ? baseValues(object, keys(object)) : [];
11527     }
11528
11529     /**
11530      * Creates an array of the own and inherited enumerable property values of `object`.
11531      *
11532      * **Note:** Non-object values are coerced to objects.
11533      *
11534      * @static
11535      * @memberOf _
11536      * @category Object
11537      * @param {Object} object The object to query.
11538      * @returns {Array} Returns the array of property values.
11539      * @example
11540      *
11541      * function Foo() {
11542      *   this.a = 1;
11543      *   this.b = 2;
11544      * }
11545      *
11546      * Foo.prototype.c = 3;
11547      *
11548      * _.valuesIn(new Foo);
11549      * // => [1, 2, 3] (iteration order is not guaranteed)
11550      */
11551     function valuesIn(object) {
11552       return object == null ? baseValues(object, keysIn(object)) : [];
11553     }
11554
11555     /*------------------------------------------------------------------------*/
11556
11557     /**
11558      * Clamps `number` within the inclusive `lower` and `upper` bounds.
11559      *
11560      * @static
11561      * @memberOf _
11562      * @category Number
11563      * @param {number} number The number to clamp.
11564      * @param {number} [lower] The lower bound.
11565      * @param {number} upper The upper bound.
11566      * @returns {number} Returns the clamped number.
11567      * @example
11568      *
11569      * _.clamp(-10, -5, 5);
11570      * // => -5
11571      *
11572      * _.clamp(10, -5, 5);
11573      * // => 5
11574      */
11575     function clamp(number, lower, upper) {
11576       if (upper === undefined) {
11577         upper = lower;
11578         lower = undefined;
11579       }
11580       if (upper !== undefined) {
11581         upper = toNumber(upper);
11582         upper = upper === upper ? upper : 0;
11583       }
11584       if (lower !== undefined) {
11585         lower = toNumber(lower);
11586         lower = lower === lower ? lower : 0;
11587       }
11588       return baseClamp(toNumber(number), lower, upper);
11589     }
11590
11591     /**
11592      * Checks if `n` is between `start` and up to but not including, `end`. If
11593      * `end` is not specified it's set to `start` with `start` then set to `0`.
11594      * If `start` is greater than `end` the params are swapped to support
11595      * negative ranges.
11596      *
11597      * @static
11598      * @memberOf _
11599      * @category Number
11600      * @param {number} number The number to check.
11601      * @param {number} [start=0] The start of the range.
11602      * @param {number} end The end of the range.
11603      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
11604      * @example
11605      *
11606      * _.inRange(3, 2, 4);
11607      * // => true
11608      *
11609      * _.inRange(4, 8);
11610      * // => true
11611      *
11612      * _.inRange(4, 2);
11613      * // => false
11614      *
11615      * _.inRange(2, 2);
11616      * // => false
11617      *
11618      * _.inRange(1.2, 2);
11619      * // => true
11620      *
11621      * _.inRange(5.2, 4);
11622      * // => false
11623      *
11624      * _.inRange(-3, -2, -6);
11625      * // => true
11626      */
11627     function inRange(number, start, end) {
11628       start = toNumber(start) || 0;
11629       if (end === undefined) {
11630         end = start;
11631         start = 0;
11632       } else {
11633         end = toNumber(end) || 0;
11634       }
11635       number = toNumber(number);
11636       return baseInRange(number, start, end);
11637     }
11638
11639     /**
11640      * Produces a random number between the inclusive `lower` and `upper` bounds.
11641      * If only one argument is provided a number between `0` and the given number
11642      * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
11643      * a floating-point number is returned instead of an integer.
11644      *
11645      * **Note:** JavaScript follows the IEEE-754 standard for resolving
11646      * floating-point values which can produce unexpected results.
11647      *
11648      * @static
11649      * @memberOf _
11650      * @category Number
11651      * @param {number} [lower=0] The lower bound.
11652      * @param {number} [upper=1] The upper bound.
11653      * @param {boolean} [floating] Specify returning a floating-point number.
11654      * @returns {number} Returns the random number.
11655      * @example
11656      *
11657      * _.random(0, 5);
11658      * // => an integer between 0 and 5
11659      *
11660      * _.random(5);
11661      * // => also an integer between 0 and 5
11662      *
11663      * _.random(5, true);
11664      * // => a floating-point number between 0 and 5
11665      *
11666      * _.random(1.2, 5.2);
11667      * // => a floating-point number between 1.2 and 5.2
11668      */
11669     function random(lower, upper, floating) {
11670       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
11671         upper = floating = undefined;
11672       }
11673       if (floating === undefined) {
11674         if (typeof upper == 'boolean') {
11675           floating = upper;
11676           upper = undefined;
11677         }
11678         else if (typeof lower == 'boolean') {
11679           floating = lower;
11680           lower = undefined;
11681         }
11682       }
11683       if (lower === undefined && upper === undefined) {
11684         lower = 0;
11685         upper = 1;
11686       }
11687       else {
11688         lower = toNumber(lower) || 0;
11689         if (upper === undefined) {
11690           upper = lower;
11691           lower = 0;
11692         } else {
11693           upper = toNumber(upper) || 0;
11694         }
11695       }
11696       if (lower > upper) {
11697         var temp = lower;
11698         lower = upper;
11699         upper = temp;
11700       }
11701       if (floating || lower % 1 || upper % 1) {
11702         var rand = nativeRandom();
11703         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
11704       }
11705       return baseRandom(lower, upper);
11706     }
11707
11708     /*------------------------------------------------------------------------*/
11709
11710     /**
11711      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
11712      *
11713      * @static
11714      * @memberOf _
11715      * @category String
11716      * @param {string} [string=''] The string to convert.
11717      * @returns {string} Returns the camel cased string.
11718      * @example
11719      *
11720      * _.camelCase('Foo Bar');
11721      * // => 'fooBar'
11722      *
11723      * _.camelCase('--foo-bar');
11724      * // => 'fooBar'
11725      *
11726      * _.camelCase('__foo_bar__');
11727      * // => 'fooBar'
11728      */
11729     var camelCase = createCompounder(function(result, word, index) {
11730       word = word.toLowerCase();
11731       return result + (index ? capitalize(word) : word);
11732     });
11733
11734     /**
11735      * Converts the first character of `string` to upper case and the remaining
11736      * to lower case.
11737      *
11738      * @static
11739      * @memberOf _
11740      * @category String
11741      * @param {string} [string=''] The string to capitalize.
11742      * @returns {string} Returns the capitalized string.
11743      * @example
11744      *
11745      * _.capitalize('FRED');
11746      * // => 'Fred'
11747      */
11748     function capitalize(string) {
11749       return upperFirst(toString(string).toLowerCase());
11750     }
11751
11752     /**
11753      * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
11754      * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
11755      *
11756      * @static
11757      * @memberOf _
11758      * @category String
11759      * @param {string} [string=''] The string to deburr.
11760      * @returns {string} Returns the deburred string.
11761      * @example
11762      *
11763      * _.deburr('déjà vu');
11764      * // => 'deja vu'
11765      */
11766     function deburr(string) {
11767       string = toString(string);
11768       return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
11769     }
11770
11771     /**
11772      * Checks if `string` ends with the given target string.
11773      *
11774      * @static
11775      * @memberOf _
11776      * @category String
11777      * @param {string} [string=''] The string to search.
11778      * @param {string} [target] The string to search for.
11779      * @param {number} [position=string.length] The position to search from.
11780      * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
11781      * @example
11782      *
11783      * _.endsWith('abc', 'c');
11784      * // => true
11785      *
11786      * _.endsWith('abc', 'b');
11787      * // => false
11788      *
11789      * _.endsWith('abc', 'b', 2);
11790      * // => true
11791      */
11792     function endsWith(string, target, position) {
11793       string = toString(string);
11794       target = typeof target == 'string' ? target : (target + '');
11795
11796       var length = string.length;
11797       position = position === undefined
11798         ? length
11799         : baseClamp(toInteger(position), 0, length);
11800
11801       position -= target.length;
11802       return position >= 0 && string.indexOf(target, position) == position;
11803     }
11804
11805     /**
11806      * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
11807      * their corresponding HTML entities.
11808      *
11809      * **Note:** No other characters are escaped. To escape additional
11810      * characters use a third-party library like [_he_](https://mths.be/he).
11811      *
11812      * Though the ">" character is escaped for symmetry, characters like
11813      * ">" and "/" don't need escaping in HTML and have no special meaning
11814      * unless they're part of a tag or unquoted attribute value.
11815      * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
11816      * (under "semi-related fun fact") for more details.
11817      *
11818      * Backticks are escaped because in IE < 9, they can break out of
11819      * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
11820      * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
11821      * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
11822      * for more details.
11823      *
11824      * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
11825      * to reduce XSS vectors.
11826      *
11827      * @static
11828      * @memberOf _
11829      * @category String
11830      * @param {string} [string=''] The string to escape.
11831      * @returns {string} Returns the escaped string.
11832      * @example
11833      *
11834      * _.escape('fred, barney, & pebbles');
11835      * // => 'fred, barney, &amp; pebbles'
11836      */
11837     function escape(string) {
11838       string = toString(string);
11839       return (string && reHasUnescapedHtml.test(string))
11840         ? string.replace(reUnescapedHtml, escapeHtmlChar)
11841         : string;
11842     }
11843
11844     /**
11845      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
11846      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
11847      *
11848      * @static
11849      * @memberOf _
11850      * @category String
11851      * @param {string} [string=''] The string to escape.
11852      * @returns {string} Returns the escaped string.
11853      * @example
11854      *
11855      * _.escapeRegExp('[lodash](https://lodash.com/)');
11856      * // => '\[lodash\]\(https://lodash\.com/\)'
11857      */
11858     function escapeRegExp(string) {
11859       string = toString(string);
11860       return (string && reHasRegExpChar.test(string))
11861         ? string.replace(reRegExpChar, '\\$&')
11862         : string;
11863     }
11864
11865     /**
11866      * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
11867      *
11868      * @static
11869      * @memberOf _
11870      * @category String
11871      * @param {string} [string=''] The string to convert.
11872      * @returns {string} Returns the kebab cased string.
11873      * @example
11874      *
11875      * _.kebabCase('Foo Bar');
11876      * // => 'foo-bar'
11877      *
11878      * _.kebabCase('fooBar');
11879      * // => 'foo-bar'
11880      *
11881      * _.kebabCase('__foo_bar__');
11882      * // => 'foo-bar'
11883      */
11884     var kebabCase = createCompounder(function(result, word, index) {
11885       return result + (index ? '-' : '') + word.toLowerCase();
11886     });
11887
11888     /**
11889      * Converts `string`, as space separated words, to lower case.
11890      *
11891      * @static
11892      * @memberOf _
11893      * @category String
11894      * @param {string} [string=''] The string to convert.
11895      * @returns {string} Returns the lower cased string.
11896      * @example
11897      *
11898      * _.lowerCase('--Foo-Bar');
11899      * // => 'foo bar'
11900      *
11901      * _.lowerCase('fooBar');
11902      * // => 'foo bar'
11903      *
11904      * _.lowerCase('__FOO_BAR__');
11905      * // => 'foo bar'
11906      */
11907     var lowerCase = createCompounder(function(result, word, index) {
11908       return result + (index ? ' ' : '') + word.toLowerCase();
11909     });
11910
11911     /**
11912      * Converts the first character of `string` to lower case.
11913      *
11914      * @static
11915      * @memberOf _
11916      * @category String
11917      * @param {string} [string=''] The string to convert.
11918      * @returns {string} Returns the converted string.
11919      * @example
11920      *
11921      * _.lowerFirst('Fred');
11922      * // => 'fred'
11923      *
11924      * _.lowerFirst('FRED');
11925      * // => 'fRED'
11926      */
11927     var lowerFirst = createCaseFirst('toLowerCase');
11928
11929     /**
11930      * Converts the first character of `string` to upper case.
11931      *
11932      * @static
11933      * @memberOf _
11934      * @category String
11935      * @param {string} [string=''] The string to convert.
11936      * @returns {string} Returns the converted string.
11937      * @example
11938      *
11939      * _.upperFirst('fred');
11940      * // => 'Fred'
11941      *
11942      * _.upperFirst('FRED');
11943      * // => 'FRED'
11944      */
11945     var upperFirst = createCaseFirst('toUpperCase');
11946
11947     /**
11948      * Pads `string` on the left and right sides if it's shorter than `length`.
11949      * Padding characters are truncated if they can't be evenly divided by `length`.
11950      *
11951      * @static
11952      * @memberOf _
11953      * @category String
11954      * @param {string} [string=''] The string to pad.
11955      * @param {number} [length=0] The padding length.
11956      * @param {string} [chars=' '] The string used as padding.
11957      * @returns {string} Returns the padded string.
11958      * @example
11959      *
11960      * _.pad('abc', 8);
11961      * // => '  abc   '
11962      *
11963      * _.pad('abc', 8, '_-');
11964      * // => '_-abc_-_'
11965      *
11966      * _.pad('abc', 3);
11967      * // => 'abc'
11968      */
11969     function pad(string, length, chars) {
11970       string = toString(string);
11971       length = toInteger(length);
11972
11973       var strLength = stringSize(string);
11974       if (!length || strLength >= length) {
11975         return string;
11976       }
11977       var mid = (length - strLength) / 2,
11978           leftLength = nativeFloor(mid),
11979           rightLength = nativeCeil(mid);
11980
11981       return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
11982     }
11983
11984     /**
11985      * Pads `string` on the right side if it's shorter than `length`. Padding
11986      * characters are truncated if they exceed `length`.
11987      *
11988      * @static
11989      * @memberOf _
11990      * @category String
11991      * @param {string} [string=''] The string to pad.
11992      * @param {number} [length=0] The padding length.
11993      * @param {string} [chars=' '] The string used as padding.
11994      * @returns {string} Returns the padded string.
11995      * @example
11996      *
11997      * _.padEnd('abc', 6);
11998      * // => 'abc   '
11999      *
12000      * _.padEnd('abc', 6, '_-');
12001      * // => 'abc_-_'
12002      *
12003      * _.padEnd('abc', 3);
12004      * // => 'abc'
12005      */
12006     function padEnd(string, length, chars) {
12007       string = toString(string);
12008       return string + createPadding(string, length, chars);
12009     }
12010
12011     /**
12012      * Pads `string` on the left side if it's shorter than `length`. Padding
12013      * characters are truncated if they exceed `length`.
12014      *
12015      * @static
12016      * @memberOf _
12017      * @category String
12018      * @param {string} [string=''] The string to pad.
12019      * @param {number} [length=0] The padding length.
12020      * @param {string} [chars=' '] The string used as padding.
12021      * @returns {string} Returns the padded string.
12022      * @example
12023      *
12024      * _.padStart('abc', 6);
12025      * // => '   abc'
12026      *
12027      * _.padStart('abc', 6, '_-');
12028      * // => '_-_abc'
12029      *
12030      * _.padStart('abc', 3);
12031      * // => 'abc'
12032      */
12033     function padStart(string, length, chars) {
12034       string = toString(string);
12035       return createPadding(string, length, chars) + string;
12036     }
12037
12038     /**
12039      * Converts `string` to an integer of the specified radix. If `radix` is
12040      * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
12041      * in which case a `radix` of `16` is used.
12042      *
12043      * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E)
12044      * of `parseInt`.
12045      *
12046      * @static
12047      * @memberOf _
12048      * @category String
12049      * @param {string} string The string to convert.
12050      * @param {number} [radix] The radix to interpret `value` by.
12051      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12052      * @returns {number} Returns the converted integer.
12053      * @example
12054      *
12055      * _.parseInt('08');
12056      * // => 8
12057      *
12058      * _.map(['6', '08', '10'], _.parseInt);
12059      * // => [6, 8, 10]
12060      */
12061     function parseInt(string, radix, guard) {
12062       // Chrome fails to trim leading <BOM> whitespace characters.
12063       // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
12064       if (guard || radix == null) {
12065         radix = 0;
12066       } else if (radix) {
12067         radix = +radix;
12068       }
12069       string = toString(string).replace(reTrim, '');
12070       return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
12071     }
12072
12073     /**
12074      * Repeats the given string `n` times.
12075      *
12076      * @static
12077      * @memberOf _
12078      * @category String
12079      * @param {string} [string=''] The string to repeat.
12080      * @param {number} [n=0] The number of times to repeat the string.
12081      * @returns {string} Returns the repeated string.
12082      * @example
12083      *
12084      * _.repeat('*', 3);
12085      * // => '***'
12086      *
12087      * _.repeat('abc', 2);
12088      * // => 'abcabc'
12089      *
12090      * _.repeat('abc', 0);
12091      * // => ''
12092      */
12093     function repeat(string, n) {
12094       string = toString(string);
12095       n = toInteger(n);
12096
12097       var result = '';
12098       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
12099         return result;
12100       }
12101       // Leverage the exponentiation by squaring algorithm for a faster repeat.
12102       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
12103       do {
12104         if (n % 2) {
12105           result += string;
12106         }
12107         n = nativeFloor(n / 2);
12108         string += string;
12109       } while (n);
12110
12111       return result;
12112     }
12113
12114     /**
12115      * Replaces matches for `pattern` in `string` with `replacement`.
12116      *
12117      * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
12118      *
12119      * @static
12120      * @memberOf _
12121      * @category String
12122      * @param {string} [string=''] The string to modify.
12123      * @param {RegExp|string} pattern The pattern to replace.
12124      * @param {Function|string} replacement The match replacement.
12125      * @returns {string} Returns the modified string.
12126      * @example
12127      *
12128      * _.replace('Hi Fred', 'Fred', 'Barney');
12129      * // => 'Hi Barney'
12130      */
12131     function replace() {
12132       var args = arguments,
12133           string = toString(args[0]);
12134
12135       return args.length < 3 ? string : string.replace(args[1], args[2]);
12136     }
12137
12138     /**
12139      * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
12140      *
12141      * @static
12142      * @memberOf _
12143      * @category String
12144      * @param {string} [string=''] The string to convert.
12145      * @returns {string} Returns the snake cased string.
12146      * @example
12147      *
12148      * _.snakeCase('Foo Bar');
12149      * // => 'foo_bar'
12150      *
12151      * _.snakeCase('fooBar');
12152      * // => 'foo_bar'
12153      *
12154      * _.snakeCase('--foo-bar');
12155      * // => 'foo_bar'
12156      */
12157     var snakeCase = createCompounder(function(result, word, index) {
12158       return result + (index ? '_' : '') + word.toLowerCase();
12159     });
12160
12161     /**
12162      * Splits `string` by `separator`.
12163      *
12164      * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
12165      *
12166      * @static
12167      * @memberOf _
12168      * @category String
12169      * @param {string} [string=''] The string to split.
12170      * @param {RegExp|string} separator The separator pattern to split by.
12171      * @param {number} [limit] The length to truncate results to.
12172      * @returns {Array} Returns the new array of string segments.
12173      * @example
12174      *
12175      * _.split('a-b-c', '-', 2);
12176      * // => ['a', 'b']
12177      */
12178     function split(string, separator, limit) {
12179       return toString(string).split(separator, limit);
12180     }
12181
12182     /**
12183      * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
12184      *
12185      * @static
12186      * @memberOf _
12187      * @category String
12188      * @param {string} [string=''] The string to convert.
12189      * @returns {string} Returns the start cased string.
12190      * @example
12191      *
12192      * _.startCase('--foo-bar');
12193      * // => 'Foo Bar'
12194      *
12195      * _.startCase('fooBar');
12196      * // => 'Foo Bar'
12197      *
12198      * _.startCase('__foo_bar__');
12199      * // => 'Foo Bar'
12200      */
12201     var startCase = createCompounder(function(result, word, index) {
12202       return result + (index ? ' ' : '') + capitalize(word);
12203     });
12204
12205     /**
12206      * Checks if `string` starts with the given target string.
12207      *
12208      * @static
12209      * @memberOf _
12210      * @category String
12211      * @param {string} [string=''] The string to search.
12212      * @param {string} [target] The string to search for.
12213      * @param {number} [position=0] The position to search from.
12214      * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
12215      * @example
12216      *
12217      * _.startsWith('abc', 'a');
12218      * // => true
12219      *
12220      * _.startsWith('abc', 'b');
12221      * // => false
12222      *
12223      * _.startsWith('abc', 'b', 1);
12224      * // => true
12225      */
12226     function startsWith(string, target, position) {
12227       string = toString(string);
12228       position = baseClamp(toInteger(position), 0, string.length);
12229       return string.lastIndexOf(target, position) == position;
12230     }
12231
12232     /**
12233      * Creates a compiled template function that can interpolate data properties
12234      * in "interpolate" delimiters, HTML-escape interpolated data properties in
12235      * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
12236      * properties may be accessed as free variables in the template. If a setting
12237      * object is provided it takes precedence over `_.templateSettings` values.
12238      *
12239      * **Note:** In the development build `_.template` utilizes
12240      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
12241      * for easier debugging.
12242      *
12243      * For more information on precompiling templates see
12244      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
12245      *
12246      * For more information on Chrome extension sandboxes see
12247      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
12248      *
12249      * @static
12250      * @memberOf _
12251      * @category String
12252      * @param {string} [string=''] The template string.
12253      * @param {Object} [options] The options object.
12254      * @param {RegExp} [options.escape] The HTML "escape" delimiter.
12255      * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
12256      * @param {Object} [options.imports] An object to import into the template as free variables.
12257      * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
12258      * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
12259      * @param {string} [options.variable] The data object variable name.
12260      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12261      * @returns {Function} Returns the compiled template function.
12262      * @example
12263      *
12264      * // using the "interpolate" delimiter to create a compiled template
12265      * var compiled = _.template('hello <%= user %>!');
12266      * compiled({ 'user': 'fred' });
12267      * // => 'hello fred!'
12268      *
12269      * // using the HTML "escape" delimiter to escape data property values
12270      * var compiled = _.template('<b><%- value %></b>');
12271      * compiled({ 'value': '<script>' });
12272      * // => '<b>&lt;script&gt;</b>'
12273      *
12274      * // using the "evaluate" delimiter to execute JavaScript and generate HTML
12275      * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
12276      * compiled({ 'users': ['fred', 'barney'] });
12277      * // => '<li>fred</li><li>barney</li>'
12278      *
12279      * // using the internal `print` function in "evaluate" delimiters
12280      * var compiled = _.template('<% print("hello " + user); %>!');
12281      * compiled({ 'user': 'barney' });
12282      * // => 'hello barney!'
12283      *
12284      * // using the ES delimiter as an alternative to the default "interpolate" delimiter
12285      * var compiled = _.template('hello ${ user }!');
12286      * compiled({ 'user': 'pebbles' });
12287      * // => 'hello pebbles!'
12288      *
12289      * // using custom template delimiters
12290      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
12291      * var compiled = _.template('hello {{ user }}!');
12292      * compiled({ 'user': 'mustache' });
12293      * // => 'hello mustache!'
12294      *
12295      * // using backslashes to treat delimiters as plain text
12296      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
12297      * compiled({ 'value': 'ignored' });
12298      * // => '<%- value %>'
12299      *
12300      * // using the `imports` option to import `jQuery` as `jq`
12301      * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
12302      * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
12303      * compiled({ 'users': ['fred', 'barney'] });
12304      * // => '<li>fred</li><li>barney</li>'
12305      *
12306      * // using the `sourceURL` option to specify a custom sourceURL for the template
12307      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
12308      * compiled(data);
12309      * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
12310      *
12311      * // using the `variable` option to ensure a with-statement isn't used in the compiled template
12312      * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
12313      * compiled.source;
12314      * // => function(data) {
12315      * //   var __t, __p = '';
12316      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
12317      * //   return __p;
12318      * // }
12319      *
12320      * // using the `source` property to inline compiled templates for meaningful
12321      * // line numbers in error messages and a stack trace
12322      * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
12323      *   var JST = {\
12324      *     "main": ' + _.template(mainText).source + '\
12325      *   };\
12326      * ');
12327      */
12328     function template(string, options, guard) {
12329       // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
12330       // and Laura Doktorova's doT.js (https://github.com/olado/doT).
12331       var settings = lodash.templateSettings;
12332
12333       if (guard && isIterateeCall(string, options, guard)) {
12334         options = undefined;
12335       }
12336       string = toString(string);
12337       options = assignInWith({}, options, settings, assignInDefaults);
12338
12339       var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
12340           importsKeys = keys(imports),
12341           importsValues = baseValues(imports, importsKeys);
12342
12343       var isEscaping,
12344           isEvaluating,
12345           index = 0,
12346           interpolate = options.interpolate || reNoMatch,
12347           source = "__p += '";
12348
12349       // Compile the regexp to match each delimiter.
12350       var reDelimiters = RegExp(
12351         (options.escape || reNoMatch).source + '|' +
12352         interpolate.source + '|' +
12353         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
12354         (options.evaluate || reNoMatch).source + '|$'
12355       , 'g');
12356
12357       // Use a sourceURL for easier debugging.
12358       var sourceURL = '//# sourceURL=' +
12359         ('sourceURL' in options
12360           ? options.sourceURL
12361           : ('lodash.templateSources[' + (++templateCounter) + ']')
12362         ) + '\n';
12363
12364       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
12365         interpolateValue || (interpolateValue = esTemplateValue);
12366
12367         // Escape characters that can't be included in string literals.
12368         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
12369
12370         // Replace delimiters with snippets.
12371         if (escapeValue) {
12372           isEscaping = true;
12373           source += "' +\n__e(" + escapeValue + ") +\n'";
12374         }
12375         if (evaluateValue) {
12376           isEvaluating = true;
12377           source += "';\n" + evaluateValue + ";\n__p += '";
12378         }
12379         if (interpolateValue) {
12380           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
12381         }
12382         index = offset + match.length;
12383
12384         // The JS engine embedded in Adobe products needs `match` returned in
12385         // order to produce the correct `offset` value.
12386         return match;
12387       });
12388
12389       source += "';\n";
12390
12391       // If `variable` is not specified wrap a with-statement around the generated
12392       // code to add the data object to the top of the scope chain.
12393       var variable = options.variable;
12394       if (!variable) {
12395         source = 'with (obj) {\n' + source + '\n}\n';
12396       }
12397       // Cleanup code by stripping empty strings.
12398       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
12399         .replace(reEmptyStringMiddle, '$1')
12400         .replace(reEmptyStringTrailing, '$1;');
12401
12402       // Frame code as the function body.
12403       source = 'function(' + (variable || 'obj') + ') {\n' +
12404         (variable
12405           ? ''
12406           : 'obj || (obj = {});\n'
12407         ) +
12408         "var __t, __p = ''" +
12409         (isEscaping
12410            ? ', __e = _.escape'
12411            : ''
12412         ) +
12413         (isEvaluating
12414           ? ', __j = Array.prototype.join;\n' +
12415             "function print() { __p += __j.call(arguments, '') }\n"
12416           : ';\n'
12417         ) +
12418         source +
12419         'return __p\n}';
12420
12421       var result = attempt(function() {
12422         return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);
12423       });
12424
12425       // Provide the compiled function's source by its `toString` method or
12426       // the `source` property as a convenience for inlining compiled templates.
12427       result.source = source;
12428       if (isError(result)) {
12429         throw result;
12430       }
12431       return result;
12432     }
12433
12434     /**
12435      * Converts `string`, as a whole, to lower case.
12436      *
12437      * @static
12438      * @memberOf _
12439      * @category String
12440      * @param {string} [string=''] The string to convert.
12441      * @returns {string} Returns the lower cased string.
12442      * @example
12443      *
12444      * _.toLower('--Foo-Bar');
12445      * // => '--foo-bar'
12446      *
12447      * _.toLower('fooBar');
12448      * // => 'foobar'
12449      *
12450      * _.toLower('__FOO_BAR__');
12451      * // => '__foo_bar__'
12452      */
12453     function toLower(value) {
12454       return toString(value).toLowerCase();
12455     }
12456
12457     /**
12458      * Converts `string`, as a whole, to upper case.
12459      *
12460      * @static
12461      * @memberOf _
12462      * @category String
12463      * @param {string} [string=''] The string to convert.
12464      * @returns {string} Returns the upper cased string.
12465      * @example
12466      *
12467      * _.toUpper('--foo-bar');
12468      * // => '--FOO-BAR'
12469      *
12470      * _.toUpper('fooBar');
12471      * // => 'FOOBAR'
12472      *
12473      * _.toUpper('__foo_bar__');
12474      * // => '__FOO_BAR__'
12475      */
12476     function toUpper(value) {
12477       return toString(value).toUpperCase();
12478     }
12479
12480     /**
12481      * Removes leading and trailing whitespace or specified characters from `string`.
12482      *
12483      * @static
12484      * @memberOf _
12485      * @category String
12486      * @param {string} [string=''] The string to trim.
12487      * @param {string} [chars=whitespace] The characters to trim.
12488      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12489      * @returns {string} Returns the trimmed string.
12490      * @example
12491      *
12492      * _.trim('  abc  ');
12493      * // => 'abc'
12494      *
12495      * _.trim('-_-abc-_-', '_-');
12496      * // => 'abc'
12497      *
12498      * _.map(['  foo  ', '  bar  '], _.trim);
12499      * // => ['foo', 'bar']
12500      */
12501     function trim(string, chars, guard) {
12502       string = toString(string);
12503       if (!string) {
12504         return string;
12505       }
12506       if (guard || chars === undefined) {
12507         return string.replace(reTrim, '');
12508       }
12509       chars = (chars + '');
12510       if (!chars) {
12511         return string;
12512       }
12513       var strSymbols = stringToArray(string),
12514           chrSymbols = stringToArray(chars);
12515
12516       return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join('');
12517     }
12518
12519     /**
12520      * Removes trailing whitespace or specified characters from `string`.
12521      *
12522      * @static
12523      * @memberOf _
12524      * @category String
12525      * @param {string} [string=''] The string to trim.
12526      * @param {string} [chars=whitespace] The characters to trim.
12527      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12528      * @returns {string} Returns the trimmed string.
12529      * @example
12530      *
12531      * _.trimEnd('  abc  ');
12532      * // => '  abc'
12533      *
12534      * _.trimEnd('-_-abc-_-', '_-');
12535      * // => '-_-abc'
12536      */
12537     function trimEnd(string, chars, guard) {
12538       string = toString(string);
12539       if (!string) {
12540         return string;
12541       }
12542       if (guard || chars === undefined) {
12543         return string.replace(reTrimEnd, '');
12544       }
12545       chars = (chars + '');
12546       if (!chars) {
12547         return string;
12548       }
12549       var strSymbols = stringToArray(string);
12550       return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join('');
12551     }
12552
12553     /**
12554      * Removes leading whitespace or specified characters from `string`.
12555      *
12556      * @static
12557      * @memberOf _
12558      * @category String
12559      * @param {string} [string=''] The string to trim.
12560      * @param {string} [chars=whitespace] The characters to trim.
12561      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12562      * @returns {string} Returns the trimmed string.
12563      * @example
12564      *
12565      * _.trimStart('  abc  ');
12566      * // => 'abc  '
12567      *
12568      * _.trimStart('-_-abc-_-', '_-');
12569      * // => 'abc-_-'
12570      */
12571     function trimStart(string, chars, guard) {
12572       string = toString(string);
12573       if (!string) {
12574         return string;
12575       }
12576       if (guard || chars === undefined) {
12577         return string.replace(reTrimStart, '');
12578       }
12579       chars = (chars + '');
12580       if (!chars) {
12581         return string;
12582       }
12583       var strSymbols = stringToArray(string);
12584       return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).join('');
12585     }
12586
12587     /**
12588      * Truncates `string` if it's longer than the given maximum string length.
12589      * The last characters of the truncated string are replaced with the omission
12590      * string which defaults to "...".
12591      *
12592      * @static
12593      * @memberOf _
12594      * @category String
12595      * @param {string} [string=''] The string to truncate.
12596      * @param {Object} [options] The options object.
12597      * @param {number} [options.length=30] The maximum string length.
12598      * @param {string} [options.omission='...'] The string to indicate text is omitted.
12599      * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
12600      * @returns {string} Returns the truncated string.
12601      * @example
12602      *
12603      * _.truncate('hi-diddly-ho there, neighborino');
12604      * // => 'hi-diddly-ho there, neighbo...'
12605      *
12606      * _.truncate('hi-diddly-ho there, neighborino', {
12607      *   'length': 24,
12608      *   'separator': ' '
12609      * });
12610      * // => 'hi-diddly-ho there,...'
12611      *
12612      * _.truncate('hi-diddly-ho there, neighborino', {
12613      *   'length': 24,
12614      *   'separator': /,? +/
12615      * });
12616      * // => 'hi-diddly-ho there...'
12617      *
12618      * _.truncate('hi-diddly-ho there, neighborino', {
12619      *   'omission': ' [...]'
12620      * });
12621      * // => 'hi-diddly-ho there, neig [...]'
12622      */
12623     function truncate(string, options) {
12624       var length = DEFAULT_TRUNC_LENGTH,
12625           omission = DEFAULT_TRUNC_OMISSION;
12626
12627       if (isObject(options)) {
12628         var separator = 'separator' in options ? options.separator : separator;
12629         length = 'length' in options ? toInteger(options.length) : length;
12630         omission = 'omission' in options ? toString(options.omission) : omission;
12631       }
12632       string = toString(string);
12633
12634       var strLength = string.length;
12635       if (reHasComplexSymbol.test(string)) {
12636         var strSymbols = stringToArray(string);
12637         strLength = strSymbols.length;
12638       }
12639       if (length >= strLength) {
12640         return string;
12641       }
12642       var end = length - stringSize(omission);
12643       if (end < 1) {
12644         return omission;
12645       }
12646       var result = strSymbols
12647         ? strSymbols.slice(0, end).join('')
12648         : string.slice(0, end);
12649
12650       if (separator === undefined) {
12651         return result + omission;
12652       }
12653       if (strSymbols) {
12654         end += (result.length - end);
12655       }
12656       if (isRegExp(separator)) {
12657         if (string.slice(end).search(separator)) {
12658           var match,
12659               substring = result;
12660
12661           if (!separator.global) {
12662             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
12663           }
12664           separator.lastIndex = 0;
12665           while ((match = separator.exec(substring))) {
12666             var newEnd = match.index;
12667           }
12668           result = result.slice(0, newEnd === undefined ? end : newEnd);
12669         }
12670       } else if (string.indexOf(separator, end) != end) {
12671         var index = result.lastIndexOf(separator);
12672         if (index > -1) {
12673           result = result.slice(0, index);
12674         }
12675       }
12676       return result + omission;
12677     }
12678
12679     /**
12680      * The inverse of `_.escape`; this method converts the HTML entities
12681      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their
12682      * corresponding characters.
12683      *
12684      * **Note:** No other HTML entities are unescaped. To unescape additional HTML
12685      * entities use a third-party library like [_he_](https://mths.be/he).
12686      *
12687      * @static
12688      * @memberOf _
12689      * @category String
12690      * @param {string} [string=''] The string to unescape.
12691      * @returns {string} Returns the unescaped string.
12692      * @example
12693      *
12694      * _.unescape('fred, barney, &amp; pebbles');
12695      * // => 'fred, barney, & pebbles'
12696      */
12697     function unescape(string) {
12698       string = toString(string);
12699       return (string && reHasEscapedHtml.test(string))
12700         ? string.replace(reEscapedHtml, unescapeHtmlChar)
12701         : string;
12702     }
12703
12704     /**
12705      * Converts `string`, as space separated words, to upper case.
12706      *
12707      * @static
12708      * @memberOf _
12709      * @category String
12710      * @param {string} [string=''] The string to convert.
12711      * @returns {string} Returns the upper cased string.
12712      * @example
12713      *
12714      * _.upperCase('--foo-bar');
12715      * // => 'FOO BAR'
12716      *
12717      * _.upperCase('fooBar');
12718      * // => 'FOO BAR'
12719      *
12720      * _.upperCase('__foo_bar__');
12721      * // => 'FOO BAR'
12722      */
12723     var upperCase = createCompounder(function(result, word, index) {
12724       return result + (index ? ' ' : '') + word.toUpperCase();
12725     });
12726
12727     /**
12728      * Splits `string` into an array of its words.
12729      *
12730      * @static
12731      * @memberOf _
12732      * @category String
12733      * @param {string} [string=''] The string to inspect.
12734      * @param {RegExp|string} [pattern] The pattern to match words.
12735      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12736      * @returns {Array} Returns the words of `string`.
12737      * @example
12738      *
12739      * _.words('fred, barney, & pebbles');
12740      * // => ['fred', 'barney', 'pebbles']
12741      *
12742      * _.words('fred, barney, & pebbles', /[^, ]+/g);
12743      * // => ['fred', 'barney', '&', 'pebbles']
12744      */
12745     function words(string, pattern, guard) {
12746       string = toString(string);
12747       pattern = guard ? undefined : pattern;
12748
12749       if (pattern === undefined) {
12750         pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
12751       }
12752       return string.match(pattern) || [];
12753     }
12754
12755     /*------------------------------------------------------------------------*/
12756
12757     /**
12758      * Attempts to invoke `func`, returning either the result or the caught error
12759      * object. Any additional arguments are provided to `func` when it's invoked.
12760      *
12761      * @static
12762      * @memberOf _
12763      * @category Util
12764      * @param {Function} func The function to attempt.
12765      * @returns {*} Returns the `func` result or error object.
12766      * @example
12767      *
12768      * // avoid throwing errors for invalid selectors
12769      * var elements = _.attempt(function(selector) {
12770      *   return document.querySelectorAll(selector);
12771      * }, '>_>');
12772      *
12773      * if (_.isError(elements)) {
12774      *   elements = [];
12775      * }
12776      */
12777     var attempt = rest(function(func, args) {
12778       try {
12779         return apply(func, undefined, args);
12780       } catch (e) {
12781         return isError(e) ? e : new Error(e);
12782       }
12783     });
12784
12785     /**
12786      * Binds methods of an object to the object itself, overwriting the existing
12787      * method.
12788      *
12789      * **Note:** This method doesn't set the "length" property of bound functions.
12790      *
12791      * @static
12792      * @memberOf _
12793      * @category Util
12794      * @param {Object} object The object to bind and assign the bound methods to.
12795      * @param {...(string|string[])} methodNames The object method names to bind,
12796      *  specified individually or in arrays.
12797      * @returns {Object} Returns `object`.
12798      * @example
12799      *
12800      * var view = {
12801      *   'label': 'docs',
12802      *   'onClick': function() {
12803      *     console.log('clicked ' + this.label);
12804      *   }
12805      * };
12806      *
12807      * _.bindAll(view, 'onClick');
12808      * jQuery(element).on('click', view.onClick);
12809      * // => logs 'clicked docs' when clicked
12810      */
12811     var bindAll = rest(function(object, methodNames) {
12812       arrayEach(baseFlatten(methodNames), function(key) {
12813         object[key] = bind(object[key], object);
12814       });
12815       return object;
12816     });
12817
12818     /**
12819      * Creates a function that iterates over `pairs` invoking the corresponding
12820      * function of the first predicate to return truthy. The predicate-function
12821      * pairs are invoked with the `this` binding and arguments of the created
12822      * function.
12823      *
12824      * @static
12825      * @memberOf _
12826      * @category Util
12827      * @param {Array} pairs The predicate-function pairs.
12828      * @returns {Function} Returns the new function.
12829      * @example
12830      *
12831      * var func = _.cond([
12832      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
12833      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
12834      *   [_.constant(true),                _.constant('no match')]
12835      * ])
12836      *
12837      * func({ 'a': 1, 'b': 2 });
12838      * // => 'matches A'
12839      *
12840      * func({ 'a': 0, 'b': 1 });
12841      * // => 'matches B'
12842      *
12843      * func({ 'a': '1', 'b': '2' });
12844      * // => 'no match'
12845      */
12846     function cond(pairs) {
12847       var length = pairs ? pairs.length : 0,
12848           toIteratee = getIteratee();
12849
12850       pairs = !length ? [] : arrayMap(pairs, function(pair) {
12851         if (typeof pair[1] != 'function') {
12852           throw new TypeError(FUNC_ERROR_TEXT);
12853         }
12854         return [toIteratee(pair[0]), pair[1]];
12855       });
12856
12857       return rest(function(args) {
12858         var index = -1;
12859         while (++index < length) {
12860           var pair = pairs[index];
12861           if (apply(pair[0], this, args)) {
12862             return apply(pair[1], this, args);
12863           }
12864         }
12865       });
12866     }
12867
12868     /**
12869      * Creates a function that invokes the predicate properties of `source` with
12870      * the corresponding property values of a given object, returning `true` if
12871      * all predicates return truthy, else `false`.
12872      *
12873      * @static
12874      * @memberOf _
12875      * @category Util
12876      * @param {Object} source The object of property predicates to conform to.
12877      * @returns {Function} Returns the new function.
12878      * @example
12879      *
12880      * var users = [
12881      *   { 'user': 'barney', 'age': 36 },
12882      *   { 'user': 'fred',   'age': 40 }
12883      * ];
12884      *
12885      * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
12886      * // => [{ 'user': 'fred', 'age': 40 }]
12887      */
12888     function conforms(source) {
12889       return baseConforms(baseClone(source, true));
12890     }
12891
12892     /**
12893      * Creates a function that returns `value`.
12894      *
12895      * @static
12896      * @memberOf _
12897      * @category Util
12898      * @param {*} value The value to return from the new function.
12899      * @returns {Function} Returns the new function.
12900      * @example
12901      *
12902      * var object = { 'user': 'fred' };
12903      * var getter = _.constant(object);
12904      *
12905      * getter() === object;
12906      * // => true
12907      */
12908     function constant(value) {
12909       return function() {
12910         return value;
12911       };
12912     }
12913
12914     /**
12915      * Creates a function that returns the result of invoking the provided
12916      * functions with the `this` binding of the created function, where each
12917      * successive invocation is supplied the return value of the previous.
12918      *
12919      * @static
12920      * @memberOf _
12921      * @category Util
12922      * @param {...(Function|Function[])} [funcs] Functions to invoke.
12923      * @returns {Function} Returns the new function.
12924      * @example
12925      *
12926      * function square(n) {
12927      *   return n * n;
12928      * }
12929      *
12930      * var addSquare = _.flow(_.add, square);
12931      * addSquare(1, 2);
12932      * // => 9
12933      */
12934     var flow = createFlow();
12935
12936     /**
12937      * This method is like `_.flow` except that it creates a function that
12938      * invokes the provided functions from right to left.
12939      *
12940      * @static
12941      * @memberOf _
12942      * @category Util
12943      * @param {...(Function|Function[])} [funcs] Functions to invoke.
12944      * @returns {Function} Returns the new function.
12945      * @example
12946      *
12947      * function square(n) {
12948      *   return n * n;
12949      * }
12950      *
12951      * var addSquare = _.flowRight(square, _.add);
12952      * addSquare(1, 2);
12953      * // => 9
12954      */
12955     var flowRight = createFlow(true);
12956
12957     /**
12958      * This method returns the first argument provided to it.
12959      *
12960      * @static
12961      * @memberOf _
12962      * @category Util
12963      * @param {*} value Any value.
12964      * @returns {*} Returns `value`.
12965      * @example
12966      *
12967      * var object = { 'user': 'fred' };
12968      *
12969      * _.identity(object) === object;
12970      * // => true
12971      */
12972     function identity(value) {
12973       return value;
12974     }
12975
12976     /**
12977      * Creates a function that invokes `func` with the arguments of the created
12978      * function. If `func` is a property name the created callback returns the
12979      * property value for a given element. If `func` is an object the created
12980      * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`.
12981      *
12982      * @static
12983      * @memberOf _
12984      * @category Util
12985      * @param {*} [func=_.identity] The value to convert to a callback.
12986      * @returns {Function} Returns the callback.
12987      * @example
12988      *
12989      * var users = [
12990      *   { 'user': 'barney', 'age': 36 },
12991      *   { 'user': 'fred',   'age': 40 }
12992      * ];
12993      *
12994      * // create custom iteratee shorthands
12995      * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
12996      *   var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
12997      *   return !p ? callback(func) : function(object) {
12998      *     return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
12999      *   };
13000      * });
13001      *
13002      * _.filter(users, 'age > 36');
13003      * // => [{ 'user': 'fred', 'age': 40 }]
13004      */
13005     function iteratee(func) {
13006       return (isObjectLike(func) && !isArray(func))
13007         ? matches(func)
13008         : baseIteratee(func);
13009     }
13010
13011     /**
13012      * Creates a function that performs a deep partial comparison between a given
13013      * object and `source`, returning `true` if the given object has equivalent
13014      * property values, else `false`.
13015      *
13016      * **Note:** This method supports comparing the same values as `_.isEqual`.
13017      *
13018      * @static
13019      * @memberOf _
13020      * @category Util
13021      * @param {Object} source The object of property values to match.
13022      * @returns {Function} Returns the new function.
13023      * @example
13024      *
13025      * var users = [
13026      *   { 'user': 'barney', 'age': 36, 'active': true },
13027      *   { 'user': 'fred',   'age': 40, 'active': false }
13028      * ];
13029      *
13030      * _.filter(users, _.matches({ 'age': 40, 'active': false }));
13031      * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
13032      */
13033     function matches(source) {
13034       return baseMatches(baseClone(source, true));
13035     }
13036
13037     /**
13038      * Creates a function that performs a deep partial comparison between the
13039      * value at `path` of a given object to `srcValue`, returning `true` if the
13040      * object value is equivalent, else `false`.
13041      *
13042      * **Note:** This method supports comparing the same values as `_.isEqual`.
13043      *
13044      * @static
13045      * @memberOf _
13046      * @category Util
13047      * @param {Array|string} path The path of the property to get.
13048      * @param {*} srcValue The value to match.
13049      * @returns {Function} Returns the new function.
13050      * @example
13051      *
13052      * var users = [
13053      *   { 'user': 'barney' },
13054      *   { 'user': 'fred' }
13055      * ];
13056      *
13057      * _.find(users, _.matchesProperty('user', 'fred'));
13058      * // => { 'user': 'fred' }
13059      */
13060     function matchesProperty(path, srcValue) {
13061       return baseMatchesProperty(path, baseClone(srcValue, true));
13062     }
13063
13064     /**
13065      * Creates a function that invokes the method at `path` of a given object.
13066      * Any additional arguments are provided to the invoked method.
13067      *
13068      * @static
13069      * @memberOf _
13070      * @category Util
13071      * @param {Array|string} path The path of the method to invoke.
13072      * @param {...*} [args] The arguments to invoke the method with.
13073      * @returns {Function} Returns the new function.
13074      * @example
13075      *
13076      * var objects = [
13077      *   { 'a': { 'b': { 'c': _.constant(2) } } },
13078      *   { 'a': { 'b': { 'c': _.constant(1) } } }
13079      * ];
13080      *
13081      * _.map(objects, _.method('a.b.c'));
13082      * // => [2, 1]
13083      *
13084      * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
13085      * // => [1, 2]
13086      */
13087     var method = rest(function(path, args) {
13088       return function(object) {
13089         return baseInvoke(object, path, args);
13090       };
13091     });
13092
13093     /**
13094      * The opposite of `_.method`; this method creates a function that invokes
13095      * the method at a given path of `object`. Any additional arguments are
13096      * provided to the invoked method.
13097      *
13098      * @static
13099      * @memberOf _
13100      * @category Util
13101      * @param {Object} object The object to query.
13102      * @param {...*} [args] The arguments to invoke the method with.
13103      * @returns {Function} Returns the new function.
13104      * @example
13105      *
13106      * var array = _.times(3, _.constant),
13107      *     object = { 'a': array, 'b': array, 'c': array };
13108      *
13109      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
13110      * // => [2, 0]
13111      *
13112      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
13113      * // => [2, 0]
13114      */
13115     var methodOf = rest(function(object, args) {
13116       return function(path) {
13117         return baseInvoke(object, path, args);
13118       };
13119     });
13120
13121     /**
13122      * Adds all own enumerable function properties of a source object to the
13123      * destination object. If `object` is a function then methods are added to
13124      * its prototype as well.
13125      *
13126      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
13127      * avoid conflicts caused by modifying the original.
13128      *
13129      * @static
13130      * @memberOf _
13131      * @category Util
13132      * @param {Function|Object} [object=lodash] The destination object.
13133      * @param {Object} source The object of functions to add.
13134      * @param {Object} [options] The options object.
13135      * @param {boolean} [options.chain=true] Specify whether the functions added
13136      *  are chainable.
13137      * @returns {Function|Object} Returns `object`.
13138      * @example
13139      *
13140      * function vowels(string) {
13141      *   return _.filter(string, function(v) {
13142      *     return /[aeiou]/i.test(v);
13143      *   });
13144      * }
13145      *
13146      * _.mixin({ 'vowels': vowels });
13147      * _.vowels('fred');
13148      * // => ['e']
13149      *
13150      * _('fred').vowels().value();
13151      * // => ['e']
13152      *
13153      * _.mixin({ 'vowels': vowels }, { 'chain': false });
13154      * _('fred').vowels();
13155      * // => ['e']
13156      */
13157     function mixin(object, source, options) {
13158       var props = keys(source),
13159           methodNames = baseFunctions(source, props);
13160
13161       if (options == null &&
13162           !(isObject(source) && (methodNames.length || !props.length))) {
13163         options = source;
13164         source = object;
13165         object = this;
13166         methodNames = baseFunctions(source, keys(source));
13167       }
13168       var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
13169           isFunc = isFunction(object);
13170
13171       arrayEach(methodNames, function(methodName) {
13172         var func = source[methodName];
13173         object[methodName] = func;
13174         if (isFunc) {
13175           object.prototype[methodName] = function() {
13176             var chainAll = this.__chain__;
13177             if (chain || chainAll) {
13178               var result = object(this.__wrapped__),
13179                   actions = result.__actions__ = copyArray(this.__actions__);
13180
13181               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
13182               result.__chain__ = chainAll;
13183               return result;
13184             }
13185             return func.apply(object, arrayPush([this.value()], arguments));
13186           };
13187         }
13188       });
13189
13190       return object;
13191     }
13192
13193     /**
13194      * Reverts the `_` variable to its previous value and returns a reference to
13195      * the `lodash` function.
13196      *
13197      * @static
13198      * @memberOf _
13199      * @category Util
13200      * @returns {Function} Returns the `lodash` function.
13201      * @example
13202      *
13203      * var lodash = _.noConflict();
13204      */
13205     function noConflict() {
13206       root._ = oldDash;
13207       return this;
13208     }
13209
13210     /**
13211      * A no-operation function that returns `undefined` regardless of the
13212      * arguments it receives.
13213      *
13214      * @static
13215      * @memberOf _
13216      * @category Util
13217      * @example
13218      *
13219      * var object = { 'user': 'fred' };
13220      *
13221      * _.noop(object) === undefined;
13222      * // => true
13223      */
13224     function noop() {
13225       // No operation performed.
13226     }
13227
13228     /**
13229      * Creates a function that returns its nth argument.
13230      *
13231      * @static
13232      * @memberOf _
13233      * @category Util
13234      * @param {number} [n=0] The index of the argument to return.
13235      * @returns {Function} Returns the new function.
13236      * @example
13237      *
13238      * var func = _.nthArg(1);
13239      *
13240      * func('a', 'b', 'c');
13241      * // => 'b'
13242      */
13243     function nthArg(n) {
13244       n = toInteger(n);
13245       return function() {
13246         return arguments[n];
13247       };
13248     }
13249
13250     /**
13251      * Creates a function that invokes `iteratees` with the arguments provided
13252      * to the created function and returns their results.
13253      *
13254      * @static
13255      * @memberOf _
13256      * @category Util
13257      * @param {...(Function|Function[])} iteratees The iteratees to invoke.
13258      * @returns {Function} Returns the new function.
13259      * @example
13260      *
13261      * var func = _.over(Math.max, Math.min);
13262      *
13263      * func(1, 2, 3, 4);
13264      * // => [4, 1]
13265      */
13266     var over = createOver(arrayMap);
13267
13268     /**
13269      * Creates a function that checks if **all** of the `predicates` return
13270      * truthy when invoked with the arguments provided to the created function.
13271      *
13272      * @static
13273      * @memberOf _
13274      * @category Util
13275      * @param {...(Function|Function[])} predicates The predicates to check.
13276      * @returns {Function} Returns the new function.
13277      * @example
13278      *
13279      * var func = _.overEvery(Boolean, isFinite);
13280      *
13281      * func('1');
13282      * // => true
13283      *
13284      * func(null);
13285      * // => false
13286      *
13287      * func(NaN);
13288      * // => false
13289      */
13290     var overEvery = createOver(arrayEvery);
13291
13292     /**
13293      * Creates a function that checks if **any** of the `predicates` return
13294      * truthy when invoked with the arguments provided to the created function.
13295      *
13296      * @static
13297      * @memberOf _
13298      * @category Util
13299      * @param {...(Function|Function[])} predicates The predicates to check.
13300      * @returns {Function} Returns the new function.
13301      * @example
13302      *
13303      * var func = _.overSome(Boolean, isFinite);
13304      *
13305      * func('1');
13306      * // => true
13307      *
13308      * func(null);
13309      * // => true
13310      *
13311      * func(NaN);
13312      * // => false
13313      */
13314     var overSome = createOver(arraySome);
13315
13316     /**
13317      * Creates a function that returns the value at `path` of a given object.
13318      *
13319      * @static
13320      * @memberOf _
13321      * @category Util
13322      * @param {Array|string} path The path of the property to get.
13323      * @returns {Function} Returns the new function.
13324      * @example
13325      *
13326      * var objects = [
13327      *   { 'a': { 'b': { 'c': 2 } } },
13328      *   { 'a': { 'b': { 'c': 1 } } }
13329      * ];
13330      *
13331      * _.map(objects, _.property('a.b.c'));
13332      * // => [2, 1]
13333      *
13334      * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
13335      * // => [1, 2]
13336      */
13337     function property(path) {
13338       return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
13339     }
13340
13341     /**
13342      * The opposite of `_.property`; this method creates a function that returns
13343      * the value at a given path of `object`.
13344      *
13345      * @static
13346      * @memberOf _
13347      * @category Util
13348      * @param {Object} object The object to query.
13349      * @returns {Function} Returns the new function.
13350      * @example
13351      *
13352      * var array = [0, 1, 2],
13353      *     object = { 'a': array, 'b': array, 'c': array };
13354      *
13355      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
13356      * // => [2, 0]
13357      *
13358      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
13359      * // => [2, 0]
13360      */
13361     function propertyOf(object) {
13362       return function(path) {
13363         return object == null ? undefined : baseGet(object, path);
13364       };
13365     }
13366
13367     /**
13368      * Creates an array of numbers (positive and/or negative) progressing from
13369      * `start` up to, but not including, `end`. A step of `-1` is used if a negative
13370      * `start` is specified without an `end` or `step`. If `end` is not specified
13371      * it's set to `start` with `start` then set to `0`.  If `end` is less than
13372      * `start` a zero-length range is created unless a negative `step` is specified.
13373      *
13374      * **Note:** JavaScript follows the IEEE-754 standard for resolving
13375      * floating-point values which can produce unexpected results.
13376      *
13377      * @static
13378      * @memberOf _
13379      * @category Util
13380      * @param {number} [start=0] The start of the range.
13381      * @param {number} end The end of the range.
13382      * @param {number} [step=1] The value to increment or decrement by.
13383      * @returns {Array} Returns the new array of numbers.
13384      * @example
13385      *
13386      * _.range(4);
13387      * // => [0, 1, 2, 3]
13388      *
13389      * _.range(-4);
13390      * // => [0, -1, -2, -3]
13391      *
13392      * _.range(1, 5);
13393      * // => [1, 2, 3, 4]
13394      *
13395      * _.range(0, 20, 5);
13396      * // => [0, 5, 10, 15]
13397      *
13398      * _.range(0, -4, -1);
13399      * // => [0, -1, -2, -3]
13400      *
13401      * _.range(1, 4, 0);
13402      * // => [1, 1, 1]
13403      *
13404      * _.range(0);
13405      * // => []
13406      */
13407     var range = createRange();
13408
13409     /**
13410      * This method is like `_.range` except that it populates values in
13411      * descending order.
13412      *
13413      * @static
13414      * @memberOf _
13415      * @category Util
13416      * @param {number} [start=0] The start of the range.
13417      * @param {number} end The end of the range.
13418      * @param {number} [step=1] The value to increment or decrement by.
13419      * @returns {Array} Returns the new array of numbers.
13420      * @example
13421      *
13422      * _.rangeRight(4);
13423      * // => [3, 2, 1, 0]
13424      *
13425      * _.rangeRight(-4);
13426      * // => [-3, -2, -1, 0]
13427      *
13428      * _.rangeRight(1, 5);
13429      * // => [4, 3, 2, 1]
13430      *
13431      * _.rangeRight(0, 20, 5);
13432      * // => [15, 10, 5, 0]
13433      *
13434      * _.rangeRight(0, -4, -1);
13435      * // => [-3, -2, -1, 0]
13436      *
13437      * _.rangeRight(1, 4, 0);
13438      * // => [1, 1, 1]
13439      *
13440      * _.rangeRight(0);
13441      * // => []
13442      */
13443     var rangeRight = createRange(true);
13444
13445     /**
13446      * Invokes the iteratee function `n` times, returning an array of the results
13447      * of each invocation. The iteratee is invoked with one argument; (index).
13448      *
13449      * @static
13450      * @memberOf _
13451      * @category Util
13452      * @param {number} n The number of times to invoke `iteratee`.
13453      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13454      * @returns {Array} Returns the array of results.
13455      * @example
13456      *
13457      * _.times(3, String);
13458      * // => ['0', '1', '2']
13459      *
13460      *  _.times(4, _.constant(true));
13461      * // => [true, true, true, true]
13462      */
13463     function times(n, iteratee) {
13464       n = toInteger(n);
13465       if (n < 1 || n > MAX_SAFE_INTEGER) {
13466         return [];
13467       }
13468       var index = MAX_ARRAY_LENGTH,
13469           length = nativeMin(n, MAX_ARRAY_LENGTH);
13470
13471       iteratee = toFunction(iteratee);
13472       n -= MAX_ARRAY_LENGTH;
13473
13474       var result = baseTimes(length, iteratee);
13475       while (++index < n) {
13476         iteratee(index);
13477       }
13478       return result;
13479     }
13480
13481     /**
13482      * Converts `value` to a property path array.
13483      *
13484      * @static
13485      * @memberOf _
13486      * @category Util
13487      * @param {*} value The value to convert.
13488      * @returns {Array} Returns the new property path array.
13489      * @example
13490      *
13491      * _.toPath('a.b.c');
13492      * // => ['a', 'b', 'c']
13493      *
13494      * _.toPath('a[0].b.c');
13495      * // => ['a', '0', 'b', 'c']
13496      *
13497      * var path = ['a', 'b', 'c'],
13498      *     newPath = _.toPath(path);
13499      *
13500      * console.log(newPath);
13501      * // => ['a', 'b', 'c']
13502      *
13503      * console.log(path === newPath);
13504      * // => false
13505      */
13506     function toPath(value) {
13507       return isArray(value) ? arrayMap(value, String) : stringToPath(value);
13508     }
13509
13510     /**
13511      * Generates a unique ID. If `prefix` is provided the ID is appended to it.
13512      *
13513      * @static
13514      * @memberOf _
13515      * @category Util
13516      * @param {string} [prefix] The value to prefix the ID with.
13517      * @returns {string} Returns the unique ID.
13518      * @example
13519      *
13520      * _.uniqueId('contact_');
13521      * // => 'contact_104'
13522      *
13523      * _.uniqueId();
13524      * // => '105'
13525      */
13526     function uniqueId(prefix) {
13527       var id = ++idCounter;
13528       return toString(prefix) + id;
13529     }
13530
13531     /*------------------------------------------------------------------------*/
13532
13533     /**
13534      * Adds two numbers.
13535      *
13536      * @static
13537      * @memberOf _
13538      * @category Math
13539      * @param {number} augend The first number in an addition.
13540      * @param {number} addend The second number in an addition.
13541      * @returns {number} Returns the total.
13542      * @example
13543      *
13544      * _.add(6, 4);
13545      * // => 10
13546      */
13547     function add(augend, addend) {
13548       var result;
13549       if (augend !== undefined) {
13550         result = augend;
13551       }
13552       if (addend !== undefined) {
13553         result = result === undefined ? addend : (result + addend);
13554       }
13555       return result;
13556     }
13557
13558     /**
13559      * Computes `number` rounded up to `precision`.
13560      *
13561      * @static
13562      * @memberOf _
13563      * @category Math
13564      * @param {number} number The number to round up.
13565      * @param {number} [precision=0] The precision to round up to.
13566      * @returns {number} Returns the rounded up number.
13567      * @example
13568      *
13569      * _.ceil(4.006);
13570      * // => 5
13571      *
13572      * _.ceil(6.004, 2);
13573      * // => 6.01
13574      *
13575      * _.ceil(6040, -2);
13576      * // => 6100
13577      */
13578     var ceil = createRound('ceil');
13579
13580     /**
13581      * Computes `number` rounded down to `precision`.
13582      *
13583      * @static
13584      * @memberOf _
13585      * @category Math
13586      * @param {number} number The number to round down.
13587      * @param {number} [precision=0] The precision to round down to.
13588      * @returns {number} Returns the rounded down number.
13589      * @example
13590      *
13591      * _.floor(4.006);
13592      * // => 4
13593      *
13594      * _.floor(0.046, 2);
13595      * // => 0.04
13596      *
13597      * _.floor(4060, -2);
13598      * // => 4000
13599      */
13600     var floor = createRound('floor');
13601
13602     /**
13603      * Computes the maximum value of `array`. If `array` is empty or falsey
13604      * `undefined` is returned.
13605      *
13606      * @static
13607      * @memberOf _
13608      * @category Math
13609      * @param {Array} array The array to iterate over.
13610      * @returns {*} Returns the maximum value.
13611      * @example
13612      *
13613      * _.max([4, 2, 8, 6]);
13614      * // => 8
13615      *
13616      * _.max([]);
13617      * // => undefined
13618      */
13619     function max(array) {
13620       return (array && array.length)
13621         ? baseExtremum(array, identity, gt)
13622         : undefined;
13623     }
13624
13625     /**
13626      * This method is like `_.max` except that it accepts `iteratee` which is
13627      * invoked for each element in `array` to generate the criterion by which
13628      * the value is ranked. The iteratee is invoked with one argument: (value).
13629      *
13630      * @static
13631      * @memberOf _
13632      * @category Math
13633      * @param {Array} array The array to iterate over.
13634      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13635      * @returns {*} Returns the maximum value.
13636      * @example
13637      *
13638      * var objects = [{ 'n': 1 }, { 'n': 2 }];
13639      *
13640      * _.maxBy(objects, function(o) { return o.a; });
13641      * // => { 'n': 2 }
13642      *
13643      * // using the `_.property` iteratee shorthand
13644      * _.maxBy(objects, 'n');
13645      * // => { 'n': 2 }
13646      */
13647     function maxBy(array, iteratee) {
13648       return (array && array.length)
13649         ? baseExtremum(array, getIteratee(iteratee), gt)
13650         : undefined;
13651     }
13652
13653     /**
13654      * Computes the mean of the values in `array`.
13655      *
13656      * @static
13657      * @memberOf _
13658      * @category Math
13659      * @param {Array} array The array to iterate over.
13660      * @returns {number} Returns the mean.
13661      * @example
13662      *
13663      * _.mean([4, 2, 8, 6]);
13664      * // => 5
13665      */
13666     function mean(array) {
13667       return sum(array) / (array ? array.length : 0);
13668     }
13669
13670     /**
13671      * Computes the minimum value of `array`. If `array` is empty or falsey
13672      * `undefined` is returned.
13673      *
13674      * @static
13675      * @memberOf _
13676      * @category Math
13677      * @param {Array} array The array to iterate over.
13678      * @returns {*} Returns the minimum value.
13679      * @example
13680      *
13681      * _.min([4, 2, 8, 6]);
13682      * // => 2
13683      *
13684      * _.min([]);
13685      * // => undefined
13686      */
13687     function min(array) {
13688       return (array && array.length)
13689         ? baseExtremum(array, identity, lt)
13690         : undefined;
13691     }
13692
13693     /**
13694      * This method is like `_.min` except that it accepts `iteratee` which is
13695      * invoked for each element in `array` to generate the criterion by which
13696      * the value is ranked. The iteratee is invoked with one argument: (value).
13697      *
13698      * @static
13699      * @memberOf _
13700      * @category Math
13701      * @param {Array} array The array to iterate over.
13702      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13703      * @returns {*} Returns the minimum value.
13704      * @example
13705      *
13706      * var objects = [{ 'n': 1 }, { 'n': 2 }];
13707      *
13708      * _.minBy(objects, function(o) { return o.a; });
13709      * // => { 'n': 1 }
13710      *
13711      * // using the `_.property` iteratee shorthand
13712      * _.minBy(objects, 'n');
13713      * // => { 'n': 1 }
13714      */
13715     function minBy(array, iteratee) {
13716       return (array && array.length)
13717         ? baseExtremum(array, getIteratee(iteratee), lt)
13718         : undefined;
13719     }
13720
13721     /**
13722      * Computes `number` rounded to `precision`.
13723      *
13724      * @static
13725      * @memberOf _
13726      * @category Math
13727      * @param {number} number The number to round.
13728      * @param {number} [precision=0] The precision to round to.
13729      * @returns {number} Returns the rounded number.
13730      * @example
13731      *
13732      * _.round(4.006);
13733      * // => 4
13734      *
13735      * _.round(4.006, 2);
13736      * // => 4.01
13737      *
13738      * _.round(4060, -2);
13739      * // => 4100
13740      */
13741     var round = createRound('round');
13742
13743     /**
13744      * Subtract two numbers.
13745      *
13746      * @static
13747      * @memberOf _
13748      * @category Math
13749      * @param {number} minuend The first number in a subtraction.
13750      * @param {number} subtrahend The second number in a subtraction.
13751      * @returns {number} Returns the difference.
13752      * @example
13753      *
13754      * _.subtract(6, 4);
13755      * // => 2
13756      */
13757     function subtract(minuend, subtrahend) {
13758       var result;
13759       if (minuend !== undefined) {
13760         result = minuend;
13761       }
13762       if (subtrahend !== undefined) {
13763         result = result === undefined ? subtrahend : (result - subtrahend);
13764       }
13765       return result;
13766     }
13767
13768     /**
13769      * Computes the sum of the values in `array`.
13770      *
13771      * @static
13772      * @memberOf _
13773      * @category Math
13774      * @param {Array} array The array to iterate over.
13775      * @returns {number} Returns the sum.
13776      * @example
13777      *
13778      * _.sum([4, 2, 8, 6]);
13779      * // => 20
13780      */
13781     function sum(array) {
13782       return (array && array.length)
13783         ? baseSum(array, identity)
13784         : undefined;
13785     }
13786
13787     /**
13788      * This method is like `_.sum` except that it accepts `iteratee` which is
13789      * invoked for each element in `array` to generate the value to be summed.
13790      * The iteratee is invoked with one argument: (value).
13791      *
13792      * @static
13793      * @memberOf _
13794      * @category Math
13795      * @param {Array} array The array to iterate over.
13796      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13797      * @returns {number} Returns the sum.
13798      * @example
13799      *
13800      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
13801      *
13802      * _.sumBy(objects, function(o) { return o.n; });
13803      * // => 20
13804      *
13805      * // using the `_.property` iteratee shorthand
13806      * _.sumBy(objects, 'n');
13807      * // => 20
13808      */
13809     function sumBy(array, iteratee) {
13810       return (array && array.length)
13811         ? baseSum(array, getIteratee(iteratee))
13812         : undefined;
13813     }
13814
13815     /*------------------------------------------------------------------------*/
13816
13817     // Ensure wrappers are instances of `baseLodash`.
13818     lodash.prototype = baseLodash.prototype;
13819
13820     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
13821     LodashWrapper.prototype.constructor = LodashWrapper;
13822
13823     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
13824     LazyWrapper.prototype.constructor = LazyWrapper;
13825
13826     // Avoid inheriting from `Object.prototype` when possible.
13827     Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
13828
13829     // Add functions to the `MapCache`.
13830     MapCache.prototype.clear = mapClear;
13831     MapCache.prototype['delete'] = mapDelete;
13832     MapCache.prototype.get = mapGet;
13833     MapCache.prototype.has = mapHas;
13834     MapCache.prototype.set = mapSet;
13835
13836     // Add functions to the `SetCache`.
13837     SetCache.prototype.push = cachePush;
13838
13839     // Add functions to the `Stack` cache.
13840     Stack.prototype.clear = stackClear;
13841     Stack.prototype['delete'] = stackDelete;
13842     Stack.prototype.get = stackGet;
13843     Stack.prototype.has = stackHas;
13844     Stack.prototype.set = stackSet;
13845
13846     // Assign cache to `_.memoize`.
13847     memoize.Cache = MapCache;
13848
13849     // Add functions that return wrapped values when chaining.
13850     lodash.after = after;
13851     lodash.ary = ary;
13852     lodash.assign = assign;
13853     lodash.assignIn = assignIn;
13854     lodash.assignInWith = assignInWith;
13855     lodash.assignWith = assignWith;
13856     lodash.at = at;
13857     lodash.before = before;
13858     lodash.bind = bind;
13859     lodash.bindAll = bindAll;
13860     lodash.bindKey = bindKey;
13861     lodash.chain = chain;
13862     lodash.chunk = chunk;
13863     lodash.compact = compact;
13864     lodash.concat = concat;
13865     lodash.cond = cond;
13866     lodash.conforms = conforms;
13867     lodash.constant = constant;
13868     lodash.countBy = countBy;
13869     lodash.create = create;
13870     lodash.curry = curry;
13871     lodash.curryRight = curryRight;
13872     lodash.debounce = debounce;
13873     lodash.defaults = defaults;
13874     lodash.defaultsDeep = defaultsDeep;
13875     lodash.defer = defer;
13876     lodash.delay = delay;
13877     lodash.difference = difference;
13878     lodash.differenceBy = differenceBy;
13879     lodash.differenceWith = differenceWith;
13880     lodash.drop = drop;
13881     lodash.dropRight = dropRight;
13882     lodash.dropRightWhile = dropRightWhile;
13883     lodash.dropWhile = dropWhile;
13884     lodash.fill = fill;
13885     lodash.filter = filter;
13886     lodash.flatMap = flatMap;
13887     lodash.flatten = flatten;
13888     lodash.flattenDeep = flattenDeep;
13889     lodash.flip = flip;
13890     lodash.flow = flow;
13891     lodash.flowRight = flowRight;
13892     lodash.fromPairs = fromPairs;
13893     lodash.functions = functions;
13894     lodash.functionsIn = functionsIn;
13895     lodash.groupBy = groupBy;
13896     lodash.initial = initial;
13897     lodash.intersection = intersection;
13898     lodash.intersectionBy = intersectionBy;
13899     lodash.intersectionWith = intersectionWith;
13900     lodash.invert = invert;
13901     lodash.invokeMap = invokeMap;
13902     lodash.iteratee = iteratee;
13903     lodash.keyBy = keyBy;
13904     lodash.keys = keys;
13905     lodash.keysIn = keysIn;
13906     lodash.map = map;
13907     lodash.mapKeys = mapKeys;
13908     lodash.mapValues = mapValues;
13909     lodash.matches = matches;
13910     lodash.matchesProperty = matchesProperty;
13911     lodash.memoize = memoize;
13912     lodash.merge = merge;
13913     lodash.mergeWith = mergeWith;
13914     lodash.method = method;
13915     lodash.methodOf = methodOf;
13916     lodash.mixin = mixin;
13917     lodash.negate = negate;
13918     lodash.nthArg = nthArg;
13919     lodash.omit = omit;
13920     lodash.omitBy = omitBy;
13921     lodash.once = once;
13922     lodash.orderBy = orderBy;
13923     lodash.over = over;
13924     lodash.overArgs = overArgs;
13925     lodash.overEvery = overEvery;
13926     lodash.overSome = overSome;
13927     lodash.partial = partial;
13928     lodash.partialRight = partialRight;
13929     lodash.partition = partition;
13930     lodash.pick = pick;
13931     lodash.pickBy = pickBy;
13932     lodash.property = property;
13933     lodash.propertyOf = propertyOf;
13934     lodash.pull = pull;
13935     lodash.pullAll = pullAll;
13936     lodash.pullAllBy = pullAllBy;
13937     lodash.pullAt = pullAt;
13938     lodash.range = range;
13939     lodash.rangeRight = rangeRight;
13940     lodash.rearg = rearg;
13941     lodash.reject = reject;
13942     lodash.remove = remove;
13943     lodash.rest = rest;
13944     lodash.reverse = reverse;
13945     lodash.sampleSize = sampleSize;
13946     lodash.set = set;
13947     lodash.setWith = setWith;
13948     lodash.shuffle = shuffle;
13949     lodash.slice = slice;
13950     lodash.sortBy = sortBy;
13951     lodash.sortedUniq = sortedUniq;
13952     lodash.sortedUniqBy = sortedUniqBy;
13953     lodash.split = split;
13954     lodash.spread = spread;
13955     lodash.tail = tail;
13956     lodash.take = take;
13957     lodash.takeRight = takeRight;
13958     lodash.takeRightWhile = takeRightWhile;
13959     lodash.takeWhile = takeWhile;
13960     lodash.tap = tap;
13961     lodash.throttle = throttle;
13962     lodash.thru = thru;
13963     lodash.toArray = toArray;
13964     lodash.toPairs = toPairs;
13965     lodash.toPairsIn = toPairsIn;
13966     lodash.toPath = toPath;
13967     lodash.toPlainObject = toPlainObject;
13968     lodash.transform = transform;
13969     lodash.unary = unary;
13970     lodash.union = union;
13971     lodash.unionBy = unionBy;
13972     lodash.unionWith = unionWith;
13973     lodash.uniq = uniq;
13974     lodash.uniqBy = uniqBy;
13975     lodash.uniqWith = uniqWith;
13976     lodash.unset = unset;
13977     lodash.unzip = unzip;
13978     lodash.unzipWith = unzipWith;
13979     lodash.values = values;
13980     lodash.valuesIn = valuesIn;
13981     lodash.without = without;
13982     lodash.words = words;
13983     lodash.wrap = wrap;
13984     lodash.xor = xor;
13985     lodash.xorBy = xorBy;
13986     lodash.xorWith = xorWith;
13987     lodash.zip = zip;
13988     lodash.zipObject = zipObject;
13989     lodash.zipWith = zipWith;
13990
13991     // Add aliases.
13992     lodash.each = forEach;
13993     lodash.eachRight = forEachRight;
13994     lodash.extend = assignIn;
13995     lodash.extendWith = assignInWith;
13996
13997     // Add functions to `lodash.prototype`.
13998     mixin(lodash, lodash);
13999
14000     /*------------------------------------------------------------------------*/
14001
14002     // Add functions that return unwrapped values when chaining.
14003     lodash.add = add;
14004     lodash.attempt = attempt;
14005     lodash.camelCase = camelCase;
14006     lodash.capitalize = capitalize;
14007     lodash.ceil = ceil;
14008     lodash.clamp = clamp;
14009     lodash.clone = clone;
14010     lodash.cloneDeep = cloneDeep;
14011     lodash.cloneDeepWith = cloneDeepWith;
14012     lodash.cloneWith = cloneWith;
14013     lodash.deburr = deburr;
14014     lodash.endsWith = endsWith;
14015     lodash.eq = eq;
14016     lodash.escape = escape;
14017     lodash.escapeRegExp = escapeRegExp;
14018     lodash.every = every;
14019     lodash.find = find;
14020     lodash.findIndex = findIndex;
14021     lodash.findKey = findKey;
14022     lodash.findLast = findLast;
14023     lodash.findLastIndex = findLastIndex;
14024     lodash.findLastKey = findLastKey;
14025     lodash.floor = floor;
14026     lodash.forEach = forEach;
14027     lodash.forEachRight = forEachRight;
14028     lodash.forIn = forIn;
14029     lodash.forInRight = forInRight;
14030     lodash.forOwn = forOwn;
14031     lodash.forOwnRight = forOwnRight;
14032     lodash.get = get;
14033     lodash.gt = gt;
14034     lodash.gte = gte;
14035     lodash.has = has;
14036     lodash.hasIn = hasIn;
14037     lodash.head = head;
14038     lodash.identity = identity;
14039     lodash.includes = includes;
14040     lodash.indexOf = indexOf;
14041     lodash.inRange = inRange;
14042     lodash.invoke = invoke;
14043     lodash.isArguments = isArguments;
14044     lodash.isArray = isArray;
14045     lodash.isArrayLike = isArrayLike;
14046     lodash.isArrayLikeObject = isArrayLikeObject;
14047     lodash.isBoolean = isBoolean;
14048     lodash.isDate = isDate;
14049     lodash.isElement = isElement;
14050     lodash.isEmpty = isEmpty;
14051     lodash.isEqual = isEqual;
14052     lodash.isEqualWith = isEqualWith;
14053     lodash.isError = isError;
14054     lodash.isFinite = isFinite;
14055     lodash.isFunction = isFunction;
14056     lodash.isInteger = isInteger;
14057     lodash.isLength = isLength;
14058     lodash.isMatch = isMatch;
14059     lodash.isMatchWith = isMatchWith;
14060     lodash.isNaN = isNaN;
14061     lodash.isNative = isNative;
14062     lodash.isNil = isNil;
14063     lodash.isNull = isNull;
14064     lodash.isNumber = isNumber;
14065     lodash.isObject = isObject;
14066     lodash.isObjectLike = isObjectLike;
14067     lodash.isPlainObject = isPlainObject;
14068     lodash.isRegExp = isRegExp;
14069     lodash.isSafeInteger = isSafeInteger;
14070     lodash.isString = isString;
14071     lodash.isSymbol = isSymbol;
14072     lodash.isTypedArray = isTypedArray;
14073     lodash.isUndefined = isUndefined;
14074     lodash.join = join;
14075     lodash.kebabCase = kebabCase;
14076     lodash.last = last;
14077     lodash.lastIndexOf = lastIndexOf;
14078     lodash.lowerCase = lowerCase;
14079     lodash.lowerFirst = lowerFirst;
14080     lodash.lt = lt;
14081     lodash.lte = lte;
14082     lodash.max = max;
14083     lodash.maxBy = maxBy;
14084     lodash.mean = mean;
14085     lodash.min = min;
14086     lodash.minBy = minBy;
14087     lodash.noConflict = noConflict;
14088     lodash.noop = noop;
14089     lodash.now = now;
14090     lodash.pad = pad;
14091     lodash.padEnd = padEnd;
14092     lodash.padStart = padStart;
14093     lodash.parseInt = parseInt;
14094     lodash.random = random;
14095     lodash.reduce = reduce;
14096     lodash.reduceRight = reduceRight;
14097     lodash.repeat = repeat;
14098     lodash.replace = replace;
14099     lodash.result = result;
14100     lodash.round = round;
14101     lodash.runInContext = runInContext;
14102     lodash.sample = sample;
14103     lodash.size = size;
14104     lodash.snakeCase = snakeCase;
14105     lodash.some = some;
14106     lodash.sortedIndex = sortedIndex;
14107     lodash.sortedIndexBy = sortedIndexBy;
14108     lodash.sortedIndexOf = sortedIndexOf;
14109     lodash.sortedLastIndex = sortedLastIndex;
14110     lodash.sortedLastIndexBy = sortedLastIndexBy;
14111     lodash.sortedLastIndexOf = sortedLastIndexOf;
14112     lodash.startCase = startCase;
14113     lodash.startsWith = startsWith;
14114     lodash.subtract = subtract;
14115     lodash.sum = sum;
14116     lodash.sumBy = sumBy;
14117     lodash.template = template;
14118     lodash.times = times;
14119     lodash.toInteger = toInteger;
14120     lodash.toLength = toLength;
14121     lodash.toLower = toLower;
14122     lodash.toNumber = toNumber;
14123     lodash.toSafeInteger = toSafeInteger;
14124     lodash.toString = toString;
14125     lodash.toUpper = toUpper;
14126     lodash.trim = trim;
14127     lodash.trimEnd = trimEnd;
14128     lodash.trimStart = trimStart;
14129     lodash.truncate = truncate;
14130     lodash.unescape = unescape;
14131     lodash.uniqueId = uniqueId;
14132     lodash.upperCase = upperCase;
14133     lodash.upperFirst = upperFirst;
14134
14135     // Add aliases.
14136     lodash.first = head;
14137
14138     mixin(lodash, (function() {
14139       var source = {};
14140       baseForOwn(lodash, function(func, methodName) {
14141         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
14142           source[methodName] = func;
14143         }
14144       });
14145       return source;
14146     }()), { 'chain': false });
14147
14148     /*------------------------------------------------------------------------*/
14149
14150     /**
14151      * The semantic version number.
14152      *
14153      * @static
14154      * @memberOf _
14155      * @type string
14156      */
14157     lodash.VERSION = VERSION;
14158
14159     // Assign default placeholders.
14160     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
14161       lodash[methodName].placeholder = lodash;
14162     });
14163
14164     // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
14165     arrayEach(['drop', 'take'], function(methodName, index) {
14166       LazyWrapper.prototype[methodName] = function(n) {
14167         var filtered = this.__filtered__;
14168         if (filtered && !index) {
14169           return new LazyWrapper(this);
14170         }
14171         n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
14172
14173         var result = this.clone();
14174         if (filtered) {
14175           result.__takeCount__ = nativeMin(n, result.__takeCount__);
14176         } else {
14177           result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
14178         }
14179         return result;
14180       };
14181
14182       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
14183         return this.reverse()[methodName](n).reverse();
14184       };
14185     });
14186
14187     // Add `LazyWrapper` methods that accept an `iteratee` value.
14188     arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
14189       var type = index + 1,
14190           isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
14191
14192       LazyWrapper.prototype[methodName] = function(iteratee) {
14193         var result = this.clone();
14194         result.__iteratees__.push({ 'iteratee': getIteratee(iteratee, 3), 'type': type });
14195         result.__filtered__ = result.__filtered__ || isFilter;
14196         return result;
14197       };
14198     });
14199
14200     // Add `LazyWrapper` methods for `_.head` and `_.last`.
14201     arrayEach(['head', 'last'], function(methodName, index) {
14202       var takeName = 'take' + (index ? 'Right' : '');
14203
14204       LazyWrapper.prototype[methodName] = function() {
14205         return this[takeName](1).value()[0];
14206       };
14207     });
14208
14209     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
14210     arrayEach(['initial', 'tail'], function(methodName, index) {
14211       var dropName = 'drop' + (index ? '' : 'Right');
14212
14213       LazyWrapper.prototype[methodName] = function() {
14214         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
14215       };
14216     });
14217
14218     LazyWrapper.prototype.compact = function() {
14219       return this.filter(identity);
14220     };
14221
14222     LazyWrapper.prototype.find = function(predicate) {
14223       return this.filter(predicate).head();
14224     };
14225
14226     LazyWrapper.prototype.findLast = function(predicate) {
14227       return this.reverse().find(predicate);
14228     };
14229
14230     LazyWrapper.prototype.invokeMap = rest(function(path, args) {
14231       if (typeof path == 'function') {
14232         return new LazyWrapper(this);
14233       }
14234       return this.map(function(value) {
14235         return baseInvoke(value, path, args);
14236       });
14237     });
14238
14239     LazyWrapper.prototype.reject = function(predicate) {
14240       predicate = getIteratee(predicate, 3);
14241       return this.filter(function(value) {
14242         return !predicate(value);
14243       });
14244     };
14245
14246     LazyWrapper.prototype.slice = function(start, end) {
14247       start = toInteger(start);
14248
14249       var result = this;
14250       if (result.__filtered__ && (start > 0 || end < 0)) {
14251         return new LazyWrapper(result);
14252       }
14253       if (start < 0) {
14254         result = result.takeRight(-start);
14255       } else if (start) {
14256         result = result.drop(start);
14257       }
14258       if (end !== undefined) {
14259         end = toInteger(end);
14260         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
14261       }
14262       return result;
14263     };
14264
14265     LazyWrapper.prototype.takeRightWhile = function(predicate) {
14266       return this.reverse().takeWhile(predicate).reverse();
14267     };
14268
14269     LazyWrapper.prototype.toArray = function() {
14270       return this.take(MAX_ARRAY_LENGTH);
14271     };
14272
14273     // Add `LazyWrapper` methods to `lodash.prototype`.
14274     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14275       var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
14276           isTaker = /^(?:head|last)$/.test(methodName),
14277           lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
14278           retUnwrapped = isTaker || /^find/.test(methodName);
14279
14280       if (!lodashFunc) {
14281         return;
14282       }
14283       lodash.prototype[methodName] = function() {
14284         var value = this.__wrapped__,
14285             args = isTaker ? [1] : arguments,
14286             isLazy = value instanceof LazyWrapper,
14287             iteratee = args[0],
14288             useLazy = isLazy || isArray(value);
14289
14290         var interceptor = function(value) {
14291           var result = lodashFunc.apply(lodash, arrayPush([value], args));
14292           return (isTaker && chainAll) ? result[0] : result;
14293         };
14294
14295         if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
14296           // Avoid lazy use if the iteratee has a "length" value other than `1`.
14297           isLazy = useLazy = false;
14298         }
14299         var chainAll = this.__chain__,
14300             isHybrid = !!this.__actions__.length,
14301             isUnwrapped = retUnwrapped && !chainAll,
14302             onlyLazy = isLazy && !isHybrid;
14303
14304         if (!retUnwrapped && useLazy) {
14305           value = onlyLazy ? value : new LazyWrapper(this);
14306           var result = func.apply(value, args);
14307           result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
14308           return new LodashWrapper(result, chainAll);
14309         }
14310         if (isUnwrapped && onlyLazy) {
14311           return func.apply(this, args);
14312         }
14313         result = this.thru(interceptor);
14314         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
14315       };
14316     });
14317
14318     // Add `Array` and `String` methods to `lodash.prototype`.
14319     arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
14320       var func = arrayProto[methodName],
14321           chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
14322           retUnwrapped = /^(?:pop|shift)$/.test(methodName);
14323
14324       lodash.prototype[methodName] = function() {
14325         var args = arguments;
14326         if (retUnwrapped && !this.__chain__) {
14327           return func.apply(this.value(), args);
14328         }
14329         return this[chainName](function(value) {
14330           return func.apply(value, args);
14331         });
14332       };
14333     });
14334
14335     // Map minified function names to their real names.
14336     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14337       var lodashFunc = lodash[methodName];
14338       if (lodashFunc) {
14339         var key = (lodashFunc.name + ''),
14340             names = realNames[key] || (realNames[key] = []);
14341
14342         names.push({ 'name': methodName, 'func': lodashFunc });
14343       }
14344     });
14345
14346     realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];
14347
14348     // Add functions to the lazy wrapper.
14349     LazyWrapper.prototype.clone = lazyClone;
14350     LazyWrapper.prototype.reverse = lazyReverse;
14351     LazyWrapper.prototype.value = lazyValue;
14352
14353     // Add chaining functions to the `lodash` wrapper.
14354     lodash.prototype.at = wrapperAt;
14355     lodash.prototype.chain = wrapperChain;
14356     lodash.prototype.commit = wrapperCommit;
14357     lodash.prototype.flatMap = wrapperFlatMap;
14358     lodash.prototype.next = wrapperNext;
14359     lodash.prototype.plant = wrapperPlant;
14360     lodash.prototype.reverse = wrapperReverse;
14361     lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
14362
14363     if (iteratorSymbol) {
14364       lodash.prototype[iteratorSymbol] = wrapperToIterator;
14365     }
14366     return lodash;
14367   }
14368
14369   /*--------------------------------------------------------------------------*/
14370
14371   // Export lodash.
14372   var _ = runInContext();
14373
14374   // Expose lodash on the free variable `window` or `self` when available. This
14375   // prevents errors in cases where lodash is loaded by a script tag in the presence
14376   // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
14377   (freeWindow || freeSelf || {})._ = _;
14378
14379   // Some AMD build optimizers like r.js check for condition patterns like the following:
14380   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
14381     // Define as an anonymous module so, through path mapping, it can be
14382     // referenced as the "underscore" module.
14383     define(function() {
14384       return _;
14385     });
14386   }
14387   // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
14388   else if (freeExports && freeModule) {
14389     // Export for Node.js.
14390     if (moduleExports) {
14391       (freeModule.exports = _)._ = _;
14392     }
14393     // Export for CommonJS support.
14394     freeExports._ = _;
14395   }
14396   else {
14397     // Export to the global object.
14398     root._ = _;
14399   }
14400 }.call(this));