Built motion from commit 99feb03.|0.0.140
[motion.git] / public / bower_components / lodash / dist / lodash.js
1 /**
2  * @license
3  * lodash 4.5.1 (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.5.1';
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       weakSetTag = '[object WeakSet]';
87
88   var arrayBufferTag = '[object ArrayBuffer]',
89       float32Tag = '[object Float32Array]',
90       float64Tag = '[object Float64Array]',
91       int8Tag = '[object Int8Array]',
92       int16Tag = '[object Int16Array]',
93       int32Tag = '[object Int32Array]',
94       uint8Tag = '[object Uint8Array]',
95       uint8ClampedTag = '[object Uint8ClampedArray]',
96       uint16Tag = '[object Uint16Array]',
97       uint32Tag = '[object Uint32Array]';
98
99   /** Used to match empty string literals in compiled template source. */
100   var reEmptyStringLeading = /\b__p \+= '';/g,
101       reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
102       reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
103
104   /** Used to match HTML entities and HTML characters. */
105   var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
106       reUnescapedHtml = /[&<>"'`]/g,
107       reHasEscapedHtml = RegExp(reEscapedHtml.source),
108       reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
109
110   /** Used to match template delimiters. */
111   var reEscape = /<%-([\s\S]+?)%>/g,
112       reEvaluate = /<%([\s\S]+?)%>/g,
113       reInterpolate = /<%=([\s\S]+?)%>/g;
114
115   /** Used to match property names within property paths. */
116   var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
117       reIsPlainProp = /^\w*$/,
118       rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
119
120   /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
121   var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
122       reHasRegExpChar = RegExp(reRegExpChar.source);
123
124   /** Used to match leading and trailing whitespace. */
125   var reTrim = /^\s+|\s+$/g,
126       reTrimStart = /^\s+/,
127       reTrimEnd = /\s+$/;
128
129   /** Used to match backslashes in property paths. */
130   var reEscapeChar = /\\(\\)?/g;
131
132   /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
133   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
134
135   /** Used to match `RegExp` flags from their coerced string values. */
136   var reFlags = /\w*$/;
137
138   /** Used to detect hexadecimal string values. */
139   var reHasHexPrefix = /^0x/i;
140
141   /** Used to detect bad signed hexadecimal string values. */
142   var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
143
144   /** Used to detect binary string values. */
145   var reIsBinary = /^0b[01]+$/i;
146
147   /** Used to detect host constructors (Safari > 5). */
148   var reIsHostCtor = /^\[object .+?Constructor\]$/;
149
150   /** Used to detect octal string values. */
151   var reIsOctal = /^0o[0-7]+$/i;
152
153   /** Used to detect unsigned integer values. */
154   var reIsUint = /^(?:0|[1-9]\d*)$/;
155
156   /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
157   var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
158
159   /** Used to ensure capturing order of template delimiters. */
160   var reNoMatch = /($^)/;
161
162   /** Used to match unescaped characters in compiled string literals. */
163   var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
164
165   /** Used to compose unicode character classes. */
166   var rsAstralRange = '\\ud800-\\udfff',
167       rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
168       rsComboSymbolsRange = '\\u20d0-\\u20f0',
169       rsDingbatRange = '\\u2700-\\u27bf',
170       rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
171       rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
172       rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
173       rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
174       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',
175       rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
176       rsVarRange = '\\ufe0e\\ufe0f',
177       rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
178
179   /** Used to compose unicode capture groups. */
180   var rsAstral = '[' + rsAstralRange + ']',
181       rsBreak = '[' + rsBreakRange + ']',
182       rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
183       rsDigits = '\\d+',
184       rsDingbat = '[' + rsDingbatRange + ']',
185       rsLower = '[' + rsLowerRange + ']',
186       rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
187       rsFitz = '\\ud83c[\\udffb-\\udfff]',
188       rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
189       rsNonAstral = '[^' + rsAstralRange + ']',
190       rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
191       rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
192       rsUpper = '[' + rsUpperRange + ']',
193       rsZWJ = '\\u200d';
194
195   /** Used to compose unicode regexes. */
196   var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
197       rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
198       reOptMod = rsModifier + '?',
199       rsOptVar = '[' + rsVarRange + ']?',
200       rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
201       rsSeq = rsOptVar + reOptMod + rsOptJoin,
202       rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
203       rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
204
205   /**
206    * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
207    * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
208    */
209   var reComboMark = RegExp(rsCombo, 'g');
210
211   /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
212   var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
213
214   /** 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/). */
215   var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
216
217   /** Used to match non-compound words composed of alphanumeric characters. */
218   var reBasicWord = /[a-zA-Z0-9]+/g;
219
220   /** Used to match complex or compound words. */
221   var reComplexWord = RegExp([
222     rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
223     rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
224     rsUpper + '?' + rsLowerMisc + '+',
225     rsUpper + '+',
226     rsDigits,
227     rsEmoji
228   ].join('|'), 'g');
229
230   /** Used to detect strings that need a more robust regexp to match words. */
231   var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
232
233   /** Used to assign default `context` object properties. */
234   var contextProps = [
235     'Array', 'Buffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
236     'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
237     'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
238     'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
239     'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
240   ];
241
242   /** Used to make template sourceURLs easier to identify. */
243   var templateCounter = -1;
244
245   /** Used to identify `toStringTag` values of typed arrays. */
246   var typedArrayTags = {};
247   typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
248   typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
249   typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
250   typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
251   typedArrayTags[uint32Tag] = true;
252   typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
253   typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
254   typedArrayTags[dateTag] = typedArrayTags[errorTag] =
255   typedArrayTags[funcTag] = typedArrayTags[mapTag] =
256   typedArrayTags[numberTag] = typedArrayTags[objectTag] =
257   typedArrayTags[regexpTag] = typedArrayTags[setTag] =
258   typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
259
260   /** Used to identify `toStringTag` values supported by `_.clone`. */
261   var cloneableTags = {};
262   cloneableTags[argsTag] = cloneableTags[arrayTag] =
263   cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
264   cloneableTags[dateTag] = cloneableTags[float32Tag] =
265   cloneableTags[float64Tag] = cloneableTags[int8Tag] =
266   cloneableTags[int16Tag] = cloneableTags[int32Tag] =
267   cloneableTags[mapTag] = cloneableTags[numberTag] =
268   cloneableTags[objectTag] = cloneableTags[regexpTag] =
269   cloneableTags[setTag] = cloneableTags[stringTag] =
270   cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
271   cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
272   cloneableTags[uint32Tag] = true;
273   cloneableTags[errorTag] = cloneableTags[funcTag] =
274   cloneableTags[weakMapTag] = false;
275
276   /** Used to map latin-1 supplementary letters to basic latin letters. */
277   var deburredLetters = {
278     '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
279     '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
280     '\xc7': 'C',  '\xe7': 'c',
281     '\xd0': 'D',  '\xf0': 'd',
282     '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
283     '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
284     '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
285     '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
286     '\xd1': 'N',  '\xf1': 'n',
287     '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
288     '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
289     '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
290     '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
291     '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
292     '\xc6': 'Ae', '\xe6': 'ae',
293     '\xde': 'Th', '\xfe': 'th',
294     '\xdf': 'ss'
295   };
296
297   /** Used to map characters to HTML entities. */
298   var htmlEscapes = {
299     '&': '&amp;',
300     '<': '&lt;',
301     '>': '&gt;',
302     '"': '&quot;',
303     "'": '&#39;',
304     '`': '&#96;'
305   };
306
307   /** Used to map HTML entities to characters. */
308   var htmlUnescapes = {
309     '&amp;': '&',
310     '&lt;': '<',
311     '&gt;': '>',
312     '&quot;': '"',
313     '&#39;': "'",
314     '&#96;': '`'
315   };
316
317   /** Used to determine if values are of the language type `Object`. */
318   var objectTypes = {
319     'function': true,
320     'object': true
321   };
322
323   /** Used to escape characters for inclusion in compiled string literals. */
324   var stringEscapes = {
325     '\\': '\\',
326     "'": "'",
327     '\n': 'n',
328     '\r': 'r',
329     '\u2028': 'u2028',
330     '\u2029': 'u2029'
331   };
332
333   /** Built-in method references without a dependency on `root`. */
334   var freeParseFloat = parseFloat,
335       freeParseInt = parseInt;
336
337   /** Detect free variable `exports`. */
338   var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
339     ? exports
340     : undefined;
341
342   /** Detect free variable `module`. */
343   var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
344     ? module
345     : undefined;
346
347   /** Detect the popular CommonJS extension `module.exports`. */
348   var moduleExports = (freeModule && freeModule.exports === freeExports)
349     ? freeExports
350     : undefined;
351
352   /** Detect free variable `global` from Node.js. */
353   var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
354
355   /** Detect free variable `self`. */
356   var freeSelf = checkGlobal(objectTypes[typeof self] && self);
357
358   /** Detect free variable `window`. */
359   var freeWindow = checkGlobal(objectTypes[typeof window] && window);
360
361   /** Detect `this` as the global object. */
362   var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
363
364   /**
365    * Used as a reference to the global object.
366    *
367    * The `this` value is used if it's the global object to avoid Greasemonkey's
368    * restricted `window` object, otherwise the `window` object is used.
369    */
370   var root = freeGlobal ||
371     ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
372       freeSelf || thisGlobal || Function('return this')();
373
374   /*--------------------------------------------------------------------------*/
375
376   /**
377    * Adds the key-value `pair` to `map`.
378    *
379    * @private
380    * @param {Object} map The map to modify.
381    * @param {Array} pair The key-value pair to add.
382    * @returns {Object} Returns `map`.
383    */
384   function addMapEntry(map, pair) {
385     map.set(pair[0], pair[1]);
386     return map;
387   }
388
389   /**
390    * Adds `value` to `set`.
391    *
392    * @private
393    * @param {Object} set The set to modify.
394    * @param {*} value The value to add.
395    * @returns {Object} Returns `set`.
396    */
397   function addSetEntry(set, value) {
398     set.add(value);
399     return set;
400   }
401
402   /**
403    * A faster alternative to `Function#apply`, this function invokes `func`
404    * with the `this` binding of `thisArg` and the arguments of `args`.
405    *
406    * @private
407    * @param {Function} func The function to invoke.
408    * @param {*} thisArg The `this` binding of `func`.
409    * @param {...*} args The arguments to invoke `func` with.
410    * @returns {*} Returns the result of `func`.
411    */
412   function apply(func, thisArg, args) {
413     var length = args.length;
414     switch (length) {
415       case 0: return func.call(thisArg);
416       case 1: return func.call(thisArg, args[0]);
417       case 2: return func.call(thisArg, args[0], args[1]);
418       case 3: return func.call(thisArg, args[0], args[1], args[2]);
419     }
420     return func.apply(thisArg, args);
421   }
422
423   /**
424    * A specialized version of `baseAggregator` for arrays.
425    *
426    * @private
427    * @param {Array} array The array to iterate over.
428    * @param {Function} setter The function to set `accumulator` values.
429    * @param {Function} iteratee The iteratee to transform keys.
430    * @param {Object} accumulator The initial aggregated object.
431    * @returns {Function} Returns `accumulator`.
432    */
433   function arrayAggregator(array, setter, iteratee, accumulator) {
434     var index = -1,
435         length = array.length;
436
437     while (++index < length) {
438       var value = array[index];
439       setter(accumulator, value, iteratee(value), array);
440     }
441     return accumulator;
442   }
443
444   /**
445    * Creates a new array concatenating `array` with `other`.
446    *
447    * @private
448    * @param {Array} array The first array to concatenate.
449    * @param {Array} other The second array to concatenate.
450    * @returns {Array} Returns the new concatenated array.
451    */
452   function arrayConcat(array, other) {
453     var index = -1,
454         length = array.length,
455         othIndex = -1,
456         othLength = other.length,
457         result = Array(length + othLength);
458
459     while (++index < length) {
460       result[index] = array[index];
461     }
462     while (++othIndex < othLength) {
463       result[index++] = other[othIndex];
464     }
465     return result;
466   }
467
468   /**
469    * A specialized version of `_.forEach` for arrays without support for
470    * iteratee shorthands.
471    *
472    * @private
473    * @param {Array} array The array to iterate over.
474    * @param {Function} iteratee The function invoked per iteration.
475    * @returns {Array} Returns `array`.
476    */
477   function arrayEach(array, iteratee) {
478     var index = -1,
479         length = array.length;
480
481     while (++index < length) {
482       if (iteratee(array[index], index, array) === false) {
483         break;
484       }
485     }
486     return array;
487   }
488
489   /**
490    * A specialized version of `_.forEachRight` for arrays without support for
491    * iteratee shorthands.
492    *
493    * @private
494    * @param {Array} array The array to iterate over.
495    * @param {Function} iteratee The function invoked per iteration.
496    * @returns {Array} Returns `array`.
497    */
498   function arrayEachRight(array, iteratee) {
499     var length = array.length;
500
501     while (length--) {
502       if (iteratee(array[length], length, array) === false) {
503         break;
504       }
505     }
506     return array;
507   }
508
509   /**
510    * A specialized version of `_.every` for arrays without support for
511    * iteratee shorthands.
512    *
513    * @private
514    * @param {Array} array The array to iterate over.
515    * @param {Function} predicate The function invoked per iteration.
516    * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
517    */
518   function arrayEvery(array, predicate) {
519     var index = -1,
520         length = array.length;
521
522     while (++index < length) {
523       if (!predicate(array[index], index, array)) {
524         return false;
525       }
526     }
527     return true;
528   }
529
530   /**
531    * A specialized version of `_.filter` for arrays without support for
532    * iteratee shorthands.
533    *
534    * @private
535    * @param {Array} array The array to iterate over.
536    * @param {Function} predicate The function invoked per iteration.
537    * @returns {Array} Returns the new filtered array.
538    */
539   function arrayFilter(array, predicate) {
540     var index = -1,
541         length = array.length,
542         resIndex = -1,
543         result = [];
544
545     while (++index < length) {
546       var value = array[index];
547       if (predicate(value, index, array)) {
548         result[++resIndex] = value;
549       }
550     }
551     return result;
552   }
553
554   /**
555    * A specialized version of `_.includes` for arrays without support for
556    * specifying an index to search from.
557    *
558    * @private
559    * @param {Array} array The array to search.
560    * @param {*} target The value to search for.
561    * @returns {boolean} Returns `true` if `target` is found, else `false`.
562    */
563   function arrayIncludes(array, value) {
564     return !!array.length && baseIndexOf(array, value, 0) > -1;
565   }
566
567   /**
568    * A specialized version of `_.includesWith` for arrays without support for
569    * specifying an index to search from.
570    *
571    * @private
572    * @param {Array} array The array to search.
573    * @param {*} target The value to search for.
574    * @param {Function} comparator The comparator invoked per element.
575    * @returns {boolean} Returns `true` if `target` is found, else `false`.
576    */
577   function arrayIncludesWith(array, value, comparator) {
578     var index = -1,
579         length = array.length;
580
581     while (++index < length) {
582       if (comparator(value, array[index])) {
583         return true;
584       }
585     }
586     return false;
587   }
588
589   /**
590    * A specialized version of `_.map` for arrays without support for iteratee
591    * shorthands.
592    *
593    * @private
594    * @param {Array} array The array to iterate over.
595    * @param {Function} iteratee The function invoked per iteration.
596    * @returns {Array} Returns the new mapped array.
597    */
598   function arrayMap(array, iteratee) {
599     var index = -1,
600         length = array.length,
601         result = Array(length);
602
603     while (++index < length) {
604       result[index] = iteratee(array[index], index, array);
605     }
606     return result;
607   }
608
609   /**
610    * Appends the elements of `values` to `array`.
611    *
612    * @private
613    * @param {Array} array The array to modify.
614    * @param {Array} values The values to append.
615    * @returns {Array} Returns `array`.
616    */
617   function arrayPush(array, values) {
618     var index = -1,
619         length = values.length,
620         offset = array.length;
621
622     while (++index < length) {
623       array[offset + index] = values[index];
624     }
625     return array;
626   }
627
628   /**
629    * A specialized version of `_.reduce` for arrays without support for
630    * iteratee shorthands.
631    *
632    * @private
633    * @param {Array} array The array to iterate over.
634    * @param {Function} iteratee The function invoked per iteration.
635    * @param {*} [accumulator] The initial value.
636    * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
637    * @returns {*} Returns the accumulated value.
638    */
639   function arrayReduce(array, iteratee, accumulator, initAccum) {
640     var index = -1,
641         length = array.length;
642
643     if (initAccum && length) {
644       accumulator = array[++index];
645     }
646     while (++index < length) {
647       accumulator = iteratee(accumulator, array[index], index, array);
648     }
649     return accumulator;
650   }
651
652   /**
653    * A specialized version of `_.reduceRight` for arrays without support for
654    * iteratee shorthands.
655    *
656    * @private
657    * @param {Array} array The array to iterate over.
658    * @param {Function} iteratee The function invoked per iteration.
659    * @param {*} [accumulator] The initial value.
660    * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value.
661    * @returns {*} Returns the accumulated value.
662    */
663   function arrayReduceRight(array, iteratee, accumulator, initAccum) {
664     var length = array.length;
665     if (initAccum && length) {
666       accumulator = array[--length];
667     }
668     while (length--) {
669       accumulator = iteratee(accumulator, array[length], length, array);
670     }
671     return accumulator;
672   }
673
674   /**
675    * A specialized version of `_.some` for arrays without support for iteratee
676    * shorthands.
677    *
678    * @private
679    * @param {Array} array The array to iterate over.
680    * @param {Function} predicate The function invoked per iteration.
681    * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
682    */
683   function arraySome(array, predicate) {
684     var index = -1,
685         length = array.length;
686
687     while (++index < length) {
688       if (predicate(array[index], index, array)) {
689         return true;
690       }
691     }
692     return false;
693   }
694
695   /**
696    * The base implementation of methods like `_.max` and `_.min` which accepts a
697    * `comparator` to determine the extremum value.
698    *
699    * @private
700    * @param {Array} array The array to iterate over.
701    * @param {Function} iteratee The iteratee invoked per iteration.
702    * @param {Function} comparator The comparator used to compare values.
703    * @returns {*} Returns the extremum value.
704    */
705   function baseExtremum(array, iteratee, comparator) {
706     var index = -1,
707         length = array.length;
708
709     while (++index < length) {
710       var value = array[index],
711           current = iteratee(value);
712
713       if (current != null && (computed === undefined
714             ? current === current
715             : comparator(current, computed)
716           )) {
717         var computed = current,
718             result = value;
719       }
720     }
721     return result;
722   }
723
724   /**
725    * The base implementation of methods like `_.find` and `_.findKey`, without
726    * support for iteratee shorthands, which iterates over `collection` using
727    * `eachFunc`.
728    *
729    * @private
730    * @param {Array|Object} collection The collection to search.
731    * @param {Function} predicate The function invoked per iteration.
732    * @param {Function} eachFunc The function to iterate over `collection`.
733    * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
734    * @returns {*} Returns the found element or its key, else `undefined`.
735    */
736   function baseFind(collection, predicate, eachFunc, retKey) {
737     var result;
738     eachFunc(collection, function(value, key, collection) {
739       if (predicate(value, key, collection)) {
740         result = retKey ? key : value;
741         return false;
742       }
743     });
744     return result;
745   }
746
747   /**
748    * The base implementation of `_.findIndex` and `_.findLastIndex` without
749    * support for iteratee shorthands.
750    *
751    * @private
752    * @param {Array} array The array to search.
753    * @param {Function} predicate The function invoked per iteration.
754    * @param {boolean} [fromRight] Specify iterating from right to left.
755    * @returns {number} Returns the index of the matched value, else `-1`.
756    */
757   function baseFindIndex(array, predicate, fromRight) {
758     var length = array.length,
759         index = fromRight ? length : -1;
760
761     while ((fromRight ? index-- : ++index < length)) {
762       if (predicate(array[index], index, array)) {
763         return index;
764       }
765     }
766     return -1;
767   }
768
769   /**
770    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
771    *
772    * @private
773    * @param {Array} array The array to search.
774    * @param {*} value The value to search for.
775    * @param {number} fromIndex The index to search from.
776    * @returns {number} Returns the index of the matched value, else `-1`.
777    */
778   function baseIndexOf(array, value, fromIndex) {
779     if (value !== value) {
780       return indexOfNaN(array, fromIndex);
781     }
782     var index = fromIndex - 1,
783         length = array.length;
784
785     while (++index < length) {
786       if (array[index] === value) {
787         return index;
788       }
789     }
790     return -1;
791   }
792
793   /**
794    * The base implementation of `_.reduce` and `_.reduceRight`, without support
795    * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
796    *
797    * @private
798    * @param {Array|Object} collection The collection to iterate over.
799    * @param {Function} iteratee The function invoked per iteration.
800    * @param {*} accumulator The initial value.
801    * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
802    * @param {Function} eachFunc The function to iterate over `collection`.
803    * @returns {*} Returns the accumulated value.
804    */
805   function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
806     eachFunc(collection, function(value, index, collection) {
807       accumulator = initAccum
808         ? (initAccum = false, value)
809         : iteratee(accumulator, value, index, collection);
810     });
811     return accumulator;
812   }
813
814   /**
815    * The base implementation of `_.sortBy` which uses `comparer` to define
816    * the sort order of `array` and replaces criteria objects with their
817    * corresponding values.
818    *
819    * @private
820    * @param {Array} array The array to sort.
821    * @param {Function} comparer The function to define sort order.
822    * @returns {Array} Returns `array`.
823    */
824   function baseSortBy(array, comparer) {
825     var length = array.length;
826
827     array.sort(comparer);
828     while (length--) {
829       array[length] = array[length].value;
830     }
831     return array;
832   }
833
834   /**
835    * The base implementation of `_.sum` without support for iteratee shorthands.
836    *
837    * @private
838    * @param {Array} array The array to iterate over.
839    * @param {Function} iteratee The function invoked per iteration.
840    * @returns {number} Returns the sum.
841    */
842   function baseSum(array, iteratee) {
843     var result,
844         index = -1,
845         length = array.length;
846
847     while (++index < length) {
848       var current = iteratee(array[index]);
849       if (current !== undefined) {
850         result = result === undefined ? current : (result + current);
851       }
852     }
853     return result;
854   }
855
856   /**
857    * The base implementation of `_.times` without support for iteratee shorthands
858    * or max array length checks.
859    *
860    * @private
861    * @param {number} n The number of times to invoke `iteratee`.
862    * @param {Function} iteratee The function invoked per iteration.
863    * @returns {Array} Returns the array of results.
864    */
865   function baseTimes(n, iteratee) {
866     var index = -1,
867         result = Array(n);
868
869     while (++index < n) {
870       result[index] = iteratee(index);
871     }
872     return result;
873   }
874
875   /**
876    * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
877    * of key-value pairs for `object` corresponding to the property names of `props`.
878    *
879    * @private
880    * @param {Object} object The object to query.
881    * @param {Array} props The property names to get values for.
882    * @returns {Object} Returns the new array of key-value pairs.
883    */
884   function baseToPairs(object, props) {
885     return arrayMap(props, function(key) {
886       return [key, object[key]];
887     });
888   }
889
890   /**
891    * The base implementation of `_.unary` without support for storing wrapper metadata.
892    *
893    * @private
894    * @param {Function} func The function to cap arguments for.
895    * @returns {Function} Returns the new function.
896    */
897   function baseUnary(func) {
898     return function(value) {
899       return func(value);
900     };
901   }
902
903   /**
904    * The base implementation of `_.values` and `_.valuesIn` which creates an
905    * array of `object` property values corresponding to the property names
906    * of `props`.
907    *
908    * @private
909    * @param {Object} object The object to query.
910    * @param {Array} props The property names to get values for.
911    * @returns {Object} Returns the array of property values.
912    */
913   function baseValues(object, props) {
914     return arrayMap(props, function(key) {
915       return object[key];
916     });
917   }
918
919   /**
920    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
921    * that is not found in the character symbols.
922    *
923    * @private
924    * @param {Array} strSymbols The string symbols to inspect.
925    * @param {Array} chrSymbols The character symbols to find.
926    * @returns {number} Returns the index of the first unmatched string symbol.
927    */
928   function charsStartIndex(strSymbols, chrSymbols) {
929     var index = -1,
930         length = strSymbols.length;
931
932     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
933     return index;
934   }
935
936   /**
937    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
938    * that is not found in the character symbols.
939    *
940    * @private
941    * @param {Array} strSymbols The string symbols to inspect.
942    * @param {Array} chrSymbols The character symbols to find.
943    * @returns {number} Returns the index of the last unmatched string symbol.
944    */
945   function charsEndIndex(strSymbols, chrSymbols) {
946     var index = strSymbols.length;
947
948     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
949     return index;
950   }
951
952   /**
953    * Checks if `value` is a global object.
954    *
955    * @private
956    * @param {*} value The value to check.
957    * @returns {null|Object} Returns `value` if it's a global object, else `null`.
958    */
959   function checkGlobal(value) {
960     return (value && value.Object === Object) ? value : null;
961   }
962
963   /**
964    * Compares values to sort them in ascending order.
965    *
966    * @private
967    * @param {*} value The value to compare.
968    * @param {*} other The other value to compare.
969    * @returns {number} Returns the sort order indicator for `value`.
970    */
971   function compareAscending(value, other) {
972     if (value !== other) {
973       var valIsNull = value === null,
974           valIsUndef = value === undefined,
975           valIsReflexive = value === value;
976
977       var othIsNull = other === null,
978           othIsUndef = other === undefined,
979           othIsReflexive = other === other;
980
981       if ((value > other && !othIsNull) || !valIsReflexive ||
982           (valIsNull && !othIsUndef && othIsReflexive) ||
983           (valIsUndef && othIsReflexive)) {
984         return 1;
985       }
986       if ((value < other && !valIsNull) || !othIsReflexive ||
987           (othIsNull && !valIsUndef && valIsReflexive) ||
988           (othIsUndef && valIsReflexive)) {
989         return -1;
990       }
991     }
992     return 0;
993   }
994
995   /**
996    * Used by `_.orderBy` to compare multiple properties of a value to another
997    * and stable sort them.
998    *
999    * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
1000    * specify an order of "desc" for descending or "asc" for ascending sort order
1001    * of corresponding values.
1002    *
1003    * @private
1004    * @param {Object} object The object to compare.
1005    * @param {Object} other The other object to compare.
1006    * @param {boolean[]|string[]} orders The order to sort by for each property.
1007    * @returns {number} Returns the sort order indicator for `object`.
1008    */
1009   function compareMultiple(object, other, orders) {
1010     var index = -1,
1011         objCriteria = object.criteria,
1012         othCriteria = other.criteria,
1013         length = objCriteria.length,
1014         ordersLength = orders.length;
1015
1016     while (++index < length) {
1017       var result = compareAscending(objCriteria[index], othCriteria[index]);
1018       if (result) {
1019         if (index >= ordersLength) {
1020           return result;
1021         }
1022         var order = orders[index];
1023         return result * (order == 'desc' ? -1 : 1);
1024       }
1025     }
1026     // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
1027     // that causes it, under certain circumstances, to provide the same value for
1028     // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
1029     // for more details.
1030     //
1031     // This also ensures a stable sort in V8 and other engines.
1032     // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
1033     return object.index - other.index;
1034   }
1035
1036   /**
1037    * Gets the number of `placeholder` occurrences in `array`.
1038    *
1039    * @private
1040    * @param {Array} array The array to inspect.
1041    * @param {*} placeholder The placeholder to search for.
1042    * @returns {number} Returns the placeholder count.
1043    */
1044   function countHolders(array, placeholder) {
1045     var length = array.length,
1046         result = 0;
1047
1048     while (length--) {
1049       if (array[length] === placeholder) {
1050         result++;
1051       }
1052     }
1053     return result;
1054   }
1055
1056   /**
1057    * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
1058    *
1059    * @private
1060    * @param {string} letter The matched letter to deburr.
1061    * @returns {string} Returns the deburred letter.
1062    */
1063   function deburrLetter(letter) {
1064     return deburredLetters[letter];
1065   }
1066
1067   /**
1068    * Used by `_.escape` to convert characters to HTML entities.
1069    *
1070    * @private
1071    * @param {string} chr The matched character to escape.
1072    * @returns {string} Returns the escaped character.
1073    */
1074   function escapeHtmlChar(chr) {
1075     return htmlEscapes[chr];
1076   }
1077
1078   /**
1079    * Used by `_.template` to escape characters for inclusion in compiled string literals.
1080    *
1081    * @private
1082    * @param {string} chr The matched character to escape.
1083    * @returns {string} Returns the escaped character.
1084    */
1085   function escapeStringChar(chr) {
1086     return '\\' + stringEscapes[chr];
1087   }
1088
1089   /**
1090    * Gets the index at which the first occurrence of `NaN` is found in `array`.
1091    *
1092    * @private
1093    * @param {Array} array The array to search.
1094    * @param {number} fromIndex The index to search from.
1095    * @param {boolean} [fromRight] Specify iterating from right to left.
1096    * @returns {number} Returns the index of the matched `NaN`, else `-1`.
1097    */
1098   function indexOfNaN(array, fromIndex, fromRight) {
1099     var length = array.length,
1100         index = fromIndex + (fromRight ? 0 : -1);
1101
1102     while ((fromRight ? index-- : ++index < length)) {
1103       var other = array[index];
1104       if (other !== other) {
1105         return index;
1106       }
1107     }
1108     return -1;
1109   }
1110
1111   /**
1112    * Checks if `value` is a host object in IE < 9.
1113    *
1114    * @private
1115    * @param {*} value The value to check.
1116    * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
1117    */
1118   function isHostObject(value) {
1119     // Many host objects are `Object` objects that can coerce to strings
1120     // despite having improperly defined `toString` methods.
1121     var result = false;
1122     if (value != null && typeof value.toString != 'function') {
1123       try {
1124         result = !!(value + '');
1125       } catch (e) {}
1126     }
1127     return result;
1128   }
1129
1130   /**
1131    * Checks if `value` is a valid array-like index.
1132    *
1133    * @private
1134    * @param {*} value The value to check.
1135    * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
1136    * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
1137    */
1138   function isIndex(value, length) {
1139     value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
1140     length = length == null ? MAX_SAFE_INTEGER : length;
1141     return value > -1 && value % 1 == 0 && value < length;
1142   }
1143
1144   /**
1145    * Converts `iterator` to an array.
1146    *
1147    * @private
1148    * @param {Object} iterator The iterator to convert.
1149    * @returns {Array} Returns the converted array.
1150    */
1151   function iteratorToArray(iterator) {
1152     var data,
1153         result = [];
1154
1155     while (!(data = iterator.next()).done) {
1156       result.push(data.value);
1157     }
1158     return result;
1159   }
1160
1161   /**
1162    * Converts `map` to an array.
1163    *
1164    * @private
1165    * @param {Object} map The map to convert.
1166    * @returns {Array} Returns the converted array.
1167    */
1168   function mapToArray(map) {
1169     var index = -1,
1170         result = Array(map.size);
1171
1172     map.forEach(function(value, key) {
1173       result[++index] = [key, value];
1174     });
1175     return result;
1176   }
1177
1178   /**
1179    * Replaces all `placeholder` elements in `array` with an internal placeholder
1180    * and returns an array of their indexes.
1181    *
1182    * @private
1183    * @param {Array} array The array to modify.
1184    * @param {*} placeholder The placeholder to replace.
1185    * @returns {Array} Returns the new array of placeholder indexes.
1186    */
1187   function replaceHolders(array, placeholder) {
1188     var index = -1,
1189         length = array.length,
1190         resIndex = -1,
1191         result = [];
1192
1193     while (++index < length) {
1194       var value = array[index];
1195       if (value === placeholder || value === PLACEHOLDER) {
1196         array[index] = PLACEHOLDER;
1197         result[++resIndex] = index;
1198       }
1199     }
1200     return result;
1201   }
1202
1203   /**
1204    * Converts `set` to an array.
1205    *
1206    * @private
1207    * @param {Object} set The set to convert.
1208    * @returns {Array} Returns the converted array.
1209    */
1210   function setToArray(set) {
1211     var index = -1,
1212         result = Array(set.size);
1213
1214     set.forEach(function(value) {
1215       result[++index] = value;
1216     });
1217     return result;
1218   }
1219
1220   /**
1221    * Gets the number of symbols in `string`.
1222    *
1223    * @private
1224    * @param {string} string The string to inspect.
1225    * @returns {number} Returns the string size.
1226    */
1227   function stringSize(string) {
1228     if (!(string && reHasComplexSymbol.test(string))) {
1229       return string.length;
1230     }
1231     var result = reComplexSymbol.lastIndex = 0;
1232     while (reComplexSymbol.test(string)) {
1233       result++;
1234     }
1235     return result;
1236   }
1237
1238   /**
1239    * Converts `string` to an array.
1240    *
1241    * @private
1242    * @param {string} string The string to convert.
1243    * @returns {Array} Returns the converted array.
1244    */
1245   function stringToArray(string) {
1246     return string.match(reComplexSymbol);
1247   }
1248
1249   /**
1250    * Used by `_.unescape` to convert HTML entities to characters.
1251    *
1252    * @private
1253    * @param {string} chr The matched character to unescape.
1254    * @returns {string} Returns the unescaped character.
1255    */
1256   function unescapeHtmlChar(chr) {
1257     return htmlUnescapes[chr];
1258   }
1259
1260   /*--------------------------------------------------------------------------*/
1261
1262   /**
1263    * Create a new pristine `lodash` function using the `context` object.
1264    *
1265    * @static
1266    * @memberOf _
1267    * @category Util
1268    * @param {Object} [context=root] The context object.
1269    * @returns {Function} Returns a new `lodash` function.
1270    * @example
1271    *
1272    * _.mixin({ 'foo': _.constant('foo') });
1273    *
1274    * var lodash = _.runInContext();
1275    * lodash.mixin({ 'bar': lodash.constant('bar') });
1276    *
1277    * _.isFunction(_.foo);
1278    * // => true
1279    * _.isFunction(_.bar);
1280    * // => false
1281    *
1282    * lodash.isFunction(lodash.foo);
1283    * // => false
1284    * lodash.isFunction(lodash.bar);
1285    * // => true
1286    *
1287    * // Use `context` to mock `Date#getTime` use in `_.now`.
1288    * var mock = _.runInContext({
1289    *   'Date': function() {
1290    *     return { 'getTime': getTimeMock };
1291    *   }
1292    * });
1293    *
1294    * // Create a suped-up `defer` in Node.js.
1295    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1296    */
1297   function runInContext(context) {
1298     context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
1299
1300     /** Built-in constructor references. */
1301     var Date = context.Date,
1302         Error = context.Error,
1303         Math = context.Math,
1304         RegExp = context.RegExp,
1305         TypeError = context.TypeError;
1306
1307     /** Used for built-in method references. */
1308     var arrayProto = context.Array.prototype,
1309         objectProto = context.Object.prototype;
1310
1311     /** Used to resolve the decompiled source of functions. */
1312     var funcToString = context.Function.prototype.toString;
1313
1314     /** Used to check objects for own properties. */
1315     var hasOwnProperty = objectProto.hasOwnProperty;
1316
1317     /** Used to generate unique IDs. */
1318     var idCounter = 0;
1319
1320     /** Used to infer the `Object` constructor. */
1321     var objectCtorString = funcToString.call(Object);
1322
1323     /**
1324      * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1325      * of values.
1326      */
1327     var objectToString = objectProto.toString;
1328
1329     /** Used to restore the original `_` reference in `_.noConflict`. */
1330     var oldDash = root._;
1331
1332     /** Used to detect if a method is native. */
1333     var reIsNative = RegExp('^' +
1334       funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1335       .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1336     );
1337
1338     /** Built-in value references. */
1339     var Buffer = moduleExports ? context.Buffer : undefined,
1340         Reflect = context.Reflect,
1341         Symbol = context.Symbol,
1342         Uint8Array = context.Uint8Array,
1343         clearTimeout = context.clearTimeout,
1344         enumerate = Reflect ? Reflect.enumerate : undefined,
1345         getPrototypeOf = Object.getPrototypeOf,
1346         getOwnPropertySymbols = Object.getOwnPropertySymbols,
1347         iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
1348         objectCreate = Object.create,
1349         propertyIsEnumerable = objectProto.propertyIsEnumerable,
1350         setTimeout = context.setTimeout,
1351         splice = arrayProto.splice;
1352
1353     /* Built-in method references for those with the same name as other `lodash` methods. */
1354     var nativeCeil = Math.ceil,
1355         nativeFloor = Math.floor,
1356         nativeIsFinite = context.isFinite,
1357         nativeJoin = arrayProto.join,
1358         nativeKeys = Object.keys,
1359         nativeMax = Math.max,
1360         nativeMin = Math.min,
1361         nativeParseInt = context.parseInt,
1362         nativeRandom = Math.random,
1363         nativeReverse = arrayProto.reverse;
1364
1365     /* Built-in method references that are verified to be native. */
1366     var Map = getNative(context, 'Map'),
1367         Set = getNative(context, 'Set'),
1368         WeakMap = getNative(context, 'WeakMap'),
1369         nativeCreate = getNative(Object, 'create');
1370
1371     /** Used to store function metadata. */
1372     var metaMap = WeakMap && new WeakMap;
1373
1374     /** Used to detect maps, sets, and weakmaps. */
1375     var mapCtorString = Map ? funcToString.call(Map) : '',
1376         setCtorString = Set ? funcToString.call(Set) : '',
1377         weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : '';
1378
1379     /** Used to convert symbols to primitives and strings. */
1380     var symbolProto = Symbol ? Symbol.prototype : undefined,
1381         symbolValueOf = Symbol ? symbolProto.valueOf : undefined,
1382         symbolToString = Symbol ? symbolProto.toString : undefined;
1383
1384     /** Used to lookup unminified function names. */
1385     var realNames = {};
1386
1387     /*------------------------------------------------------------------------*/
1388
1389     /**
1390      * Creates a `lodash` object which wraps `value` to enable implicit method
1391      * chaining. Methods that operate on and return arrays, collections, and
1392      * functions can be chained together. Methods that retrieve a single value or
1393      * may return a primitive value will automatically end the chain sequence and
1394      * return the unwrapped value. Otherwise, the value must be unwrapped with
1395      * `_#value`.
1396      *
1397      * Explicit chaining, which must be unwrapped with `_#value` in all cases,
1398      * may be enabled using `_.chain`.
1399      *
1400      * The execution of chained methods is lazy, that is, it's deferred until
1401      * `_#value` is implicitly or explicitly called.
1402      *
1403      * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
1404      * fusion is an optimization to merge iteratee calls; this avoids the creation
1405      * of intermediate arrays and can greatly reduce the number of iteratee executions.
1406      * Sections of a chain sequence qualify for shortcut fusion if the section is
1407      * applied to an array of at least two hundred elements and any iteratees
1408      * accept only one argument. The heuristic for whether a section qualifies
1409      * for shortcut fusion is subject to change.
1410      *
1411      * Chaining is supported in custom builds as long as the `_#value` method is
1412      * directly or indirectly included in the build.
1413      *
1414      * In addition to lodash methods, wrappers have `Array` and `String` methods.
1415      *
1416      * The wrapper `Array` methods are:
1417      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1418      *
1419      * The wrapper `String` methods are:
1420      * `replace` and `split`
1421      *
1422      * The wrapper methods that support shortcut fusion are:
1423      * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1424      * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1425      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1426      *
1427      * The chainable wrapper methods are:
1428      * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1429      * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1430      * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1431      * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
1432      * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
1433      * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`,
1434      * `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`,
1435      * `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`,
1436      * `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`,
1437      * `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`,
1438      * `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`,
1439      * `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`,
1440      * `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`,
1441      * `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`,
1442      * `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`,
1443      * `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`,
1444      * `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`,
1445      * `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`,
1446      * `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`,
1447      * `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`,
1448      * `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`,
1449      * `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith`
1450      *
1451      * The wrapper methods that are **not** chainable by default are:
1452      * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1453      * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
1454      * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
1455      * `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`, `forIn`,
1456      * `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`,
1457      * `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`,
1458      * `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
1459      * `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`,
1460      * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`,
1461      * `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
1462      * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
1463      * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`,
1464      * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`,
1465      * `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`,
1466      * `now`, `pad`, `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`,
1467      * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `sample`,
1468      * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`,
1469      * `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`,
1470      * `sum`, `sumBy`, `template`, `times`, `toLower`, `toInteger`, `toLength`,
1471      * `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`,
1472      * `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`,
1473      * `value`, and `words`
1474      *
1475      * @name _
1476      * @constructor
1477      * @category Seq
1478      * @param {*} value The value to wrap in a `lodash` instance.
1479      * @returns {Object} Returns the new `lodash` wrapper instance.
1480      * @example
1481      *
1482      * function square(n) {
1483      *   return n * n;
1484      * }
1485      *
1486      * var wrapped = _([1, 2, 3]);
1487      *
1488      * // Returns an unwrapped value.
1489      * wrapped.reduce(_.add);
1490      * // => 6
1491      *
1492      * // Returns a wrapped value.
1493      * var squares = wrapped.map(square);
1494      *
1495      * _.isArray(squares);
1496      * // => false
1497      *
1498      * _.isArray(squares.value());
1499      * // => true
1500      */
1501     function lodash(value) {
1502       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1503         if (value instanceof LodashWrapper) {
1504           return value;
1505         }
1506         if (hasOwnProperty.call(value, '__wrapped__')) {
1507           return wrapperClone(value);
1508         }
1509       }
1510       return new LodashWrapper(value);
1511     }
1512
1513     /**
1514      * The function whose prototype all chaining wrappers inherit from.
1515      *
1516      * @private
1517      */
1518     function baseLodash() {
1519       // No operation performed.
1520     }
1521
1522     /**
1523      * The base constructor for creating `lodash` wrapper objects.
1524      *
1525      * @private
1526      * @param {*} value The value to wrap.
1527      * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
1528      */
1529     function LodashWrapper(value, chainAll) {
1530       this.__wrapped__ = value;
1531       this.__actions__ = [];
1532       this.__chain__ = !!chainAll;
1533       this.__index__ = 0;
1534       this.__values__ = undefined;
1535     }
1536
1537     /**
1538      * By default, the template delimiters used by lodash are like those in
1539      * embedded Ruby (ERB). Change the following template settings to use
1540      * alternative delimiters.
1541      *
1542      * @static
1543      * @memberOf _
1544      * @type {Object}
1545      */
1546     lodash.templateSettings = {
1547
1548       /**
1549        * Used to detect `data` property values to be HTML-escaped.
1550        *
1551        * @memberOf _.templateSettings
1552        * @type {RegExp}
1553        */
1554       'escape': reEscape,
1555
1556       /**
1557        * Used to detect code to be evaluated.
1558        *
1559        * @memberOf _.templateSettings
1560        * @type {RegExp}
1561        */
1562       'evaluate': reEvaluate,
1563
1564       /**
1565        * Used to detect `data` property values to inject.
1566        *
1567        * @memberOf _.templateSettings
1568        * @type {RegExp}
1569        */
1570       'interpolate': reInterpolate,
1571
1572       /**
1573        * Used to reference the data object in the template text.
1574        *
1575        * @memberOf _.templateSettings
1576        * @type {string}
1577        */
1578       'variable': '',
1579
1580       /**
1581        * Used to import variables into the compiled template.
1582        *
1583        * @memberOf _.templateSettings
1584        * @type {Object}
1585        */
1586       'imports': {
1587
1588         /**
1589          * A reference to the `lodash` function.
1590          *
1591          * @memberOf _.templateSettings.imports
1592          * @type {Function}
1593          */
1594         '_': lodash
1595       }
1596     };
1597
1598     /*------------------------------------------------------------------------*/
1599
1600     /**
1601      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1602      *
1603      * @private
1604      * @constructor
1605      * @param {*} value The value to wrap.
1606      */
1607     function LazyWrapper(value) {
1608       this.__wrapped__ = value;
1609       this.__actions__ = [];
1610       this.__dir__ = 1;
1611       this.__filtered__ = false;
1612       this.__iteratees__ = [];
1613       this.__takeCount__ = MAX_ARRAY_LENGTH;
1614       this.__views__ = [];
1615     }
1616
1617     /**
1618      * Creates a clone of the lazy wrapper object.
1619      *
1620      * @private
1621      * @name clone
1622      * @memberOf LazyWrapper
1623      * @returns {Object} Returns the cloned `LazyWrapper` object.
1624      */
1625     function lazyClone() {
1626       var result = new LazyWrapper(this.__wrapped__);
1627       result.__actions__ = copyArray(this.__actions__);
1628       result.__dir__ = this.__dir__;
1629       result.__filtered__ = this.__filtered__;
1630       result.__iteratees__ = copyArray(this.__iteratees__);
1631       result.__takeCount__ = this.__takeCount__;
1632       result.__views__ = copyArray(this.__views__);
1633       return result;
1634     }
1635
1636     /**
1637      * Reverses the direction of lazy iteration.
1638      *
1639      * @private
1640      * @name reverse
1641      * @memberOf LazyWrapper
1642      * @returns {Object} Returns the new reversed `LazyWrapper` object.
1643      */
1644     function lazyReverse() {
1645       if (this.__filtered__) {
1646         var result = new LazyWrapper(this);
1647         result.__dir__ = -1;
1648         result.__filtered__ = true;
1649       } else {
1650         result = this.clone();
1651         result.__dir__ *= -1;
1652       }
1653       return result;
1654     }
1655
1656     /**
1657      * Extracts the unwrapped value from its lazy wrapper.
1658      *
1659      * @private
1660      * @name value
1661      * @memberOf LazyWrapper
1662      * @returns {*} Returns the unwrapped value.
1663      */
1664     function lazyValue() {
1665       var array = this.__wrapped__.value(),
1666           dir = this.__dir__,
1667           isArr = isArray(array),
1668           isRight = dir < 0,
1669           arrLength = isArr ? array.length : 0,
1670           view = getView(0, arrLength, this.__views__),
1671           start = view.start,
1672           end = view.end,
1673           length = end - start,
1674           index = isRight ? end : (start - 1),
1675           iteratees = this.__iteratees__,
1676           iterLength = iteratees.length,
1677           resIndex = 0,
1678           takeCount = nativeMin(length, this.__takeCount__);
1679
1680       if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
1681           (arrLength == length && takeCount == length)) {
1682         return baseWrapperValue(array, this.__actions__);
1683       }
1684       var result = [];
1685
1686       outer:
1687       while (length-- && resIndex < takeCount) {
1688         index += dir;
1689
1690         var iterIndex = -1,
1691             value = array[index];
1692
1693         while (++iterIndex < iterLength) {
1694           var data = iteratees[iterIndex],
1695               iteratee = data.iteratee,
1696               type = data.type,
1697               computed = iteratee(value);
1698
1699           if (type == LAZY_MAP_FLAG) {
1700             value = computed;
1701           } else if (!computed) {
1702             if (type == LAZY_FILTER_FLAG) {
1703               continue outer;
1704             } else {
1705               break outer;
1706             }
1707           }
1708         }
1709         result[resIndex++] = value;
1710       }
1711       return result;
1712     }
1713
1714     /*------------------------------------------------------------------------*/
1715
1716     /**
1717      * Creates an hash object.
1718      *
1719      * @private
1720      * @constructor
1721      * @returns {Object} Returns the new hash object.
1722      */
1723     function Hash() {}
1724
1725     /**
1726      * Removes `key` and its value from the hash.
1727      *
1728      * @private
1729      * @param {Object} hash The hash to modify.
1730      * @param {string} key The key of the value to remove.
1731      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1732      */
1733     function hashDelete(hash, key) {
1734       return hashHas(hash, key) && delete hash[key];
1735     }
1736
1737     /**
1738      * Gets the hash value for `key`.
1739      *
1740      * @private
1741      * @param {Object} hash The hash to query.
1742      * @param {string} key The key of the value to get.
1743      * @returns {*} Returns the entry value.
1744      */
1745     function hashGet(hash, key) {
1746       if (nativeCreate) {
1747         var result = hash[key];
1748         return result === HASH_UNDEFINED ? undefined : result;
1749       }
1750       return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
1751     }
1752
1753     /**
1754      * Checks if a hash value for `key` exists.
1755      *
1756      * @private
1757      * @param {Object} hash The hash to query.
1758      * @param {string} key The key of the entry to check.
1759      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1760      */
1761     function hashHas(hash, key) {
1762       return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
1763     }
1764
1765     /**
1766      * Sets the hash `key` to `value`.
1767      *
1768      * @private
1769      * @param {Object} hash The hash to modify.
1770      * @param {string} key The key of the value to set.
1771      * @param {*} value The value to set.
1772      */
1773     function hashSet(hash, key, value) {
1774       hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1775     }
1776
1777     /*------------------------------------------------------------------------*/
1778
1779     /**
1780      * Creates a map cache object to store key-value pairs.
1781      *
1782      * @private
1783      * @constructor
1784      * @param {Array} [values] The values to cache.
1785      */
1786     function MapCache(values) {
1787       var index = -1,
1788           length = values ? values.length : 0;
1789
1790       this.clear();
1791       while (++index < length) {
1792         var entry = values[index];
1793         this.set(entry[0], entry[1]);
1794       }
1795     }
1796
1797     /**
1798      * Removes all key-value entries from the map.
1799      *
1800      * @private
1801      * @name clear
1802      * @memberOf MapCache
1803      */
1804     function mapClear() {
1805       this.__data__ = {
1806         'hash': new Hash,
1807         'map': Map ? new Map : [],
1808         'string': new Hash
1809       };
1810     }
1811
1812     /**
1813      * Removes `key` and its value from the map.
1814      *
1815      * @private
1816      * @name delete
1817      * @memberOf MapCache
1818      * @param {string} key The key of the value to remove.
1819      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1820      */
1821     function mapDelete(key) {
1822       var data = this.__data__;
1823       if (isKeyable(key)) {
1824         return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
1825       }
1826       return Map ? data.map['delete'](key) : assocDelete(data.map, key);
1827     }
1828
1829     /**
1830      * Gets the map value for `key`.
1831      *
1832      * @private
1833      * @name get
1834      * @memberOf MapCache
1835      * @param {string} key The key of the value to get.
1836      * @returns {*} Returns the entry value.
1837      */
1838     function mapGet(key) {
1839       var data = this.__data__;
1840       if (isKeyable(key)) {
1841         return hashGet(typeof key == 'string' ? data.string : data.hash, key);
1842       }
1843       return Map ? data.map.get(key) : assocGet(data.map, key);
1844     }
1845
1846     /**
1847      * Checks if a map value for `key` exists.
1848      *
1849      * @private
1850      * @name has
1851      * @memberOf MapCache
1852      * @param {string} key The key of the entry to check.
1853      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1854      */
1855     function mapHas(key) {
1856       var data = this.__data__;
1857       if (isKeyable(key)) {
1858         return hashHas(typeof key == 'string' ? data.string : data.hash, key);
1859       }
1860       return Map ? data.map.has(key) : assocHas(data.map, key);
1861     }
1862
1863     /**
1864      * Sets the map `key` to `value`.
1865      *
1866      * @private
1867      * @name set
1868      * @memberOf MapCache
1869      * @param {string} key The key of the value to set.
1870      * @param {*} value The value to set.
1871      * @returns {Object} Returns the map cache object.
1872      */
1873     function mapSet(key, value) {
1874       var data = this.__data__;
1875       if (isKeyable(key)) {
1876         hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
1877       } else if (Map) {
1878         data.map.set(key, value);
1879       } else {
1880         assocSet(data.map, key, value);
1881       }
1882       return this;
1883     }
1884
1885     /*------------------------------------------------------------------------*/
1886
1887     /**
1888      *
1889      * Creates a set cache object to store unique values.
1890      *
1891      * @private
1892      * @constructor
1893      * @param {Array} [values] The values to cache.
1894      */
1895     function SetCache(values) {
1896       var index = -1,
1897           length = values ? values.length : 0;
1898
1899       this.__data__ = new MapCache;
1900       while (++index < length) {
1901         this.push(values[index]);
1902       }
1903     }
1904
1905     /**
1906      * Checks if `value` is in `cache`.
1907      *
1908      * @private
1909      * @param {Object} cache The set cache to search.
1910      * @param {*} value The value to search for.
1911      * @returns {number} Returns `true` if `value` is found, else `false`.
1912      */
1913     function cacheHas(cache, value) {
1914       var map = cache.__data__;
1915       if (isKeyable(value)) {
1916         var data = map.__data__,
1917             hash = typeof value == 'string' ? data.string : data.hash;
1918
1919         return hash[value] === HASH_UNDEFINED;
1920       }
1921       return map.has(value);
1922     }
1923
1924     /**
1925      * Adds `value` to the set cache.
1926      *
1927      * @private
1928      * @name push
1929      * @memberOf SetCache
1930      * @param {*} value The value to cache.
1931      */
1932     function cachePush(value) {
1933       var map = this.__data__;
1934       if (isKeyable(value)) {
1935         var data = map.__data__,
1936             hash = typeof value == 'string' ? data.string : data.hash;
1937
1938         hash[value] = HASH_UNDEFINED;
1939       }
1940       else {
1941         map.set(value, HASH_UNDEFINED);
1942       }
1943     }
1944
1945     /*------------------------------------------------------------------------*/
1946
1947     /**
1948      * Creates a stack cache object to store key-value pairs.
1949      *
1950      * @private
1951      * @constructor
1952      * @param {Array} [values] The values to cache.
1953      */
1954     function Stack(values) {
1955       var index = -1,
1956           length = values ? values.length : 0;
1957
1958       this.clear();
1959       while (++index < length) {
1960         var entry = values[index];
1961         this.set(entry[0], entry[1]);
1962       }
1963     }
1964
1965     /**
1966      * Removes all key-value entries from the stack.
1967      *
1968      * @private
1969      * @name clear
1970      * @memberOf Stack
1971      */
1972     function stackClear() {
1973       this.__data__ = { 'array': [], 'map': null };
1974     }
1975
1976     /**
1977      * Removes `key` and its value from the stack.
1978      *
1979      * @private
1980      * @name delete
1981      * @memberOf Stack
1982      * @param {string} key The key of the value to remove.
1983      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1984      */
1985     function stackDelete(key) {
1986       var data = this.__data__,
1987           array = data.array;
1988
1989       return array ? assocDelete(array, key) : data.map['delete'](key);
1990     }
1991
1992     /**
1993      * Gets the stack value for `key`.
1994      *
1995      * @private
1996      * @name get
1997      * @memberOf Stack
1998      * @param {string} key The key of the value to get.
1999      * @returns {*} Returns the entry value.
2000      */
2001     function stackGet(key) {
2002       var data = this.__data__,
2003           array = data.array;
2004
2005       return array ? assocGet(array, key) : data.map.get(key);
2006     }
2007
2008     /**
2009      * Checks if a stack value for `key` exists.
2010      *
2011      * @private
2012      * @name has
2013      * @memberOf Stack
2014      * @param {string} key The key of the entry to check.
2015      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2016      */
2017     function stackHas(key) {
2018       var data = this.__data__,
2019           array = data.array;
2020
2021       return array ? assocHas(array, key) : data.map.has(key);
2022     }
2023
2024     /**
2025      * Sets the stack `key` to `value`.
2026      *
2027      * @private
2028      * @name set
2029      * @memberOf Stack
2030      * @param {string} key The key of the value to set.
2031      * @param {*} value The value to set.
2032      * @returns {Object} Returns the stack cache object.
2033      */
2034     function stackSet(key, value) {
2035       var data = this.__data__,
2036           array = data.array;
2037
2038       if (array) {
2039         if (array.length < (LARGE_ARRAY_SIZE - 1)) {
2040           assocSet(array, key, value);
2041         } else {
2042           data.array = null;
2043           data.map = new MapCache(array);
2044         }
2045       }
2046       var map = data.map;
2047       if (map) {
2048         map.set(key, value);
2049       }
2050       return this;
2051     }
2052
2053     /*------------------------------------------------------------------------*/
2054
2055     /**
2056      * Removes `key` and its value from the associative array.
2057      *
2058      * @private
2059      * @param {Array} array The array to query.
2060      * @param {string} key The key of the value to remove.
2061      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2062      */
2063     function assocDelete(array, key) {
2064       var index = assocIndexOf(array, key);
2065       if (index < 0) {
2066         return false;
2067       }
2068       var lastIndex = array.length - 1;
2069       if (index == lastIndex) {
2070         array.pop();
2071       } else {
2072         splice.call(array, index, 1);
2073       }
2074       return true;
2075     }
2076
2077     /**
2078      * Gets the associative array value for `key`.
2079      *
2080      * @private
2081      * @param {Array} array The array to query.
2082      * @param {string} key The key of the value to get.
2083      * @returns {*} Returns the entry value.
2084      */
2085     function assocGet(array, key) {
2086       var index = assocIndexOf(array, key);
2087       return index < 0 ? undefined : array[index][1];
2088     }
2089
2090     /**
2091      * Checks if an associative array value for `key` exists.
2092      *
2093      * @private
2094      * @param {Array} array The array to query.
2095      * @param {string} key The key of the entry to check.
2096      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2097      */
2098     function assocHas(array, key) {
2099       return assocIndexOf(array, key) > -1;
2100     }
2101
2102     /**
2103      * Gets the index at which the first occurrence of `key` is found in `array`
2104      * of key-value pairs.
2105      *
2106      * @private
2107      * @param {Array} array The array to search.
2108      * @param {*} key The key to search for.
2109      * @returns {number} Returns the index of the matched value, else `-1`.
2110      */
2111     function assocIndexOf(array, key) {
2112       var length = array.length;
2113       while (length--) {
2114         if (eq(array[length][0], key)) {
2115           return length;
2116         }
2117       }
2118       return -1;
2119     }
2120
2121     /**
2122      * Sets the associative array `key` to `value`.
2123      *
2124      * @private
2125      * @param {Array} array The array to modify.
2126      * @param {string} key The key of the value to set.
2127      * @param {*} value The value to set.
2128      */
2129     function assocSet(array, key, value) {
2130       var index = assocIndexOf(array, key);
2131       if (index < 0) {
2132         array.push([key, value]);
2133       } else {
2134         array[index][1] = value;
2135       }
2136     }
2137
2138     /*------------------------------------------------------------------------*/
2139
2140     /**
2141      * Used by `_.defaults` to customize its `_.assignIn` use.
2142      *
2143      * @private
2144      * @param {*} objValue The destination value.
2145      * @param {*} srcValue The source value.
2146      * @param {string} key The key of the property to assign.
2147      * @param {Object} object The parent object of `objValue`.
2148      * @returns {*} Returns the value to assign.
2149      */
2150     function assignInDefaults(objValue, srcValue, key, object) {
2151       if (objValue === undefined ||
2152           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2153         return srcValue;
2154       }
2155       return objValue;
2156     }
2157
2158     /**
2159      * This function is like `assignValue` except that it doesn't assign `undefined` values.
2160      *
2161      * @private
2162      * @param {Object} object The object to modify.
2163      * @param {string} key The key of the property to assign.
2164      * @param {*} value The value to assign.
2165      */
2166     function assignMergeValue(object, key, value) {
2167       if ((value !== undefined && !eq(object[key], value)) ||
2168           (typeof key == 'number' && value === undefined && !(key in object))) {
2169         object[key] = value;
2170       }
2171     }
2172
2173     /**
2174      * Assigns `value` to `key` of `object` if the existing value is not equivalent
2175      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
2176      * for equality comparisons.
2177      *
2178      * @private
2179      * @param {Object} object The object to modify.
2180      * @param {string} key The key of the property to assign.
2181      * @param {*} value The value to assign.
2182      */
2183     function assignValue(object, key, value) {
2184       var objValue = object[key];
2185       if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2186           (value === undefined && !(key in object))) {
2187         object[key] = value;
2188       }
2189     }
2190
2191     /**
2192      * Aggregates elements of `collection` on `accumulator` with keys transformed
2193      * by `iteratee` and values set by `setter`.
2194      *
2195      * @private
2196      * @param {Array|Object} collection The collection to iterate over.
2197      * @param {Function} setter The function to set `accumulator` values.
2198      * @param {Function} iteratee The iteratee to transform keys.
2199      * @param {Object} accumulator The initial aggregated object.
2200      * @returns {Function} Returns `accumulator`.
2201      */
2202     function baseAggregator(collection, setter, iteratee, accumulator) {
2203       baseEach(collection, function(value, key, collection) {
2204         setter(accumulator, value, iteratee(value), collection);
2205       });
2206       return accumulator;
2207     }
2208
2209     /**
2210      * The base implementation of `_.assign` without support for multiple sources
2211      * or `customizer` functions.
2212      *
2213      * @private
2214      * @param {Object} object The destination object.
2215      * @param {Object} source The source object.
2216      * @returns {Object} Returns `object`.
2217      */
2218     function baseAssign(object, source) {
2219       return object && copyObject(source, keys(source), object);
2220     }
2221
2222     /**
2223      * The base implementation of `_.at` without support for individual paths.
2224      *
2225      * @private
2226      * @param {Object} object The object to iterate over.
2227      * @param {string[]} paths The property paths of elements to pick.
2228      * @returns {Array} Returns the new array of picked elements.
2229      */
2230     function baseAt(object, paths) {
2231       var index = -1,
2232           isNil = object == null,
2233           length = paths.length,
2234           result = Array(length);
2235
2236       while (++index < length) {
2237         result[index] = isNil ? undefined : get(object, paths[index]);
2238       }
2239       return result;
2240     }
2241
2242     /**
2243      * Casts `value` to an empty array if it's not an array like object.
2244      *
2245      * @private
2246      * @param {*} value The value to inspect.
2247      * @returns {Array} Returns the array-like object.
2248      */
2249     function baseCastArrayLikeObject(value) {
2250       return isArrayLikeObject(value) ? value : [];
2251     }
2252
2253     /**
2254      * Casts `value` to `identity` if it's not a function.
2255      *
2256      * @private
2257      * @param {*} value The value to inspect.
2258      * @returns {Array} Returns the array-like object.
2259      */
2260     function baseCastFunction(value) {
2261       return typeof value == 'function' ? value : identity;
2262     }
2263
2264     /**
2265      * Casts `value` to a path array if it's not one.
2266      *
2267      * @private
2268      * @param {*} value The value to inspect.
2269      * @returns {Array} Returns the cast property path array.
2270      */
2271     function baseCastPath(value) {
2272       return isArray(value) ? value : stringToPath(value);
2273     }
2274
2275     /**
2276      * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
2277      *
2278      * @private
2279      * @param {number} number The number to clamp.
2280      * @param {number} [lower] The lower bound.
2281      * @param {number} upper The upper bound.
2282      * @returns {number} Returns the clamped number.
2283      */
2284     function baseClamp(number, lower, upper) {
2285       if (number === number) {
2286         if (upper !== undefined) {
2287           number = number <= upper ? number : upper;
2288         }
2289         if (lower !== undefined) {
2290           number = number >= lower ? number : lower;
2291         }
2292       }
2293       return number;
2294     }
2295
2296     /**
2297      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2298      * traversed objects.
2299      *
2300      * @private
2301      * @param {*} value The value to clone.
2302      * @param {boolean} [isDeep] Specify a deep clone.
2303      * @param {Function} [customizer] The function to customize cloning.
2304      * @param {string} [key] The key of `value`.
2305      * @param {Object} [object] The parent object of `value`.
2306      * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2307      * @returns {*} Returns the cloned value.
2308      */
2309     function baseClone(value, isDeep, customizer, key, object, stack) {
2310       var result;
2311       if (customizer) {
2312         result = object ? customizer(value, key, object, stack) : customizer(value);
2313       }
2314       if (result !== undefined) {
2315         return result;
2316       }
2317       if (!isObject(value)) {
2318         return value;
2319       }
2320       var isArr = isArray(value);
2321       if (isArr) {
2322         result = initCloneArray(value);
2323         if (!isDeep) {
2324           return copyArray(value, result);
2325         }
2326       } else {
2327         var tag = getTag(value),
2328             isFunc = tag == funcTag || tag == genTag;
2329
2330         if (isBuffer(value)) {
2331           return cloneBuffer(value, isDeep);
2332         }
2333         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2334           if (isHostObject(value)) {
2335             return object ? value : {};
2336           }
2337           result = initCloneObject(isFunc ? {} : value);
2338           if (!isDeep) {
2339             return copySymbols(value, baseAssign(result, value));
2340           }
2341         } else {
2342           if (!cloneableTags[tag]) {
2343             return object ? value : {};
2344           }
2345           result = initCloneByTag(value, tag, isDeep);
2346         }
2347       }
2348       // Check for circular references and return its corresponding clone.
2349       stack || (stack = new Stack);
2350       var stacked = stack.get(value);
2351       if (stacked) {
2352         return stacked;
2353       }
2354       stack.set(value, result);
2355
2356       // Recursively populate clone (susceptible to call stack limits).
2357       (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
2358         assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
2359       });
2360       return isArr ? result : copySymbols(value, result);
2361     }
2362
2363     /**
2364      * The base implementation of `_.conforms` which doesn't clone `source`.
2365      *
2366      * @private
2367      * @param {Object} source The object of property predicates to conform to.
2368      * @returns {Function} Returns the new function.
2369      */
2370     function baseConforms(source) {
2371       var props = keys(source),
2372           length = props.length;
2373
2374       return function(object) {
2375         if (object == null) {
2376           return !length;
2377         }
2378         var index = length;
2379         while (index--) {
2380           var key = props[index],
2381               predicate = source[key],
2382               value = object[key];
2383
2384           if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
2385             return false;
2386           }
2387         }
2388         return true;
2389       };
2390     }
2391
2392     /**
2393      * The base implementation of `_.create` without support for assigning
2394      * properties to the created object.
2395      *
2396      * @private
2397      * @param {Object} prototype The object to inherit from.
2398      * @returns {Object} Returns the new object.
2399      */
2400     function baseCreate(proto) {
2401       return isObject(proto) ? objectCreate(proto) : {};
2402     }
2403
2404     /**
2405      * The base implementation of `_.delay` and `_.defer` which accepts an array
2406      * of `func` arguments.
2407      *
2408      * @private
2409      * @param {Function} func The function to delay.
2410      * @param {number} wait The number of milliseconds to delay invocation.
2411      * @param {Object} args The arguments to provide to `func`.
2412      * @returns {number} Returns the timer id.
2413      */
2414     function baseDelay(func, wait, args) {
2415       if (typeof func != 'function') {
2416         throw new TypeError(FUNC_ERROR_TEXT);
2417       }
2418       return setTimeout(function() { func.apply(undefined, args); }, wait);
2419     }
2420
2421     /**
2422      * The base implementation of methods like `_.difference` without support for
2423      * excluding multiple arrays or iteratee shorthands.
2424      *
2425      * @private
2426      * @param {Array} array The array to inspect.
2427      * @param {Array} values The values to exclude.
2428      * @param {Function} [iteratee] The iteratee invoked per element.
2429      * @param {Function} [comparator] The comparator invoked per element.
2430      * @returns {Array} Returns the new array of filtered values.
2431      */
2432     function baseDifference(array, values, iteratee, comparator) {
2433       var index = -1,
2434           includes = arrayIncludes,
2435           isCommon = true,
2436           length = array.length,
2437           result = [],
2438           valuesLength = values.length;
2439
2440       if (!length) {
2441         return result;
2442       }
2443       if (iteratee) {
2444         values = arrayMap(values, baseUnary(iteratee));
2445       }
2446       if (comparator) {
2447         includes = arrayIncludesWith;
2448         isCommon = false;
2449       }
2450       else if (values.length >= LARGE_ARRAY_SIZE) {
2451         includes = cacheHas;
2452         isCommon = false;
2453         values = new SetCache(values);
2454       }
2455       outer:
2456       while (++index < length) {
2457         var value = array[index],
2458             computed = iteratee ? iteratee(value) : value;
2459
2460         if (isCommon && computed === computed) {
2461           var valuesIndex = valuesLength;
2462           while (valuesIndex--) {
2463             if (values[valuesIndex] === computed) {
2464               continue outer;
2465             }
2466           }
2467           result.push(value);
2468         }
2469         else if (!includes(values, computed, comparator)) {
2470           result.push(value);
2471         }
2472       }
2473       return result;
2474     }
2475
2476     /**
2477      * The base implementation of `_.forEach` without support for iteratee shorthands.
2478      *
2479      * @private
2480      * @param {Array|Object} collection The collection to iterate over.
2481      * @param {Function} iteratee The function invoked per iteration.
2482      * @returns {Array|Object} Returns `collection`.
2483      */
2484     var baseEach = createBaseEach(baseForOwn);
2485
2486     /**
2487      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2488      *
2489      * @private
2490      * @param {Array|Object} collection The collection to iterate over.
2491      * @param {Function} iteratee The function invoked per iteration.
2492      * @returns {Array|Object} Returns `collection`.
2493      */
2494     var baseEachRight = createBaseEach(baseForOwnRight, true);
2495
2496     /**
2497      * The base implementation of `_.every` without support for iteratee shorthands.
2498      *
2499      * @private
2500      * @param {Array|Object} collection The collection to iterate over.
2501      * @param {Function} predicate The function invoked per iteration.
2502      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
2503      */
2504     function baseEvery(collection, predicate) {
2505       var result = true;
2506       baseEach(collection, function(value, index, collection) {
2507         result = !!predicate(value, index, collection);
2508         return result;
2509       });
2510       return result;
2511     }
2512
2513     /**
2514      * The base implementation of `_.fill` without an iteratee call guard.
2515      *
2516      * @private
2517      * @param {Array} array The array to fill.
2518      * @param {*} value The value to fill `array` with.
2519      * @param {number} [start=0] The start position.
2520      * @param {number} [end=array.length] The end position.
2521      * @returns {Array} Returns `array`.
2522      */
2523     function baseFill(array, value, start, end) {
2524       var length = array.length;
2525
2526       start = toInteger(start);
2527       if (start < 0) {
2528         start = -start > length ? 0 : (length + start);
2529       }
2530       end = (end === undefined || end > length) ? length : toInteger(end);
2531       if (end < 0) {
2532         end += length;
2533       }
2534       end = start > end ? 0 : toLength(end);
2535       while (start < end) {
2536         array[start++] = value;
2537       }
2538       return array;
2539     }
2540
2541     /**
2542      * The base implementation of `_.filter` without support for iteratee shorthands.
2543      *
2544      * @private
2545      * @param {Array|Object} collection The collection to iterate over.
2546      * @param {Function} predicate The function invoked per iteration.
2547      * @returns {Array} Returns the new filtered array.
2548      */
2549     function baseFilter(collection, predicate) {
2550       var result = [];
2551       baseEach(collection, function(value, index, collection) {
2552         if (predicate(value, index, collection)) {
2553           result.push(value);
2554         }
2555       });
2556       return result;
2557     }
2558
2559     /**
2560      * The base implementation of `_.flatten` with support for restricting flattening.
2561      *
2562      * @private
2563      * @param {Array} array The array to flatten.
2564      * @param {number} depth The maximum recursion depth.
2565      * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
2566      * @param {Array} [result=[]] The initial result value.
2567      * @returns {Array} Returns the new flattened array.
2568      */
2569     function baseFlatten(array, depth, isStrict, result) {
2570       result || (result = []);
2571
2572       var index = -1,
2573           length = array.length;
2574
2575       while (++index < length) {
2576         var value = array[index];
2577         if (depth > 0 && isArrayLikeObject(value) &&
2578             (isStrict || isArray(value) || isArguments(value))) {
2579           if (depth > 1) {
2580             // Recursively flatten arrays (susceptible to call stack limits).
2581             baseFlatten(value, depth - 1, isStrict, result);
2582           } else {
2583             arrayPush(result, value);
2584           }
2585         } else if (!isStrict) {
2586           result[result.length] = value;
2587         }
2588       }
2589       return result;
2590     }
2591
2592     /**
2593      * The base implementation of `baseForIn` and `baseForOwn` which iterates
2594      * over `object` properties returned by `keysFunc` invoking `iteratee` for
2595      * each property. Iteratee functions may exit iteration early by explicitly
2596      * returning `false`.
2597      *
2598      * @private
2599      * @param {Object} object The object to iterate over.
2600      * @param {Function} iteratee The function invoked per iteration.
2601      * @param {Function} keysFunc The function to get the keys of `object`.
2602      * @returns {Object} Returns `object`.
2603      */
2604     var baseFor = createBaseFor();
2605
2606     /**
2607      * This function is like `baseFor` except that it iterates over properties
2608      * in the opposite order.
2609      *
2610      * @private
2611      * @param {Object} object The object to iterate over.
2612      * @param {Function} iteratee The function invoked per iteration.
2613      * @param {Function} keysFunc The function to get the keys of `object`.
2614      * @returns {Object} Returns `object`.
2615      */
2616     var baseForRight = createBaseFor(true);
2617
2618     /**
2619      * The base implementation of `_.forIn` without support for iteratee shorthands.
2620      *
2621      * @private
2622      * @param {Object} object The object to iterate over.
2623      * @param {Function} iteratee The function invoked per iteration.
2624      * @returns {Object} Returns `object`.
2625      */
2626     function baseForIn(object, iteratee) {
2627       return object == null ? object : baseFor(object, iteratee, keysIn);
2628     }
2629
2630     /**
2631      * The base implementation of `_.forOwn` without support for iteratee shorthands.
2632      *
2633      * @private
2634      * @param {Object} object The object to iterate over.
2635      * @param {Function} iteratee The function invoked per iteration.
2636      * @returns {Object} Returns `object`.
2637      */
2638     function baseForOwn(object, iteratee) {
2639       return object && baseFor(object, iteratee, keys);
2640     }
2641
2642     /**
2643      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2644      *
2645      * @private
2646      * @param {Object} object The object to iterate over.
2647      * @param {Function} iteratee The function invoked per iteration.
2648      * @returns {Object} Returns `object`.
2649      */
2650     function baseForOwnRight(object, iteratee) {
2651       return object && baseForRight(object, iteratee, keys);
2652     }
2653
2654     /**
2655      * The base implementation of `_.functions` which creates an array of
2656      * `object` function property names filtered from `props`.
2657      *
2658      * @private
2659      * @param {Object} object The object to inspect.
2660      * @param {Array} props The property names to filter.
2661      * @returns {Array} Returns the new array of filtered property names.
2662      */
2663     function baseFunctions(object, props) {
2664       return arrayFilter(props, function(key) {
2665         return isFunction(object[key]);
2666       });
2667     }
2668
2669     /**
2670      * The base implementation of `_.get` without support for default values.
2671      *
2672      * @private
2673      * @param {Object} object The object to query.
2674      * @param {Array|string} path The path of the property to get.
2675      * @returns {*} Returns the resolved value.
2676      */
2677     function baseGet(object, path) {
2678       path = isKey(path, object) ? [path + ''] : baseCastPath(path);
2679
2680       var index = 0,
2681           length = path.length;
2682
2683       while (object != null && index < length) {
2684         object = object[path[index++]];
2685       }
2686       return (index && index == length) ? object : undefined;
2687     }
2688
2689     /**
2690      * The base implementation of `_.has` without support for deep paths.
2691      *
2692      * @private
2693      * @param {Object} object The object to query.
2694      * @param {Array|string} key The key to check.
2695      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2696      */
2697     function baseHas(object, key) {
2698       // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
2699       // that are composed entirely of index properties, return `false` for
2700       // `hasOwnProperty` checks of them.
2701       return hasOwnProperty.call(object, key) ||
2702         (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
2703     }
2704
2705     /**
2706      * The base implementation of `_.hasIn` without support for deep paths.
2707      *
2708      * @private
2709      * @param {Object} object The object to query.
2710      * @param {Array|string} key The key to check.
2711      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2712      */
2713     function baseHasIn(object, key) {
2714       return key in Object(object);
2715     }
2716
2717     /**
2718      * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
2719      *
2720      * @private
2721      * @param {number} number The number to check.
2722      * @param {number} start The start of the range.
2723      * @param {number} end The end of the range.
2724      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
2725      */
2726     function baseInRange(number, start, end) {
2727       return number >= nativeMin(start, end) && number < nativeMax(start, end);
2728     }
2729
2730     /**
2731      * The base implementation of methods like `_.intersection`, without support
2732      * for iteratee shorthands, that accepts an array of arrays to inspect.
2733      *
2734      * @private
2735      * @param {Array} arrays The arrays to inspect.
2736      * @param {Function} [iteratee] The iteratee invoked per element.
2737      * @param {Function} [comparator] The comparator invoked per element.
2738      * @returns {Array} Returns the new array of shared values.
2739      */
2740     function baseIntersection(arrays, iteratee, comparator) {
2741       var includes = comparator ? arrayIncludesWith : arrayIncludes,
2742           othLength = arrays.length,
2743           othIndex = othLength,
2744           caches = Array(othLength),
2745           result = [];
2746
2747       while (othIndex--) {
2748         var array = arrays[othIndex];
2749         if (othIndex && iteratee) {
2750           array = arrayMap(array, baseUnary(iteratee));
2751         }
2752         caches[othIndex] = !comparator && (iteratee || array.length >= 120)
2753           ? new SetCache(othIndex && array)
2754           : undefined;
2755       }
2756       array = arrays[0];
2757
2758       var index = -1,
2759           length = array.length,
2760           seen = caches[0];
2761
2762       outer:
2763       while (++index < length) {
2764         var value = array[index],
2765             computed = iteratee ? iteratee(value) : value;
2766
2767         if (!(seen
2768               ? cacheHas(seen, computed)
2769               : includes(result, computed, comparator)
2770             )) {
2771           var othIndex = othLength;
2772           while (--othIndex) {
2773             var cache = caches[othIndex];
2774             if (!(cache
2775                   ? cacheHas(cache, computed)
2776                   : includes(arrays[othIndex], computed, comparator))
2777                 ) {
2778               continue outer;
2779             }
2780           }
2781           if (seen) {
2782             seen.push(computed);
2783           }
2784           result.push(value);
2785         }
2786       }
2787       return result;
2788     }
2789
2790     /**
2791      * The base implementation of `_.invert` and `_.invertBy` which inverts
2792      * `object` with values transformed by `iteratee` and set by `setter`.
2793      *
2794      * @private
2795      * @param {Object} object The object to iterate over.
2796      * @param {Function} setter The function to set `accumulator` values.
2797      * @param {Function} iteratee The iteratee to transform values.
2798      * @param {Object} accumulator The initial inverted object.
2799      * @returns {Function} Returns `accumulator`.
2800      */
2801     function baseInverter(object, setter, iteratee, accumulator) {
2802       baseForOwn(object, function(value, key, object) {
2803         setter(accumulator, iteratee(value), key, object);
2804       });
2805       return accumulator;
2806     }
2807
2808     /**
2809      * The base implementation of `_.invoke` without support for individual
2810      * method arguments.
2811      *
2812      * @private
2813      * @param {Object} object The object to query.
2814      * @param {Array|string} path The path of the method to invoke.
2815      * @param {Array} args The arguments to invoke the method with.
2816      * @returns {*} Returns the result of the invoked method.
2817      */
2818     function baseInvoke(object, path, args) {
2819       if (!isKey(path, object)) {
2820         path = baseCastPath(path);
2821         object = parent(object, path);
2822         path = last(path);
2823       }
2824       var func = object == null ? object : object[path];
2825       return func == null ? undefined : apply(func, object, args);
2826     }
2827
2828     /**
2829      * The base implementation of `_.isEqual` which supports partial comparisons
2830      * and tracks traversed objects.
2831      *
2832      * @private
2833      * @param {*} value The value to compare.
2834      * @param {*} other The other value to compare.
2835      * @param {Function} [customizer] The function to customize comparisons.
2836      * @param {boolean} [bitmask] The bitmask of comparison flags.
2837      *  The bitmask may be composed of the following flags:
2838      *     1 - Unordered comparison
2839      *     2 - Partial comparison
2840      * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2841      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2842      */
2843     function baseIsEqual(value, other, customizer, bitmask, stack) {
2844       if (value === other) {
2845         return true;
2846       }
2847       if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
2848         return value !== value && other !== other;
2849       }
2850       return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
2851     }
2852
2853     /**
2854      * A specialized version of `baseIsEqual` for arrays and objects which performs
2855      * deep comparisons and tracks traversed objects enabling objects with circular
2856      * references to be compared.
2857      *
2858      * @private
2859      * @param {Object} object The object to compare.
2860      * @param {Object} other The other object to compare.
2861      * @param {Function} equalFunc The function to determine equivalents of values.
2862      * @param {Function} [customizer] The function to customize comparisons.
2863      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
2864      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2865      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2866      */
2867     function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
2868       var objIsArr = isArray(object),
2869           othIsArr = isArray(other),
2870           objTag = arrayTag,
2871           othTag = arrayTag;
2872
2873       if (!objIsArr) {
2874         objTag = getTag(object);
2875         if (objTag == argsTag) {
2876           objTag = objectTag;
2877         } else if (objTag != objectTag) {
2878           objIsArr = isTypedArray(object);
2879         }
2880       }
2881       if (!othIsArr) {
2882         othTag = getTag(other);
2883         if (othTag == argsTag) {
2884           othTag = objectTag;
2885         } else if (othTag != objectTag) {
2886           othIsArr = isTypedArray(other);
2887         }
2888       }
2889       var objIsObj = objTag == objectTag && !isHostObject(object),
2890           othIsObj = othTag == objectTag && !isHostObject(other),
2891           isSameTag = objTag == othTag;
2892
2893       if (isSameTag && !(objIsArr || objIsObj)) {
2894         return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
2895       }
2896       var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
2897       if (!isPartial) {
2898         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2899             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2900
2901         if (objIsWrapped || othIsWrapped) {
2902           return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
2903         }
2904       }
2905       if (!isSameTag) {
2906         return false;
2907       }
2908       stack || (stack = new Stack);
2909       return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
2910     }
2911
2912     /**
2913      * The base implementation of `_.isMatch` without support for iteratee shorthands.
2914      *
2915      * @private
2916      * @param {Object} object The object to inspect.
2917      * @param {Object} source The object of property values to match.
2918      * @param {Array} matchData The property names, values, and compare flags to match.
2919      * @param {Function} [customizer] The function to customize comparisons.
2920      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
2921      */
2922     function baseIsMatch(object, source, matchData, customizer) {
2923       var index = matchData.length,
2924           length = index,
2925           noCustomizer = !customizer;
2926
2927       if (object == null) {
2928         return !length;
2929       }
2930       object = Object(object);
2931       while (index--) {
2932         var data = matchData[index];
2933         if ((noCustomizer && data[2])
2934               ? data[1] !== object[data[0]]
2935               : !(data[0] in object)
2936             ) {
2937           return false;
2938         }
2939       }
2940       while (++index < length) {
2941         data = matchData[index];
2942         var key = data[0],
2943             objValue = object[key],
2944             srcValue = data[1];
2945
2946         if (noCustomizer && data[2]) {
2947           if (objValue === undefined && !(key in object)) {
2948             return false;
2949           }
2950         } else {
2951           var stack = new Stack,
2952               result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
2953
2954           if (!(result === undefined
2955                 ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
2956                 : result
2957               )) {
2958             return false;
2959           }
2960         }
2961       }
2962       return true;
2963     }
2964
2965     /**
2966      * The base implementation of `_.iteratee`.
2967      *
2968      * @private
2969      * @param {*} [value=_.identity] The value to convert to an iteratee.
2970      * @returns {Function} Returns the iteratee.
2971      */
2972     function baseIteratee(value) {
2973       var type = typeof value;
2974       if (type == 'function') {
2975         return value;
2976       }
2977       if (value == null) {
2978         return identity;
2979       }
2980       if (type == 'object') {
2981         return isArray(value)
2982           ? baseMatchesProperty(value[0], value[1])
2983           : baseMatches(value);
2984       }
2985       return property(value);
2986     }
2987
2988     /**
2989      * The base implementation of `_.keys` which doesn't skip the constructor
2990      * property of prototypes or treat sparse arrays as dense.
2991      *
2992      * @private
2993      * @param {Object} object The object to query.
2994      * @returns {Array} Returns the array of property names.
2995      */
2996     function baseKeys(object) {
2997       return nativeKeys(Object(object));
2998     }
2999
3000     /**
3001      * The base implementation of `_.keysIn` which doesn't skip the constructor
3002      * property of prototypes or treat sparse arrays as dense.
3003      *
3004      * @private
3005      * @param {Object} object The object to query.
3006      * @returns {Array} Returns the array of property names.
3007      */
3008     function baseKeysIn(object) {
3009       object = object == null ? object : Object(object);
3010
3011       var result = [];
3012       for (var key in object) {
3013         result.push(key);
3014       }
3015       return result;
3016     }
3017
3018     // Fallback for IE < 9 with es6-shim.
3019     if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
3020       baseKeysIn = function(object) {
3021         return iteratorToArray(enumerate(object));
3022       };
3023     }
3024
3025     /**
3026      * The base implementation of `_.map` without support for iteratee shorthands.
3027      *
3028      * @private
3029      * @param {Array|Object} collection The collection to iterate over.
3030      * @param {Function} iteratee The function invoked per iteration.
3031      * @returns {Array} Returns the new mapped array.
3032      */
3033     function baseMap(collection, iteratee) {
3034       var index = -1,
3035           result = isArrayLike(collection) ? Array(collection.length) : [];
3036
3037       baseEach(collection, function(value, key, collection) {
3038         result[++index] = iteratee(value, key, collection);
3039       });
3040       return result;
3041     }
3042
3043     /**
3044      * The base implementation of `_.matches` which doesn't clone `source`.
3045      *
3046      * @private
3047      * @param {Object} source The object of property values to match.
3048      * @returns {Function} Returns the new function.
3049      */
3050     function baseMatches(source) {
3051       var matchData = getMatchData(source);
3052       if (matchData.length == 1 && matchData[0][2]) {
3053         var key = matchData[0][0],
3054             value = matchData[0][1];
3055
3056         return function(object) {
3057           if (object == null) {
3058             return false;
3059           }
3060           return object[key] === value &&
3061             (value !== undefined || (key in Object(object)));
3062         };
3063       }
3064       return function(object) {
3065         return object === source || baseIsMatch(object, source, matchData);
3066       };
3067     }
3068
3069     /**
3070      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3071      *
3072      * @private
3073      * @param {string} path The path of the property to get.
3074      * @param {*} srcValue The value to match.
3075      * @returns {Function} Returns the new function.
3076      */
3077     function baseMatchesProperty(path, srcValue) {
3078       return function(object) {
3079         var objValue = get(object, path);
3080         return (objValue === undefined && objValue === srcValue)
3081           ? hasIn(object, path)
3082           : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
3083       };
3084     }
3085
3086     /**
3087      * The base implementation of `_.merge` without support for multiple sources.
3088      *
3089      * @private
3090      * @param {Object} object The destination object.
3091      * @param {Object} source The source object.
3092      * @param {number} srcIndex The index of `source`.
3093      * @param {Function} [customizer] The function to customize merged values.
3094      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
3095      */
3096     function baseMerge(object, source, srcIndex, customizer, stack) {
3097       if (object === source) {
3098         return;
3099       }
3100       var props = (isArray(source) || isTypedArray(source))
3101         ? undefined
3102         : keysIn(source);
3103
3104       arrayEach(props || source, function(srcValue, key) {
3105         if (props) {
3106           key = srcValue;
3107           srcValue = source[key];
3108         }
3109         if (isObject(srcValue)) {
3110           stack || (stack = new Stack);
3111           baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3112         }
3113         else {
3114           var newValue = customizer
3115             ? customizer(object[key], srcValue, (key + ''), object, source, stack)
3116             : undefined;
3117
3118           if (newValue === undefined) {
3119             newValue = srcValue;
3120           }
3121           assignMergeValue(object, key, newValue);
3122         }
3123       });
3124     }
3125
3126     /**
3127      * A specialized version of `baseMerge` for arrays and objects which performs
3128      * deep merges and tracks traversed objects enabling objects with circular
3129      * references to be merged.
3130      *
3131      * @private
3132      * @param {Object} object The destination object.
3133      * @param {Object} source The source object.
3134      * @param {string} key The key of the value to merge.
3135      * @param {number} srcIndex The index of `source`.
3136      * @param {Function} mergeFunc The function to merge values.
3137      * @param {Function} [customizer] The function to customize assigned values.
3138      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
3139      */
3140     function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3141       var objValue = object[key],
3142           srcValue = source[key],
3143           stacked = stack.get(srcValue);
3144
3145       if (stacked) {
3146         assignMergeValue(object, key, stacked);
3147         return;
3148       }
3149       var newValue = customizer
3150         ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3151         : undefined;
3152
3153       var isCommon = newValue === undefined;
3154
3155       if (isCommon) {
3156         newValue = srcValue;
3157         if (isArray(srcValue) || isTypedArray(srcValue)) {
3158           if (isArray(objValue)) {
3159             newValue = objValue;
3160           }
3161           else if (isArrayLikeObject(objValue)) {
3162             newValue = copyArray(objValue);
3163           }
3164           else {
3165             isCommon = false;
3166             newValue = baseClone(srcValue, true);
3167           }
3168         }
3169         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3170           if (isArguments(objValue)) {
3171             newValue = toPlainObject(objValue);
3172           }
3173           else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3174             isCommon = false;
3175             newValue = baseClone(srcValue, true);
3176           }
3177           else {
3178             newValue = objValue;
3179           }
3180         }
3181         else {
3182           isCommon = false;
3183         }
3184       }
3185       stack.set(srcValue, newValue);
3186
3187       if (isCommon) {
3188         // Recursively merge objects and arrays (susceptible to call stack limits).
3189         mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3190       }
3191       assignMergeValue(object, key, newValue);
3192     }
3193
3194     /**
3195      * The base implementation of `_.orderBy` without param guards.
3196      *
3197      * @private
3198      * @param {Array|Object} collection The collection to iterate over.
3199      * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3200      * @param {string[]} orders The sort orders of `iteratees`.
3201      * @returns {Array} Returns the new sorted array.
3202      */
3203     function baseOrderBy(collection, iteratees, orders) {
3204       var index = -1,
3205           toIteratee = getIteratee();
3206
3207       iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
3208         return toIteratee(iteratee);
3209       });
3210
3211       var result = baseMap(collection, function(value, key, collection) {
3212         var criteria = arrayMap(iteratees, function(iteratee) {
3213           return iteratee(value);
3214         });
3215         return { 'criteria': criteria, 'index': ++index, 'value': value };
3216       });
3217
3218       return baseSortBy(result, function(object, other) {
3219         return compareMultiple(object, other, orders);
3220       });
3221     }
3222
3223     /**
3224      * The base implementation of `_.pick` without support for individual
3225      * property names.
3226      *
3227      * @private
3228      * @param {Object} object The source object.
3229      * @param {string[]} props The property names to pick.
3230      * @returns {Object} Returns the new object.
3231      */
3232     function basePick(object, props) {
3233       object = Object(object);
3234       return arrayReduce(props, function(result, key) {
3235         if (key in object) {
3236           result[key] = object[key];
3237         }
3238         return result;
3239       }, {});
3240     }
3241
3242     /**
3243      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3244      *
3245      * @private
3246      * @param {Object} object The source object.
3247      * @param {Function} predicate The function invoked per property.
3248      * @returns {Object} Returns the new object.
3249      */
3250     function basePickBy(object, predicate) {
3251       var result = {};
3252       baseForIn(object, function(value, key) {
3253         if (predicate(value, key)) {
3254           result[key] = value;
3255         }
3256       });
3257       return result;
3258     }
3259
3260     /**
3261      * The base implementation of `_.property` without support for deep paths.
3262      *
3263      * @private
3264      * @param {string} key The key of the property to get.
3265      * @returns {Function} Returns the new function.
3266      */
3267     function baseProperty(key) {
3268       return function(object) {
3269         return object == null ? undefined : object[key];
3270       };
3271     }
3272
3273     /**
3274      * A specialized version of `baseProperty` which supports deep paths.
3275      *
3276      * @private
3277      * @param {Array|string} path The path of the property to get.
3278      * @returns {Function} Returns the new function.
3279      */
3280     function basePropertyDeep(path) {
3281       return function(object) {
3282         return baseGet(object, path);
3283       };
3284     }
3285
3286     /**
3287      * The base implementation of `_.pullAll`.
3288      *
3289      * @private
3290      * @param {Array} array The array to modify.
3291      * @param {Array} values The values to remove.
3292      * @returns {Array} Returns `array`.
3293      */
3294     function basePullAll(array, values) {
3295       return basePullAllBy(array, values);
3296     }
3297
3298     /**
3299      * The base implementation of `_.pullAllBy` without support for iteratee
3300      * shorthands.
3301      *
3302      * @private
3303      * @param {Array} array The array to modify.
3304      * @param {Array} values The values to remove.
3305      * @param {Function} [iteratee] The iteratee invoked per element.
3306      * @returns {Array} Returns `array`.
3307      */
3308     function basePullAllBy(array, values, iteratee) {
3309       var index = -1,
3310           length = values.length,
3311           seen = array;
3312
3313       if (iteratee) {
3314         seen = arrayMap(array, function(value) { return iteratee(value); });
3315       }
3316       while (++index < length) {
3317         var fromIndex = 0,
3318             value = values[index],
3319             computed = iteratee ? iteratee(value) : value;
3320
3321         while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
3322           if (seen !== array) {
3323             splice.call(seen, fromIndex, 1);
3324           }
3325           splice.call(array, fromIndex, 1);
3326         }
3327       }
3328       return array;
3329     }
3330
3331     /**
3332      * The base implementation of `_.pullAt` without support for individual
3333      * indexes or capturing the removed elements.
3334      *
3335      * @private
3336      * @param {Array} array The array to modify.
3337      * @param {number[]} indexes The indexes of elements to remove.
3338      * @returns {Array} Returns `array`.
3339      */
3340     function basePullAt(array, indexes) {
3341       var length = array ? indexes.length : 0,
3342           lastIndex = length - 1;
3343
3344       while (length--) {
3345         var index = indexes[length];
3346         if (lastIndex == length || index != previous) {
3347           var previous = index;
3348           if (isIndex(index)) {
3349             splice.call(array, index, 1);
3350           }
3351           else if (!isKey(index, array)) {
3352             var path = baseCastPath(index),
3353                 object = parent(array, path);
3354
3355             if (object != null) {
3356               delete object[last(path)];
3357             }
3358           }
3359           else {
3360             delete array[index];
3361           }
3362         }
3363       }
3364       return array;
3365     }
3366
3367     /**
3368      * The base implementation of `_.random` without support for returning
3369      * floating-point numbers.
3370      *
3371      * @private
3372      * @param {number} lower The lower bound.
3373      * @param {number} upper The upper bound.
3374      * @returns {number} Returns the random number.
3375      */
3376     function baseRandom(lower, upper) {
3377       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3378     }
3379
3380     /**
3381      * The base implementation of `_.range` and `_.rangeRight` which doesn't
3382      * coerce arguments to numbers.
3383      *
3384      * @private
3385      * @param {number} start The start of the range.
3386      * @param {number} end The end of the range.
3387      * @param {number} step The value to increment or decrement by.
3388      * @param {boolean} [fromRight] Specify iterating from right to left.
3389      * @returns {Array} Returns the new array of numbers.
3390      */
3391     function baseRange(start, end, step, fromRight) {
3392       var index = -1,
3393           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3394           result = Array(length);
3395
3396       while (length--) {
3397         result[fromRight ? length : ++index] = start;
3398         start += step;
3399       }
3400       return result;
3401     }
3402
3403     /**
3404      * The base implementation of `_.set`.
3405      *
3406      * @private
3407      * @param {Object} object The object to query.
3408      * @param {Array|string} path The path of the property to set.
3409      * @param {*} value The value to set.
3410      * @param {Function} [customizer] The function to customize path creation.
3411      * @returns {Object} Returns `object`.
3412      */
3413     function baseSet(object, path, value, customizer) {
3414       path = isKey(path, object) ? [path + ''] : baseCastPath(path);
3415
3416       var index = -1,
3417           length = path.length,
3418           lastIndex = length - 1,
3419           nested = object;
3420
3421       while (nested != null && ++index < length) {
3422         var key = path[index];
3423         if (isObject(nested)) {
3424           var newValue = value;
3425           if (index != lastIndex) {
3426             var objValue = nested[key];
3427             newValue = customizer ? customizer(objValue, key, nested) : undefined;
3428             if (newValue === undefined) {
3429               newValue = objValue == null
3430                 ? (isIndex(path[index + 1]) ? [] : {})
3431                 : objValue;
3432             }
3433           }
3434           assignValue(nested, key, newValue);
3435         }
3436         nested = nested[key];
3437       }
3438       return object;
3439     }
3440
3441     /**
3442      * The base implementation of `setData` without support for hot loop detection.
3443      *
3444      * @private
3445      * @param {Function} func The function to associate metadata with.
3446      * @param {*} data The metadata.
3447      * @returns {Function} Returns `func`.
3448      */
3449     var baseSetData = !metaMap ? identity : function(func, data) {
3450       metaMap.set(func, data);
3451       return func;
3452     };
3453
3454     /**
3455      * The base implementation of `_.slice` without an iteratee call guard.
3456      *
3457      * @private
3458      * @param {Array} array The array to slice.
3459      * @param {number} [start=0] The start position.
3460      * @param {number} [end=array.length] The end position.
3461      * @returns {Array} Returns the slice of `array`.
3462      */
3463     function baseSlice(array, start, end) {
3464       var index = -1,
3465           length = array.length;
3466
3467       if (start < 0) {
3468         start = -start > length ? 0 : (length + start);
3469       }
3470       end = end > length ? length : end;
3471       if (end < 0) {
3472         end += length;
3473       }
3474       length = start > end ? 0 : ((end - start) >>> 0);
3475       start >>>= 0;
3476
3477       var result = Array(length);
3478       while (++index < length) {
3479         result[index] = array[index + start];
3480       }
3481       return result;
3482     }
3483
3484     /**
3485      * The base implementation of `_.some` without support for iteratee shorthands.
3486      *
3487      * @private
3488      * @param {Array|Object} collection The collection to iterate over.
3489      * @param {Function} predicate The function invoked per iteration.
3490      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
3491      */
3492     function baseSome(collection, predicate) {
3493       var result;
3494
3495       baseEach(collection, function(value, index, collection) {
3496         result = predicate(value, index, collection);
3497         return !result;
3498       });
3499       return !!result;
3500     }
3501
3502     /**
3503      * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
3504      * performs a binary search of `array` to determine the index at which `value`
3505      * should be inserted into `array` in order to maintain its sort order.
3506      *
3507      * @private
3508      * @param {Array} array The sorted array to inspect.
3509      * @param {*} value The value to evaluate.
3510      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3511      * @returns {number} Returns the index at which `value` should be inserted
3512      *  into `array`.
3513      */
3514     function baseSortedIndex(array, value, retHighest) {
3515       var low = 0,
3516           high = array ? array.length : low;
3517
3518       if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
3519         while (low < high) {
3520           var mid = (low + high) >>> 1,
3521               computed = array[mid];
3522
3523           if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
3524             low = mid + 1;
3525           } else {
3526             high = mid;
3527           }
3528         }
3529         return high;
3530       }
3531       return baseSortedIndexBy(array, value, identity, retHighest);
3532     }
3533
3534     /**
3535      * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
3536      * which invokes `iteratee` for `value` and each element of `array` to compute
3537      * their sort ranking. The iteratee is invoked with one argument; (value).
3538      *
3539      * @private
3540      * @param {Array} array The sorted array to inspect.
3541      * @param {*} value The value to evaluate.
3542      * @param {Function} iteratee The iteratee invoked per element.
3543      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3544      * @returns {number} Returns the index at which `value` should be inserted into `array`.
3545      */
3546     function baseSortedIndexBy(array, value, iteratee, retHighest) {
3547       value = iteratee(value);
3548
3549       var low = 0,
3550           high = array ? array.length : 0,
3551           valIsNaN = value !== value,
3552           valIsNull = value === null,
3553           valIsUndef = value === undefined;
3554
3555       while (low < high) {
3556         var mid = nativeFloor((low + high) / 2),
3557             computed = iteratee(array[mid]),
3558             isDef = computed !== undefined,
3559             isReflexive = computed === computed;
3560
3561         if (valIsNaN) {
3562           var setLow = isReflexive || retHighest;
3563         } else if (valIsNull) {
3564           setLow = isReflexive && isDef && (retHighest || computed != null);
3565         } else if (valIsUndef) {
3566           setLow = isReflexive && (retHighest || isDef);
3567         } else if (computed == null) {
3568           setLow = false;
3569         } else {
3570           setLow = retHighest ? (computed <= value) : (computed < value);
3571         }
3572         if (setLow) {
3573           low = mid + 1;
3574         } else {
3575           high = mid;
3576         }
3577       }
3578       return nativeMin(high, MAX_ARRAY_INDEX);
3579     }
3580
3581     /**
3582      * The base implementation of `_.sortedUniq`.
3583      *
3584      * @private
3585      * @param {Array} array The array to inspect.
3586      * @returns {Array} Returns the new duplicate free array.
3587      */
3588     function baseSortedUniq(array) {
3589       return baseSortedUniqBy(array);
3590     }
3591
3592     /**
3593      * The base implementation of `_.sortedUniqBy` without support for iteratee
3594      * shorthands.
3595      *
3596      * @private
3597      * @param {Array} array The array to inspect.
3598      * @param {Function} [iteratee] The iteratee invoked per element.
3599      * @returns {Array} Returns the new duplicate free array.
3600      */
3601     function baseSortedUniqBy(array, iteratee) {
3602       var index = 0,
3603           length = array.length,
3604           value = array[0],
3605           computed = iteratee ? iteratee(value) : value,
3606           seen = computed,
3607           resIndex = 0,
3608           result = [value];
3609
3610       while (++index < length) {
3611         value = array[index],
3612         computed = iteratee ? iteratee(value) : value;
3613
3614         if (!eq(computed, seen)) {
3615           seen = computed;
3616           result[++resIndex] = value;
3617         }
3618       }
3619       return result;
3620     }
3621
3622     /**
3623      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
3624      *
3625      * @private
3626      * @param {Array} array The array to inspect.
3627      * @param {Function} [iteratee] The iteratee invoked per element.
3628      * @param {Function} [comparator] The comparator invoked per element.
3629      * @returns {Array} Returns the new duplicate free array.
3630      */
3631     function baseUniq(array, iteratee, comparator) {
3632       var index = -1,
3633           includes = arrayIncludes,
3634           length = array.length,
3635           isCommon = true,
3636           result = [],
3637           seen = result;
3638
3639       if (comparator) {
3640         isCommon = false;
3641         includes = arrayIncludesWith;
3642       }
3643       else if (length >= LARGE_ARRAY_SIZE) {
3644         var set = iteratee ? null : createSet(array);
3645         if (set) {
3646           return setToArray(set);
3647         }
3648         isCommon = false;
3649         includes = cacheHas;
3650         seen = new SetCache;
3651       }
3652       else {
3653         seen = iteratee ? [] : result;
3654       }
3655       outer:
3656       while (++index < length) {
3657         var value = array[index],
3658             computed = iteratee ? iteratee(value) : value;
3659
3660         if (isCommon && computed === computed) {
3661           var seenIndex = seen.length;
3662           while (seenIndex--) {
3663             if (seen[seenIndex] === computed) {
3664               continue outer;
3665             }
3666           }
3667           if (iteratee) {
3668             seen.push(computed);
3669           }
3670           result.push(value);
3671         }
3672         else if (!includes(seen, computed, comparator)) {
3673           if (seen !== result) {
3674             seen.push(computed);
3675           }
3676           result.push(value);
3677         }
3678       }
3679       return result;
3680     }
3681
3682     /**
3683      * The base implementation of `_.unset`.
3684      *
3685      * @private
3686      * @param {Object} object The object to modify.
3687      * @param {Array|string} path The path of the property to unset.
3688      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
3689      */
3690     function baseUnset(object, path) {
3691       path = isKey(path, object) ? [path + ''] : baseCastPath(path);
3692       object = parent(object, path);
3693       var key = last(path);
3694       return (object != null && has(object, key)) ? delete object[key] : true;
3695     }
3696
3697     /**
3698      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
3699      * without support for iteratee shorthands.
3700      *
3701      * @private
3702      * @param {Array} array The array to query.
3703      * @param {Function} predicate The function invoked per iteration.
3704      * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
3705      * @param {boolean} [fromRight] Specify iterating from right to left.
3706      * @returns {Array} Returns the slice of `array`.
3707      */
3708     function baseWhile(array, predicate, isDrop, fromRight) {
3709       var length = array.length,
3710           index = fromRight ? length : -1;
3711
3712       while ((fromRight ? index-- : ++index < length) &&
3713         predicate(array[index], index, array)) {}
3714
3715       return isDrop
3716         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
3717         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
3718     }
3719
3720     /**
3721      * The base implementation of `wrapperValue` which returns the result of
3722      * performing a sequence of actions on the unwrapped `value`, where each
3723      * successive action is supplied the return value of the previous.
3724      *
3725      * @private
3726      * @param {*} value The unwrapped value.
3727      * @param {Array} actions Actions to perform to resolve the unwrapped value.
3728      * @returns {*} Returns the resolved value.
3729      */
3730     function baseWrapperValue(value, actions) {
3731       var result = value;
3732       if (result instanceof LazyWrapper) {
3733         result = result.value();
3734       }
3735       return arrayReduce(actions, function(result, action) {
3736         return action.func.apply(action.thisArg, arrayPush([result], action.args));
3737       }, result);
3738     }
3739
3740     /**
3741      * The base implementation of methods like `_.xor`, without support for
3742      * iteratee shorthands, that accepts an array of arrays to inspect.
3743      *
3744      * @private
3745      * @param {Array} arrays The arrays to inspect.
3746      * @param {Function} [iteratee] The iteratee invoked per element.
3747      * @param {Function} [comparator] The comparator invoked per element.
3748      * @returns {Array} Returns the new array of values.
3749      */
3750     function baseXor(arrays, iteratee, comparator) {
3751       var index = -1,
3752           length = arrays.length;
3753
3754       while (++index < length) {
3755         var result = result
3756           ? arrayPush(
3757               baseDifference(result, arrays[index], iteratee, comparator),
3758               baseDifference(arrays[index], result, iteratee, comparator)
3759             )
3760           : arrays[index];
3761       }
3762       return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
3763     }
3764
3765     /**
3766      * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
3767      *
3768      * @private
3769      * @param {Array} props The property names.
3770      * @param {Array} values The property values.
3771      * @param {Function} assignFunc The function to assign values.
3772      * @returns {Object} Returns the new object.
3773      */
3774     function baseZipObject(props, values, assignFunc) {
3775       var index = -1,
3776           length = props.length,
3777           valsLength = values.length,
3778           result = {};
3779
3780       while (++index < length) {
3781         assignFunc(result, props[index], index < valsLength ? values[index] : undefined);
3782       }
3783       return result;
3784     }
3785
3786     /**
3787      * Creates a clone of  `buffer`.
3788      *
3789      * @private
3790      * @param {Buffer} buffer The buffer to clone.
3791      * @param {boolean} [isDeep] Specify a deep clone.
3792      * @returns {Buffer} Returns the cloned buffer.
3793      */
3794     function cloneBuffer(buffer, isDeep) {
3795       if (isDeep) {
3796         return buffer.slice();
3797       }
3798       var Ctor = buffer.constructor,
3799           result = new Ctor(buffer.length);
3800
3801       buffer.copy(result);
3802       return result;
3803     }
3804
3805     /**
3806      * Creates a clone of `arrayBuffer`.
3807      *
3808      * @private
3809      * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
3810      * @returns {ArrayBuffer} Returns the cloned array buffer.
3811      */
3812     function cloneArrayBuffer(arrayBuffer) {
3813       var Ctor = arrayBuffer.constructor,
3814           result = new Ctor(arrayBuffer.byteLength),
3815           view = new Uint8Array(result);
3816
3817       view.set(new Uint8Array(arrayBuffer));
3818       return result;
3819     }
3820
3821     /**
3822      * Creates a clone of `map`.
3823      *
3824      * @private
3825      * @param {Object} map The map to clone.
3826      * @returns {Object} Returns the cloned map.
3827      */
3828     function cloneMap(map) {
3829       var Ctor = map.constructor;
3830       return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
3831     }
3832
3833     /**
3834      * Creates a clone of `regexp`.
3835      *
3836      * @private
3837      * @param {Object} regexp The regexp to clone.
3838      * @returns {Object} Returns the cloned regexp.
3839      */
3840     function cloneRegExp(regexp) {
3841       var Ctor = regexp.constructor,
3842           result = new Ctor(regexp.source, reFlags.exec(regexp));
3843
3844       result.lastIndex = regexp.lastIndex;
3845       return result;
3846     }
3847
3848     /**
3849      * Creates a clone of `set`.
3850      *
3851      * @private
3852      * @param {Object} set The set to clone.
3853      * @returns {Object} Returns the cloned set.
3854      */
3855     function cloneSet(set) {
3856       var Ctor = set.constructor;
3857       return arrayReduce(setToArray(set), addSetEntry, new Ctor);
3858     }
3859
3860     /**
3861      * Creates a clone of the `symbol` object.
3862      *
3863      * @private
3864      * @param {Object} symbol The symbol object to clone.
3865      * @returns {Object} Returns the cloned symbol object.
3866      */
3867     function cloneSymbol(symbol) {
3868       return Symbol ? Object(symbolValueOf.call(symbol)) : {};
3869     }
3870
3871     /**
3872      * Creates a clone of `typedArray`.
3873      *
3874      * @private
3875      * @param {Object} typedArray The typed array to clone.
3876      * @param {boolean} [isDeep] Specify a deep clone.
3877      * @returns {Object} Returns the cloned typed array.
3878      */
3879     function cloneTypedArray(typedArray, isDeep) {
3880       var arrayBuffer = typedArray.buffer,
3881           buffer = isDeep ? cloneArrayBuffer(arrayBuffer) : arrayBuffer,
3882           Ctor = typedArray.constructor;
3883
3884       return new Ctor(buffer, typedArray.byteOffset, typedArray.length);
3885     }
3886
3887     /**
3888      * Creates an array that is the composition of partially applied arguments,
3889      * placeholders, and provided arguments into a single array of arguments.
3890      *
3891      * @private
3892      * @param {Array|Object} args The provided arguments.
3893      * @param {Array} partials The arguments to prepend to those provided.
3894      * @param {Array} holders The `partials` placeholder indexes.
3895      * @params {boolean} [isCurried] Specify composing for a curried function.
3896      * @returns {Array} Returns the new array of composed arguments.
3897      */
3898     function composeArgs(args, partials, holders, isCurried) {
3899       var argsIndex = -1,
3900           argsLength = args.length,
3901           holdersLength = holders.length,
3902           leftIndex = -1,
3903           leftLength = partials.length,
3904           rangeLength = nativeMax(argsLength - holdersLength, 0),
3905           result = Array(leftLength + rangeLength),
3906           isUncurried = !isCurried;
3907
3908       while (++leftIndex < leftLength) {
3909         result[leftIndex] = partials[leftIndex];
3910       }
3911       while (++argsIndex < holdersLength) {
3912         if (isUncurried || argsIndex < argsLength) {
3913           result[holders[argsIndex]] = args[argsIndex];
3914         }
3915       }
3916       while (rangeLength--) {
3917         result[leftIndex++] = args[argsIndex++];
3918       }
3919       return result;
3920     }
3921
3922     /**
3923      * This function is like `composeArgs` except that the arguments composition
3924      * is tailored for `_.partialRight`.
3925      *
3926      * @private
3927      * @param {Array|Object} args The provided arguments.
3928      * @param {Array} partials The arguments to append to those provided.
3929      * @param {Array} holders The `partials` placeholder indexes.
3930      * @params {boolean} [isCurried] Specify composing for a curried function.
3931      * @returns {Array} Returns the new array of composed arguments.
3932      */
3933     function composeArgsRight(args, partials, holders, isCurried) {
3934       var argsIndex = -1,
3935           argsLength = args.length,
3936           holdersIndex = -1,
3937           holdersLength = holders.length,
3938           rightIndex = -1,
3939           rightLength = partials.length,
3940           rangeLength = nativeMax(argsLength - holdersLength, 0),
3941           result = Array(rangeLength + rightLength),
3942           isUncurried = !isCurried;
3943
3944       while (++argsIndex < rangeLength) {
3945         result[argsIndex] = args[argsIndex];
3946       }
3947       var offset = argsIndex;
3948       while (++rightIndex < rightLength) {
3949         result[offset + rightIndex] = partials[rightIndex];
3950       }
3951       while (++holdersIndex < holdersLength) {
3952         if (isUncurried || argsIndex < argsLength) {
3953           result[offset + holders[holdersIndex]] = args[argsIndex++];
3954         }
3955       }
3956       return result;
3957     }
3958
3959     /**
3960      * Copies the values of `source` to `array`.
3961      *
3962      * @private
3963      * @param {Array} source The array to copy values from.
3964      * @param {Array} [array=[]] The array to copy values to.
3965      * @returns {Array} Returns `array`.
3966      */
3967     function copyArray(source, array) {
3968       var index = -1,
3969           length = source.length;
3970
3971       array || (array = Array(length));
3972       while (++index < length) {
3973         array[index] = source[index];
3974       }
3975       return array;
3976     }
3977
3978     /**
3979      * Copies properties of `source` to `object`.
3980      *
3981      * @private
3982      * @param {Object} source The object to copy properties from.
3983      * @param {Array} props The property names to copy.
3984      * @param {Object} [object={}] The object to copy properties to.
3985      * @returns {Object} Returns `object`.
3986      */
3987     function copyObject(source, props, object) {
3988       return copyObjectWith(source, props, object);
3989     }
3990
3991     /**
3992      * This function is like `copyObject` except that it accepts a function to
3993      * customize copied values.
3994      *
3995      * @private
3996      * @param {Object} source The object to copy properties from.
3997      * @param {Array} props The property names to copy.
3998      * @param {Object} [object={}] The object to copy properties to.
3999      * @param {Function} [customizer] The function to customize copied values.
4000      * @returns {Object} Returns `object`.
4001      */
4002     function copyObjectWith(source, props, object, customizer) {
4003       object || (object = {});
4004
4005       var index = -1,
4006           length = props.length;
4007
4008       while (++index < length) {
4009         var key = props[index];
4010
4011         var newValue = customizer
4012           ? customizer(object[key], source[key], key, object, source)
4013           : source[key];
4014
4015         assignValue(object, key, newValue);
4016       }
4017       return object;
4018     }
4019
4020     /**
4021      * Copies own symbol properties of `source` to `object`.
4022      *
4023      * @private
4024      * @param {Object} source The object to copy symbols from.
4025      * @param {Object} [object={}] The object to copy symbols to.
4026      * @returns {Object} Returns `object`.
4027      */
4028     function copySymbols(source, object) {
4029       return copyObject(source, getSymbols(source), object);
4030     }
4031
4032     /**
4033      * Creates a function like `_.groupBy`.
4034      *
4035      * @private
4036      * @param {Function} setter The function to set accumulator values.
4037      * @param {Function} [initializer] The accumulator object initializer.
4038      * @returns {Function} Returns the new aggregator function.
4039      */
4040     function createAggregator(setter, initializer) {
4041       return function(collection, iteratee) {
4042         var func = isArray(collection) ? arrayAggregator : baseAggregator,
4043             accumulator = initializer ? initializer() : {};
4044
4045         return func(collection, setter, getIteratee(iteratee), accumulator);
4046       };
4047     }
4048
4049     /**
4050      * Creates a function like `_.assign`.
4051      *
4052      * @private
4053      * @param {Function} assigner The function to assign values.
4054      * @returns {Function} Returns the new assigner function.
4055      */
4056     function createAssigner(assigner) {
4057       return rest(function(object, sources) {
4058         var index = -1,
4059             length = sources.length,
4060             customizer = length > 1 ? sources[length - 1] : undefined,
4061             guard = length > 2 ? sources[2] : undefined;
4062
4063         customizer = typeof customizer == 'function'
4064           ? (length--, customizer)
4065           : undefined;
4066
4067         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4068           customizer = length < 3 ? undefined : customizer;
4069           length = 1;
4070         }
4071         object = Object(object);
4072         while (++index < length) {
4073           var source = sources[index];
4074           if (source) {
4075             assigner(object, source, index, customizer);
4076           }
4077         }
4078         return object;
4079       });
4080     }
4081
4082     /**
4083      * Creates a `baseEach` or `baseEachRight` function.
4084      *
4085      * @private
4086      * @param {Function} eachFunc The function to iterate over a collection.
4087      * @param {boolean} [fromRight] Specify iterating from right to left.
4088      * @returns {Function} Returns the new base function.
4089      */
4090     function createBaseEach(eachFunc, fromRight) {
4091       return function(collection, iteratee) {
4092         if (collection == null) {
4093           return collection;
4094         }
4095         if (!isArrayLike(collection)) {
4096           return eachFunc(collection, iteratee);
4097         }
4098         var length = collection.length,
4099             index = fromRight ? length : -1,
4100             iterable = Object(collection);
4101
4102         while ((fromRight ? index-- : ++index < length)) {
4103           if (iteratee(iterable[index], index, iterable) === false) {
4104             break;
4105           }
4106         }
4107         return collection;
4108       };
4109     }
4110
4111     /**
4112      * Creates a base function for methods like `_.forIn`.
4113      *
4114      * @private
4115      * @param {boolean} [fromRight] Specify iterating from right to left.
4116      * @returns {Function} Returns the new base function.
4117      */
4118     function createBaseFor(fromRight) {
4119       return function(object, iteratee, keysFunc) {
4120         var index = -1,
4121             iterable = Object(object),
4122             props = keysFunc(object),
4123             length = props.length;
4124
4125         while (length--) {
4126           var key = props[fromRight ? length : ++index];
4127           if (iteratee(iterable[key], key, iterable) === false) {
4128             break;
4129           }
4130         }
4131         return object;
4132       };
4133     }
4134
4135     /**
4136      * Creates a function that wraps `func` to invoke it with the optional `this`
4137      * binding of `thisArg`.
4138      *
4139      * @private
4140      * @param {Function} func The function to wrap.
4141      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4142      * @param {*} [thisArg] The `this` binding of `func`.
4143      * @returns {Function} Returns the new wrapped function.
4144      */
4145     function createBaseWrapper(func, bitmask, thisArg) {
4146       var isBind = bitmask & BIND_FLAG,
4147           Ctor = createCtorWrapper(func);
4148
4149       function wrapper() {
4150         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4151         return fn.apply(isBind ? thisArg : this, arguments);
4152       }
4153       return wrapper;
4154     }
4155
4156     /**
4157      * Creates a function like `_.lowerFirst`.
4158      *
4159      * @private
4160      * @param {string} methodName The name of the `String` case method to use.
4161      * @returns {Function} Returns the new function.
4162      */
4163     function createCaseFirst(methodName) {
4164       return function(string) {
4165         string = toString(string);
4166
4167         var strSymbols = reHasComplexSymbol.test(string)
4168           ? stringToArray(string)
4169           : undefined;
4170
4171         var chr = strSymbols ? strSymbols[0] : string.charAt(0),
4172             trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
4173
4174         return chr[methodName]() + trailing;
4175       };
4176     }
4177
4178     /**
4179      * Creates a function like `_.camelCase`.
4180      *
4181      * @private
4182      * @param {Function} callback The function to combine each word.
4183      * @returns {Function} Returns the new compounder function.
4184      */
4185     function createCompounder(callback) {
4186       return function(string) {
4187         return arrayReduce(words(deburr(string)), callback, '');
4188       };
4189     }
4190
4191     /**
4192      * Creates a function that produces an instance of `Ctor` regardless of
4193      * whether it was invoked as part of a `new` expression or by `call` or `apply`.
4194      *
4195      * @private
4196      * @param {Function} Ctor The constructor to wrap.
4197      * @returns {Function} Returns the new wrapped function.
4198      */
4199     function createCtorWrapper(Ctor) {
4200       return function() {
4201         // Use a `switch` statement to work with class constructors.
4202         // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
4203         // for more details.
4204         var args = arguments;
4205         switch (args.length) {
4206           case 0: return new Ctor;
4207           case 1: return new Ctor(args[0]);
4208           case 2: return new Ctor(args[0], args[1]);
4209           case 3: return new Ctor(args[0], args[1], args[2]);
4210           case 4: return new Ctor(args[0], args[1], args[2], args[3]);
4211           case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
4212           case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
4213           case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
4214         }
4215         var thisBinding = baseCreate(Ctor.prototype),
4216             result = Ctor.apply(thisBinding, args);
4217
4218         // Mimic the constructor's `return` behavior.
4219         // See https://es5.github.io/#x13.2.2 for more details.
4220         return isObject(result) ? result : thisBinding;
4221       };
4222     }
4223
4224     /**
4225      * Creates a function that wraps `func` to enable currying.
4226      *
4227      * @private
4228      * @param {Function} func The function to wrap.
4229      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4230      * @param {number} arity The arity of `func`.
4231      * @returns {Function} Returns the new wrapped function.
4232      */
4233     function createCurryWrapper(func, bitmask, arity) {
4234       var Ctor = createCtorWrapper(func);
4235
4236       function wrapper() {
4237         var length = arguments.length,
4238             args = Array(length),
4239             index = length,
4240             placeholder = getPlaceholder(wrapper);
4241
4242         while (index--) {
4243           args[index] = arguments[index];
4244         }
4245         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
4246           ? []
4247           : replaceHolders(args, placeholder);
4248
4249         length -= holders.length;
4250         if (length < arity) {
4251           return createRecurryWrapper(
4252             func, bitmask, createHybridWrapper, wrapper.placeholder, undefined,
4253             args, holders, undefined, undefined, arity - length);
4254         }
4255         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4256         return apply(fn, this, args);
4257       }
4258       return wrapper;
4259     }
4260
4261     /**
4262      * Creates a `_.flow` or `_.flowRight` function.
4263      *
4264      * @private
4265      * @param {boolean} [fromRight] Specify iterating from right to left.
4266      * @returns {Function} Returns the new flow function.
4267      */
4268     function createFlow(fromRight) {
4269       return rest(function(funcs) {
4270         funcs = baseFlatten(funcs, 1);
4271
4272         var length = funcs.length,
4273             index = length,
4274             prereq = LodashWrapper.prototype.thru;
4275
4276         if (fromRight) {
4277           funcs.reverse();
4278         }
4279         while (index--) {
4280           var func = funcs[index];
4281           if (typeof func != 'function') {
4282             throw new TypeError(FUNC_ERROR_TEXT);
4283           }
4284           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
4285             var wrapper = new LodashWrapper([], true);
4286           }
4287         }
4288         index = wrapper ? index : length;
4289         while (++index < length) {
4290           func = funcs[index];
4291
4292           var funcName = getFuncName(func),
4293               data = funcName == 'wrapper' ? getData(func) : undefined;
4294
4295           if (data && isLaziable(data[0]) &&
4296                 data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) &&
4297                 !data[4].length && data[9] == 1
4298               ) {
4299             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
4300           } else {
4301             wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
4302           }
4303         }
4304         return function() {
4305           var args = arguments,
4306               value = args[0];
4307
4308           if (wrapper && args.length == 1 &&
4309               isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
4310             return wrapper.plant(value).value();
4311           }
4312           var index = 0,
4313               result = length ? funcs[index].apply(this, args) : value;
4314
4315           while (++index < length) {
4316             result = funcs[index].call(this, result);
4317           }
4318           return result;
4319         };
4320       });
4321     }
4322
4323     /**
4324      * Creates a function that wraps `func` to invoke it with optional `this`
4325      * binding of `thisArg`, partial application, and currying.
4326      *
4327      * @private
4328      * @param {Function|string} func The function or method name to wrap.
4329      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4330      * @param {*} [thisArg] The `this` binding of `func`.
4331      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4332      * @param {Array} [holders] The `partials` placeholder indexes.
4333      * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
4334      * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
4335      * @param {Array} [argPos] The argument positions of the new function.
4336      * @param {number} [ary] The arity cap of `func`.
4337      * @param {number} [arity] The arity of `func`.
4338      * @returns {Function} Returns the new wrapped function.
4339      */
4340     function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
4341       var isAry = bitmask & ARY_FLAG,
4342           isBind = bitmask & BIND_FLAG,
4343           isBindKey = bitmask & BIND_KEY_FLAG,
4344           isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
4345           isFlip = bitmask & FLIP_FLAG,
4346           Ctor = isBindKey ? undefined : createCtorWrapper(func);
4347
4348       function wrapper() {
4349         var length = arguments.length,
4350             index = length,
4351             args = Array(length);
4352
4353         while (index--) {
4354           args[index] = arguments[index];
4355         }
4356         if (isCurried) {
4357           var placeholder = getPlaceholder(wrapper),
4358               holdersCount = countHolders(args, placeholder);
4359         }
4360         if (partials) {
4361           args = composeArgs(args, partials, holders, isCurried);
4362         }
4363         if (partialsRight) {
4364           args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
4365         }
4366         length -= holdersCount;
4367         if (isCurried && length < arity) {
4368           var newHolders = replaceHolders(args, placeholder);
4369           return createRecurryWrapper(
4370             func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg,
4371             args, newHolders, argPos, ary, arity - length
4372           );
4373         }
4374         var thisBinding = isBind ? thisArg : this,
4375             fn = isBindKey ? thisBinding[func] : func;
4376
4377         length = args.length;
4378         if (argPos) {
4379           args = reorder(args, argPos);
4380         } else if (isFlip && length > 1) {
4381           args.reverse();
4382         }
4383         if (isAry && ary < length) {
4384           args.length = ary;
4385         }
4386         if (this && this !== root && this instanceof wrapper) {
4387           fn = Ctor || createCtorWrapper(fn);
4388         }
4389         return fn.apply(thisBinding, args);
4390       }
4391       return wrapper;
4392     }
4393
4394     /**
4395      * Creates a function like `_.invertBy`.
4396      *
4397      * @private
4398      * @param {Function} setter The function to set accumulator values.
4399      * @param {Function} toIteratee The function to resolve iteratees.
4400      * @returns {Function} Returns the new inverter function.
4401      */
4402     function createInverter(setter, toIteratee) {
4403       return function(object, iteratee) {
4404         return baseInverter(object, setter, toIteratee(iteratee), {});
4405       };
4406     }
4407
4408     /**
4409      * Creates a function like `_.over`.
4410      *
4411      * @private
4412      * @param {Function} arrayFunc The function to iterate over iteratees.
4413      * @returns {Function} Returns the new invoker function.
4414      */
4415     function createOver(arrayFunc) {
4416       return rest(function(iteratees) {
4417         iteratees = arrayMap(baseFlatten(iteratees, 1), getIteratee());
4418         return rest(function(args) {
4419           var thisArg = this;
4420           return arrayFunc(iteratees, function(iteratee) {
4421             return apply(iteratee, thisArg, args);
4422           });
4423         });
4424       });
4425     }
4426
4427     /**
4428      * Creates the padding for `string` based on `length`. The `chars` string
4429      * is truncated if the number of characters exceeds `length`.
4430      *
4431      * @private
4432      * @param {string} string The string to create padding for.
4433      * @param {number} [length=0] The padding length.
4434      * @param {string} [chars=' '] The string used as padding.
4435      * @returns {string} Returns the padding for `string`.
4436      */
4437     function createPadding(string, length, chars) {
4438       length = toInteger(length);
4439
4440       var strLength = stringSize(string);
4441       if (!length || strLength >= length) {
4442         return '';
4443       }
4444       var padLength = length - strLength;
4445       chars = chars === undefined ? ' ' : (chars + '');
4446
4447       var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
4448       return reHasComplexSymbol.test(chars)
4449         ? stringToArray(result).slice(0, padLength).join('')
4450         : result.slice(0, padLength);
4451     }
4452
4453     /**
4454      * Creates a function that wraps `func` to invoke it with the optional `this`
4455      * binding of `thisArg` and the `partials` prepended to those provided to
4456      * the wrapper.
4457      *
4458      * @private
4459      * @param {Function} func The function to wrap.
4460      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4461      * @param {*} thisArg The `this` binding of `func`.
4462      * @param {Array} partials The arguments to prepend to those provided to the new function.
4463      * @returns {Function} Returns the new wrapped function.
4464      */
4465     function createPartialWrapper(func, bitmask, thisArg, partials) {
4466       var isBind = bitmask & BIND_FLAG,
4467           Ctor = createCtorWrapper(func);
4468
4469       function wrapper() {
4470         var argsIndex = -1,
4471             argsLength = arguments.length,
4472             leftIndex = -1,
4473             leftLength = partials.length,
4474             args = Array(leftLength + argsLength),
4475             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4476
4477         while (++leftIndex < leftLength) {
4478           args[leftIndex] = partials[leftIndex];
4479         }
4480         while (argsLength--) {
4481           args[leftIndex++] = arguments[++argsIndex];
4482         }
4483         return apply(fn, isBind ? thisArg : this, args);
4484       }
4485       return wrapper;
4486     }
4487
4488     /**
4489      * Creates a `_.range` or `_.rangeRight` function.
4490      *
4491      * @private
4492      * @param {boolean} [fromRight] Specify iterating from right to left.
4493      * @returns {Function} Returns the new range function.
4494      */
4495     function createRange(fromRight) {
4496       return function(start, end, step) {
4497         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
4498           end = step = undefined;
4499         }
4500         // Ensure the sign of `-0` is preserved.
4501         start = toNumber(start);
4502         start = start === start ? start : 0;
4503         if (end === undefined) {
4504           end = start;
4505           start = 0;
4506         } else {
4507           end = toNumber(end) || 0;
4508         }
4509         step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
4510         return baseRange(start, end, step, fromRight);
4511       };
4512     }
4513
4514     /**
4515      * Creates a function that wraps `func` to continue currying.
4516      *
4517      * @private
4518      * @param {Function} func The function to wrap.
4519      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4520      * @param {Function} wrapFunc The function to create the `func` wrapper.
4521      * @param {*} placeholder The placeholder value.
4522      * @param {*} [thisArg] The `this` binding of `func`.
4523      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4524      * @param {Array} [holders] The `partials` placeholder indexes.
4525      * @param {Array} [argPos] The argument positions of the new function.
4526      * @param {number} [ary] The arity cap of `func`.
4527      * @param {number} [arity] The arity of `func`.
4528      * @returns {Function} Returns the new wrapped function.
4529      */
4530     function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
4531       var isCurry = bitmask & CURRY_FLAG,
4532           newArgPos = argPos ? copyArray(argPos) : undefined,
4533           newHolders = isCurry ? holders : undefined,
4534           newHoldersRight = isCurry ? undefined : holders,
4535           newPartials = isCurry ? partials : undefined,
4536           newPartialsRight = isCurry ? undefined : partials;
4537
4538       bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
4539       bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
4540
4541       if (!(bitmask & CURRY_BOUND_FLAG)) {
4542         bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
4543       }
4544       var newData = [
4545         func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
4546         newHoldersRight, newArgPos, ary, arity
4547       ];
4548
4549       var result = wrapFunc.apply(undefined, newData);
4550       if (isLaziable(func)) {
4551         setData(result, newData);
4552       }
4553       result.placeholder = placeholder;
4554       return result;
4555     }
4556
4557     /**
4558      * Creates a function like `_.round`.
4559      *
4560      * @private
4561      * @param {string} methodName The name of the `Math` method to use when rounding.
4562      * @returns {Function} Returns the new round function.
4563      */
4564     function createRound(methodName) {
4565       var func = Math[methodName];
4566       return function(number, precision) {
4567         number = toNumber(number);
4568         precision = toInteger(precision);
4569         if (precision) {
4570           // Shift with exponential notation to avoid floating-point issues.
4571           // See [MDN](https://mdn.io/round#Examples) for more details.
4572           var pair = (toString(number) + 'e').split('e'),
4573               value = func(pair[0] + 'e' + (+pair[1] + precision));
4574
4575           pair = (toString(value) + 'e').split('e');
4576           return +(pair[0] + 'e' + (+pair[1] - precision));
4577         }
4578         return func(number);
4579       };
4580     }
4581
4582     /**
4583      * Creates a set of `values`.
4584      *
4585      * @private
4586      * @param {Array} values The values to add to the set.
4587      * @returns {Object} Returns the new set.
4588      */
4589     var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
4590       return new Set(values);
4591     };
4592
4593     /**
4594      * Creates a function that either curries or invokes `func` with optional
4595      * `this` binding and partially applied arguments.
4596      *
4597      * @private
4598      * @param {Function|string} func The function or method name to wrap.
4599      * @param {number} bitmask The bitmask of wrapper flags.
4600      *  The bitmask may be composed of the following flags:
4601      *     1 - `_.bind`
4602      *     2 - `_.bindKey`
4603      *     4 - `_.curry` or `_.curryRight` of a bound function
4604      *     8 - `_.curry`
4605      *    16 - `_.curryRight`
4606      *    32 - `_.partial`
4607      *    64 - `_.partialRight`
4608      *   128 - `_.rearg`
4609      *   256 - `_.ary`
4610      * @param {*} [thisArg] The `this` binding of `func`.
4611      * @param {Array} [partials] The arguments to be partially applied.
4612      * @param {Array} [holders] The `partials` placeholder indexes.
4613      * @param {Array} [argPos] The argument positions of the new function.
4614      * @param {number} [ary] The arity cap of `func`.
4615      * @param {number} [arity] The arity of `func`.
4616      * @returns {Function} Returns the new wrapped function.
4617      */
4618     function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
4619       var isBindKey = bitmask & BIND_KEY_FLAG;
4620       if (!isBindKey && typeof func != 'function') {
4621         throw new TypeError(FUNC_ERROR_TEXT);
4622       }
4623       var length = partials ? partials.length : 0;
4624       if (!length) {
4625         bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
4626         partials = holders = undefined;
4627       }
4628       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
4629       arity = arity === undefined ? arity : toInteger(arity);
4630       length -= holders ? holders.length : 0;
4631
4632       if (bitmask & PARTIAL_RIGHT_FLAG) {
4633         var partialsRight = partials,
4634             holdersRight = holders;
4635
4636         partials = holders = undefined;
4637       }
4638       var data = isBindKey ? undefined : getData(func);
4639
4640       var newData = [
4641         func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
4642         argPos, ary, arity
4643       ];
4644
4645       if (data) {
4646         mergeData(newData, data);
4647       }
4648       func = newData[0];
4649       bitmask = newData[1];
4650       thisArg = newData[2];
4651       partials = newData[3];
4652       holders = newData[4];
4653       arity = newData[9] = newData[9] == null
4654         ? (isBindKey ? 0 : func.length)
4655         : nativeMax(newData[9] - length, 0);
4656
4657       if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
4658         bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
4659       }
4660       if (!bitmask || bitmask == BIND_FLAG) {
4661         var result = createBaseWrapper(func, bitmask, thisArg);
4662       } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
4663         result = createCurryWrapper(func, bitmask, arity);
4664       } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
4665         result = createPartialWrapper(func, bitmask, thisArg, partials);
4666       } else {
4667         result = createHybridWrapper.apply(undefined, newData);
4668       }
4669       var setter = data ? baseSetData : setData;
4670       return setter(result, newData);
4671     }
4672
4673     /**
4674      * A specialized version of `baseIsEqualDeep` for arrays with support for
4675      * partial deep comparisons.
4676      *
4677      * @private
4678      * @param {Array} array The array to compare.
4679      * @param {Array} other The other array to compare.
4680      * @param {Function} equalFunc The function to determine equivalents of values.
4681      * @param {Function} [customizer] The function to customize comparisons.
4682      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4683      * @param {Object} [stack] Tracks traversed `array` and `other` objects.
4684      * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
4685      */
4686     function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
4687       var index = -1,
4688           isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4689           isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
4690           arrLength = array.length,
4691           othLength = other.length;
4692
4693       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
4694         return false;
4695       }
4696       // Assume cyclic values are equal.
4697       var stacked = stack.get(array);
4698       if (stacked) {
4699         return stacked == other;
4700       }
4701       var result = true;
4702       stack.set(array, other);
4703
4704       // Ignore non-index properties.
4705       while (++index < arrLength) {
4706         var arrValue = array[index],
4707             othValue = other[index];
4708
4709         if (customizer) {
4710           var compared = isPartial
4711             ? customizer(othValue, arrValue, index, other, array, stack)
4712             : customizer(arrValue, othValue, index, array, other, stack);
4713         }
4714         if (compared !== undefined) {
4715           if (compared) {
4716             continue;
4717           }
4718           result = false;
4719           break;
4720         }
4721         // Recursively compare arrays (susceptible to call stack limits).
4722         if (isUnordered) {
4723           if (!arraySome(other, function(othValue) {
4724                 return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
4725               })) {
4726             result = false;
4727             break;
4728           }
4729         } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
4730           result = false;
4731           break;
4732         }
4733       }
4734       stack['delete'](array);
4735       return result;
4736     }
4737
4738     /**
4739      * A specialized version of `baseIsEqualDeep` for comparing objects of
4740      * the same `toStringTag`.
4741      *
4742      * **Note:** This function only supports comparing values with tags of
4743      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4744      *
4745      * @private
4746      * @param {Object} object The object to compare.
4747      * @param {Object} other The other object to compare.
4748      * @param {string} tag The `toStringTag` of the objects to compare.
4749      * @param {Function} equalFunc The function to determine equivalents of values.
4750      * @param {Function} [customizer] The function to customize comparisons.
4751      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4752      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4753      */
4754     function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
4755       switch (tag) {
4756         case arrayBufferTag:
4757           if ((object.byteLength != other.byteLength) ||
4758               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
4759             return false;
4760           }
4761           return true;
4762
4763         case boolTag:
4764         case dateTag:
4765           // Coerce dates and booleans to numbers, dates to milliseconds and booleans
4766           // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
4767           return +object == +other;
4768
4769         case errorTag:
4770           return object.name == other.name && object.message == other.message;
4771
4772         case numberTag:
4773           // Treat `NaN` vs. `NaN` as equal.
4774           return (object != +object) ? other != +other : object == +other;
4775
4776         case regexpTag:
4777         case stringTag:
4778           // Coerce regexes to strings and treat strings primitives and string
4779           // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
4780           return object == (other + '');
4781
4782         case mapTag:
4783           var convert = mapToArray;
4784
4785         case setTag:
4786           var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
4787           convert || (convert = setToArray);
4788
4789           // Recursively compare objects (susceptible to call stack limits).
4790           return (isPartial || object.size == other.size) &&
4791             equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
4792
4793         case symbolTag:
4794           return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
4795       }
4796       return false;
4797     }
4798
4799     /**
4800      * A specialized version of `baseIsEqualDeep` for objects with support for
4801      * partial deep comparisons.
4802      *
4803      * @private
4804      * @param {Object} object The object to compare.
4805      * @param {Object} other The other object to compare.
4806      * @param {Function} equalFunc The function to determine equivalents of values.
4807      * @param {Function} [customizer] The function to customize comparisons.
4808      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4809      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
4810      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4811      */
4812     function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
4813       var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4814           objProps = keys(object),
4815           objLength = objProps.length,
4816           othProps = keys(other),
4817           othLength = othProps.length;
4818
4819       if (objLength != othLength && !isPartial) {
4820         return false;
4821       }
4822       var index = objLength;
4823       while (index--) {
4824         var key = objProps[index];
4825         if (!(isPartial ? key in other : baseHas(other, key))) {
4826           return false;
4827         }
4828       }
4829       // Assume cyclic values are equal.
4830       var stacked = stack.get(object);
4831       if (stacked) {
4832         return stacked == other;
4833       }
4834       var result = true;
4835       stack.set(object, other);
4836
4837       var skipCtor = isPartial;
4838       while (++index < objLength) {
4839         key = objProps[index];
4840         var objValue = object[key],
4841             othValue = other[key];
4842
4843         if (customizer) {
4844           var compared = isPartial
4845             ? customizer(othValue, objValue, key, other, object, stack)
4846             : customizer(objValue, othValue, key, object, other, stack);
4847         }
4848         // Recursively compare objects (susceptible to call stack limits).
4849         if (!(compared === undefined
4850               ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
4851               : compared
4852             )) {
4853           result = false;
4854           break;
4855         }
4856         skipCtor || (skipCtor = key == 'constructor');
4857       }
4858       if (result && !skipCtor) {
4859         var objCtor = object.constructor,
4860             othCtor = other.constructor;
4861
4862         // Non `Object` object instances with different constructors are not equal.
4863         if (objCtor != othCtor &&
4864             ('constructor' in object && 'constructor' in other) &&
4865             !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
4866               typeof othCtor == 'function' && othCtor instanceof othCtor)) {
4867           result = false;
4868         }
4869       }
4870       stack['delete'](object);
4871       return result;
4872     }
4873
4874     /**
4875      * Gets metadata for `func`.
4876      *
4877      * @private
4878      * @param {Function} func The function to query.
4879      * @returns {*} Returns the metadata for `func`.
4880      */
4881     var getData = !metaMap ? noop : function(func) {
4882       return metaMap.get(func);
4883     };
4884
4885     /**
4886      * Gets the name of `func`.
4887      *
4888      * @private
4889      * @param {Function} func The function to query.
4890      * @returns {string} Returns the function name.
4891      */
4892     function getFuncName(func) {
4893       var result = (func.name + ''),
4894           array = realNames[result],
4895           length = hasOwnProperty.call(realNames, result) ? array.length : 0;
4896
4897       while (length--) {
4898         var data = array[length],
4899             otherFunc = data.func;
4900         if (otherFunc == null || otherFunc == func) {
4901           return data.name;
4902         }
4903       }
4904       return result;
4905     }
4906
4907     /**
4908      * Gets the appropriate "iteratee" function. If the `_.iteratee` method is
4909      * customized this function returns the custom method, otherwise it returns
4910      * `baseIteratee`. If arguments are provided the chosen function is invoked
4911      * with them and its result is returned.
4912      *
4913      * @private
4914      * @param {*} [value] The value to convert to an iteratee.
4915      * @param {number} [arity] The arity of the created iteratee.
4916      * @returns {Function} Returns the chosen function or its result.
4917      */
4918     function getIteratee() {
4919       var result = lodash.iteratee || iteratee;
4920       result = result === iteratee ? baseIteratee : result;
4921       return arguments.length ? result(arguments[0], arguments[1]) : result;
4922     }
4923
4924     /**
4925      * Gets the "length" property value of `object`.
4926      *
4927      * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
4928      * that affects Safari on at least iOS 8.1-8.3 ARM64.
4929      *
4930      * @private
4931      * @param {Object} object The object to query.
4932      * @returns {*} Returns the "length" value.
4933      */
4934     var getLength = baseProperty('length');
4935
4936     /**
4937      * Gets the property names, values, and compare flags of `object`.
4938      *
4939      * @private
4940      * @param {Object} object The object to query.
4941      * @returns {Array} Returns the match data of `object`.
4942      */
4943     function getMatchData(object) {
4944       var result = toPairs(object),
4945           length = result.length;
4946
4947       while (length--) {
4948         result[length][2] = isStrictComparable(result[length][1]);
4949       }
4950       return result;
4951     }
4952
4953     /**
4954      * Gets the native function at `key` of `object`.
4955      *
4956      * @private
4957      * @param {Object} object The object to query.
4958      * @param {string} key The key of the method to get.
4959      * @returns {*} Returns the function if it's native, else `undefined`.
4960      */
4961     function getNative(object, key) {
4962       var value = object == null ? undefined : object[key];
4963       return isNative(value) ? value : undefined;
4964     }
4965
4966     /**
4967      * Gets the argument placeholder value for `func`.
4968      *
4969      * @private
4970      * @param {Function} func The function to inspect.
4971      * @returns {*} Returns the placeholder value.
4972      */
4973     function getPlaceholder(func) {
4974       var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
4975       return object.placeholder;
4976     }
4977
4978     /**
4979      * Creates an array of the own symbol properties of `object`.
4980      *
4981      * @private
4982      * @param {Object} object The object to query.
4983      * @returns {Array} Returns the array of symbols.
4984      */
4985     var getSymbols = getOwnPropertySymbols || function() {
4986       return [];
4987     };
4988
4989     /**
4990      * Gets the `toStringTag` of `value`.
4991      *
4992      * @private
4993      * @param {*} value The value to query.
4994      * @returns {string} Returns the `toStringTag`.
4995      */
4996     function getTag(value) {
4997       return objectToString.call(value);
4998     }
4999
5000     // Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps.
5001     if ((Map && getTag(new Map) != mapTag) ||
5002         (Set && getTag(new Set) != setTag) ||
5003         (WeakMap && getTag(new WeakMap) != weakMapTag)) {
5004       getTag = function(value) {
5005         var result = objectToString.call(value),
5006             Ctor = result == objectTag ? value.constructor : null,
5007             ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
5008
5009         if (ctorString) {
5010           switch (ctorString) {
5011             case mapCtorString: return mapTag;
5012             case setCtorString: return setTag;
5013             case weakMapCtorString: return weakMapTag;
5014           }
5015         }
5016         return result;
5017       };
5018     }
5019
5020     /**
5021      * Gets the view, applying any `transforms` to the `start` and `end` positions.
5022      *
5023      * @private
5024      * @param {number} start The start of the view.
5025      * @param {number} end The end of the view.
5026      * @param {Array} transforms The transformations to apply to the view.
5027      * @returns {Object} Returns an object containing the `start` and `end`
5028      *  positions of the view.
5029      */
5030     function getView(start, end, transforms) {
5031       var index = -1,
5032           length = transforms.length;
5033
5034       while (++index < length) {
5035         var data = transforms[index],
5036             size = data.size;
5037
5038         switch (data.type) {
5039           case 'drop':      start += size; break;
5040           case 'dropRight': end -= size; break;
5041           case 'take':      end = nativeMin(end, start + size); break;
5042           case 'takeRight': start = nativeMax(start, end - size); break;
5043         }
5044       }
5045       return { 'start': start, 'end': end };
5046     }
5047
5048     /**
5049      * Checks if `path` exists on `object`.
5050      *
5051      * @private
5052      * @param {Object} object The object to query.
5053      * @param {Array|string} path The path to check.
5054      * @param {Function} hasFunc The function to check properties.
5055      * @returns {boolean} Returns `true` if `path` exists, else `false`.
5056      */
5057     function hasPath(object, path, hasFunc) {
5058       if (object == null) {
5059         return false;
5060       }
5061       var result = hasFunc(object, path);
5062       if (!result && !isKey(path)) {
5063         path = baseCastPath(path);
5064         object = parent(object, path);
5065         if (object != null) {
5066           path = last(path);
5067           result = hasFunc(object, path);
5068         }
5069       }
5070       var length = object ? object.length : undefined;
5071       return result || (
5072         !!length && isLength(length) && isIndex(path, length) &&
5073         (isArray(object) || isString(object) || isArguments(object))
5074       );
5075     }
5076
5077     /**
5078      * Initializes an array clone.
5079      *
5080      * @private
5081      * @param {Array} array The array to clone.
5082      * @returns {Array} Returns the initialized clone.
5083      */
5084     function initCloneArray(array) {
5085       var length = array.length,
5086           result = array.constructor(length);
5087
5088       // Add properties assigned by `RegExp#exec`.
5089       if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
5090         result.index = array.index;
5091         result.input = array.input;
5092       }
5093       return result;
5094     }
5095
5096     /**
5097      * Initializes an object clone.
5098      *
5099      * @private
5100      * @param {Object} object The object to clone.
5101      * @returns {Object} Returns the initialized clone.
5102      */
5103     function initCloneObject(object) {
5104       return (isFunction(object.constructor) && !isPrototype(object))
5105         ? baseCreate(getPrototypeOf(object))
5106         : {};
5107     }
5108
5109     /**
5110      * Initializes an object clone based on its `toStringTag`.
5111      *
5112      * **Note:** This function only supports cloning values with tags of
5113      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5114      *
5115      * @private
5116      * @param {Object} object The object to clone.
5117      * @param {string} tag The `toStringTag` of the object to clone.
5118      * @param {boolean} [isDeep] Specify a deep clone.
5119      * @returns {Object} Returns the initialized clone.
5120      */
5121     function initCloneByTag(object, tag, isDeep) {
5122       var Ctor = object.constructor;
5123       switch (tag) {
5124         case arrayBufferTag:
5125           return cloneArrayBuffer(object);
5126
5127         case boolTag:
5128         case dateTag:
5129           return new Ctor(+object);
5130
5131         case float32Tag: case float64Tag:
5132         case int8Tag: case int16Tag: case int32Tag:
5133         case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
5134           return cloneTypedArray(object, isDeep);
5135
5136         case mapTag:
5137           return cloneMap(object);
5138
5139         case numberTag:
5140         case stringTag:
5141           return new Ctor(object);
5142
5143         case regexpTag:
5144           return cloneRegExp(object);
5145
5146         case setTag:
5147           return cloneSet(object);
5148
5149         case symbolTag:
5150           return cloneSymbol(object);
5151       }
5152     }
5153
5154     /**
5155      * Creates an array of index keys for `object` values of arrays,
5156      * `arguments` objects, and strings, otherwise `null` is returned.
5157      *
5158      * @private
5159      * @param {Object} object The object to query.
5160      * @returns {Array|null} Returns index keys, else `null`.
5161      */
5162     function indexKeys(object) {
5163       var length = object ? object.length : undefined;
5164       if (isLength(length) &&
5165           (isArray(object) || isString(object) || isArguments(object))) {
5166         return baseTimes(length, String);
5167       }
5168       return null;
5169     }
5170
5171     /**
5172      * Checks if the given arguments are from an iteratee call.
5173      *
5174      * @private
5175      * @param {*} value The potential iteratee value argument.
5176      * @param {*} index The potential iteratee index or key argument.
5177      * @param {*} object The potential iteratee object argument.
5178      * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
5179      */
5180     function isIterateeCall(value, index, object) {
5181       if (!isObject(object)) {
5182         return false;
5183       }
5184       var type = typeof index;
5185       if (type == 'number'
5186           ? (isArrayLike(object) && isIndex(index, object.length))
5187           : (type == 'string' && index in object)) {
5188         return eq(object[index], value);
5189       }
5190       return false;
5191     }
5192
5193     /**
5194      * Checks if `value` is a property name and not a property path.
5195      *
5196      * @private
5197      * @param {*} value The value to check.
5198      * @param {Object} [object] The object to query keys on.
5199      * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
5200      */
5201     function isKey(value, object) {
5202       if (typeof value == 'number') {
5203         return true;
5204       }
5205       return !isArray(value) &&
5206         (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
5207           (object != null && value in Object(object)));
5208     }
5209
5210     /**
5211      * Checks if `value` is suitable for use as unique object key.
5212      *
5213      * @private
5214      * @param {*} value The value to check.
5215      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
5216      */
5217     function isKeyable(value) {
5218       var type = typeof value;
5219       return type == 'number' || type == 'boolean' ||
5220         (type == 'string' && value != '__proto__') || value == null;
5221     }
5222
5223     /**
5224      * Checks if `func` has a lazy counterpart.
5225      *
5226      * @private
5227      * @param {Function} func The function to check.
5228      * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
5229      */
5230     function isLaziable(func) {
5231       var funcName = getFuncName(func),
5232           other = lodash[funcName];
5233
5234       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
5235         return false;
5236       }
5237       if (func === other) {
5238         return true;
5239       }
5240       var data = getData(other);
5241       return !!data && func === data[0];
5242     }
5243
5244     /**
5245      * Checks if `value` is likely a prototype object.
5246      *
5247      * @private
5248      * @param {*} value The value to check.
5249      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
5250      */
5251     function isPrototype(value) {
5252       var Ctor = value && value.constructor,
5253           proto = (isFunction(Ctor) && Ctor.prototype) || objectProto;
5254
5255       return value === proto;
5256     }
5257
5258     /**
5259      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
5260      *
5261      * @private
5262      * @param {*} value The value to check.
5263      * @returns {boolean} Returns `true` if `value` if suitable for strict
5264      *  equality comparisons, else `false`.
5265      */
5266     function isStrictComparable(value) {
5267       return value === value && !isObject(value);
5268     }
5269
5270     /**
5271      * Merges the function metadata of `source` into `data`.
5272      *
5273      * Merging metadata reduces the number of wrappers used to invoke a function.
5274      * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
5275      * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
5276      * modify function arguments, making the order in which they are executed important,
5277      * preventing the merging of metadata. However, we make an exception for a safe
5278      * combined case where curried functions have `_.ary` and or `_.rearg` applied.
5279      *
5280      * @private
5281      * @param {Array} data The destination metadata.
5282      * @param {Array} source The source metadata.
5283      * @returns {Array} Returns `data`.
5284      */
5285     function mergeData(data, source) {
5286       var bitmask = data[1],
5287           srcBitmask = source[1],
5288           newBitmask = bitmask | srcBitmask,
5289           isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
5290
5291       var isCombo =
5292         ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) ||
5293         ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
5294         ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
5295
5296       // Exit early if metadata can't be merged.
5297       if (!(isCommon || isCombo)) {
5298         return data;
5299       }
5300       // Use source `thisArg` if available.
5301       if (srcBitmask & BIND_FLAG) {
5302         data[2] = source[2];
5303         // Set when currying a bound function.
5304         newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG;
5305       }
5306       // Compose partial arguments.
5307       var value = source[3];
5308       if (value) {
5309         var partials = data[3];
5310         data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
5311         data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
5312       }
5313       // Compose partial right arguments.
5314       value = source[5];
5315       if (value) {
5316         partials = data[5];
5317         data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
5318         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
5319       }
5320       // Use source `argPos` if available.
5321       value = source[7];
5322       if (value) {
5323         data[7] = copyArray(value);
5324       }
5325       // Use source `ary` if it's smaller.
5326       if (srcBitmask & ARY_FLAG) {
5327         data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
5328       }
5329       // Use source `arity` if one is not provided.
5330       if (data[9] == null) {
5331         data[9] = source[9];
5332       }
5333       // Use source `func` and merge bitmasks.
5334       data[0] = source[0];
5335       data[1] = newBitmask;
5336
5337       return data;
5338     }
5339
5340     /**
5341      * Used by `_.defaultsDeep` to customize its `_.merge` use.
5342      *
5343      * @private
5344      * @param {*} objValue The destination value.
5345      * @param {*} srcValue The source value.
5346      * @param {string} key The key of the property to merge.
5347      * @param {Object} object The parent object of `objValue`.
5348      * @param {Object} source The parent object of `srcValue`.
5349      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
5350      * @returns {*} Returns the value to assign.
5351      */
5352     function mergeDefaults(objValue, srcValue, key, object, source, stack) {
5353       if (isObject(objValue) && isObject(srcValue)) {
5354         stack.set(srcValue, objValue);
5355         baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
5356       }
5357       return objValue;
5358     }
5359
5360     /**
5361      * Gets the parent value at `path` of `object`.
5362      *
5363      * @private
5364      * @param {Object} object The object to query.
5365      * @param {Array} path The path to get the parent value of.
5366      * @returns {*} Returns the parent value.
5367      */
5368     function parent(object, path) {
5369       return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
5370     }
5371
5372     /**
5373      * Reorder `array` according to the specified indexes where the element at
5374      * the first index is assigned as the first element, the element at
5375      * the second index is assigned as the second element, and so on.
5376      *
5377      * @private
5378      * @param {Array} array The array to reorder.
5379      * @param {Array} indexes The arranged array indexes.
5380      * @returns {Array} Returns `array`.
5381      */
5382     function reorder(array, indexes) {
5383       var arrLength = array.length,
5384           length = nativeMin(indexes.length, arrLength),
5385           oldArray = copyArray(array);
5386
5387       while (length--) {
5388         var index = indexes[length];
5389         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5390       }
5391       return array;
5392     }
5393
5394     /**
5395      * Sets metadata for `func`.
5396      *
5397      * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
5398      * period of time, it will trip its breaker and transition to an identity function
5399      * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
5400      * for more details.
5401      *
5402      * @private
5403      * @param {Function} func The function to associate metadata with.
5404      * @param {*} data The metadata.
5405      * @returns {Function} Returns `func`.
5406      */
5407     var setData = (function() {
5408       var count = 0,
5409           lastCalled = 0;
5410
5411       return function(key, value) {
5412         var stamp = now(),
5413             remaining = HOT_SPAN - (stamp - lastCalled);
5414
5415         lastCalled = stamp;
5416         if (remaining > 0) {
5417           if (++count >= HOT_COUNT) {
5418             return key;
5419           }
5420         } else {
5421           count = 0;
5422         }
5423         return baseSetData(key, value);
5424       };
5425     }());
5426
5427     /**
5428      * Converts `string` to a property path array.
5429      *
5430      * @private
5431      * @param {string} string The string to convert.
5432      * @returns {Array} Returns the property path array.
5433      */
5434     function stringToPath(string) {
5435       var result = [];
5436       toString(string).replace(rePropName, function(match, number, quote, string) {
5437         result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
5438       });
5439       return result;
5440     }
5441
5442     /**
5443      * Creates a clone of `wrapper`.
5444      *
5445      * @private
5446      * @param {Object} wrapper The wrapper to clone.
5447      * @returns {Object} Returns the cloned wrapper.
5448      */
5449     function wrapperClone(wrapper) {
5450       if (wrapper instanceof LazyWrapper) {
5451         return wrapper.clone();
5452       }
5453       var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
5454       result.__actions__ = copyArray(wrapper.__actions__);
5455       result.__index__  = wrapper.__index__;
5456       result.__values__ = wrapper.__values__;
5457       return result;
5458     }
5459
5460     /*------------------------------------------------------------------------*/
5461
5462     /**
5463      * Creates an array of elements split into groups the length of `size`.
5464      * If `array` can't be split evenly, the final chunk will be the remaining
5465      * elements.
5466      *
5467      * @static
5468      * @memberOf _
5469      * @category Array
5470      * @param {Array} array The array to process.
5471      * @param {number} [size=0] The length of each chunk.
5472      * @returns {Array} Returns the new array containing chunks.
5473      * @example
5474      *
5475      * _.chunk(['a', 'b', 'c', 'd'], 2);
5476      * // => [['a', 'b'], ['c', 'd']]
5477      *
5478      * _.chunk(['a', 'b', 'c', 'd'], 3);
5479      * // => [['a', 'b', 'c'], ['d']]
5480      */
5481     function chunk(array, size) {
5482       size = nativeMax(toInteger(size), 0);
5483
5484       var length = array ? array.length : 0;
5485       if (!length || size < 1) {
5486         return [];
5487       }
5488       var index = 0,
5489           resIndex = -1,
5490           result = Array(nativeCeil(length / size));
5491
5492       while (index < length) {
5493         result[++resIndex] = baseSlice(array, index, (index += size));
5494       }
5495       return result;
5496     }
5497
5498     /**
5499      * Creates an array with all falsey values removed. The values `false`, `null`,
5500      * `0`, `""`, `undefined`, and `NaN` are falsey.
5501      *
5502      * @static
5503      * @memberOf _
5504      * @category Array
5505      * @param {Array} array The array to compact.
5506      * @returns {Array} Returns the new array of filtered values.
5507      * @example
5508      *
5509      * _.compact([0, 1, false, 2, '', 3]);
5510      * // => [1, 2, 3]
5511      */
5512     function compact(array) {
5513       var index = -1,
5514           length = array ? array.length : 0,
5515           resIndex = -1,
5516           result = [];
5517
5518       while (++index < length) {
5519         var value = array[index];
5520         if (value) {
5521           result[++resIndex] = value;
5522         }
5523       }
5524       return result;
5525     }
5526
5527     /**
5528      * Creates a new array concatenating `array` with any additional arrays
5529      * and/or values.
5530      *
5531      * @static
5532      * @memberOf _
5533      * @category Array
5534      * @param {Array} array The array to concatenate.
5535      * @param {...*} [values] The values to concatenate.
5536      * @returns {Array} Returns the new concatenated array.
5537      * @example
5538      *
5539      * var array = [1];
5540      * var other = _.concat(array, 2, [3], [[4]]);
5541      *
5542      * console.log(other);
5543      * // => [1, 2, 3, [4]]
5544      *
5545      * console.log(array);
5546      * // => [1]
5547      */
5548     var concat = rest(function(array, values) {
5549       if (!isArray(array)) {
5550         array = array == null ? [] : [Object(array)];
5551       }
5552       values = baseFlatten(values, 1);
5553       return arrayConcat(array, values);
5554     });
5555
5556     /**
5557      * Creates an array of unique `array` values not included in the other
5558      * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5559      * for equality comparisons.
5560      *
5561      * @static
5562      * @memberOf _
5563      * @category Array
5564      * @param {Array} array The array to inspect.
5565      * @param {...Array} [values] The values to exclude.
5566      * @returns {Array} Returns the new array of filtered values.
5567      * @example
5568      *
5569      * _.difference([3, 2, 1], [4, 2]);
5570      * // => [3, 1]
5571      */
5572     var difference = rest(function(array, values) {
5573       return isArrayLikeObject(array)
5574         ? baseDifference(array, baseFlatten(values, 1, true))
5575         : [];
5576     });
5577
5578     /**
5579      * This method is like `_.difference` except that it accepts `iteratee` which
5580      * is invoked for each element of `array` and `values` to generate the criterion
5581      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5582      *
5583      * @static
5584      * @memberOf _
5585      * @category Array
5586      * @param {Array} array The array to inspect.
5587      * @param {...Array} [values] The values to exclude.
5588      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5589      * @returns {Array} Returns the new array of filtered values.
5590      * @example
5591      *
5592      * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
5593      * // => [3.1, 1.3]
5594      *
5595      * // The `_.property` iteratee shorthand.
5596      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
5597      * // => [{ 'x': 2 }]
5598      */
5599     var differenceBy = rest(function(array, values) {
5600       var iteratee = last(values);
5601       if (isArrayLikeObject(iteratee)) {
5602         iteratee = undefined;
5603       }
5604       return isArrayLikeObject(array)
5605         ? baseDifference(array, baseFlatten(values, 1, true), getIteratee(iteratee))
5606         : [];
5607     });
5608
5609     /**
5610      * This method is like `_.difference` except that it accepts `comparator`
5611      * which is invoked to compare elements of `array` to `values`. The comparator
5612      * is invoked with two arguments: (arrVal, othVal).
5613      *
5614      * @static
5615      * @memberOf _
5616      * @category Array
5617      * @param {Array} array The array to inspect.
5618      * @param {...Array} [values] The values to exclude.
5619      * @param {Function} [comparator] The comparator invoked per element.
5620      * @returns {Array} Returns the new array of filtered values.
5621      * @example
5622      *
5623      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5624      *
5625      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
5626      * // => [{ 'x': 2, 'y': 1 }]
5627      */
5628     var differenceWith = rest(function(array, values) {
5629       var comparator = last(values);
5630       if (isArrayLikeObject(comparator)) {
5631         comparator = undefined;
5632       }
5633       return isArrayLikeObject(array)
5634         ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator)
5635         : [];
5636     });
5637
5638     /**
5639      * Creates a slice of `array` with `n` elements dropped from the beginning.
5640      *
5641      * @static
5642      * @memberOf _
5643      * @category Array
5644      * @param {Array} array The array to query.
5645      * @param {number} [n=1] The number of elements to drop.
5646      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5647      * @returns {Array} Returns the slice of `array`.
5648      * @example
5649      *
5650      * _.drop([1, 2, 3]);
5651      * // => [2, 3]
5652      *
5653      * _.drop([1, 2, 3], 2);
5654      * // => [3]
5655      *
5656      * _.drop([1, 2, 3], 5);
5657      * // => []
5658      *
5659      * _.drop([1, 2, 3], 0);
5660      * // => [1, 2, 3]
5661      */
5662     function drop(array, n, guard) {
5663       var length = array ? array.length : 0;
5664       if (!length) {
5665         return [];
5666       }
5667       n = (guard || n === undefined) ? 1 : toInteger(n);
5668       return baseSlice(array, n < 0 ? 0 : n, length);
5669     }
5670
5671     /**
5672      * Creates a slice of `array` with `n` elements dropped from the end.
5673      *
5674      * @static
5675      * @memberOf _
5676      * @category Array
5677      * @param {Array} array The array to query.
5678      * @param {number} [n=1] The number of elements to drop.
5679      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5680      * @returns {Array} Returns the slice of `array`.
5681      * @example
5682      *
5683      * _.dropRight([1, 2, 3]);
5684      * // => [1, 2]
5685      *
5686      * _.dropRight([1, 2, 3], 2);
5687      * // => [1]
5688      *
5689      * _.dropRight([1, 2, 3], 5);
5690      * // => []
5691      *
5692      * _.dropRight([1, 2, 3], 0);
5693      * // => [1, 2, 3]
5694      */
5695     function dropRight(array, n, guard) {
5696       var length = array ? array.length : 0;
5697       if (!length) {
5698         return [];
5699       }
5700       n = (guard || n === undefined) ? 1 : toInteger(n);
5701       n = length - n;
5702       return baseSlice(array, 0, n < 0 ? 0 : n);
5703     }
5704
5705     /**
5706      * Creates a slice of `array` excluding elements dropped from the end.
5707      * Elements are dropped until `predicate` returns falsey. The predicate is
5708      * invoked with three arguments: (value, index, array).
5709      *
5710      * @static
5711      * @memberOf _
5712      * @category Array
5713      * @param {Array} array The array to query.
5714      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5715      * @returns {Array} Returns the slice of `array`.
5716      * @example
5717      *
5718      * var users = [
5719      *   { 'user': 'barney',  'active': true },
5720      *   { 'user': 'fred',    'active': false },
5721      *   { 'user': 'pebbles', 'active': false }
5722      * ];
5723      *
5724      * _.dropRightWhile(users, function(o) { return !o.active; });
5725      * // => objects for ['barney']
5726      *
5727      * // The `_.matches` iteratee shorthand.
5728      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
5729      * // => objects for ['barney', 'fred']
5730      *
5731      * // The `_.matchesProperty` iteratee shorthand.
5732      * _.dropRightWhile(users, ['active', false]);
5733      * // => objects for ['barney']
5734      *
5735      * // The `_.property` iteratee shorthand.
5736      * _.dropRightWhile(users, 'active');
5737      * // => objects for ['barney', 'fred', 'pebbles']
5738      */
5739     function dropRightWhile(array, predicate) {
5740       return (array && array.length)
5741         ? baseWhile(array, getIteratee(predicate, 3), true, true)
5742         : [];
5743     }
5744
5745     /**
5746      * Creates a slice of `array` excluding elements dropped from the beginning.
5747      * Elements are dropped until `predicate` returns falsey. The predicate is
5748      * invoked with three arguments: (value, index, array).
5749      *
5750      * @static
5751      * @memberOf _
5752      * @category Array
5753      * @param {Array} array The array to query.
5754      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5755      * @returns {Array} Returns the slice of `array`.
5756      * @example
5757      *
5758      * var users = [
5759      *   { 'user': 'barney',  'active': false },
5760      *   { 'user': 'fred',    'active': false },
5761      *   { 'user': 'pebbles', 'active': true }
5762      * ];
5763      *
5764      * _.dropWhile(users, function(o) { return !o.active; });
5765      * // => objects for ['pebbles']
5766      *
5767      * // The `_.matches` iteratee shorthand.
5768      * _.dropWhile(users, { 'user': 'barney', 'active': false });
5769      * // => objects for ['fred', 'pebbles']
5770      *
5771      * // The `_.matchesProperty` iteratee shorthand.
5772      * _.dropWhile(users, ['active', false]);
5773      * // => objects for ['pebbles']
5774      *
5775      * // The `_.property` iteratee shorthand.
5776      * _.dropWhile(users, 'active');
5777      * // => objects for ['barney', 'fred', 'pebbles']
5778      */
5779     function dropWhile(array, predicate) {
5780       return (array && array.length)
5781         ? baseWhile(array, getIteratee(predicate, 3), true)
5782         : [];
5783     }
5784
5785     /**
5786      * Fills elements of `array` with `value` from `start` up to, but not
5787      * including, `end`.
5788      *
5789      * **Note:** This method mutates `array`.
5790      *
5791      * @static
5792      * @memberOf _
5793      * @category Array
5794      * @param {Array} array The array to fill.
5795      * @param {*} value The value to fill `array` with.
5796      * @param {number} [start=0] The start position.
5797      * @param {number} [end=array.length] The end position.
5798      * @returns {Array} Returns `array`.
5799      * @example
5800      *
5801      * var array = [1, 2, 3];
5802      *
5803      * _.fill(array, 'a');
5804      * console.log(array);
5805      * // => ['a', 'a', 'a']
5806      *
5807      * _.fill(Array(3), 2);
5808      * // => [2, 2, 2]
5809      *
5810      * _.fill([4, 6, 8, 10], '*', 1, 3);
5811      * // => [4, '*', '*', 10]
5812      */
5813     function fill(array, value, start, end) {
5814       var length = array ? array.length : 0;
5815       if (!length) {
5816         return [];
5817       }
5818       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
5819         start = 0;
5820         end = length;
5821       }
5822       return baseFill(array, value, start, end);
5823     }
5824
5825     /**
5826      * This method is like `_.find` except that it returns the index of the first
5827      * element `predicate` returns truthy for instead of the element itself.
5828      *
5829      * @static
5830      * @memberOf _
5831      * @category Array
5832      * @param {Array} array The array to search.
5833      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5834      * @returns {number} Returns the index of the found element, else `-1`.
5835      * @example
5836      *
5837      * var users = [
5838      *   { 'user': 'barney',  'active': false },
5839      *   { 'user': 'fred',    'active': false },
5840      *   { 'user': 'pebbles', 'active': true }
5841      * ];
5842      *
5843      * _.findIndex(users, function(o) { return o.user == 'barney'; });
5844      * // => 0
5845      *
5846      * // The `_.matches` iteratee shorthand.
5847      * _.findIndex(users, { 'user': 'fred', 'active': false });
5848      * // => 1
5849      *
5850      * // The `_.matchesProperty` iteratee shorthand.
5851      * _.findIndex(users, ['active', false]);
5852      * // => 0
5853      *
5854      * // The `_.property` iteratee shorthand.
5855      * _.findIndex(users, 'active');
5856      * // => 2
5857      */
5858     function findIndex(array, predicate) {
5859       return (array && array.length)
5860         ? baseFindIndex(array, getIteratee(predicate, 3))
5861         : -1;
5862     }
5863
5864     /**
5865      * This method is like `_.findIndex` except that it iterates over elements
5866      * of `collection` from right to left.
5867      *
5868      * @static
5869      * @memberOf _
5870      * @category Array
5871      * @param {Array} array The array to search.
5872      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5873      * @returns {number} Returns the index of the found element, else `-1`.
5874      * @example
5875      *
5876      * var users = [
5877      *   { 'user': 'barney',  'active': true },
5878      *   { 'user': 'fred',    'active': false },
5879      *   { 'user': 'pebbles', 'active': false }
5880      * ];
5881      *
5882      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
5883      * // => 2
5884      *
5885      * // The `_.matches` iteratee shorthand.
5886      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
5887      * // => 0
5888      *
5889      * // The `_.matchesProperty` iteratee shorthand.
5890      * _.findLastIndex(users, ['active', false]);
5891      * // => 2
5892      *
5893      * // The `_.property` iteratee shorthand.
5894      * _.findLastIndex(users, 'active');
5895      * // => 0
5896      */
5897     function findLastIndex(array, predicate) {
5898       return (array && array.length)
5899         ? baseFindIndex(array, getIteratee(predicate, 3), true)
5900         : -1;
5901     }
5902
5903     /**
5904      * Flattens `array` a single level deep.
5905      *
5906      * @static
5907      * @memberOf _
5908      * @category Array
5909      * @param {Array} array The array to flatten.
5910      * @returns {Array} Returns the new flattened array.
5911      * @example
5912      *
5913      * _.flatten([1, [2, [3, [4]], 5]]);
5914      * // => [1, 2, [3, [4]], 5]
5915      */
5916     function flatten(array) {
5917       var length = array ? array.length : 0;
5918       return length ? baseFlatten(array, 1) : [];
5919     }
5920
5921     /**
5922      * Recursively flattens `array`.
5923      *
5924      * @static
5925      * @memberOf _
5926      * @category Array
5927      * @param {Array} array The array to flatten.
5928      * @returns {Array} Returns the new flattened array.
5929      * @example
5930      *
5931      * _.flattenDeep([1, [2, [3, [4]], 5]]);
5932      * // => [1, 2, 3, 4, 5]
5933      */
5934     function flattenDeep(array) {
5935       var length = array ? array.length : 0;
5936       return length ? baseFlatten(array, INFINITY) : [];
5937     }
5938
5939     /**
5940      * Recursively flatten `array` up to `depth` times.
5941      *
5942      * @static
5943      * @memberOf _
5944      * @category Array
5945      * @param {Array} array The array to flatten.
5946      * @param {number} [depth=1] The maximum recursion depth.
5947      * @returns {Array} Returns the new flattened array.
5948      * @example
5949      *
5950      * var array = [1, [2, [3, [4]], 5]];
5951      *
5952      * _.flattenDepth(array, 1);
5953      * // => [1, 2, [3, [4]], 5]
5954      *
5955      * _.flattenDepth(array, 2);
5956      * // => [1, 2, 3, [4], 5]
5957      */
5958     function flattenDepth(array, depth) {
5959       var length = array ? array.length : 0;
5960       if (!length) {
5961         return [];
5962       }
5963       depth = depth === undefined ? 1 : toInteger(depth);
5964       return baseFlatten(array, depth);
5965     }
5966
5967     /**
5968      * The inverse of `_.toPairs`; this method returns an object composed
5969      * from key-value `pairs`.
5970      *
5971      * @static
5972      * @memberOf _
5973      * @category Array
5974      * @param {Array} pairs The key-value pairs.
5975      * @returns {Object} Returns the new object.
5976      * @example
5977      *
5978      * _.fromPairs([['fred', 30], ['barney', 40]]);
5979      * // => { 'fred': 30, 'barney': 40 }
5980      */
5981     function fromPairs(pairs) {
5982       var index = -1,
5983           length = pairs ? pairs.length : 0,
5984           result = {};
5985
5986       while (++index < length) {
5987         var pair = pairs[index];
5988         result[pair[0]] = pair[1];
5989       }
5990       return result;
5991     }
5992
5993     /**
5994      * Gets the first element of `array`.
5995      *
5996      * @static
5997      * @memberOf _
5998      * @alias first
5999      * @category Array
6000      * @param {Array} array The array to query.
6001      * @returns {*} Returns the first element of `array`.
6002      * @example
6003      *
6004      * _.head([1, 2, 3]);
6005      * // => 1
6006      *
6007      * _.head([]);
6008      * // => undefined
6009      */
6010     function head(array) {
6011       return array ? array[0] : undefined;
6012     }
6013
6014     /**
6015      * Gets the index at which the first occurrence of `value` is found in `array`
6016      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6017      * for equality comparisons. If `fromIndex` is negative, it's used as the offset
6018      * from the end of `array`.
6019      *
6020      * @static
6021      * @memberOf _
6022      * @category Array
6023      * @param {Array} array The array to search.
6024      * @param {*} value The value to search for.
6025      * @param {number} [fromIndex=0] The index to search from.
6026      * @returns {number} Returns the index of the matched value, else `-1`.
6027      * @example
6028      *
6029      * _.indexOf([1, 2, 1, 2], 2);
6030      * // => 1
6031      *
6032      * // Search from the `fromIndex`.
6033      * _.indexOf([1, 2, 1, 2], 2, 2);
6034      * // => 3
6035      */
6036     function indexOf(array, value, fromIndex) {
6037       var length = array ? array.length : 0;
6038       if (!length) {
6039         return -1;
6040       }
6041       fromIndex = toInteger(fromIndex);
6042       if (fromIndex < 0) {
6043         fromIndex = nativeMax(length + fromIndex, 0);
6044       }
6045       return baseIndexOf(array, value, fromIndex);
6046     }
6047
6048     /**
6049      * Gets all but the last element of `array`.
6050      *
6051      * @static
6052      * @memberOf _
6053      * @category Array
6054      * @param {Array} array The array to query.
6055      * @returns {Array} Returns the slice of `array`.
6056      * @example
6057      *
6058      * _.initial([1, 2, 3]);
6059      * // => [1, 2]
6060      */
6061     function initial(array) {
6062       return dropRight(array, 1);
6063     }
6064
6065     /**
6066      * Creates an array of unique values that are included in all given arrays
6067      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6068      * for equality comparisons.
6069      *
6070      * @static
6071      * @memberOf _
6072      * @category Array
6073      * @param {...Array} [arrays] The arrays to inspect.
6074      * @returns {Array} Returns the new array of shared values.
6075      * @example
6076      *
6077      * _.intersection([2, 1], [4, 2], [1, 2]);
6078      * // => [2]
6079      */
6080     var intersection = rest(function(arrays) {
6081       var mapped = arrayMap(arrays, baseCastArrayLikeObject);
6082       return (mapped.length && mapped[0] === arrays[0])
6083         ? baseIntersection(mapped)
6084         : [];
6085     });
6086
6087     /**
6088      * This method is like `_.intersection` except that it accepts `iteratee`
6089      * which is invoked for each element of each `arrays` to generate the criterion
6090      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
6091      *
6092      * @static
6093      * @memberOf _
6094      * @category Array
6095      * @param {...Array} [arrays] The arrays to inspect.
6096      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6097      * @returns {Array} Returns the new array of shared values.
6098      * @example
6099      *
6100      * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6101      * // => [2.1]
6102      *
6103      * // The `_.property` iteratee shorthand.
6104      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6105      * // => [{ 'x': 1 }]
6106      */
6107     var intersectionBy = rest(function(arrays) {
6108       var iteratee = last(arrays),
6109           mapped = arrayMap(arrays, baseCastArrayLikeObject);
6110
6111       if (iteratee === last(mapped)) {
6112         iteratee = undefined;
6113       } else {
6114         mapped.pop();
6115       }
6116       return (mapped.length && mapped[0] === arrays[0])
6117         ? baseIntersection(mapped, getIteratee(iteratee))
6118         : [];
6119     });
6120
6121     /**
6122      * This method is like `_.intersection` except that it accepts `comparator`
6123      * which is invoked to compare elements of `arrays`. The comparator is invoked
6124      * with two arguments: (arrVal, othVal).
6125      *
6126      * @static
6127      * @memberOf _
6128      * @category Array
6129      * @param {...Array} [arrays] The arrays to inspect.
6130      * @param {Function} [comparator] The comparator invoked per element.
6131      * @returns {Array} Returns the new array of shared values.
6132      * @example
6133      *
6134      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6135      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6136      *
6137      * _.intersectionWith(objects, others, _.isEqual);
6138      * // => [{ 'x': 1, 'y': 2 }]
6139      */
6140     var intersectionWith = rest(function(arrays) {
6141       var comparator = last(arrays),
6142           mapped = arrayMap(arrays, baseCastArrayLikeObject);
6143
6144       if (comparator === last(mapped)) {
6145         comparator = undefined;
6146       } else {
6147         mapped.pop();
6148       }
6149       return (mapped.length && mapped[0] === arrays[0])
6150         ? baseIntersection(mapped, undefined, comparator)
6151         : [];
6152     });
6153
6154     /**
6155      * Converts all elements in `array` into a string separated by `separator`.
6156      *
6157      * @static
6158      * @memberOf _
6159      * @category Array
6160      * @param {Array} array The array to convert.
6161      * @param {string} [separator=','] The element separator.
6162      * @returns {string} Returns the joined string.
6163      * @example
6164      *
6165      * _.join(['a', 'b', 'c'], '~');
6166      * // => 'a~b~c'
6167      */
6168     function join(array, separator) {
6169       return array ? nativeJoin.call(array, separator) : '';
6170     }
6171
6172     /**
6173      * Gets the last element of `array`.
6174      *
6175      * @static
6176      * @memberOf _
6177      * @category Array
6178      * @param {Array} array The array to query.
6179      * @returns {*} Returns the last element of `array`.
6180      * @example
6181      *
6182      * _.last([1, 2, 3]);
6183      * // => 3
6184      */
6185     function last(array) {
6186       var length = array ? array.length : 0;
6187       return length ? array[length - 1] : undefined;
6188     }
6189
6190     /**
6191      * This method is like `_.indexOf` except that it iterates over elements of
6192      * `array` from right to left.
6193      *
6194      * @static
6195      * @memberOf _
6196      * @category Array
6197      * @param {Array} array The array to search.
6198      * @param {*} value The value to search for.
6199      * @param {number} [fromIndex=array.length-1] The index to search from.
6200      * @returns {number} Returns the index of the matched value, else `-1`.
6201      * @example
6202      *
6203      * _.lastIndexOf([1, 2, 1, 2], 2);
6204      * // => 3
6205      *
6206      * // Search from the `fromIndex`.
6207      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
6208      * // => 1
6209      */
6210     function lastIndexOf(array, value, fromIndex) {
6211       var length = array ? array.length : 0;
6212       if (!length) {
6213         return -1;
6214       }
6215       var index = length;
6216       if (fromIndex !== undefined) {
6217         index = toInteger(fromIndex);
6218         index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
6219       }
6220       if (value !== value) {
6221         return indexOfNaN(array, index, true);
6222       }
6223       while (index--) {
6224         if (array[index] === value) {
6225           return index;
6226         }
6227       }
6228       return -1;
6229     }
6230
6231     /**
6232      * Removes all given values from `array` using
6233      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6234      * for equality comparisons.
6235      *
6236      * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
6237      * to remove elements from an array by predicate.
6238      *
6239      * @static
6240      * @memberOf _
6241      * @category Array
6242      * @param {Array} array The array to modify.
6243      * @param {...*} [values] The values to remove.
6244      * @returns {Array} Returns `array`.
6245      * @example
6246      *
6247      * var array = [1, 2, 3, 1, 2, 3];
6248      *
6249      * _.pull(array, 2, 3);
6250      * console.log(array);
6251      * // => [1, 1]
6252      */
6253     var pull = rest(pullAll);
6254
6255     /**
6256      * This method is like `_.pull` except that it accepts an array of values to remove.
6257      *
6258      * **Note:** Unlike `_.difference`, this method mutates `array`.
6259      *
6260      * @static
6261      * @memberOf _
6262      * @category Array
6263      * @param {Array} array The array to modify.
6264      * @param {Array} values The values to remove.
6265      * @returns {Array} Returns `array`.
6266      * @example
6267      *
6268      * var array = [1, 2, 3, 1, 2, 3];
6269      *
6270      * _.pullAll(array, [2, 3]);
6271      * console.log(array);
6272      * // => [1, 1]
6273      */
6274     function pullAll(array, values) {
6275       return (array && array.length && values && values.length)
6276         ? basePullAll(array, values)
6277         : array;
6278     }
6279
6280     /**
6281      * This method is like `_.pullAll` except that it accepts `iteratee` which is
6282      * invoked for each element of `array` and `values` to generate the criterion
6283      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
6284      *
6285      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
6286      *
6287      * @static
6288      * @memberOf _
6289      * @category Array
6290      * @param {Array} array The array to modify.
6291      * @param {Array} values The values to remove.
6292      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6293      * @returns {Array} Returns `array`.
6294      * @example
6295      *
6296      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
6297      *
6298      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
6299      * console.log(array);
6300      * // => [{ 'x': 2 }]
6301      */
6302     function pullAllBy(array, values, iteratee) {
6303       return (array && array.length && values && values.length)
6304         ? basePullAllBy(array, values, getIteratee(iteratee))
6305         : array;
6306     }
6307
6308     /**
6309      * Removes elements from `array` corresponding to `indexes` and returns an
6310      * array of removed elements.
6311      *
6312      * **Note:** Unlike `_.at`, this method mutates `array`.
6313      *
6314      * @static
6315      * @memberOf _
6316      * @category Array
6317      * @param {Array} array The array to modify.
6318      * @param {...(number|number[])} [indexes] The indexes of elements to remove,
6319      *  specified individually or in arrays.
6320      * @returns {Array} Returns the new array of removed elements.
6321      * @example
6322      *
6323      * var array = [5, 10, 15, 20];
6324      * var evens = _.pullAt(array, 1, 3);
6325      *
6326      * console.log(array);
6327      * // => [5, 15]
6328      *
6329      * console.log(evens);
6330      * // => [10, 20]
6331      */
6332     var pullAt = rest(function(array, indexes) {
6333       indexes = arrayMap(baseFlatten(indexes, 1), String);
6334
6335       var result = baseAt(array, indexes);
6336       basePullAt(array, indexes.sort(compareAscending));
6337       return result;
6338     });
6339
6340     /**
6341      * Removes all elements from `array` that `predicate` returns truthy for
6342      * and returns an array of the removed elements. The predicate is invoked
6343      * with three arguments: (value, index, array).
6344      *
6345      * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
6346      * to pull elements from an array by value.
6347      *
6348      * @static
6349      * @memberOf _
6350      * @category Array
6351      * @param {Array} array The array to modify.
6352      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6353      * @returns {Array} Returns the new array of removed elements.
6354      * @example
6355      *
6356      * var array = [1, 2, 3, 4];
6357      * var evens = _.remove(array, function(n) {
6358      *   return n % 2 == 0;
6359      * });
6360      *
6361      * console.log(array);
6362      * // => [1, 3]
6363      *
6364      * console.log(evens);
6365      * // => [2, 4]
6366      */
6367     function remove(array, predicate) {
6368       var result = [];
6369       if (!(array && array.length)) {
6370         return result;
6371       }
6372       var index = -1,
6373           indexes = [],
6374           length = array.length;
6375
6376       predicate = getIteratee(predicate, 3);
6377       while (++index < length) {
6378         var value = array[index];
6379         if (predicate(value, index, array)) {
6380           result.push(value);
6381           indexes.push(index);
6382         }
6383       }
6384       basePullAt(array, indexes);
6385       return result;
6386     }
6387
6388     /**
6389      * Reverses `array` so that the first element becomes the last, the second
6390      * element becomes the second to last, and so on.
6391      *
6392      * **Note:** This method mutates `array` and is based on
6393      * [`Array#reverse`](https://mdn.io/Array/reverse).
6394      *
6395      * @static
6396      * @memberOf _
6397      * @category Array
6398      * @returns {Array} Returns `array`.
6399      * @example
6400      *
6401      * var array = [1, 2, 3];
6402      *
6403      * _.reverse(array);
6404      * // => [3, 2, 1]
6405      *
6406      * console.log(array);
6407      * // => [3, 2, 1]
6408      */
6409     function reverse(array) {
6410       return array ? nativeReverse.call(array) : array;
6411     }
6412
6413     /**
6414      * Creates a slice of `array` from `start` up to, but not including, `end`.
6415      *
6416      * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
6417      * to ensure dense arrays are returned.
6418      *
6419      * @static
6420      * @memberOf _
6421      * @category Array
6422      * @param {Array} array The array to slice.
6423      * @param {number} [start=0] The start position.
6424      * @param {number} [end=array.length] The end position.
6425      * @returns {Array} Returns the slice of `array`.
6426      */
6427     function slice(array, start, end) {
6428       var length = array ? array.length : 0;
6429       if (!length) {
6430         return [];
6431       }
6432       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
6433         start = 0;
6434         end = length;
6435       }
6436       else {
6437         start = start == null ? 0 : toInteger(start);
6438         end = end === undefined ? length : toInteger(end);
6439       }
6440       return baseSlice(array, start, end);
6441     }
6442
6443     /**
6444      * Uses a binary search to determine the lowest index at which `value` should
6445      * be inserted into `array` in order to maintain its sort order.
6446      *
6447      * @static
6448      * @memberOf _
6449      * @category Array
6450      * @param {Array} array The sorted array to inspect.
6451      * @param {*} value The value to evaluate.
6452      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6453      * @example
6454      *
6455      * _.sortedIndex([30, 50], 40);
6456      * // => 1
6457      *
6458      * _.sortedIndex([4, 5], 4);
6459      * // => 0
6460      */
6461     function sortedIndex(array, value) {
6462       return baseSortedIndex(array, value);
6463     }
6464
6465     /**
6466      * This method is like `_.sortedIndex` except that it accepts `iteratee`
6467      * which is invoked for `value` and each element of `array` to compute their
6468      * sort ranking. The iteratee is invoked with one argument: (value).
6469      *
6470      * @static
6471      * @memberOf _
6472      * @category Array
6473      * @param {Array} array The sorted array to inspect.
6474      * @param {*} value The value to evaluate.
6475      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6476      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6477      * @example
6478      *
6479      * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
6480      *
6481      * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
6482      * // => 1
6483      *
6484      * // The `_.property` iteratee shorthand.
6485      * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6486      * // => 0
6487      */
6488     function sortedIndexBy(array, value, iteratee) {
6489       return baseSortedIndexBy(array, value, getIteratee(iteratee));
6490     }
6491
6492     /**
6493      * This method is like `_.indexOf` except that it performs a binary
6494      * search on a sorted `array`.
6495      *
6496      * @static
6497      * @memberOf _
6498      * @category Array
6499      * @param {Array} array The array to search.
6500      * @param {*} value The value to search for.
6501      * @returns {number} Returns the index of the matched value, else `-1`.
6502      * @example
6503      *
6504      * _.sortedIndexOf([1, 1, 2, 2], 2);
6505      * // => 2
6506      */
6507     function sortedIndexOf(array, value) {
6508       var length = array ? array.length : 0;
6509       if (length) {
6510         var index = baseSortedIndex(array, value);
6511         if (index < length && eq(array[index], value)) {
6512           return index;
6513         }
6514       }
6515       return -1;
6516     }
6517
6518     /**
6519      * This method is like `_.sortedIndex` except that it returns the highest
6520      * index at which `value` should be inserted into `array` in order to
6521      * maintain its sort order.
6522      *
6523      * @static
6524      * @memberOf _
6525      * @category Array
6526      * @param {Array} array The sorted array to inspect.
6527      * @param {*} value The value to evaluate.
6528      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6529      * @example
6530      *
6531      * _.sortedLastIndex([4, 5], 4);
6532      * // => 1
6533      */
6534     function sortedLastIndex(array, value) {
6535       return baseSortedIndex(array, value, true);
6536     }
6537
6538     /**
6539      * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
6540      * which is invoked for `value` and each element of `array` to compute their
6541      * sort ranking. The iteratee is invoked with one argument: (value).
6542      *
6543      * @static
6544      * @memberOf _
6545      * @category Array
6546      * @param {Array} array The sorted array to inspect.
6547      * @param {*} value The value to evaluate.
6548      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6549      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6550      * @example
6551      *
6552      * // The `_.property` iteratee shorthand.
6553      * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6554      * // => 1
6555      */
6556     function sortedLastIndexBy(array, value, iteratee) {
6557       return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
6558     }
6559
6560     /**
6561      * This method is like `_.lastIndexOf` except that it performs a binary
6562      * search on a sorted `array`.
6563      *
6564      * @static
6565      * @memberOf _
6566      * @category Array
6567      * @param {Array} array The array to search.
6568      * @param {*} value The value to search for.
6569      * @returns {number} Returns the index of the matched value, else `-1`.
6570      * @example
6571      *
6572      * _.sortedLastIndexOf([1, 1, 2, 2], 2);
6573      * // => 3
6574      */
6575     function sortedLastIndexOf(array, value) {
6576       var length = array ? array.length : 0;
6577       if (length) {
6578         var index = baseSortedIndex(array, value, true) - 1;
6579         if (eq(array[index], value)) {
6580           return index;
6581         }
6582       }
6583       return -1;
6584     }
6585
6586     /**
6587      * This method is like `_.uniq` except that it's designed and optimized
6588      * for sorted arrays.
6589      *
6590      * @static
6591      * @memberOf _
6592      * @category Array
6593      * @param {Array} array The array to inspect.
6594      * @returns {Array} Returns the new duplicate free array.
6595      * @example
6596      *
6597      * _.sortedUniq([1, 1, 2]);
6598      * // => [1, 2]
6599      */
6600     function sortedUniq(array) {
6601       return (array && array.length)
6602         ? baseSortedUniq(array)
6603         : [];
6604     }
6605
6606     /**
6607      * This method is like `_.uniqBy` except that it's designed and optimized
6608      * for sorted arrays.
6609      *
6610      * @static
6611      * @memberOf _
6612      * @category Array
6613      * @param {Array} array The array to inspect.
6614      * @param {Function} [iteratee] The iteratee invoked per element.
6615      * @returns {Array} Returns the new duplicate free array.
6616      * @example
6617      *
6618      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
6619      * // => [1.1, 2.3]
6620      */
6621     function sortedUniqBy(array, iteratee) {
6622       return (array && array.length)
6623         ? baseSortedUniqBy(array, getIteratee(iteratee))
6624         : [];
6625     }
6626
6627     /**
6628      * Gets all but the first element of `array`.
6629      *
6630      * @static
6631      * @memberOf _
6632      * @category Array
6633      * @param {Array} array The array to query.
6634      * @returns {Array} Returns the slice of `array`.
6635      * @example
6636      *
6637      * _.tail([1, 2, 3]);
6638      * // => [2, 3]
6639      */
6640     function tail(array) {
6641       return drop(array, 1);
6642     }
6643
6644     /**
6645      * Creates a slice of `array` with `n` elements taken from the beginning.
6646      *
6647      * @static
6648      * @memberOf _
6649      * @category Array
6650      * @param {Array} array The array to query.
6651      * @param {number} [n=1] The number of elements to take.
6652      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6653      * @returns {Array} Returns the slice of `array`.
6654      * @example
6655      *
6656      * _.take([1, 2, 3]);
6657      * // => [1]
6658      *
6659      * _.take([1, 2, 3], 2);
6660      * // => [1, 2]
6661      *
6662      * _.take([1, 2, 3], 5);
6663      * // => [1, 2, 3]
6664      *
6665      * _.take([1, 2, 3], 0);
6666      * // => []
6667      */
6668     function take(array, n, guard) {
6669       if (!(array && array.length)) {
6670         return [];
6671       }
6672       n = (guard || n === undefined) ? 1 : toInteger(n);
6673       return baseSlice(array, 0, n < 0 ? 0 : n);
6674     }
6675
6676     /**
6677      * Creates a slice of `array` with `n` elements taken from the end.
6678      *
6679      * @static
6680      * @memberOf _
6681      * @category Array
6682      * @param {Array} array The array to query.
6683      * @param {number} [n=1] The number of elements to take.
6684      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6685      * @returns {Array} Returns the slice of `array`.
6686      * @example
6687      *
6688      * _.takeRight([1, 2, 3]);
6689      * // => [3]
6690      *
6691      * _.takeRight([1, 2, 3], 2);
6692      * // => [2, 3]
6693      *
6694      * _.takeRight([1, 2, 3], 5);
6695      * // => [1, 2, 3]
6696      *
6697      * _.takeRight([1, 2, 3], 0);
6698      * // => []
6699      */
6700     function takeRight(array, n, guard) {
6701       var length = array ? array.length : 0;
6702       if (!length) {
6703         return [];
6704       }
6705       n = (guard || n === undefined) ? 1 : toInteger(n);
6706       n = length - n;
6707       return baseSlice(array, n < 0 ? 0 : n, length);
6708     }
6709
6710     /**
6711      * Creates a slice of `array` with elements taken from the end. Elements are
6712      * taken until `predicate` returns falsey. The predicate is invoked with three
6713      * arguments: (value, index, array).
6714      *
6715      * @static
6716      * @memberOf _
6717      * @category Array
6718      * @param {Array} array The array to query.
6719      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6720      * @returns {Array} Returns the slice of `array`.
6721      * @example
6722      *
6723      * var users = [
6724      *   { 'user': 'barney',  'active': true },
6725      *   { 'user': 'fred',    'active': false },
6726      *   { 'user': 'pebbles', 'active': false }
6727      * ];
6728      *
6729      * _.takeRightWhile(users, function(o) { return !o.active; });
6730      * // => objects for ['fred', 'pebbles']
6731      *
6732      * // The `_.matches` iteratee shorthand.
6733      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
6734      * // => objects for ['pebbles']
6735      *
6736      * // The `_.matchesProperty` iteratee shorthand.
6737      * _.takeRightWhile(users, ['active', false]);
6738      * // => objects for ['fred', 'pebbles']
6739      *
6740      * // The `_.property` iteratee shorthand.
6741      * _.takeRightWhile(users, 'active');
6742      * // => []
6743      */
6744     function takeRightWhile(array, predicate) {
6745       return (array && array.length)
6746         ? baseWhile(array, getIteratee(predicate, 3), false, true)
6747         : [];
6748     }
6749
6750     /**
6751      * Creates a slice of `array` with elements taken from the beginning. Elements
6752      * are taken until `predicate` returns falsey. The predicate is invoked with
6753      * three arguments: (value, index, array).
6754      *
6755      * @static
6756      * @memberOf _
6757      * @category Array
6758      * @param {Array} array The array to query.
6759      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6760      * @returns {Array} Returns the slice of `array`.
6761      * @example
6762      *
6763      * var users = [
6764      *   { 'user': 'barney',  'active': false },
6765      *   { 'user': 'fred',    'active': false},
6766      *   { 'user': 'pebbles', 'active': true }
6767      * ];
6768      *
6769      * _.takeWhile(users, function(o) { return !o.active; });
6770      * // => objects for ['barney', 'fred']
6771      *
6772      * // The `_.matches` iteratee shorthand.
6773      * _.takeWhile(users, { 'user': 'barney', 'active': false });
6774      * // => objects for ['barney']
6775      *
6776      * // The `_.matchesProperty` iteratee shorthand.
6777      * _.takeWhile(users, ['active', false]);
6778      * // => objects for ['barney', 'fred']
6779      *
6780      * // The `_.property` iteratee shorthand.
6781      * _.takeWhile(users, 'active');
6782      * // => []
6783      */
6784     function takeWhile(array, predicate) {
6785       return (array && array.length)
6786         ? baseWhile(array, getIteratee(predicate, 3))
6787         : [];
6788     }
6789
6790     /**
6791      * Creates an array of unique values, in order, from all given arrays using
6792      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6793      * for equality comparisons.
6794      *
6795      * @static
6796      * @memberOf _
6797      * @category Array
6798      * @param {...Array} [arrays] The arrays to inspect.
6799      * @returns {Array} Returns the new array of combined values.
6800      * @example
6801      *
6802      * _.union([2, 1], [4, 2], [1, 2]);
6803      * // => [2, 1, 4]
6804      */
6805     var union = rest(function(arrays) {
6806       return baseUniq(baseFlatten(arrays, 1, true));
6807     });
6808
6809     /**
6810      * This method is like `_.union` except that it accepts `iteratee` which is
6811      * invoked for each element of each `arrays` to generate the criterion by which
6812      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6813      *
6814      * @static
6815      * @memberOf _
6816      * @category Array
6817      * @param {...Array} [arrays] The arrays to inspect.
6818      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6819      * @returns {Array} Returns the new array of combined values.
6820      * @example
6821      *
6822      * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6823      * // => [2.1, 1.2, 4.3]
6824      *
6825      * // The `_.property` iteratee shorthand.
6826      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6827      * // => [{ 'x': 1 }, { 'x': 2 }]
6828      */
6829     var unionBy = rest(function(arrays) {
6830       var iteratee = last(arrays);
6831       if (isArrayLikeObject(iteratee)) {
6832         iteratee = undefined;
6833       }
6834       return baseUniq(baseFlatten(arrays, 1, true), getIteratee(iteratee));
6835     });
6836
6837     /**
6838      * This method is like `_.union` except that it accepts `comparator` which
6839      * is invoked to compare elements of `arrays`. The comparator is invoked
6840      * with two arguments: (arrVal, othVal).
6841      *
6842      * @static
6843      * @memberOf _
6844      * @category Array
6845      * @param {...Array} [arrays] The arrays to inspect.
6846      * @param {Function} [comparator] The comparator invoked per element.
6847      * @returns {Array} Returns the new array of combined values.
6848      * @example
6849      *
6850      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6851      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6852      *
6853      * _.unionWith(objects, others, _.isEqual);
6854      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6855      */
6856     var unionWith = rest(function(arrays) {
6857       var comparator = last(arrays);
6858       if (isArrayLikeObject(comparator)) {
6859         comparator = undefined;
6860       }
6861       return baseUniq(baseFlatten(arrays, 1, true), undefined, comparator);
6862     });
6863
6864     /**
6865      * Creates a duplicate-free version of an array, using
6866      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6867      * for equality comparisons, in which only the first occurrence of each element
6868      * is kept.
6869      *
6870      * @static
6871      * @memberOf _
6872      * @category Array
6873      * @param {Array} array The array to inspect.
6874      * @returns {Array} Returns the new duplicate free array.
6875      * @example
6876      *
6877      * _.uniq([2, 1, 2]);
6878      * // => [2, 1]
6879      */
6880     function uniq(array) {
6881       return (array && array.length)
6882         ? baseUniq(array)
6883         : [];
6884     }
6885
6886     /**
6887      * This method is like `_.uniq` except that it accepts `iteratee` which is
6888      * invoked for each element in `array` to generate the criterion by which
6889      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6890      *
6891      * @static
6892      * @memberOf _
6893      * @category Array
6894      * @param {Array} array The array to inspect.
6895      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6896      * @returns {Array} Returns the new duplicate free array.
6897      * @example
6898      *
6899      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
6900      * // => [2.1, 1.2]
6901      *
6902      * // The `_.property` iteratee shorthand.
6903      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
6904      * // => [{ 'x': 1 }, { 'x': 2 }]
6905      */
6906     function uniqBy(array, iteratee) {
6907       return (array && array.length)
6908         ? baseUniq(array, getIteratee(iteratee))
6909         : [];
6910     }
6911
6912     /**
6913      * This method is like `_.uniq` except that it accepts `comparator` which
6914      * is invoked to compare elements of `array`. The comparator is invoked with
6915      * two arguments: (arrVal, othVal).
6916      *
6917      * @static
6918      * @memberOf _
6919      * @category Array
6920      * @param {Array} array The array to inspect.
6921      * @param {Function} [comparator] The comparator invoked per element.
6922      * @returns {Array} Returns the new duplicate free array.
6923      * @example
6924      *
6925      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
6926      *
6927      * _.uniqWith(objects, _.isEqual);
6928      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
6929      */
6930     function uniqWith(array, comparator) {
6931       return (array && array.length)
6932         ? baseUniq(array, undefined, comparator)
6933         : [];
6934     }
6935
6936     /**
6937      * This method is like `_.zip` except that it accepts an array of grouped
6938      * elements and creates an array regrouping the elements to their pre-zip
6939      * configuration.
6940      *
6941      * @static
6942      * @memberOf _
6943      * @category Array
6944      * @param {Array} array The array of grouped elements to process.
6945      * @returns {Array} Returns the new array of regrouped elements.
6946      * @example
6947      *
6948      * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
6949      * // => [['fred', 30, true], ['barney', 40, false]]
6950      *
6951      * _.unzip(zipped);
6952      * // => [['fred', 'barney'], [30, 40], [true, false]]
6953      */
6954     function unzip(array) {
6955       if (!(array && array.length)) {
6956         return [];
6957       }
6958       var length = 0;
6959       array = arrayFilter(array, function(group) {
6960         if (isArrayLikeObject(group)) {
6961           length = nativeMax(group.length, length);
6962           return true;
6963         }
6964       });
6965       return baseTimes(length, function(index) {
6966         return arrayMap(array, baseProperty(index));
6967       });
6968     }
6969
6970     /**
6971      * This method is like `_.unzip` except that it accepts `iteratee` to specify
6972      * how regrouped values should be combined. The iteratee is invoked with the
6973      * elements of each group: (...group).
6974      *
6975      * @static
6976      * @memberOf _
6977      * @category Array
6978      * @param {Array} array The array of grouped elements to process.
6979      * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
6980      * @returns {Array} Returns the new array of regrouped elements.
6981      * @example
6982      *
6983      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
6984      * // => [[1, 10, 100], [2, 20, 200]]
6985      *
6986      * _.unzipWith(zipped, _.add);
6987      * // => [3, 30, 300]
6988      */
6989     function unzipWith(array, iteratee) {
6990       if (!(array && array.length)) {
6991         return [];
6992       }
6993       var result = unzip(array);
6994       if (iteratee == null) {
6995         return result;
6996       }
6997       return arrayMap(result, function(group) {
6998         return apply(iteratee, undefined, group);
6999       });
7000     }
7001
7002     /**
7003      * Creates an array excluding all given values using
7004      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7005      * for equality comparisons.
7006      *
7007      * @static
7008      * @memberOf _
7009      * @category Array
7010      * @param {Array} array The array to filter.
7011      * @param {...*} [values] The values to exclude.
7012      * @returns {Array} Returns the new array of filtered values.
7013      * @example
7014      *
7015      * _.without([1, 2, 1, 3], 1, 2);
7016      * // => [3]
7017      */
7018     var without = rest(function(array, values) {
7019       return isArrayLikeObject(array)
7020         ? baseDifference(array, values)
7021         : [];
7022     });
7023
7024     /**
7025      * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
7026      * of the given arrays.
7027      *
7028      * @static
7029      * @memberOf _
7030      * @category Array
7031      * @param {...Array} [arrays] The arrays to inspect.
7032      * @returns {Array} Returns the new array of values.
7033      * @example
7034      *
7035      * _.xor([2, 1], [4, 2]);
7036      * // => [1, 4]
7037      */
7038     var xor = rest(function(arrays) {
7039       return baseXor(arrayFilter(arrays, isArrayLikeObject));
7040     });
7041
7042     /**
7043      * This method is like `_.xor` except that it accepts `iteratee` which is
7044      * invoked for each element of each `arrays` to generate the criterion by which
7045      * uniqueness is computed. The iteratee is invoked with one argument: (value).
7046      *
7047      * @static
7048      * @memberOf _
7049      * @category Array
7050      * @param {...Array} [arrays] The arrays to inspect.
7051      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
7052      * @returns {Array} Returns the new array of values.
7053      * @example
7054      *
7055      * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
7056      * // => [1.2, 4.3]
7057      *
7058      * // The `_.property` iteratee shorthand.
7059      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7060      * // => [{ 'x': 2 }]
7061      */
7062     var xorBy = rest(function(arrays) {
7063       var iteratee = last(arrays);
7064       if (isArrayLikeObject(iteratee)) {
7065         iteratee = undefined;
7066       }
7067       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
7068     });
7069
7070     /**
7071      * This method is like `_.xor` except that it accepts `comparator` which is
7072      * invoked to compare elements of `arrays`. The comparator is invoked with
7073      * two arguments: (arrVal, othVal).
7074      *
7075      * @static
7076      * @memberOf _
7077      * @category Array
7078      * @param {...Array} [arrays] The arrays to inspect.
7079      * @param {Function} [comparator] The comparator invoked per element.
7080      * @returns {Array} Returns the new array of values.
7081      * @example
7082      *
7083      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7084      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7085      *
7086      * _.xorWith(objects, others, _.isEqual);
7087      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
7088      */
7089     var xorWith = rest(function(arrays) {
7090       var comparator = last(arrays);
7091       if (isArrayLikeObject(comparator)) {
7092         comparator = undefined;
7093       }
7094       return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
7095     });
7096
7097     /**
7098      * Creates an array of grouped elements, the first of which contains the first
7099      * elements of the given arrays, the second of which contains the second elements
7100      * of the given arrays, and so on.
7101      *
7102      * @static
7103      * @memberOf _
7104      * @category Array
7105      * @param {...Array} [arrays] The arrays to process.
7106      * @returns {Array} Returns the new array of grouped elements.
7107      * @example
7108      *
7109      * _.zip(['fred', 'barney'], [30, 40], [true, false]);
7110      * // => [['fred', 30, true], ['barney', 40, false]]
7111      */
7112     var zip = rest(unzip);
7113
7114     /**
7115      * This method is like `_.fromPairs` except that it accepts two arrays,
7116      * one of property names and one of corresponding values.
7117      *
7118      * @static
7119      * @memberOf _
7120      * @category Array
7121      * @param {Array} [props=[]] The property names.
7122      * @param {Array} [values=[]] The property values.
7123      * @returns {Object} Returns the new object.
7124      * @example
7125      *
7126      * _.zipObject(['a', 'b'], [1, 2]);
7127      * // => { 'a': 1, 'b': 2 }
7128      */
7129     function zipObject(props, values) {
7130       return baseZipObject(props || [], values || [], assignValue);
7131     }
7132
7133     /**
7134      * This method is like `_.zipObject` except that it supports property paths.
7135      *
7136      * @static
7137      * @memberOf _
7138      * @category Array
7139      * @param {Array} [props=[]] The property names.
7140      * @param {Array} [values=[]] The property values.
7141      * @returns {Object} Returns the new object.
7142      * @example
7143      *
7144      * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
7145      * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
7146      */
7147     function zipObjectDeep(props, values) {
7148       return baseZipObject(props || [], values || [], baseSet);
7149     }
7150
7151     /**
7152      * This method is like `_.zip` except that it accepts `iteratee` to specify
7153      * how grouped values should be combined. The iteratee is invoked with the
7154      * elements of each group: (...group).
7155      *
7156      * @static
7157      * @memberOf _
7158      * @category Array
7159      * @param {...Array} [arrays] The arrays to process.
7160      * @param {Function} [iteratee=_.identity] The function to combine grouped values.
7161      * @returns {Array} Returns the new array of grouped elements.
7162      * @example
7163      *
7164      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
7165      *   return a + b + c;
7166      * });
7167      * // => [111, 222]
7168      */
7169     var zipWith = rest(function(arrays) {
7170       var length = arrays.length,
7171           iteratee = length > 1 ? arrays[length - 1] : undefined;
7172
7173       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
7174       return unzipWith(arrays, iteratee);
7175     });
7176
7177     /*------------------------------------------------------------------------*/
7178
7179     /**
7180      * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
7181      * The result of such method chaining must be unwrapped with `_#value`.
7182      *
7183      * @static
7184      * @memberOf _
7185      * @category Seq
7186      * @param {*} value The value to wrap.
7187      * @returns {Object} Returns the new `lodash` wrapper instance.
7188      * @example
7189      *
7190      * var users = [
7191      *   { 'user': 'barney',  'age': 36 },
7192      *   { 'user': 'fred',    'age': 40 },
7193      *   { 'user': 'pebbles', 'age': 1 }
7194      * ];
7195      *
7196      * var youngest = _
7197      *   .chain(users)
7198      *   .sortBy('age')
7199      *   .map(function(o) {
7200      *     return o.user + ' is ' + o.age;
7201      *   })
7202      *   .head()
7203      *   .value();
7204      * // => 'pebbles is 1'
7205      */
7206     function chain(value) {
7207       var result = lodash(value);
7208       result.__chain__ = true;
7209       return result;
7210     }
7211
7212     /**
7213      * This method invokes `interceptor` and returns `value`. The interceptor
7214      * is invoked with one argument; (value). The purpose of this method is to
7215      * "tap into" a method chain in order to modify intermediate results.
7216      *
7217      * @static
7218      * @memberOf _
7219      * @category Seq
7220      * @param {*} value The value to provide to `interceptor`.
7221      * @param {Function} interceptor The function to invoke.
7222      * @returns {*} Returns `value`.
7223      * @example
7224      *
7225      * _([1, 2, 3])
7226      *  .tap(function(array) {
7227      *    // Mutate input array.
7228      *    array.pop();
7229      *  })
7230      *  .reverse()
7231      *  .value();
7232      * // => [2, 1]
7233      */
7234     function tap(value, interceptor) {
7235       interceptor(value);
7236       return value;
7237     }
7238
7239     /**
7240      * This method is like `_.tap` except that it returns the result of `interceptor`.
7241      * The purpose of this method is to "pass thru" values replacing intermediate
7242      * results in a method chain.
7243      *
7244      * @static
7245      * @memberOf _
7246      * @category Seq
7247      * @param {*} value The value to provide to `interceptor`.
7248      * @param {Function} interceptor The function to invoke.
7249      * @returns {*} Returns the result of `interceptor`.
7250      * @example
7251      *
7252      * _('  abc  ')
7253      *  .chain()
7254      *  .trim()
7255      *  .thru(function(value) {
7256      *    return [value];
7257      *  })
7258      *  .value();
7259      * // => ['abc']
7260      */
7261     function thru(value, interceptor) {
7262       return interceptor(value);
7263     }
7264
7265     /**
7266      * This method is the wrapper version of `_.at`.
7267      *
7268      * @name at
7269      * @memberOf _
7270      * @category Seq
7271      * @param {...(string|string[])} [paths] The property paths of elements to pick,
7272      *  specified individually or in arrays.
7273      * @returns {Object} Returns the new `lodash` wrapper instance.
7274      * @example
7275      *
7276      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
7277      *
7278      * _(object).at(['a[0].b.c', 'a[1]']).value();
7279      * // => [3, 4]
7280      *
7281      * _(['a', 'b', 'c']).at(0, 2).value();
7282      * // => ['a', 'c']
7283      */
7284     var wrapperAt = rest(function(paths) {
7285       paths = baseFlatten(paths, 1);
7286       var length = paths.length,
7287           start = length ? paths[0] : 0,
7288           value = this.__wrapped__,
7289           interceptor = function(object) { return baseAt(object, paths); };
7290
7291       if (length > 1 || this.__actions__.length ||
7292           !(value instanceof LazyWrapper) || !isIndex(start)) {
7293         return this.thru(interceptor);
7294       }
7295       value = value.slice(start, +start + (length ? 1 : 0));
7296       value.__actions__.push({
7297         'func': thru,
7298         'args': [interceptor],
7299         'thisArg': undefined
7300       });
7301       return new LodashWrapper(value, this.__chain__).thru(function(array) {
7302         if (length && !array.length) {
7303           array.push(undefined);
7304         }
7305         return array;
7306       });
7307     });
7308
7309     /**
7310      * Enables explicit method chaining on the wrapper object.
7311      *
7312      * @name chain
7313      * @memberOf _
7314      * @category Seq
7315      * @returns {Object} Returns the new `lodash` wrapper instance.
7316      * @example
7317      *
7318      * var users = [
7319      *   { 'user': 'barney', 'age': 36 },
7320      *   { 'user': 'fred',   'age': 40 }
7321      * ];
7322      *
7323      * // A sequence without explicit chaining.
7324      * _(users).head();
7325      * // => { 'user': 'barney', 'age': 36 }
7326      *
7327      * // A sequence with explicit chaining.
7328      * _(users)
7329      *   .chain()
7330      *   .head()
7331      *   .pick('user')
7332      *   .value();
7333      * // => { 'user': 'barney' }
7334      */
7335     function wrapperChain() {
7336       return chain(this);
7337     }
7338
7339     /**
7340      * Executes the chained sequence and returns the wrapped result.
7341      *
7342      * @name commit
7343      * @memberOf _
7344      * @category Seq
7345      * @returns {Object} Returns the new `lodash` wrapper instance.
7346      * @example
7347      *
7348      * var array = [1, 2];
7349      * var wrapped = _(array).push(3);
7350      *
7351      * console.log(array);
7352      * // => [1, 2]
7353      *
7354      * wrapped = wrapped.commit();
7355      * console.log(array);
7356      * // => [1, 2, 3]
7357      *
7358      * wrapped.last();
7359      * // => 3
7360      *
7361      * console.log(array);
7362      * // => [1, 2, 3]
7363      */
7364     function wrapperCommit() {
7365       return new LodashWrapper(this.value(), this.__chain__);
7366     }
7367
7368     /**
7369      * This method is the wrapper version of `_.flatMap`.
7370      *
7371      * @name flatMap
7372      * @memberOf _
7373      * @category Seq
7374      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7375      * @returns {Object} Returns the new `lodash` wrapper instance.
7376      * @example
7377      *
7378      * function duplicate(n) {
7379      *   return [n, n];
7380      * }
7381      *
7382      * _([1, 2]).flatMap(duplicate).value();
7383      * // => [1, 1, 2, 2]
7384      */
7385     function wrapperFlatMap(iteratee) {
7386       return this.map(iteratee).flatten();
7387     }
7388
7389     /**
7390      * Gets the next value on a wrapped object following the
7391      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
7392      *
7393      * @name next
7394      * @memberOf _
7395      * @category Seq
7396      * @returns {Object} Returns the next iterator value.
7397      * @example
7398      *
7399      * var wrapped = _([1, 2]);
7400      *
7401      * wrapped.next();
7402      * // => { 'done': false, 'value': 1 }
7403      *
7404      * wrapped.next();
7405      * // => { 'done': false, 'value': 2 }
7406      *
7407      * wrapped.next();
7408      * // => { 'done': true, 'value': undefined }
7409      */
7410     function wrapperNext() {
7411       if (this.__values__ === undefined) {
7412         this.__values__ = toArray(this.value());
7413       }
7414       var done = this.__index__ >= this.__values__.length,
7415           value = done ? undefined : this.__values__[this.__index__++];
7416
7417       return { 'done': done, 'value': value };
7418     }
7419
7420     /**
7421      * Enables the wrapper to be iterable.
7422      *
7423      * @name Symbol.iterator
7424      * @memberOf _
7425      * @category Seq
7426      * @returns {Object} Returns the wrapper object.
7427      * @example
7428      *
7429      * var wrapped = _([1, 2]);
7430      *
7431      * wrapped[Symbol.iterator]() === wrapped;
7432      * // => true
7433      *
7434      * Array.from(wrapped);
7435      * // => [1, 2]
7436      */
7437     function wrapperToIterator() {
7438       return this;
7439     }
7440
7441     /**
7442      * Creates a clone of the chained sequence planting `value` as the wrapped value.
7443      *
7444      * @name plant
7445      * @memberOf _
7446      * @category Seq
7447      * @param {*} value The value to plant.
7448      * @returns {Object} Returns the new `lodash` wrapper instance.
7449      * @example
7450      *
7451      * function square(n) {
7452      *   return n * n;
7453      * }
7454      *
7455      * var wrapped = _([1, 2]).map(square);
7456      * var other = wrapped.plant([3, 4]);
7457      *
7458      * other.value();
7459      * // => [9, 16]
7460      *
7461      * wrapped.value();
7462      * // => [1, 4]
7463      */
7464     function wrapperPlant(value) {
7465       var result,
7466           parent = this;
7467
7468       while (parent instanceof baseLodash) {
7469         var clone = wrapperClone(parent);
7470         clone.__index__ = 0;
7471         clone.__values__ = undefined;
7472         if (result) {
7473           previous.__wrapped__ = clone;
7474         } else {
7475           result = clone;
7476         }
7477         var previous = clone;
7478         parent = parent.__wrapped__;
7479       }
7480       previous.__wrapped__ = value;
7481       return result;
7482     }
7483
7484     /**
7485      * This method is the wrapper version of `_.reverse`.
7486      *
7487      * **Note:** This method mutates the wrapped array.
7488      *
7489      * @name reverse
7490      * @memberOf _
7491      * @category Seq
7492      * @returns {Object} Returns the new `lodash` wrapper instance.
7493      * @example
7494      *
7495      * var array = [1, 2, 3];
7496      *
7497      * _(array).reverse().value()
7498      * // => [3, 2, 1]
7499      *
7500      * console.log(array);
7501      * // => [3, 2, 1]
7502      */
7503     function wrapperReverse() {
7504       var value = this.__wrapped__;
7505       if (value instanceof LazyWrapper) {
7506         var wrapped = value;
7507         if (this.__actions__.length) {
7508           wrapped = new LazyWrapper(this);
7509         }
7510         wrapped = wrapped.reverse();
7511         wrapped.__actions__.push({
7512           'func': thru,
7513           'args': [reverse],
7514           'thisArg': undefined
7515         });
7516         return new LodashWrapper(wrapped, this.__chain__);
7517       }
7518       return this.thru(reverse);
7519     }
7520
7521     /**
7522      * Executes the chained sequence to extract the unwrapped value.
7523      *
7524      * @name value
7525      * @memberOf _
7526      * @alias toJSON, valueOf
7527      * @category Seq
7528      * @returns {*} Returns the resolved unwrapped value.
7529      * @example
7530      *
7531      * _([1, 2, 3]).value();
7532      * // => [1, 2, 3]
7533      */
7534     function wrapperValue() {
7535       return baseWrapperValue(this.__wrapped__, this.__actions__);
7536     }
7537
7538     /*------------------------------------------------------------------------*/
7539
7540     /**
7541      * Creates an object composed of keys generated from the results of running
7542      * each element of `collection` through `iteratee`. The corresponding value
7543      * of each key is the number of times the key was returned by `iteratee`.
7544      * The iteratee is invoked with one argument: (value).
7545      *
7546      * @static
7547      * @memberOf _
7548      * @category Collection
7549      * @param {Array|Object} collection The collection to iterate over.
7550      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7551      * @returns {Object} Returns the composed aggregate object.
7552      * @example
7553      *
7554      * _.countBy([6.1, 4.2, 6.3], Math.floor);
7555      * // => { '4': 1, '6': 2 }
7556      *
7557      * _.countBy(['one', 'two', 'three'], 'length');
7558      * // => { '3': 2, '5': 1 }
7559      */
7560     var countBy = createAggregator(function(result, value, key) {
7561       hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
7562     });
7563
7564     /**
7565      * Checks if `predicate` returns truthy for **all** elements of `collection`.
7566      * Iteration is stopped once `predicate` returns falsey. The predicate is
7567      * invoked with three arguments: (value, index|key, collection).
7568      *
7569      * @static
7570      * @memberOf _
7571      * @category Collection
7572      * @param {Array|Object} collection The collection to iterate over.
7573      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7574      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
7575      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
7576      * @example
7577      *
7578      * _.every([true, 1, null, 'yes'], Boolean);
7579      * // => false
7580      *
7581      * var users = [
7582      *   { 'user': 'barney', 'active': false },
7583      *   { 'user': 'fred',   'active': false }
7584      * ];
7585      *
7586      * // The `_.matches` iteratee shorthand.
7587      * _.every(users, { 'user': 'barney', 'active': false });
7588      * // => false
7589      *
7590      * // The `_.matchesProperty` iteratee shorthand.
7591      * _.every(users, ['active', false]);
7592      * // => true
7593      *
7594      * // The `_.property` iteratee shorthand.
7595      * _.every(users, 'active');
7596      * // => false
7597      */
7598     function every(collection, predicate, guard) {
7599       var func = isArray(collection) ? arrayEvery : baseEvery;
7600       if (guard && isIterateeCall(collection, predicate, guard)) {
7601         predicate = undefined;
7602       }
7603       return func(collection, getIteratee(predicate, 3));
7604     }
7605
7606     /**
7607      * Iterates over elements of `collection`, returning an array of all elements
7608      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7609      * (value, index|key, collection).
7610      *
7611      * @static
7612      * @memberOf _
7613      * @category Collection
7614      * @param {Array|Object} collection The collection to iterate over.
7615      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7616      * @returns {Array} Returns the new filtered array.
7617      * @example
7618      *
7619      * var users = [
7620      *   { 'user': 'barney', 'age': 36, 'active': true },
7621      *   { 'user': 'fred',   'age': 40, 'active': false }
7622      * ];
7623      *
7624      * _.filter(users, function(o) { return !o.active; });
7625      * // => objects for ['fred']
7626      *
7627      * // The `_.matches` iteratee shorthand.
7628      * _.filter(users, { 'age': 36, 'active': true });
7629      * // => objects for ['barney']
7630      *
7631      * // The `_.matchesProperty` iteratee shorthand.
7632      * _.filter(users, ['active', false]);
7633      * // => objects for ['fred']
7634      *
7635      * // The `_.property` iteratee shorthand.
7636      * _.filter(users, 'active');
7637      * // => objects for ['barney']
7638      */
7639     function filter(collection, predicate) {
7640       var func = isArray(collection) ? arrayFilter : baseFilter;
7641       return func(collection, getIteratee(predicate, 3));
7642     }
7643
7644     /**
7645      * Iterates over elements of `collection`, returning the first element
7646      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7647      * (value, index|key, collection).
7648      *
7649      * @static
7650      * @memberOf _
7651      * @category Collection
7652      * @param {Array|Object} collection The collection to search.
7653      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7654      * @returns {*} Returns the matched element, else `undefined`.
7655      * @example
7656      *
7657      * var users = [
7658      *   { 'user': 'barney',  'age': 36, 'active': true },
7659      *   { 'user': 'fred',    'age': 40, 'active': false },
7660      *   { 'user': 'pebbles', 'age': 1,  'active': true }
7661      * ];
7662      *
7663      * _.find(users, function(o) { return o.age < 40; });
7664      * // => object for 'barney'
7665      *
7666      * // The `_.matches` iteratee shorthand.
7667      * _.find(users, { 'age': 1, 'active': true });
7668      * // => object for 'pebbles'
7669      *
7670      * // The `_.matchesProperty` iteratee shorthand.
7671      * _.find(users, ['active', false]);
7672      * // => object for 'fred'
7673      *
7674      * // The `_.property` iteratee shorthand.
7675      * _.find(users, 'active');
7676      * // => object for 'barney'
7677      */
7678     function find(collection, predicate) {
7679       predicate = getIteratee(predicate, 3);
7680       if (isArray(collection)) {
7681         var index = baseFindIndex(collection, predicate);
7682         return index > -1 ? collection[index] : undefined;
7683       }
7684       return baseFind(collection, predicate, baseEach);
7685     }
7686
7687     /**
7688      * This method is like `_.find` except that it iterates over elements of
7689      * `collection` from right to left.
7690      *
7691      * @static
7692      * @memberOf _
7693      * @category Collection
7694      * @param {Array|Object} collection The collection to search.
7695      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7696      * @returns {*} Returns the matched element, else `undefined`.
7697      * @example
7698      *
7699      * _.findLast([1, 2, 3, 4], function(n) {
7700      *   return n % 2 == 1;
7701      * });
7702      * // => 3
7703      */
7704     function findLast(collection, predicate) {
7705       predicate = getIteratee(predicate, 3);
7706       if (isArray(collection)) {
7707         var index = baseFindIndex(collection, predicate, true);
7708         return index > -1 ? collection[index] : undefined;
7709       }
7710       return baseFind(collection, predicate, baseEachRight);
7711     }
7712
7713     /**
7714      * Creates an array of flattened values by running each element in `collection`
7715      * through `iteratee` and concating its result to the other mapped values.
7716      * The iteratee is invoked with three arguments: (value, index|key, collection).
7717      *
7718      * @static
7719      * @memberOf _
7720      * @category Collection
7721      * @param {Array|Object} collection The collection to iterate over.
7722      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7723      * @returns {Array} Returns the new flattened array.
7724      * @example
7725      *
7726      * function duplicate(n) {
7727      *   return [n, n];
7728      * }
7729      *
7730      * _.flatMap([1, 2], duplicate);
7731      * // => [1, 1, 2, 2]
7732      */
7733     function flatMap(collection, iteratee) {
7734       return baseFlatten(map(collection, iteratee), 1);
7735     }
7736
7737     /**
7738      * Iterates over elements of `collection` invoking `iteratee` for each element.
7739      * The iteratee is invoked with three arguments: (value, index|key, collection).
7740      * Iteratee functions may exit iteration early by explicitly returning `false`.
7741      *
7742      * **Note:** As with other "Collections" methods, objects with a "length" property
7743      * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
7744      * for object iteration.
7745      *
7746      * @static
7747      * @memberOf _
7748      * @alias each
7749      * @category Collection
7750      * @param {Array|Object} collection The collection to iterate over.
7751      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7752      * @returns {Array|Object} Returns `collection`.
7753      * @example
7754      *
7755      * _([1, 2]).forEach(function(value) {
7756      *   console.log(value);
7757      * });
7758      * // => logs `1` then `2`
7759      *
7760      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
7761      *   console.log(key);
7762      * });
7763      * // => logs 'a' then 'b' (iteration order is not guaranteed)
7764      */
7765     function forEach(collection, iteratee) {
7766       return (typeof iteratee == 'function' && isArray(collection))
7767         ? arrayEach(collection, iteratee)
7768         : baseEach(collection, baseCastFunction(iteratee));
7769     }
7770
7771     /**
7772      * This method is like `_.forEach` except that it iterates over elements of
7773      * `collection` from right to left.
7774      *
7775      * @static
7776      * @memberOf _
7777      * @alias eachRight
7778      * @category Collection
7779      * @param {Array|Object} collection The collection to iterate over.
7780      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7781      * @returns {Array|Object} Returns `collection`.
7782      * @example
7783      *
7784      * _.forEachRight([1, 2], function(value) {
7785      *   console.log(value);
7786      * });
7787      * // => logs `2` then `1`
7788      */
7789     function forEachRight(collection, iteratee) {
7790       return (typeof iteratee == 'function' && isArray(collection))
7791         ? arrayEachRight(collection, iteratee)
7792         : baseEachRight(collection, baseCastFunction(iteratee));
7793     }
7794
7795     /**
7796      * Creates an object composed of keys generated from the results of running
7797      * each element of `collection` through `iteratee`. The corresponding value
7798      * of each key is an array of elements responsible for generating the key.
7799      * The iteratee is invoked with one argument: (value).
7800      *
7801      * @static
7802      * @memberOf _
7803      * @category Collection
7804      * @param {Array|Object} collection The collection to iterate over.
7805      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7806      * @returns {Object} Returns the composed aggregate object.
7807      * @example
7808      *
7809      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
7810      * // => { '4': [4.2], '6': [6.1, 6.3] }
7811      *
7812      * // The `_.property` iteratee shorthand.
7813      * _.groupBy(['one', 'two', 'three'], 'length');
7814      * // => { '3': ['one', 'two'], '5': ['three'] }
7815      */
7816     var groupBy = createAggregator(function(result, value, key) {
7817       if (hasOwnProperty.call(result, key)) {
7818         result[key].push(value);
7819       } else {
7820         result[key] = [value];
7821       }
7822     });
7823
7824     /**
7825      * Checks if `value` is in `collection`. If `collection` is a string it's checked
7826      * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7827      * is used for equality comparisons. If `fromIndex` is negative, it's used as
7828      * the offset from the end of `collection`.
7829      *
7830      * @static
7831      * @memberOf _
7832      * @category Collection
7833      * @param {Array|Object|string} collection The collection to search.
7834      * @param {*} value The value to search for.
7835      * @param {number} [fromIndex=0] The index to search from.
7836      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7837      * @returns {boolean} Returns `true` if `value` is found, else `false`.
7838      * @example
7839      *
7840      * _.includes([1, 2, 3], 1);
7841      * // => true
7842      *
7843      * _.includes([1, 2, 3], 1, 2);
7844      * // => false
7845      *
7846      * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
7847      * // => true
7848      *
7849      * _.includes('pebbles', 'eb');
7850      * // => true
7851      */
7852     function includes(collection, value, fromIndex, guard) {
7853       collection = isArrayLike(collection) ? collection : values(collection);
7854       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
7855
7856       var length = collection.length;
7857       if (fromIndex < 0) {
7858         fromIndex = nativeMax(length + fromIndex, 0);
7859       }
7860       return isString(collection)
7861         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
7862         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
7863     }
7864
7865     /**
7866      * Invokes the method at `path` of each element in `collection`, returning
7867      * an array of the results of each invoked method. Any additional arguments
7868      * are provided to each invoked method. If `methodName` is a function it's
7869      * invoked for, and `this` bound to, each element in `collection`.
7870      *
7871      * @static
7872      * @memberOf _
7873      * @category Collection
7874      * @param {Array|Object} collection The collection to iterate over.
7875      * @param {Array|Function|string} path The path of the method to invoke or
7876      *  the function invoked per iteration.
7877      * @param {...*} [args] The arguments to invoke each method with.
7878      * @returns {Array} Returns the array of results.
7879      * @example
7880      *
7881      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
7882      * // => [[1, 5, 7], [1, 2, 3]]
7883      *
7884      * _.invokeMap([123, 456], String.prototype.split, '');
7885      * // => [['1', '2', '3'], ['4', '5', '6']]
7886      */
7887     var invokeMap = rest(function(collection, path, args) {
7888       var index = -1,
7889           isFunc = typeof path == 'function',
7890           isProp = isKey(path),
7891           result = isArrayLike(collection) ? Array(collection.length) : [];
7892
7893       baseEach(collection, function(value) {
7894         var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
7895         result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
7896       });
7897       return result;
7898     });
7899
7900     /**
7901      * Creates an object composed of keys generated from the results of running
7902      * each element of `collection` through `iteratee`. The corresponding value
7903      * of each key is the last element responsible for generating the key. The
7904      * iteratee is invoked with one argument: (value).
7905      *
7906      * @static
7907      * @memberOf _
7908      * @category Collection
7909      * @param {Array|Object} collection The collection to iterate over.
7910      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7911      * @returns {Object} Returns the composed aggregate object.
7912      * @example
7913      *
7914      * var array = [
7915      *   { 'dir': 'left', 'code': 97 },
7916      *   { 'dir': 'right', 'code': 100 }
7917      * ];
7918      *
7919      * _.keyBy(array, function(o) {
7920      *   return String.fromCharCode(o.code);
7921      * });
7922      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
7923      *
7924      * _.keyBy(array, 'dir');
7925      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
7926      */
7927     var keyBy = createAggregator(function(result, value, key) {
7928       result[key] = value;
7929     });
7930
7931     /**
7932      * Creates an array of values by running each element in `collection` through
7933      * `iteratee`. The iteratee is invoked with three arguments:
7934      * (value, index|key, collection).
7935      *
7936      * Many lodash methods are guarded to work as iteratees for methods like
7937      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
7938      *
7939      * The guarded methods are:
7940      * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
7941      * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
7942      * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
7943      * and `words`
7944      *
7945      * @static
7946      * @memberOf _
7947      * @category Collection
7948      * @param {Array|Object} collection The collection to iterate over.
7949      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7950      * @returns {Array} Returns the new mapped array.
7951      * @example
7952      *
7953      * function square(n) {
7954      *   return n * n;
7955      * }
7956      *
7957      * _.map([4, 8], square);
7958      * // => [16, 64]
7959      *
7960      * _.map({ 'a': 4, 'b': 8 }, square);
7961      * // => [16, 64] (iteration order is not guaranteed)
7962      *
7963      * var users = [
7964      *   { 'user': 'barney' },
7965      *   { 'user': 'fred' }
7966      * ];
7967      *
7968      * // The `_.property` iteratee shorthand.
7969      * _.map(users, 'user');
7970      * // => ['barney', 'fred']
7971      */
7972     function map(collection, iteratee) {
7973       var func = isArray(collection) ? arrayMap : baseMap;
7974       return func(collection, getIteratee(iteratee, 3));
7975     }
7976
7977     /**
7978      * This method is like `_.sortBy` except that it allows specifying the sort
7979      * orders of the iteratees to sort by. If `orders` is unspecified, all values
7980      * are sorted in ascending order. Otherwise, specify an order of "desc" for
7981      * descending or "asc" for ascending sort order of corresponding values.
7982      *
7983      * @static
7984      * @memberOf _
7985      * @category Collection
7986      * @param {Array|Object} collection The collection to iterate over.
7987      * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
7988      * @param {string[]} [orders] The sort orders of `iteratees`.
7989      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7990      * @returns {Array} Returns the new sorted array.
7991      * @example
7992      *
7993      * var users = [
7994      *   { 'user': 'fred',   'age': 48 },
7995      *   { 'user': 'barney', 'age': 34 },
7996      *   { 'user': 'fred',   'age': 42 },
7997      *   { 'user': 'barney', 'age': 36 }
7998      * ];
7999      *
8000      * // Sort by `user` in ascending order and by `age` in descending order.
8001      * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
8002      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8003      */
8004     function orderBy(collection, iteratees, orders, guard) {
8005       if (collection == null) {
8006         return [];
8007       }
8008       if (!isArray(iteratees)) {
8009         iteratees = iteratees == null ? [] : [iteratees];
8010       }
8011       orders = guard ? undefined : orders;
8012       if (!isArray(orders)) {
8013         orders = orders == null ? [] : [orders];
8014       }
8015       return baseOrderBy(collection, iteratees, orders);
8016     }
8017
8018     /**
8019      * Creates an array of elements split into two groups, the first of which
8020      * contains elements `predicate` returns truthy for, the second of which
8021      * contains elements `predicate` returns falsey for. The predicate is
8022      * invoked with one argument: (value).
8023      *
8024      * @static
8025      * @memberOf _
8026      * @category Collection
8027      * @param {Array|Object} collection The collection to iterate over.
8028      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8029      * @returns {Array} Returns the array of grouped elements.
8030      * @example
8031      *
8032      * var users = [
8033      *   { 'user': 'barney',  'age': 36, 'active': false },
8034      *   { 'user': 'fred',    'age': 40, 'active': true },
8035      *   { 'user': 'pebbles', 'age': 1,  'active': false }
8036      * ];
8037      *
8038      * _.partition(users, function(o) { return o.active; });
8039      * // => objects for [['fred'], ['barney', 'pebbles']]
8040      *
8041      * // The `_.matches` iteratee shorthand.
8042      * _.partition(users, { 'age': 1, 'active': false });
8043      * // => objects for [['pebbles'], ['barney', 'fred']]
8044      *
8045      * // The `_.matchesProperty` iteratee shorthand.
8046      * _.partition(users, ['active', false]);
8047      * // => objects for [['barney', 'pebbles'], ['fred']]
8048      *
8049      * // The `_.property` iteratee shorthand.
8050      * _.partition(users, 'active');
8051      * // => objects for [['fred'], ['barney', 'pebbles']]
8052      */
8053     var partition = createAggregator(function(result, value, key) {
8054       result[key ? 0 : 1].push(value);
8055     }, function() { return [[], []]; });
8056
8057     /**
8058      * Reduces `collection` to a value which is the accumulated result of running
8059      * each element in `collection` through `iteratee`, where each successive
8060      * invocation is supplied the return value of the previous. If `accumulator`
8061      * is not given the first element of `collection` is used as the initial
8062      * value. The iteratee is invoked with four arguments:
8063      * (accumulator, value, index|key, collection).
8064      *
8065      * Many lodash methods are guarded to work as iteratees for methods like
8066      * `_.reduce`, `_.reduceRight`, and `_.transform`.
8067      *
8068      * The guarded methods are:
8069      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
8070      * and `sortBy`
8071      *
8072      * @static
8073      * @memberOf _
8074      * @category Collection
8075      * @param {Array|Object} collection The collection to iterate over.
8076      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8077      * @param {*} [accumulator] The initial value.
8078      * @returns {*} Returns the accumulated value.
8079      * @example
8080      *
8081      * _.reduce([1, 2], function(sum, n) {
8082      *   return sum + n;
8083      * }, 0);
8084      * // => 3
8085      *
8086      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
8087      *   (result[value] || (result[value] = [])).push(key);
8088      *   return result;
8089      * }, {});
8090      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
8091      */
8092     function reduce(collection, iteratee, accumulator) {
8093       var func = isArray(collection) ? arrayReduce : baseReduce,
8094           initAccum = arguments.length < 3;
8095
8096       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
8097     }
8098
8099     /**
8100      * This method is like `_.reduce` except that it iterates over elements of
8101      * `collection` from right to left.
8102      *
8103      * @static
8104      * @memberOf _
8105      * @category Collection
8106      * @param {Array|Object} collection The collection to iterate over.
8107      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8108      * @param {*} [accumulator] The initial value.
8109      * @returns {*} Returns the accumulated value.
8110      * @example
8111      *
8112      * var array = [[0, 1], [2, 3], [4, 5]];
8113      *
8114      * _.reduceRight(array, function(flattened, other) {
8115      *   return flattened.concat(other);
8116      * }, []);
8117      * // => [4, 5, 2, 3, 0, 1]
8118      */
8119     function reduceRight(collection, iteratee, accumulator) {
8120       var func = isArray(collection) ? arrayReduceRight : baseReduce,
8121           initAccum = arguments.length < 3;
8122
8123       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
8124     }
8125
8126     /**
8127      * The opposite of `_.filter`; this method returns the elements of `collection`
8128      * that `predicate` does **not** return truthy for.
8129      *
8130      * @static
8131      * @memberOf _
8132      * @category Collection
8133      * @param {Array|Object} collection The collection to iterate over.
8134      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8135      * @returns {Array} Returns the new filtered array.
8136      * @example
8137      *
8138      * var users = [
8139      *   { 'user': 'barney', 'age': 36, 'active': false },
8140      *   { 'user': 'fred',   'age': 40, 'active': true }
8141      * ];
8142      *
8143      * _.reject(users, function(o) { return !o.active; });
8144      * // => objects for ['fred']
8145      *
8146      * // The `_.matches` iteratee shorthand.
8147      * _.reject(users, { 'age': 40, 'active': true });
8148      * // => objects for ['barney']
8149      *
8150      * // The `_.matchesProperty` iteratee shorthand.
8151      * _.reject(users, ['active', false]);
8152      * // => objects for ['fred']
8153      *
8154      * // The `_.property` iteratee shorthand.
8155      * _.reject(users, 'active');
8156      * // => objects for ['barney']
8157      */
8158     function reject(collection, predicate) {
8159       var func = isArray(collection) ? arrayFilter : baseFilter;
8160       predicate = getIteratee(predicate, 3);
8161       return func(collection, function(value, index, collection) {
8162         return !predicate(value, index, collection);
8163       });
8164     }
8165
8166     /**
8167      * Gets a random element from `collection`.
8168      *
8169      * @static
8170      * @memberOf _
8171      * @category Collection
8172      * @param {Array|Object} collection The collection to sample.
8173      * @returns {*} Returns the random element.
8174      * @example
8175      *
8176      * _.sample([1, 2, 3, 4]);
8177      * // => 2
8178      */
8179     function sample(collection) {
8180       var array = isArrayLike(collection) ? collection : values(collection),
8181           length = array.length;
8182
8183       return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
8184     }
8185
8186     /**
8187      * Gets `n` random elements at unique keys from `collection` up to the
8188      * size of `collection`.
8189      *
8190      * @static
8191      * @memberOf _
8192      * @category Collection
8193      * @param {Array|Object} collection The collection to sample.
8194      * @param {number} [n=0] The number of elements to sample.
8195      * @returns {Array} Returns the random elements.
8196      * @example
8197      *
8198      * _.sampleSize([1, 2, 3], 2);
8199      * // => [3, 1]
8200      *
8201      * _.sampleSize([1, 2, 3], 4);
8202      * // => [2, 3, 1]
8203      */
8204     function sampleSize(collection, n) {
8205       var index = -1,
8206           result = toArray(collection),
8207           length = result.length,
8208           lastIndex = length - 1;
8209
8210       n = baseClamp(toInteger(n), 0, length);
8211       while (++index < n) {
8212         var rand = baseRandom(index, lastIndex),
8213             value = result[rand];
8214
8215         result[rand] = result[index];
8216         result[index] = value;
8217       }
8218       result.length = n;
8219       return result;
8220     }
8221
8222     /**
8223      * Creates an array of shuffled values, using a version of the
8224      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
8225      *
8226      * @static
8227      * @memberOf _
8228      * @category Collection
8229      * @param {Array|Object} collection The collection to shuffle.
8230      * @returns {Array} Returns the new shuffled array.
8231      * @example
8232      *
8233      * _.shuffle([1, 2, 3, 4]);
8234      * // => [4, 1, 3, 2]
8235      */
8236     function shuffle(collection) {
8237       return sampleSize(collection, MAX_ARRAY_LENGTH);
8238     }
8239
8240     /**
8241      * Gets the size of `collection` by returning its length for array-like
8242      * values or the number of own enumerable properties for objects.
8243      *
8244      * @static
8245      * @memberOf _
8246      * @category Collection
8247      * @param {Array|Object} collection The collection to inspect.
8248      * @returns {number} Returns the collection size.
8249      * @example
8250      *
8251      * _.size([1, 2, 3]);
8252      * // => 3
8253      *
8254      * _.size({ 'a': 1, 'b': 2 });
8255      * // => 2
8256      *
8257      * _.size('pebbles');
8258      * // => 7
8259      */
8260     function size(collection) {
8261       if (collection == null) {
8262         return 0;
8263       }
8264       if (isArrayLike(collection)) {
8265         var result = collection.length;
8266         return (result && isString(collection)) ? stringSize(collection) : result;
8267       }
8268       return keys(collection).length;
8269     }
8270
8271     /**
8272      * Checks if `predicate` returns truthy for **any** element of `collection`.
8273      * Iteration is stopped once `predicate` returns truthy. The predicate is
8274      * invoked with three arguments: (value, index|key, collection).
8275      *
8276      * @static
8277      * @memberOf _
8278      * @category Collection
8279      * @param {Array|Object} collection The collection to iterate over.
8280      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8281      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8282      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
8283      * @example
8284      *
8285      * _.some([null, 0, 'yes', false], Boolean);
8286      * // => true
8287      *
8288      * var users = [
8289      *   { 'user': 'barney', 'active': true },
8290      *   { 'user': 'fred',   'active': false }
8291      * ];
8292      *
8293      * // The `_.matches` iteratee shorthand.
8294      * _.some(users, { 'user': 'barney', 'active': false });
8295      * // => false
8296      *
8297      * // The `_.matchesProperty` iteratee shorthand.
8298      * _.some(users, ['active', false]);
8299      * // => true
8300      *
8301      * // The `_.property` iteratee shorthand.
8302      * _.some(users, 'active');
8303      * // => true
8304      */
8305     function some(collection, predicate, guard) {
8306       var func = isArray(collection) ? arraySome : baseSome;
8307       if (guard && isIterateeCall(collection, predicate, guard)) {
8308         predicate = undefined;
8309       }
8310       return func(collection, getIteratee(predicate, 3));
8311     }
8312
8313     /**
8314      * Creates an array of elements, sorted in ascending order by the results of
8315      * running each element in a collection through each iteratee. This method
8316      * performs a stable sort, that is, it preserves the original sort order of
8317      * equal elements. The iteratees are invoked with one argument: (value).
8318      *
8319      * @static
8320      * @memberOf _
8321      * @category Collection
8322      * @param {Array|Object} collection The collection to iterate over.
8323      * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
8324      *  The iteratees to sort by, specified individually or in arrays.
8325      * @returns {Array} Returns the new sorted array.
8326      * @example
8327      *
8328      * var users = [
8329      *   { 'user': 'fred',   'age': 48 },
8330      *   { 'user': 'barney', 'age': 36 },
8331      *   { 'user': 'fred',   'age': 42 },
8332      *   { 'user': 'barney', 'age': 34 }
8333      * ];
8334      *
8335      * _.sortBy(users, function(o) { return o.user; });
8336      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8337      *
8338      * _.sortBy(users, ['user', 'age']);
8339      * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
8340      *
8341      * _.sortBy(users, 'user', function(o) {
8342      *   return Math.floor(o.age / 10);
8343      * });
8344      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8345      */
8346     var sortBy = rest(function(collection, iteratees) {
8347       if (collection == null) {
8348         return [];
8349       }
8350       var length = iteratees.length;
8351       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
8352         iteratees = [];
8353       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
8354         iteratees.length = 1;
8355       }
8356       return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
8357     });
8358
8359     /*------------------------------------------------------------------------*/
8360
8361     /**
8362      * Gets the timestamp of the number of milliseconds that have elapsed since
8363      * the Unix epoch (1 January 1970 00:00:00 UTC).
8364      *
8365      * @static
8366      * @memberOf _
8367      * @type {Function}
8368      * @category Date
8369      * @returns {number} Returns the timestamp.
8370      * @example
8371      *
8372      * _.defer(function(stamp) {
8373      *   console.log(_.now() - stamp);
8374      * }, _.now());
8375      * // => logs the number of milliseconds it took for the deferred function to be invoked
8376      */
8377     var now = Date.now;
8378
8379     /*------------------------------------------------------------------------*/
8380
8381     /**
8382      * The opposite of `_.before`; this method creates a function that invokes
8383      * `func` once it's called `n` or more times.
8384      *
8385      * @static
8386      * @memberOf _
8387      * @category Function
8388      * @param {number} n The number of calls before `func` is invoked.
8389      * @param {Function} func The function to restrict.
8390      * @returns {Function} Returns the new restricted function.
8391      * @example
8392      *
8393      * var saves = ['profile', 'settings'];
8394      *
8395      * var done = _.after(saves.length, function() {
8396      *   console.log('done saving!');
8397      * });
8398      *
8399      * _.forEach(saves, function(type) {
8400      *   asyncSave({ 'type': type, 'complete': done });
8401      * });
8402      * // => logs 'done saving!' after the two async saves have completed
8403      */
8404     function after(n, func) {
8405       if (typeof func != 'function') {
8406         throw new TypeError(FUNC_ERROR_TEXT);
8407       }
8408       n = toInteger(n);
8409       return function() {
8410         if (--n < 1) {
8411           return func.apply(this, arguments);
8412         }
8413       };
8414     }
8415
8416     /**
8417      * Creates a function that accepts up to `n` arguments, ignoring any
8418      * additional arguments.
8419      *
8420      * @static
8421      * @memberOf _
8422      * @category Function
8423      * @param {Function} func The function to cap arguments for.
8424      * @param {number} [n=func.length] The arity cap.
8425      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8426      * @returns {Function} Returns the new function.
8427      * @example
8428      *
8429      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
8430      * // => [6, 8, 10]
8431      */
8432     function ary(func, n, guard) {
8433       n = guard ? undefined : n;
8434       n = (func && n == null) ? func.length : n;
8435       return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
8436     }
8437
8438     /**
8439      * Creates a function that invokes `func`, with the `this` binding and arguments
8440      * of the created function, while it's called less than `n` times. Subsequent
8441      * calls to the created function return the result of the last `func` invocation.
8442      *
8443      * @static
8444      * @memberOf _
8445      * @category Function
8446      * @param {number} n The number of calls at which `func` is no longer invoked.
8447      * @param {Function} func The function to restrict.
8448      * @returns {Function} Returns the new restricted function.
8449      * @example
8450      *
8451      * jQuery(element).on('click', _.before(5, addContactToList));
8452      * // => allows adding up to 4 contacts to the list
8453      */
8454     function before(n, func) {
8455       var result;
8456       if (typeof func != 'function') {
8457         throw new TypeError(FUNC_ERROR_TEXT);
8458       }
8459       n = toInteger(n);
8460       return function() {
8461         if (--n > 0) {
8462           result = func.apply(this, arguments);
8463         }
8464         if (n <= 1) {
8465           func = undefined;
8466         }
8467         return result;
8468       };
8469     }
8470
8471     /**
8472      * Creates a function that invokes `func` with the `this` binding of `thisArg`
8473      * and prepends any additional `_.bind` arguments to those provided to the
8474      * bound function.
8475      *
8476      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
8477      * may be used as a placeholder for partially applied arguments.
8478      *
8479      * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
8480      * property of bound functions.
8481      *
8482      * @static
8483      * @memberOf _
8484      * @category Function
8485      * @param {Function} func The function to bind.
8486      * @param {*} thisArg The `this` binding of `func`.
8487      * @param {...*} [partials] The arguments to be partially applied.
8488      * @returns {Function} Returns the new bound function.
8489      * @example
8490      *
8491      * var greet = function(greeting, punctuation) {
8492      *   return greeting + ' ' + this.user + punctuation;
8493      * };
8494      *
8495      * var object = { 'user': 'fred' };
8496      *
8497      * var bound = _.bind(greet, object, 'hi');
8498      * bound('!');
8499      * // => 'hi fred!'
8500      *
8501      * // Bound with placeholders.
8502      * var bound = _.bind(greet, object, _, '!');
8503      * bound('hi');
8504      * // => 'hi fred!'
8505      */
8506     var bind = rest(function(func, thisArg, partials) {
8507       var bitmask = BIND_FLAG;
8508       if (partials.length) {
8509         var holders = replaceHolders(partials, getPlaceholder(bind));
8510         bitmask |= PARTIAL_FLAG;
8511       }
8512       return createWrapper(func, bitmask, thisArg, partials, holders);
8513     });
8514
8515     /**
8516      * Creates a function that invokes the method at `object[key]` and prepends
8517      * any additional `_.bindKey` arguments to those provided to the bound function.
8518      *
8519      * This method differs from `_.bind` by allowing bound functions to reference
8520      * methods that may be redefined or don't yet exist.
8521      * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
8522      * for more details.
8523      *
8524      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
8525      * builds, may be used as a placeholder for partially applied arguments.
8526      *
8527      * @static
8528      * @memberOf _
8529      * @category Function
8530      * @param {Object} object The object to invoke the method on.
8531      * @param {string} key The key of the method.
8532      * @param {...*} [partials] The arguments to be partially applied.
8533      * @returns {Function} Returns the new bound function.
8534      * @example
8535      *
8536      * var object = {
8537      *   'user': 'fred',
8538      *   'greet': function(greeting, punctuation) {
8539      *     return greeting + ' ' + this.user + punctuation;
8540      *   }
8541      * };
8542      *
8543      * var bound = _.bindKey(object, 'greet', 'hi');
8544      * bound('!');
8545      * // => 'hi fred!'
8546      *
8547      * object.greet = function(greeting, punctuation) {
8548      *   return greeting + 'ya ' + this.user + punctuation;
8549      * };
8550      *
8551      * bound('!');
8552      * // => 'hiya fred!'
8553      *
8554      * // Bound with placeholders.
8555      * var bound = _.bindKey(object, 'greet', _, '!');
8556      * bound('hi');
8557      * // => 'hiya fred!'
8558      */
8559     var bindKey = rest(function(object, key, partials) {
8560       var bitmask = BIND_FLAG | BIND_KEY_FLAG;
8561       if (partials.length) {
8562         var holders = replaceHolders(partials, getPlaceholder(bindKey));
8563         bitmask |= PARTIAL_FLAG;
8564       }
8565       return createWrapper(key, bitmask, object, partials, holders);
8566     });
8567
8568     /**
8569      * Creates a function that accepts arguments of `func` and either invokes
8570      * `func` returning its result, if at least `arity` number of arguments have
8571      * been provided, or returns a function that accepts the remaining `func`
8572      * arguments, and so on. The arity of `func` may be specified if `func.length`
8573      * is not sufficient.
8574      *
8575      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
8576      * may be used as a placeholder for provided arguments.
8577      *
8578      * **Note:** This method doesn't set the "length" property of curried functions.
8579      *
8580      * @static
8581      * @memberOf _
8582      * @category Function
8583      * @param {Function} func The function to curry.
8584      * @param {number} [arity=func.length] The arity of `func`.
8585      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8586      * @returns {Function} Returns the new curried function.
8587      * @example
8588      *
8589      * var abc = function(a, b, c) {
8590      *   return [a, b, c];
8591      * };
8592      *
8593      * var curried = _.curry(abc);
8594      *
8595      * curried(1)(2)(3);
8596      * // => [1, 2, 3]
8597      *
8598      * curried(1, 2)(3);
8599      * // => [1, 2, 3]
8600      *
8601      * curried(1, 2, 3);
8602      * // => [1, 2, 3]
8603      *
8604      * // Curried with placeholders.
8605      * curried(1)(_, 3)(2);
8606      * // => [1, 2, 3]
8607      */
8608     function curry(func, arity, guard) {
8609       arity = guard ? undefined : arity;
8610       var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8611       result.placeholder = curry.placeholder;
8612       return result;
8613     }
8614
8615     /**
8616      * This method is like `_.curry` except that arguments are applied to `func`
8617      * in the manner of `_.partialRight` instead of `_.partial`.
8618      *
8619      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
8620      * builds, may be used as a placeholder for provided arguments.
8621      *
8622      * **Note:** This method doesn't set the "length" property of curried functions.
8623      *
8624      * @static
8625      * @memberOf _
8626      * @category Function
8627      * @param {Function} func The function to curry.
8628      * @param {number} [arity=func.length] The arity of `func`.
8629      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8630      * @returns {Function} Returns the new curried function.
8631      * @example
8632      *
8633      * var abc = function(a, b, c) {
8634      *   return [a, b, c];
8635      * };
8636      *
8637      * var curried = _.curryRight(abc);
8638      *
8639      * curried(3)(2)(1);
8640      * // => [1, 2, 3]
8641      *
8642      * curried(2, 3)(1);
8643      * // => [1, 2, 3]
8644      *
8645      * curried(1, 2, 3);
8646      * // => [1, 2, 3]
8647      *
8648      * // Curried with placeholders.
8649      * curried(3)(1, _)(2);
8650      * // => [1, 2, 3]
8651      */
8652     function curryRight(func, arity, guard) {
8653       arity = guard ? undefined : arity;
8654       var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8655       result.placeholder = curryRight.placeholder;
8656       return result;
8657     }
8658
8659     /**
8660      * Creates a debounced function that delays invoking `func` until after `wait`
8661      * milliseconds have elapsed since the last time the debounced function was
8662      * invoked. The debounced function comes with a `cancel` method to cancel
8663      * delayed `func` invocations and a `flush` method to immediately invoke them.
8664      * Provide an options object to indicate whether `func` should be invoked on
8665      * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
8666      * with the last arguments provided to the debounced function. Subsequent calls
8667      * to the debounced function return the result of the last `func` invocation.
8668      *
8669      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8670      * on the trailing edge of the timeout only if the debounced function is
8671      * invoked more than once during the `wait` timeout.
8672      *
8673      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8674      * for details over the differences between `_.debounce` and `_.throttle`.
8675      *
8676      * @static
8677      * @memberOf _
8678      * @category Function
8679      * @param {Function} func The function to debounce.
8680      * @param {number} [wait=0] The number of milliseconds to delay.
8681      * @param {Object} [options] The options object.
8682      * @param {boolean} [options.leading=false] Specify invoking on the leading
8683      *  edge of the timeout.
8684      * @param {number} [options.maxWait] The maximum time `func` is allowed to be
8685      *  delayed before it's invoked.
8686      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
8687      *  edge of the timeout.
8688      * @returns {Function} Returns the new debounced function.
8689      * @example
8690      *
8691      * // Avoid costly calculations while the window size is in flux.
8692      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
8693      *
8694      * // Invoke `sendMail` when clicked, debouncing subsequent calls.
8695      * jQuery(element).on('click', _.debounce(sendMail, 300, {
8696      *   'leading': true,
8697      *   'trailing': false
8698      * }));
8699      *
8700      * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
8701      * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
8702      * var source = new EventSource('/stream');
8703      * jQuery(source).on('message', debounced);
8704      *
8705      * // Cancel the trailing debounced invocation.
8706      * jQuery(window).on('popstate', debounced.cancel);
8707      */
8708     function debounce(func, wait, options) {
8709       var args,
8710           maxTimeoutId,
8711           result,
8712           stamp,
8713           thisArg,
8714           timeoutId,
8715           trailingCall,
8716           lastCalled = 0,
8717           leading = false,
8718           maxWait = false,
8719           trailing = true;
8720
8721       if (typeof func != 'function') {
8722         throw new TypeError(FUNC_ERROR_TEXT);
8723       }
8724       wait = toNumber(wait) || 0;
8725       if (isObject(options)) {
8726         leading = !!options.leading;
8727         maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
8728         trailing = 'trailing' in options ? !!options.trailing : trailing;
8729       }
8730
8731       function cancel() {
8732         if (timeoutId) {
8733           clearTimeout(timeoutId);
8734         }
8735         if (maxTimeoutId) {
8736           clearTimeout(maxTimeoutId);
8737         }
8738         lastCalled = 0;
8739         args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
8740       }
8741
8742       function complete(isCalled, id) {
8743         if (id) {
8744           clearTimeout(id);
8745         }
8746         maxTimeoutId = timeoutId = trailingCall = undefined;
8747         if (isCalled) {
8748           lastCalled = now();
8749           result = func.apply(thisArg, args);
8750           if (!timeoutId && !maxTimeoutId) {
8751             args = thisArg = undefined;
8752           }
8753         }
8754       }
8755
8756       function delayed() {
8757         var remaining = wait - (now() - stamp);
8758         if (remaining <= 0 || remaining > wait) {
8759           complete(trailingCall, maxTimeoutId);
8760         } else {
8761           timeoutId = setTimeout(delayed, remaining);
8762         }
8763       }
8764
8765       function flush() {
8766         if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
8767           result = func.apply(thisArg, args);
8768         }
8769         cancel();
8770         return result;
8771       }
8772
8773       function maxDelayed() {
8774         complete(trailing, timeoutId);
8775       }
8776
8777       function debounced() {
8778         args = arguments;
8779         stamp = now();
8780         thisArg = this;
8781         trailingCall = trailing && (timeoutId || !leading);
8782
8783         if (maxWait === false) {
8784           var leadingCall = leading && !timeoutId;
8785         } else {
8786           if (!lastCalled && !maxTimeoutId && !leading) {
8787             lastCalled = stamp;
8788           }
8789           var remaining = maxWait - (stamp - lastCalled);
8790
8791           var isCalled = (remaining <= 0 || remaining > maxWait) &&
8792             (leading || maxTimeoutId);
8793
8794           if (isCalled) {
8795             if (maxTimeoutId) {
8796               maxTimeoutId = clearTimeout(maxTimeoutId);
8797             }
8798             lastCalled = stamp;
8799             result = func.apply(thisArg, args);
8800           }
8801           else if (!maxTimeoutId) {
8802             maxTimeoutId = setTimeout(maxDelayed, remaining);
8803           }
8804         }
8805         if (isCalled && timeoutId) {
8806           timeoutId = clearTimeout(timeoutId);
8807         }
8808         else if (!timeoutId && wait !== maxWait) {
8809           timeoutId = setTimeout(delayed, wait);
8810         }
8811         if (leadingCall) {
8812           isCalled = true;
8813           result = func.apply(thisArg, args);
8814         }
8815         if (isCalled && !timeoutId && !maxTimeoutId) {
8816           args = thisArg = undefined;
8817         }
8818         return result;
8819       }
8820       debounced.cancel = cancel;
8821       debounced.flush = flush;
8822       return debounced;
8823     }
8824
8825     /**
8826      * Defers invoking the `func` until the current call stack has cleared. Any
8827      * additional arguments are provided to `func` when it's invoked.
8828      *
8829      * @static
8830      * @memberOf _
8831      * @category Function
8832      * @param {Function} func The function to defer.
8833      * @param {...*} [args] The arguments to invoke `func` with.
8834      * @returns {number} Returns the timer id.
8835      * @example
8836      *
8837      * _.defer(function(text) {
8838      *   console.log(text);
8839      * }, 'deferred');
8840      * // => logs 'deferred' after one or more milliseconds
8841      */
8842     var defer = rest(function(func, args) {
8843       return baseDelay(func, 1, args);
8844     });
8845
8846     /**
8847      * Invokes `func` after `wait` milliseconds. Any additional arguments are
8848      * provided to `func` when it's invoked.
8849      *
8850      * @static
8851      * @memberOf _
8852      * @category Function
8853      * @param {Function} func The function to delay.
8854      * @param {number} wait The number of milliseconds to delay invocation.
8855      * @param {...*} [args] The arguments to invoke `func` with.
8856      * @returns {number} Returns the timer id.
8857      * @example
8858      *
8859      * _.delay(function(text) {
8860      *   console.log(text);
8861      * }, 1000, 'later');
8862      * // => logs 'later' after one second
8863      */
8864     var delay = rest(function(func, wait, args) {
8865       return baseDelay(func, toNumber(wait) || 0, args);
8866     });
8867
8868     /**
8869      * Creates a function that invokes `func` with arguments reversed.
8870      *
8871      * @static
8872      * @memberOf _
8873      * @category Function
8874      * @param {Function} func The function to flip arguments for.
8875      * @returns {Function} Returns the new function.
8876      * @example
8877      *
8878      * var flipped = _.flip(function() {
8879      *   return _.toArray(arguments);
8880      * });
8881      *
8882      * flipped('a', 'b', 'c', 'd');
8883      * // => ['d', 'c', 'b', 'a']
8884      */
8885     function flip(func) {
8886       return createWrapper(func, FLIP_FLAG);
8887     }
8888
8889     /**
8890      * Creates a function that memoizes the result of `func`. If `resolver` is
8891      * provided it determines the cache key for storing the result based on the
8892      * arguments provided to the memoized function. By default, the first argument
8893      * provided to the memoized function is used as the map cache key. The `func`
8894      * is invoked with the `this` binding of the memoized function.
8895      *
8896      * **Note:** The cache is exposed as the `cache` property on the memoized
8897      * function. Its creation may be customized by replacing the `_.memoize.Cache`
8898      * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
8899      * method interface of `delete`, `get`, `has`, and `set`.
8900      *
8901      * @static
8902      * @memberOf _
8903      * @category Function
8904      * @param {Function} func The function to have its output memoized.
8905      * @param {Function} [resolver] The function to resolve the cache key.
8906      * @returns {Function} Returns the new memoizing function.
8907      * @example
8908      *
8909      * var object = { 'a': 1, 'b': 2 };
8910      * var other = { 'c': 3, 'd': 4 };
8911      *
8912      * var values = _.memoize(_.values);
8913      * values(object);
8914      * // => [1, 2]
8915      *
8916      * values(other);
8917      * // => [3, 4]
8918      *
8919      * object.a = 2;
8920      * values(object);
8921      * // => [1, 2]
8922      *
8923      * // Modify the result cache.
8924      * values.cache.set(object, ['a', 'b']);
8925      * values(object);
8926      * // => ['a', 'b']
8927      *
8928      * // Replace `_.memoize.Cache`.
8929      * _.memoize.Cache = WeakMap;
8930      */
8931     function memoize(func, resolver) {
8932       if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
8933         throw new TypeError(FUNC_ERROR_TEXT);
8934       }
8935       var memoized = function() {
8936         var args = arguments,
8937             key = resolver ? resolver.apply(this, args) : args[0],
8938             cache = memoized.cache;
8939
8940         if (cache.has(key)) {
8941           return cache.get(key);
8942         }
8943         var result = func.apply(this, args);
8944         memoized.cache = cache.set(key, result);
8945         return result;
8946       };
8947       memoized.cache = new memoize.Cache;
8948       return memoized;
8949     }
8950
8951     /**
8952      * Creates a function that negates the result of the predicate `func`. The
8953      * `func` predicate is invoked with the `this` binding and arguments of the
8954      * created function.
8955      *
8956      * @static
8957      * @memberOf _
8958      * @category Function
8959      * @param {Function} predicate The predicate to negate.
8960      * @returns {Function} Returns the new function.
8961      * @example
8962      *
8963      * function isEven(n) {
8964      *   return n % 2 == 0;
8965      * }
8966      *
8967      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
8968      * // => [1, 3, 5]
8969      */
8970     function negate(predicate) {
8971       if (typeof predicate != 'function') {
8972         throw new TypeError(FUNC_ERROR_TEXT);
8973       }
8974       return function() {
8975         return !predicate.apply(this, arguments);
8976       };
8977     }
8978
8979     /**
8980      * Creates a function that is restricted to invoking `func` once. Repeat calls
8981      * to the function return the value of the first invocation. The `func` is
8982      * invoked with the `this` binding and arguments of the created function.
8983      *
8984      * @static
8985      * @memberOf _
8986      * @category Function
8987      * @param {Function} func The function to restrict.
8988      * @returns {Function} Returns the new restricted function.
8989      * @example
8990      *
8991      * var initialize = _.once(createApplication);
8992      * initialize();
8993      * initialize();
8994      * // `initialize` invokes `createApplication` once
8995      */
8996     function once(func) {
8997       return before(2, func);
8998     }
8999
9000     /**
9001      * Creates a function that invokes `func` with arguments transformed by
9002      * corresponding `transforms`.
9003      *
9004      * @static
9005      * @memberOf _
9006      * @category Function
9007      * @param {Function} func The function to wrap.
9008      * @param {...(Function|Function[])} [transforms] The functions to transform
9009      * arguments, specified individually or in arrays.
9010      * @returns {Function} Returns the new function.
9011      * @example
9012      *
9013      * function doubled(n) {
9014      *   return n * 2;
9015      * }
9016      *
9017      * function square(n) {
9018      *   return n * n;
9019      * }
9020      *
9021      * var func = _.overArgs(function(x, y) {
9022      *   return [x, y];
9023      * }, square, doubled);
9024      *
9025      * func(9, 3);
9026      * // => [81, 6]
9027      *
9028      * func(10, 5);
9029      * // => [100, 10]
9030      */
9031     var overArgs = rest(function(func, transforms) {
9032       transforms = arrayMap(baseFlatten(transforms, 1), getIteratee());
9033
9034       var funcsLength = transforms.length;
9035       return rest(function(args) {
9036         var index = -1,
9037             length = nativeMin(args.length, funcsLength);
9038
9039         while (++index < length) {
9040           args[index] = transforms[index].call(this, args[index]);
9041         }
9042         return apply(func, this, args);
9043       });
9044     });
9045
9046     /**
9047      * Creates a function that invokes `func` with `partial` arguments prepended
9048      * to those provided to the new function. This method is like `_.bind` except
9049      * it does **not** alter the `this` binding.
9050      *
9051      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
9052      * builds, may be used as a placeholder for partially applied arguments.
9053      *
9054      * **Note:** This method doesn't set the "length" property of partially
9055      * applied functions.
9056      *
9057      * @static
9058      * @memberOf _
9059      * @category Function
9060      * @param {Function} func The function to partially apply arguments to.
9061      * @param {...*} [partials] The arguments to be partially applied.
9062      * @returns {Function} Returns the new partially applied function.
9063      * @example
9064      *
9065      * var greet = function(greeting, name) {
9066      *   return greeting + ' ' + name;
9067      * };
9068      *
9069      * var sayHelloTo = _.partial(greet, 'hello');
9070      * sayHelloTo('fred');
9071      * // => 'hello fred'
9072      *
9073      * // Partially applied with placeholders.
9074      * var greetFred = _.partial(greet, _, 'fred');
9075      * greetFred('hi');
9076      * // => 'hi fred'
9077      */
9078     var partial = rest(function(func, partials) {
9079       var holders = replaceHolders(partials, getPlaceholder(partial));
9080       return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
9081     });
9082
9083     /**
9084      * This method is like `_.partial` except that partially applied arguments
9085      * are appended to those provided to the new function.
9086      *
9087      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
9088      * builds, may be used as a placeholder for partially applied arguments.
9089      *
9090      * **Note:** This method doesn't set the "length" property of partially
9091      * applied functions.
9092      *
9093      * @static
9094      * @memberOf _
9095      * @category Function
9096      * @param {Function} func The function to partially apply arguments to.
9097      * @param {...*} [partials] The arguments to be partially applied.
9098      * @returns {Function} Returns the new partially applied function.
9099      * @example
9100      *
9101      * var greet = function(greeting, name) {
9102      *   return greeting + ' ' + name;
9103      * };
9104      *
9105      * var greetFred = _.partialRight(greet, 'fred');
9106      * greetFred('hi');
9107      * // => 'hi fred'
9108      *
9109      * // Partially applied with placeholders.
9110      * var sayHelloTo = _.partialRight(greet, 'hello', _);
9111      * sayHelloTo('fred');
9112      * // => 'hello fred'
9113      */
9114     var partialRight = rest(function(func, partials) {
9115       var holders = replaceHolders(partials, getPlaceholder(partialRight));
9116       return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
9117     });
9118
9119     /**
9120      * Creates a function that invokes `func` with arguments arranged according
9121      * to the specified indexes where the argument value at the first index is
9122      * provided as the first argument, the argument value at the second index is
9123      * provided as the second argument, and so on.
9124      *
9125      * @static
9126      * @memberOf _
9127      * @category Function
9128      * @param {Function} func The function to rearrange arguments for.
9129      * @param {...(number|number[])} indexes The arranged argument indexes,
9130      *  specified individually or in arrays.
9131      * @returns {Function} Returns the new function.
9132      * @example
9133      *
9134      * var rearged = _.rearg(function(a, b, c) {
9135      *   return [a, b, c];
9136      * }, 2, 0, 1);
9137      *
9138      * rearged('b', 'c', 'a')
9139      * // => ['a', 'b', 'c']
9140      */
9141     var rearg = rest(function(func, indexes) {
9142       return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1));
9143     });
9144
9145     /**
9146      * Creates a function that invokes `func` with the `this` binding of the
9147      * created function and arguments from `start` and beyond provided as an array.
9148      *
9149      * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
9150      *
9151      * @static
9152      * @memberOf _
9153      * @category Function
9154      * @param {Function} func The function to apply a rest parameter to.
9155      * @param {number} [start=func.length-1] The start position of the rest parameter.
9156      * @returns {Function} Returns the new function.
9157      * @example
9158      *
9159      * var say = _.rest(function(what, names) {
9160      *   return what + ' ' + _.initial(names).join(', ') +
9161      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
9162      * });
9163      *
9164      * say('hello', 'fred', 'barney', 'pebbles');
9165      * // => 'hello fred, barney, & pebbles'
9166      */
9167     function rest(func, start) {
9168       if (typeof func != 'function') {
9169         throw new TypeError(FUNC_ERROR_TEXT);
9170       }
9171       start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
9172       return function() {
9173         var args = arguments,
9174             index = -1,
9175             length = nativeMax(args.length - start, 0),
9176             array = Array(length);
9177
9178         while (++index < length) {
9179           array[index] = args[start + index];
9180         }
9181         switch (start) {
9182           case 0: return func.call(this, array);
9183           case 1: return func.call(this, args[0], array);
9184           case 2: return func.call(this, args[0], args[1], array);
9185         }
9186         var otherArgs = Array(start + 1);
9187         index = -1;
9188         while (++index < start) {
9189           otherArgs[index] = args[index];
9190         }
9191         otherArgs[start] = array;
9192         return apply(func, this, otherArgs);
9193       };
9194     }
9195
9196     /**
9197      * Creates a function that invokes `func` with the `this` binding of the created
9198      * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
9199      *
9200      * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
9201      *
9202      * @static
9203      * @memberOf _
9204      * @category Function
9205      * @param {Function} func The function to spread arguments over.
9206      * @param {number} [start=0] The start position of the spread.
9207      * @returns {Function} Returns the new function.
9208      * @example
9209      *
9210      * var say = _.spread(function(who, what) {
9211      *   return who + ' says ' + what;
9212      * });
9213      *
9214      * say(['fred', 'hello']);
9215      * // => 'fred says hello'
9216      *
9217      * var numbers = Promise.all([
9218      *   Promise.resolve(40),
9219      *   Promise.resolve(36)
9220      * ]);
9221      *
9222      * numbers.then(_.spread(function(x, y) {
9223      *   return x + y;
9224      * }));
9225      * // => a Promise of 76
9226      */
9227     function spread(func, start) {
9228       if (typeof func != 'function') {
9229         throw new TypeError(FUNC_ERROR_TEXT);
9230       }
9231       start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
9232       return rest(function(args) {
9233         var array = args[start],
9234             otherArgs = args.slice(0, start);
9235
9236         if (array) {
9237           arrayPush(otherArgs, array);
9238         }
9239         return apply(func, this, otherArgs);
9240       });
9241     }
9242
9243     /**
9244      * Creates a throttled function that only invokes `func` at most once per
9245      * every `wait` milliseconds. The throttled function comes with a `cancel`
9246      * method to cancel delayed `func` invocations and a `flush` method to
9247      * immediately invoke them. Provide an options object to indicate whether
9248      * `func` should be invoked on the leading and/or trailing edge of the `wait`
9249      * timeout. The `func` is invoked with the last arguments provided to the
9250      * throttled function. Subsequent calls to the throttled function return the
9251      * result of the last `func` invocation.
9252      *
9253      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
9254      * on the trailing edge of the timeout only if the throttled function is
9255      * invoked more than once during the `wait` timeout.
9256      *
9257      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
9258      * for details over the differences between `_.throttle` and `_.debounce`.
9259      *
9260      * @static
9261      * @memberOf _
9262      * @category Function
9263      * @param {Function} func The function to throttle.
9264      * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
9265      * @param {Object} [options] The options object.
9266      * @param {boolean} [options.leading=true] Specify invoking on the leading
9267      *  edge of the timeout.
9268      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
9269      *  edge of the timeout.
9270      * @returns {Function} Returns the new throttled function.
9271      * @example
9272      *
9273      * // Avoid excessively updating the position while scrolling.
9274      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
9275      *
9276      * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
9277      * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
9278      * jQuery(element).on('click', throttled);
9279      *
9280      * // Cancel the trailing throttled invocation.
9281      * jQuery(window).on('popstate', throttled.cancel);
9282      */
9283     function throttle(func, wait, options) {
9284       var leading = true,
9285           trailing = true;
9286
9287       if (typeof func != 'function') {
9288         throw new TypeError(FUNC_ERROR_TEXT);
9289       }
9290       if (isObject(options)) {
9291         leading = 'leading' in options ? !!options.leading : leading;
9292         trailing = 'trailing' in options ? !!options.trailing : trailing;
9293       }
9294       return debounce(func, wait, {
9295         'leading': leading,
9296         'maxWait': wait,
9297         'trailing': trailing
9298       });
9299     }
9300
9301     /**
9302      * Creates a function that accepts up to one argument, ignoring any
9303      * additional arguments.
9304      *
9305      * @static
9306      * @memberOf _
9307      * @category Function
9308      * @param {Function} func The function to cap arguments for.
9309      * @returns {Function} Returns the new function.
9310      * @example
9311      *
9312      * _.map(['6', '8', '10'], _.unary(parseInt));
9313      * // => [6, 8, 10]
9314      */
9315     function unary(func) {
9316       return ary(func, 1);
9317     }
9318
9319     /**
9320      * Creates a function that provides `value` to the wrapper function as its
9321      * first argument. Any additional arguments provided to the function are
9322      * appended to those provided to the wrapper function. The wrapper is invoked
9323      * with the `this` binding of the created function.
9324      *
9325      * @static
9326      * @memberOf _
9327      * @category Function
9328      * @param {*} value The value to wrap.
9329      * @param {Function} [wrapper=identity] The wrapper function.
9330      * @returns {Function} Returns the new function.
9331      * @example
9332      *
9333      * var p = _.wrap(_.escape, function(func, text) {
9334      *   return '<p>' + func(text) + '</p>';
9335      * });
9336      *
9337      * p('fred, barney, & pebbles');
9338      * // => '<p>fred, barney, &amp; pebbles</p>'
9339      */
9340     function wrap(value, wrapper) {
9341       wrapper = wrapper == null ? identity : wrapper;
9342       return partial(wrapper, value);
9343     }
9344
9345     /*------------------------------------------------------------------------*/
9346
9347     /**
9348      * Casts `value` as an array if it's not one.
9349      *
9350      * @static
9351      * @memberOf _
9352      * @category Lang
9353      * @param {*} value The value to inspect.
9354      * @returns {Array} Returns the cast array.
9355      * @example
9356      *
9357      * _.castArray(1);
9358      * // => [1]
9359      *
9360      * _.castArray({ 'a': 1 });
9361      * // => [{ 'a': 1 }]
9362      *
9363      * _.castArray('abc');
9364      * // => ['abc']
9365      *
9366      * _.castArray(null);
9367      * // => [null]
9368      *
9369      * _.castArray(undefined);
9370      * // => [undefined]
9371      *
9372      * _.castArray();
9373      * // => []
9374      *
9375      * var array = [1, 2, 3];
9376      * console.log(_.castArray(array) === array);
9377      * // => true
9378      */
9379     function castArray() {
9380       if (!arguments.length) {
9381         return [];
9382       }
9383       var value = arguments[0];
9384       return isArray(value) ? value : [value];
9385     }
9386
9387     /**
9388      * Creates a shallow clone of `value`.
9389      *
9390      * **Note:** This method is loosely based on the
9391      * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
9392      * and supports cloning arrays, array buffers, booleans, date objects, maps,
9393      * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
9394      * arrays. The own enumerable properties of `arguments` objects are cloned
9395      * as plain objects. An empty object is returned for uncloneable values such
9396      * as error objects, functions, DOM nodes, and WeakMaps.
9397      *
9398      * @static
9399      * @memberOf _
9400      * @category Lang
9401      * @param {*} value The value to clone.
9402      * @returns {*} Returns the cloned value.
9403      * @example
9404      *
9405      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9406      *
9407      * var shallow = _.clone(objects);
9408      * console.log(shallow[0] === objects[0]);
9409      * // => true
9410      */
9411     function clone(value) {
9412       return baseClone(value);
9413     }
9414
9415     /**
9416      * This method is like `_.clone` except that it accepts `customizer` which
9417      * is invoked to produce the cloned value. If `customizer` returns `undefined`
9418      * cloning is handled by the method instead. The `customizer` is invoked with
9419      * up to four arguments; (value [, index|key, object, stack]).
9420      *
9421      * @static
9422      * @memberOf _
9423      * @category Lang
9424      * @param {*} value The value to clone.
9425      * @param {Function} [customizer] The function to customize cloning.
9426      * @returns {*} Returns the cloned value.
9427      * @example
9428      *
9429      * function customizer(value) {
9430      *   if (_.isElement(value)) {
9431      *     return value.cloneNode(false);
9432      *   }
9433      * }
9434      *
9435      * var el = _.cloneWith(document.body, customizer);
9436      *
9437      * console.log(el === document.body);
9438      * // => false
9439      * console.log(el.nodeName);
9440      * // => 'BODY'
9441      * console.log(el.childNodes.length);
9442      * // => 0
9443      */
9444     function cloneWith(value, customizer) {
9445       return baseClone(value, false, customizer);
9446     }
9447
9448     /**
9449      * This method is like `_.clone` except that it recursively clones `value`.
9450      *
9451      * @static
9452      * @memberOf _
9453      * @category Lang
9454      * @param {*} value The value to recursively clone.
9455      * @returns {*} Returns the deep cloned value.
9456      * @example
9457      *
9458      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9459      *
9460      * var deep = _.cloneDeep(objects);
9461      * console.log(deep[0] === objects[0]);
9462      * // => false
9463      */
9464     function cloneDeep(value) {
9465       return baseClone(value, true);
9466     }
9467
9468     /**
9469      * This method is like `_.cloneWith` except that it recursively clones `value`.
9470      *
9471      * @static
9472      * @memberOf _
9473      * @category Lang
9474      * @param {*} value The value to recursively clone.
9475      * @param {Function} [customizer] The function to customize cloning.
9476      * @returns {*} Returns the deep cloned value.
9477      * @example
9478      *
9479      * function customizer(value) {
9480      *   if (_.isElement(value)) {
9481      *     return value.cloneNode(true);
9482      *   }
9483      * }
9484      *
9485      * var el = _.cloneDeepWith(document.body, customizer);
9486      *
9487      * console.log(el === document.body);
9488      * // => false
9489      * console.log(el.nodeName);
9490      * // => 'BODY'
9491      * console.log(el.childNodes.length);
9492      * // => 20
9493      */
9494     function cloneDeepWith(value, customizer) {
9495       return baseClone(value, true, customizer);
9496     }
9497
9498     /**
9499      * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
9500      * comparison between two values to determine if they are equivalent.
9501      *
9502      * @static
9503      * @memberOf _
9504      * @category Lang
9505      * @param {*} value The value to compare.
9506      * @param {*} other The other value to compare.
9507      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9508      * @example
9509      *
9510      * var object = { 'user': 'fred' };
9511      * var other = { 'user': 'fred' };
9512      *
9513      * _.eq(object, object);
9514      * // => true
9515      *
9516      * _.eq(object, other);
9517      * // => false
9518      *
9519      * _.eq('a', 'a');
9520      * // => true
9521      *
9522      * _.eq('a', Object('a'));
9523      * // => false
9524      *
9525      * _.eq(NaN, NaN);
9526      * // => true
9527      */
9528     function eq(value, other) {
9529       return value === other || (value !== value && other !== other);
9530     }
9531
9532     /**
9533      * Checks if `value` is greater than `other`.
9534      *
9535      * @static
9536      * @memberOf _
9537      * @category Lang
9538      * @param {*} value The value to compare.
9539      * @param {*} other The other value to compare.
9540      * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
9541      * @example
9542      *
9543      * _.gt(3, 1);
9544      * // => true
9545      *
9546      * _.gt(3, 3);
9547      * // => false
9548      *
9549      * _.gt(1, 3);
9550      * // => false
9551      */
9552     function gt(value, other) {
9553       return value > other;
9554     }
9555
9556     /**
9557      * Checks if `value` is greater than or equal to `other`.
9558      *
9559      * @static
9560      * @memberOf _
9561      * @category Lang
9562      * @param {*} value The value to compare.
9563      * @param {*} other The other value to compare.
9564      * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
9565      * @example
9566      *
9567      * _.gte(3, 1);
9568      * // => true
9569      *
9570      * _.gte(3, 3);
9571      * // => true
9572      *
9573      * _.gte(1, 3);
9574      * // => false
9575      */
9576     function gte(value, other) {
9577       return value >= other;
9578     }
9579
9580     /**
9581      * Checks if `value` is likely an `arguments` object.
9582      *
9583      * @static
9584      * @memberOf _
9585      * @category Lang
9586      * @param {*} value The value to check.
9587      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9588      * @example
9589      *
9590      * _.isArguments(function() { return arguments; }());
9591      * // => true
9592      *
9593      * _.isArguments([1, 2, 3]);
9594      * // => false
9595      */
9596     function isArguments(value) {
9597       // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
9598       return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
9599         (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
9600     }
9601
9602     /**
9603      * Checks if `value` is classified as an `Array` object.
9604      *
9605      * @static
9606      * @memberOf _
9607      * @type {Function}
9608      * @category Lang
9609      * @param {*} value The value to check.
9610      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9611      * @example
9612      *
9613      * _.isArray([1, 2, 3]);
9614      * // => true
9615      *
9616      * _.isArray(document.body.children);
9617      * // => false
9618      *
9619      * _.isArray('abc');
9620      * // => false
9621      *
9622      * _.isArray(_.noop);
9623      * // => false
9624      */
9625     var isArray = Array.isArray;
9626
9627     /**
9628      * Checks if `value` is classified as an `ArrayBuffer` object.
9629      *
9630      * @static
9631      * @memberOf _
9632      * @category Lang
9633      * @param {*} value The value to check.
9634      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9635      * @example
9636      *
9637      * _.isArrayBuffer(new ArrayBuffer(2));
9638      * // => true
9639      *
9640      * _.isArrayBuffer(new Array(2));
9641      * // => false
9642      */
9643     function isArrayBuffer(value) {
9644       return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
9645     }
9646
9647     /**
9648      * Checks if `value` is array-like. A value is considered array-like if it's
9649      * not a function and has a `value.length` that's an integer greater than or
9650      * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
9651      *
9652      * @static
9653      * @memberOf _
9654      * @category Lang
9655      * @param {*} value The value to check.
9656      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
9657      * @example
9658      *
9659      * _.isArrayLike([1, 2, 3]);
9660      * // => true
9661      *
9662      * _.isArrayLike(document.body.children);
9663      * // => true
9664      *
9665      * _.isArrayLike('abc');
9666      * // => true
9667      *
9668      * _.isArrayLike(_.noop);
9669      * // => false
9670      */
9671     function isArrayLike(value) {
9672       return value != null &&
9673         !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
9674     }
9675
9676     /**
9677      * This method is like `_.isArrayLike` except that it also checks if `value`
9678      * is an object.
9679      *
9680      * @static
9681      * @memberOf _
9682      * @category Lang
9683      * @param {*} value The value to check.
9684      * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
9685      * @example
9686      *
9687      * _.isArrayLikeObject([1, 2, 3]);
9688      * // => true
9689      *
9690      * _.isArrayLikeObject(document.body.children);
9691      * // => true
9692      *
9693      * _.isArrayLikeObject('abc');
9694      * // => false
9695      *
9696      * _.isArrayLikeObject(_.noop);
9697      * // => false
9698      */
9699     function isArrayLikeObject(value) {
9700       return isObjectLike(value) && isArrayLike(value);
9701     }
9702
9703     /**
9704      * Checks if `value` is classified as a boolean primitive or object.
9705      *
9706      * @static
9707      * @memberOf _
9708      * @category Lang
9709      * @param {*} value The value to check.
9710      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9711      * @example
9712      *
9713      * _.isBoolean(false);
9714      * // => true
9715      *
9716      * _.isBoolean(null);
9717      * // => false
9718      */
9719     function isBoolean(value) {
9720       return value === true || value === false ||
9721         (isObjectLike(value) && objectToString.call(value) == boolTag);
9722     }
9723
9724     /**
9725      * Checks if `value` is a buffer.
9726      *
9727      * @static
9728      * @memberOf _
9729      * @category Lang
9730      * @param {*} value The value to check.
9731      * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
9732      * @example
9733      *
9734      * _.isBuffer(new Buffer(2));
9735      * // => true
9736      *
9737      * _.isBuffer(new Uint8Array(2));
9738      * // => false
9739      */
9740     var isBuffer = !Buffer ? constant(false) : function(value) {
9741       return value instanceof Buffer;
9742     };
9743
9744     /**
9745      * Checks if `value` is classified as a `Date` object.
9746      *
9747      * @static
9748      * @memberOf _
9749      * @category Lang
9750      * @param {*} value The value to check.
9751      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9752      * @example
9753      *
9754      * _.isDate(new Date);
9755      * // => true
9756      *
9757      * _.isDate('Mon April 23 2012');
9758      * // => false
9759      */
9760     function isDate(value) {
9761       return isObjectLike(value) && objectToString.call(value) == dateTag;
9762     }
9763
9764     /**
9765      * Checks if `value` is likely a DOM element.
9766      *
9767      * @static
9768      * @memberOf _
9769      * @category Lang
9770      * @param {*} value The value to check.
9771      * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
9772      * @example
9773      *
9774      * _.isElement(document.body);
9775      * // => true
9776      *
9777      * _.isElement('<body>');
9778      * // => false
9779      */
9780     function isElement(value) {
9781       return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
9782     }
9783
9784     /**
9785      * Checks if `value` is empty. A value is considered empty unless it's an
9786      * `arguments` object, array, string, or jQuery-like collection with a length
9787      * greater than `0` or an object with own enumerable properties.
9788      *
9789      * @static
9790      * @memberOf _
9791      * @category Lang
9792      * @param {Array|Object|string} value The value to inspect.
9793      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
9794      * @example
9795      *
9796      * _.isEmpty(null);
9797      * // => true
9798      *
9799      * _.isEmpty(true);
9800      * // => true
9801      *
9802      * _.isEmpty(1);
9803      * // => true
9804      *
9805      * _.isEmpty([1, 2, 3]);
9806      * // => false
9807      *
9808      * _.isEmpty({ 'a': 1 });
9809      * // => false
9810      */
9811     function isEmpty(value) {
9812       if (isArrayLike(value) &&
9813           (isArray(value) || isString(value) ||
9814             isFunction(value.splice) || isArguments(value))) {
9815         return !value.length;
9816       }
9817       for (var key in value) {
9818         if (hasOwnProperty.call(value, key)) {
9819           return false;
9820         }
9821       }
9822       return true;
9823     }
9824
9825     /**
9826      * Performs a deep comparison between two values to determine if they are
9827      * equivalent.
9828      *
9829      * **Note:** This method supports comparing arrays, array buffers, booleans,
9830      * date objects, error objects, maps, numbers, `Object` objects, regexes,
9831      * sets, strings, symbols, and typed arrays. `Object` objects are compared
9832      * by their own, not inherited, enumerable properties. Functions and DOM
9833      * nodes are **not** supported.
9834      *
9835      * @static
9836      * @memberOf _
9837      * @category Lang
9838      * @param {*} value The value to compare.
9839      * @param {*} other The other value to compare.
9840      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9841      * @example
9842      *
9843      * var object = { 'user': 'fred' };
9844      * var other = { 'user': 'fred' };
9845      *
9846      * _.isEqual(object, other);
9847      * // => true
9848      *
9849      * object === other;
9850      * // => false
9851      */
9852     function isEqual(value, other) {
9853       return baseIsEqual(value, other);
9854     }
9855
9856     /**
9857      * This method is like `_.isEqual` except that it accepts `customizer` which
9858      * is invoked to compare values. If `customizer` returns `undefined` comparisons
9859      * are handled by the method instead. The `customizer` is invoked with up to
9860      * six arguments: (objValue, othValue [, index|key, object, other, stack]).
9861      *
9862      * @static
9863      * @memberOf _
9864      * @category Lang
9865      * @param {*} value The value to compare.
9866      * @param {*} other The other value to compare.
9867      * @param {Function} [customizer] The function to customize comparisons.
9868      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9869      * @example
9870      *
9871      * function isGreeting(value) {
9872      *   return /^h(?:i|ello)$/.test(value);
9873      * }
9874      *
9875      * function customizer(objValue, othValue) {
9876      *   if (isGreeting(objValue) && isGreeting(othValue)) {
9877      *     return true;
9878      *   }
9879      * }
9880      *
9881      * var array = ['hello', 'goodbye'];
9882      * var other = ['hi', 'goodbye'];
9883      *
9884      * _.isEqualWith(array, other, customizer);
9885      * // => true
9886      */
9887     function isEqualWith(value, other, customizer) {
9888       customizer = typeof customizer == 'function' ? customizer : undefined;
9889       var result = customizer ? customizer(value, other) : undefined;
9890       return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
9891     }
9892
9893     /**
9894      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
9895      * `SyntaxError`, `TypeError`, or `URIError` object.
9896      *
9897      * @static
9898      * @memberOf _
9899      * @category Lang
9900      * @param {*} value The value to check.
9901      * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
9902      * @example
9903      *
9904      * _.isError(new Error);
9905      * // => true
9906      *
9907      * _.isError(Error);
9908      * // => false
9909      */
9910     function isError(value) {
9911       if (!isObjectLike(value)) {
9912         return false;
9913       }
9914       return (objectToString.call(value) == errorTag) ||
9915         (typeof value.message == 'string' && typeof value.name == 'string');
9916     }
9917
9918     /**
9919      * Checks if `value` is a finite primitive number.
9920      *
9921      * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
9922      *
9923      * @static
9924      * @memberOf _
9925      * @category Lang
9926      * @param {*} value The value to check.
9927      * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
9928      * @example
9929      *
9930      * _.isFinite(3);
9931      * // => true
9932      *
9933      * _.isFinite(Number.MAX_VALUE);
9934      * // => true
9935      *
9936      * _.isFinite(3.14);
9937      * // => true
9938      *
9939      * _.isFinite(Infinity);
9940      * // => false
9941      */
9942     function isFinite(value) {
9943       return typeof value == 'number' && nativeIsFinite(value);
9944     }
9945
9946     /**
9947      * Checks if `value` is classified as a `Function` object.
9948      *
9949      * @static
9950      * @memberOf _
9951      * @category Lang
9952      * @param {*} value The value to check.
9953      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9954      * @example
9955      *
9956      * _.isFunction(_);
9957      * // => true
9958      *
9959      * _.isFunction(/abc/);
9960      * // => false
9961      */
9962     function isFunction(value) {
9963       // The use of `Object#toString` avoids issues with the `typeof` operator
9964       // in Safari 8 which returns 'object' for typed array constructors, and
9965       // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
9966       var tag = isObject(value) ? objectToString.call(value) : '';
9967       return tag == funcTag || tag == genTag;
9968     }
9969
9970     /**
9971      * Checks if `value` is an integer.
9972      *
9973      * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
9974      *
9975      * @static
9976      * @memberOf _
9977      * @category Lang
9978      * @param {*} value The value to check.
9979      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
9980      * @example
9981      *
9982      * _.isInteger(3);
9983      * // => true
9984      *
9985      * _.isInteger(Number.MIN_VALUE);
9986      * // => false
9987      *
9988      * _.isInteger(Infinity);
9989      * // => false
9990      *
9991      * _.isInteger('3');
9992      * // => false
9993      */
9994     function isInteger(value) {
9995       return typeof value == 'number' && value == toInteger(value);
9996     }
9997
9998     /**
9999      * Checks if `value` is a valid array-like length.
10000      *
10001      * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10002      *
10003      * @static
10004      * @memberOf _
10005      * @category Lang
10006      * @param {*} value The value to check.
10007      * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
10008      * @example
10009      *
10010      * _.isLength(3);
10011      * // => true
10012      *
10013      * _.isLength(Number.MIN_VALUE);
10014      * // => false
10015      *
10016      * _.isLength(Infinity);
10017      * // => false
10018      *
10019      * _.isLength('3');
10020      * // => false
10021      */
10022     function isLength(value) {
10023       return typeof value == 'number' &&
10024         value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
10025     }
10026
10027     /**
10028      * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
10029      * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
10030      *
10031      * @static
10032      * @memberOf _
10033      * @category Lang
10034      * @param {*} value The value to check.
10035      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
10036      * @example
10037      *
10038      * _.isObject({});
10039      * // => true
10040      *
10041      * _.isObject([1, 2, 3]);
10042      * // => true
10043      *
10044      * _.isObject(_.noop);
10045      * // => true
10046      *
10047      * _.isObject(null);
10048      * // => false
10049      */
10050     function isObject(value) {
10051       var type = typeof value;
10052       return !!value && (type == 'object' || type == 'function');
10053     }
10054
10055     /**
10056      * Checks if `value` is object-like. A value is object-like if it's not `null`
10057      * and has a `typeof` result of "object".
10058      *
10059      * @static
10060      * @memberOf _
10061      * @category Lang
10062      * @param {*} value The value to check.
10063      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
10064      * @example
10065      *
10066      * _.isObjectLike({});
10067      * // => true
10068      *
10069      * _.isObjectLike([1, 2, 3]);
10070      * // => true
10071      *
10072      * _.isObjectLike(_.noop);
10073      * // => false
10074      *
10075      * _.isObjectLike(null);
10076      * // => false
10077      */
10078     function isObjectLike(value) {
10079       return !!value && typeof value == 'object';
10080     }
10081
10082     /**
10083      * Checks if `value` is classified as a `Map` object.
10084      *
10085      * @static
10086      * @memberOf _
10087      * @category Lang
10088      * @param {*} value The value to check.
10089      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10090      * @example
10091      *
10092      * _.isMap(new Map);
10093      * // => true
10094      *
10095      * _.isMap(new WeakMap);
10096      * // => false
10097      */
10098     function isMap(value) {
10099       return isObjectLike(value) && getTag(value) == mapTag;
10100     }
10101
10102     /**
10103      * Performs a partial deep comparison between `object` and `source` to
10104      * determine if `object` contains equivalent property values. This method is
10105      * equivalent to a `_.matches` function when `source` is partially applied.
10106      *
10107      * **Note:** This method supports comparing the same values as `_.isEqual`.
10108      *
10109      * @static
10110      * @memberOf _
10111      * @category Lang
10112      * @param {Object} object The object to inspect.
10113      * @param {Object} source The object of property values to match.
10114      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
10115      * @example
10116      *
10117      * var object = { 'user': 'fred', 'age': 40 };
10118      *
10119      * _.isMatch(object, { 'age': 40 });
10120      * // => true
10121      *
10122      * _.isMatch(object, { 'age': 36 });
10123      * // => false
10124      */
10125     function isMatch(object, source) {
10126       return object === source || baseIsMatch(object, source, getMatchData(source));
10127     }
10128
10129     /**
10130      * This method is like `_.isMatch` except that it accepts `customizer` which
10131      * is invoked to compare values. If `customizer` returns `undefined` comparisons
10132      * are handled by the method instead. The `customizer` is invoked with five
10133      * arguments: (objValue, srcValue, index|key, object, source).
10134      *
10135      * @static
10136      * @memberOf _
10137      * @category Lang
10138      * @param {Object} object The object to inspect.
10139      * @param {Object} source The object of property values to match.
10140      * @param {Function} [customizer] The function to customize comparisons.
10141      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
10142      * @example
10143      *
10144      * function isGreeting(value) {
10145      *   return /^h(?:i|ello)$/.test(value);
10146      * }
10147      *
10148      * function customizer(objValue, srcValue) {
10149      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
10150      *     return true;
10151      *   }
10152      * }
10153      *
10154      * var object = { 'greeting': 'hello' };
10155      * var source = { 'greeting': 'hi' };
10156      *
10157      * _.isMatchWith(object, source, customizer);
10158      * // => true
10159      */
10160     function isMatchWith(object, source, customizer) {
10161       customizer = typeof customizer == 'function' ? customizer : undefined;
10162       return baseIsMatch(object, source, getMatchData(source), customizer);
10163     }
10164
10165     /**
10166      * Checks if `value` is `NaN`.
10167      *
10168      * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
10169      * which returns `true` for `undefined` and other non-numeric values.
10170      *
10171      * @static
10172      * @memberOf _
10173      * @category Lang
10174      * @param {*} value The value to check.
10175      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
10176      * @example
10177      *
10178      * _.isNaN(NaN);
10179      * // => true
10180      *
10181      * _.isNaN(new Number(NaN));
10182      * // => true
10183      *
10184      * isNaN(undefined);
10185      * // => true
10186      *
10187      * _.isNaN(undefined);
10188      * // => false
10189      */
10190     function isNaN(value) {
10191       // An `NaN` primitive is the only value that is not equal to itself.
10192       // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
10193       return isNumber(value) && value != +value;
10194     }
10195
10196     /**
10197      * Checks if `value` is a native function.
10198      *
10199      * @static
10200      * @memberOf _
10201      * @category Lang
10202      * @param {*} value The value to check.
10203      * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
10204      * @example
10205      *
10206      * _.isNative(Array.prototype.push);
10207      * // => true
10208      *
10209      * _.isNative(_);
10210      * // => false
10211      */
10212     function isNative(value) {
10213       if (value == null) {
10214         return false;
10215       }
10216       if (isFunction(value)) {
10217         return reIsNative.test(funcToString.call(value));
10218       }
10219       return isObjectLike(value) &&
10220         (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
10221     }
10222
10223     /**
10224      * Checks if `value` is `null`.
10225      *
10226      * @static
10227      * @memberOf _
10228      * @category Lang
10229      * @param {*} value The value to check.
10230      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
10231      * @example
10232      *
10233      * _.isNull(null);
10234      * // => true
10235      *
10236      * _.isNull(void 0);
10237      * // => false
10238      */
10239     function isNull(value) {
10240       return value === null;
10241     }
10242
10243     /**
10244      * Checks if `value` is `null` or `undefined`.
10245      *
10246      * @static
10247      * @memberOf _
10248      * @category Lang
10249      * @param {*} value The value to check.
10250      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
10251      * @example
10252      *
10253      * _.isNil(null);
10254      * // => true
10255      *
10256      * _.isNil(void 0);
10257      * // => true
10258      *
10259      * _.isNil(NaN);
10260      * // => false
10261      */
10262     function isNil(value) {
10263       return value == null;
10264     }
10265
10266     /**
10267      * Checks if `value` is classified as a `Number` primitive or object.
10268      *
10269      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
10270      * as numbers, use the `_.isFinite` method.
10271      *
10272      * @static
10273      * @memberOf _
10274      * @category Lang
10275      * @param {*} value The value to check.
10276      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10277      * @example
10278      *
10279      * _.isNumber(3);
10280      * // => true
10281      *
10282      * _.isNumber(Number.MIN_VALUE);
10283      * // => true
10284      *
10285      * _.isNumber(Infinity);
10286      * // => true
10287      *
10288      * _.isNumber('3');
10289      * // => false
10290      */
10291     function isNumber(value) {
10292       return typeof value == 'number' ||
10293         (isObjectLike(value) && objectToString.call(value) == numberTag);
10294     }
10295
10296     /**
10297      * Checks if `value` is a plain object, that is, an object created by the
10298      * `Object` constructor or one with a `[[Prototype]]` of `null`.
10299      *
10300      * @static
10301      * @memberOf _
10302      * @category Lang
10303      * @param {*} value The value to check.
10304      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
10305      * @example
10306      *
10307      * function Foo() {
10308      *   this.a = 1;
10309      * }
10310      *
10311      * _.isPlainObject(new Foo);
10312      * // => false
10313      *
10314      * _.isPlainObject([1, 2, 3]);
10315      * // => false
10316      *
10317      * _.isPlainObject({ 'x': 0, 'y': 0 });
10318      * // => true
10319      *
10320      * _.isPlainObject(Object.create(null));
10321      * // => true
10322      */
10323     function isPlainObject(value) {
10324       if (!isObjectLike(value) ||
10325           objectToString.call(value) != objectTag || isHostObject(value)) {
10326         return false;
10327       }
10328       var proto = getPrototypeOf(value);
10329       if (proto === null) {
10330         return true;
10331       }
10332       var Ctor = proto.constructor;
10333       return (typeof Ctor == 'function' &&
10334         Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
10335     }
10336
10337     /**
10338      * Checks if `value` is classified as a `RegExp` object.
10339      *
10340      * @static
10341      * @memberOf _
10342      * @category Lang
10343      * @param {*} value The value to check.
10344      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10345      * @example
10346      *
10347      * _.isRegExp(/abc/);
10348      * // => true
10349      *
10350      * _.isRegExp('/abc/');
10351      * // => false
10352      */
10353     function isRegExp(value) {
10354       return isObject(value) && objectToString.call(value) == regexpTag;
10355     }
10356
10357     /**
10358      * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
10359      * double precision number which isn't the result of a rounded unsafe integer.
10360      *
10361      * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
10362      *
10363      * @static
10364      * @memberOf _
10365      * @category Lang
10366      * @param {*} value The value to check.
10367      * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
10368      * @example
10369      *
10370      * _.isSafeInteger(3);
10371      * // => true
10372      *
10373      * _.isSafeInteger(Number.MIN_VALUE);
10374      * // => false
10375      *
10376      * _.isSafeInteger(Infinity);
10377      * // => false
10378      *
10379      * _.isSafeInteger('3');
10380      * // => false
10381      */
10382     function isSafeInteger(value) {
10383       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
10384     }
10385
10386     /**
10387      * Checks if `value` is classified as a `Set` object.
10388      *
10389      * @static
10390      * @memberOf _
10391      * @category Lang
10392      * @param {*} value The value to check.
10393      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10394      * @example
10395      *
10396      * _.isSet(new Set);
10397      * // => true
10398      *
10399      * _.isSet(new WeakSet);
10400      * // => false
10401      */
10402     function isSet(value) {
10403       return isObjectLike(value) && getTag(value) == setTag;
10404     }
10405
10406     /**
10407      * Checks if `value` is classified as a `String` primitive or object.
10408      *
10409      * @static
10410      * @memberOf _
10411      * @category Lang
10412      * @param {*} value The value to check.
10413      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10414      * @example
10415      *
10416      * _.isString('abc');
10417      * // => true
10418      *
10419      * _.isString(1);
10420      * // => false
10421      */
10422     function isString(value) {
10423       return typeof value == 'string' ||
10424         (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
10425     }
10426
10427     /**
10428      * Checks if `value` is classified as a `Symbol` primitive or object.
10429      *
10430      * @static
10431      * @memberOf _
10432      * @category Lang
10433      * @param {*} value The value to check.
10434      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10435      * @example
10436      *
10437      * _.isSymbol(Symbol.iterator);
10438      * // => true
10439      *
10440      * _.isSymbol('abc');
10441      * // => false
10442      */
10443     function isSymbol(value) {
10444       return typeof value == 'symbol' ||
10445         (isObjectLike(value) && objectToString.call(value) == symbolTag);
10446     }
10447
10448     /**
10449      * Checks if `value` is classified as a typed array.
10450      *
10451      * @static
10452      * @memberOf _
10453      * @category Lang
10454      * @param {*} value The value to check.
10455      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10456      * @example
10457      *
10458      * _.isTypedArray(new Uint8Array);
10459      * // => true
10460      *
10461      * _.isTypedArray([]);
10462      * // => false
10463      */
10464     function isTypedArray(value) {
10465       return isObjectLike(value) &&
10466         isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
10467     }
10468
10469     /**
10470      * Checks if `value` is `undefined`.
10471      *
10472      * @static
10473      * @memberOf _
10474      * @category Lang
10475      * @param {*} value The value to check.
10476      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
10477      * @example
10478      *
10479      * _.isUndefined(void 0);
10480      * // => true
10481      *
10482      * _.isUndefined(null);
10483      * // => false
10484      */
10485     function isUndefined(value) {
10486       return value === undefined;
10487     }
10488
10489     /**
10490      * Checks if `value` is classified as a `WeakMap` object.
10491      *
10492      * @static
10493      * @memberOf _
10494      * @category Lang
10495      * @param {*} value The value to check.
10496      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10497      * @example
10498      *
10499      * _.isWeakMap(new WeakMap);
10500      * // => true
10501      *
10502      * _.isWeakMap(new Map);
10503      * // => false
10504      */
10505     function isWeakMap(value) {
10506       return isObjectLike(value) && getTag(value) == weakMapTag;
10507     }
10508
10509     /**
10510      * Checks if `value` is classified as a `WeakSet` object.
10511      *
10512      * @static
10513      * @memberOf _
10514      * @category Lang
10515      * @param {*} value The value to check.
10516      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10517      * @example
10518      *
10519      * _.isWeakSet(new WeakSet);
10520      * // => true
10521      *
10522      * _.isWeakSet(new Set);
10523      * // => false
10524      */
10525     function isWeakSet(value) {
10526       return isObjectLike(value) && objectToString.call(value) == weakSetTag;
10527     }
10528
10529     /**
10530      * Checks if `value` is less than `other`.
10531      *
10532      * @static
10533      * @memberOf _
10534      * @category Lang
10535      * @param {*} value The value to compare.
10536      * @param {*} other The other value to compare.
10537      * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
10538      * @example
10539      *
10540      * _.lt(1, 3);
10541      * // => true
10542      *
10543      * _.lt(3, 3);
10544      * // => false
10545      *
10546      * _.lt(3, 1);
10547      * // => false
10548      */
10549     function lt(value, other) {
10550       return value < other;
10551     }
10552
10553     /**
10554      * Checks if `value` is less than or equal to `other`.
10555      *
10556      * @static
10557      * @memberOf _
10558      * @category Lang
10559      * @param {*} value The value to compare.
10560      * @param {*} other The other value to compare.
10561      * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
10562      * @example
10563      *
10564      * _.lte(1, 3);
10565      * // => true
10566      *
10567      * _.lte(3, 3);
10568      * // => true
10569      *
10570      * _.lte(3, 1);
10571      * // => false
10572      */
10573     function lte(value, other) {
10574       return value <= other;
10575     }
10576
10577     /**
10578      * Converts `value` to an array.
10579      *
10580      * @static
10581      * @memberOf _
10582      * @category Lang
10583      * @param {*} value The value to convert.
10584      * @returns {Array} Returns the converted array.
10585      * @example
10586      *
10587      * _.toArray({ 'a': 1, 'b': 2 });
10588      * // => [1, 2]
10589      *
10590      * _.toArray('abc');
10591      * // => ['a', 'b', 'c']
10592      *
10593      * _.toArray(1);
10594      * // => []
10595      *
10596      * _.toArray(null);
10597      * // => []
10598      */
10599     function toArray(value) {
10600       if (!value) {
10601         return [];
10602       }
10603       if (isArrayLike(value)) {
10604         return isString(value) ? stringToArray(value) : copyArray(value);
10605       }
10606       if (iteratorSymbol && value[iteratorSymbol]) {
10607         return iteratorToArray(value[iteratorSymbol]());
10608       }
10609       var tag = getTag(value),
10610           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
10611
10612       return func(value);
10613     }
10614
10615     /**
10616      * Converts `value` to an integer.
10617      *
10618      * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
10619      *
10620      * @static
10621      * @memberOf _
10622      * @category Lang
10623      * @param {*} value The value to convert.
10624      * @returns {number} Returns the converted integer.
10625      * @example
10626      *
10627      * _.toInteger(3);
10628      * // => 3
10629      *
10630      * _.toInteger(Number.MIN_VALUE);
10631      * // => 0
10632      *
10633      * _.toInteger(Infinity);
10634      * // => 1.7976931348623157e+308
10635      *
10636      * _.toInteger('3');
10637      * // => 3
10638      */
10639     function toInteger(value) {
10640       if (!value) {
10641         return value === 0 ? value : 0;
10642       }
10643       value = toNumber(value);
10644       if (value === INFINITY || value === -INFINITY) {
10645         var sign = (value < 0 ? -1 : 1);
10646         return sign * MAX_INTEGER;
10647       }
10648       var remainder = value % 1;
10649       return value === value ? (remainder ? value - remainder : value) : 0;
10650     }
10651
10652     /**
10653      * Converts `value` to an integer suitable for use as the length of an
10654      * array-like object.
10655      *
10656      * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10657      *
10658      * @static
10659      * @memberOf _
10660      * @category Lang
10661      * @param {*} value The value to convert.
10662      * @returns {number} Returns the converted integer.
10663      * @example
10664      *
10665      * _.toLength(3);
10666      * // => 3
10667      *
10668      * _.toLength(Number.MIN_VALUE);
10669      * // => 0
10670      *
10671      * _.toLength(Infinity);
10672      * // => 4294967295
10673      *
10674      * _.toLength('3');
10675      * // => 3
10676      */
10677     function toLength(value) {
10678       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
10679     }
10680
10681     /**
10682      * Converts `value` to a number.
10683      *
10684      * @static
10685      * @memberOf _
10686      * @category Lang
10687      * @param {*} value The value to process.
10688      * @returns {number} Returns the number.
10689      * @example
10690      *
10691      * _.toNumber(3);
10692      * // => 3
10693      *
10694      * _.toNumber(Number.MIN_VALUE);
10695      * // => 5e-324
10696      *
10697      * _.toNumber(Infinity);
10698      * // => Infinity
10699      *
10700      * _.toNumber('3');
10701      * // => 3
10702      */
10703     function toNumber(value) {
10704       if (isObject(value)) {
10705         var other = isFunction(value.valueOf) ? value.valueOf() : value;
10706         value = isObject(other) ? (other + '') : other;
10707       }
10708       if (typeof value != 'string') {
10709         return value === 0 ? value : +value;
10710       }
10711       value = value.replace(reTrim, '');
10712       var isBinary = reIsBinary.test(value);
10713       return (isBinary || reIsOctal.test(value))
10714         ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
10715         : (reIsBadHex.test(value) ? NAN : +value);
10716     }
10717
10718     /**
10719      * Converts `value` to a plain object flattening inherited enumerable
10720      * properties of `value` to own properties of the plain object.
10721      *
10722      * @static
10723      * @memberOf _
10724      * @category Lang
10725      * @param {*} value The value to convert.
10726      * @returns {Object} Returns the converted plain object.
10727      * @example
10728      *
10729      * function Foo() {
10730      *   this.b = 2;
10731      * }
10732      *
10733      * Foo.prototype.c = 3;
10734      *
10735      * _.assign({ 'a': 1 }, new Foo);
10736      * // => { 'a': 1, 'b': 2 }
10737      *
10738      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
10739      * // => { 'a': 1, 'b': 2, 'c': 3 }
10740      */
10741     function toPlainObject(value) {
10742       return copyObject(value, keysIn(value));
10743     }
10744
10745     /**
10746      * Converts `value` to a safe integer. A safe integer can be compared and
10747      * represented correctly.
10748      *
10749      * @static
10750      * @memberOf _
10751      * @category Lang
10752      * @param {*} value The value to convert.
10753      * @returns {number} Returns the converted integer.
10754      * @example
10755      *
10756      * _.toSafeInteger(3);
10757      * // => 3
10758      *
10759      * _.toSafeInteger(Number.MIN_VALUE);
10760      * // => 0
10761      *
10762      * _.toSafeInteger(Infinity);
10763      * // => 9007199254740991
10764      *
10765      * _.toSafeInteger('3');
10766      * // => 3
10767      */
10768     function toSafeInteger(value) {
10769       return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
10770     }
10771
10772     /**
10773      * Converts `value` to a string if it's not one. An empty string is returned
10774      * for `null` and `undefined` values. The sign of `-0` is preserved.
10775      *
10776      * @static
10777      * @memberOf _
10778      * @category Lang
10779      * @param {*} value The value to process.
10780      * @returns {string} Returns the string.
10781      * @example
10782      *
10783      * _.toString(null);
10784      * // => ''
10785      *
10786      * _.toString(-0);
10787      * // => '-0'
10788      *
10789      * _.toString([1, 2, 3]);
10790      * // => '1,2,3'
10791      */
10792     function toString(value) {
10793       // Exit early for strings to avoid a performance hit in some environments.
10794       if (typeof value == 'string') {
10795         return value;
10796       }
10797       if (value == null) {
10798         return '';
10799       }
10800       if (isSymbol(value)) {
10801         return Symbol ? symbolToString.call(value) : '';
10802       }
10803       var result = (value + '');
10804       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
10805     }
10806
10807     /*------------------------------------------------------------------------*/
10808
10809     /**
10810      * Assigns own enumerable properties of source objects to the destination
10811      * object. Source objects are applied from left to right. Subsequent sources
10812      * overwrite property assignments of previous sources.
10813      *
10814      * **Note:** This method mutates `object` and is loosely based on
10815      * [`Object.assign`](https://mdn.io/Object/assign).
10816      *
10817      * @static
10818      * @memberOf _
10819      * @category Object
10820      * @param {Object} object The destination object.
10821      * @param {...Object} [sources] The source objects.
10822      * @returns {Object} Returns `object`.
10823      * @example
10824      *
10825      * function Foo() {
10826      *   this.c = 3;
10827      * }
10828      *
10829      * function Bar() {
10830      *   this.e = 5;
10831      * }
10832      *
10833      * Foo.prototype.d = 4;
10834      * Bar.prototype.f = 6;
10835      *
10836      * _.assign({ 'a': 1 }, new Foo, new Bar);
10837      * // => { 'a': 1, 'c': 3, 'e': 5 }
10838      */
10839     var assign = createAssigner(function(object, source) {
10840       copyObject(source, keys(source), object);
10841     });
10842
10843     /**
10844      * This method is like `_.assign` except that it iterates over own and
10845      * inherited source properties.
10846      *
10847      * **Note:** This method mutates `object`.
10848      *
10849      * @static
10850      * @memberOf _
10851      * @alias extend
10852      * @category Object
10853      * @param {Object} object The destination object.
10854      * @param {...Object} [sources] The source objects.
10855      * @returns {Object} Returns `object`.
10856      * @example
10857      *
10858      * function Foo() {
10859      *   this.b = 2;
10860      * }
10861      *
10862      * function Bar() {
10863      *   this.d = 4;
10864      * }
10865      *
10866      * Foo.prototype.c = 3;
10867      * Bar.prototype.e = 5;
10868      *
10869      * _.assignIn({ 'a': 1 }, new Foo, new Bar);
10870      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
10871      */
10872     var assignIn = createAssigner(function(object, source) {
10873       copyObject(source, keysIn(source), object);
10874     });
10875
10876     /**
10877      * This method is like `_.assignIn` except that it accepts `customizer` which
10878      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10879      * assignment is handled by the method instead. The `customizer` is invoked
10880      * with five arguments: (objValue, srcValue, key, object, source).
10881      *
10882      * **Note:** This method mutates `object`.
10883      *
10884      * @static
10885      * @memberOf _
10886      * @alias extendWith
10887      * @category Object
10888      * @param {Object} object The destination object.
10889      * @param {...Object} sources The source objects.
10890      * @param {Function} [customizer] The function to customize assigned values.
10891      * @returns {Object} Returns `object`.
10892      * @example
10893      *
10894      * function customizer(objValue, srcValue) {
10895      *   return _.isUndefined(objValue) ? srcValue : objValue;
10896      * }
10897      *
10898      * var defaults = _.partialRight(_.assignInWith, customizer);
10899      *
10900      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10901      * // => { 'a': 1, 'b': 2 }
10902      */
10903     var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
10904       copyObjectWith(source, keysIn(source), object, customizer);
10905     });
10906
10907     /**
10908      * This method is like `_.assign` except that it accepts `customizer` which
10909      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10910      * assignment is handled by the method instead. The `customizer` is invoked
10911      * with five arguments: (objValue, srcValue, key, object, source).
10912      *
10913      * **Note:** This method mutates `object`.
10914      *
10915      * @static
10916      * @memberOf _
10917      * @category Object
10918      * @param {Object} object The destination object.
10919      * @param {...Object} sources The source objects.
10920      * @param {Function} [customizer] The function to customize assigned values.
10921      * @returns {Object} Returns `object`.
10922      * @example
10923      *
10924      * function customizer(objValue, srcValue) {
10925      *   return _.isUndefined(objValue) ? srcValue : objValue;
10926      * }
10927      *
10928      * var defaults = _.partialRight(_.assignWith, customizer);
10929      *
10930      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10931      * // => { 'a': 1, 'b': 2 }
10932      */
10933     var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
10934       copyObjectWith(source, keys(source), object, customizer);
10935     });
10936
10937     /**
10938      * Creates an array of values corresponding to `paths` of `object`.
10939      *
10940      * @static
10941      * @memberOf _
10942      * @category Object
10943      * @param {Object} object The object to iterate over.
10944      * @param {...(string|string[])} [paths] The property paths of elements to pick,
10945      *  specified individually or in arrays.
10946      * @returns {Array} Returns the new array of picked elements.
10947      * @example
10948      *
10949      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
10950      *
10951      * _.at(object, ['a[0].b.c', 'a[1]']);
10952      * // => [3, 4]
10953      *
10954      * _.at(['a', 'b', 'c'], 0, 2);
10955      * // => ['a', 'c']
10956      */
10957     var at = rest(function(object, paths) {
10958       return baseAt(object, baseFlatten(paths, 1));
10959     });
10960
10961     /**
10962      * Creates an object that inherits from the `prototype` object. If a `properties`
10963      * object is given its own enumerable properties are assigned to the created object.
10964      *
10965      * @static
10966      * @memberOf _
10967      * @category Object
10968      * @param {Object} prototype The object to inherit from.
10969      * @param {Object} [properties] The properties to assign to the object.
10970      * @returns {Object} Returns the new object.
10971      * @example
10972      *
10973      * function Shape() {
10974      *   this.x = 0;
10975      *   this.y = 0;
10976      * }
10977      *
10978      * function Circle() {
10979      *   Shape.call(this);
10980      * }
10981      *
10982      * Circle.prototype = _.create(Shape.prototype, {
10983      *   'constructor': Circle
10984      * });
10985      *
10986      * var circle = new Circle;
10987      * circle instanceof Circle;
10988      * // => true
10989      *
10990      * circle instanceof Shape;
10991      * // => true
10992      */
10993     function create(prototype, properties) {
10994       var result = baseCreate(prototype);
10995       return properties ? baseAssign(result, properties) : result;
10996     }
10997
10998     /**
10999      * Assigns own and inherited enumerable properties of source objects to the
11000      * destination object for all destination properties that resolve to `undefined`.
11001      * Source objects are applied from left to right. Once a property is set,
11002      * additional values of the same property are ignored.
11003      *
11004      * **Note:** This method mutates `object`.
11005      *
11006      * @static
11007      * @memberOf _
11008      * @category Object
11009      * @param {Object} object The destination object.
11010      * @param {...Object} [sources] The source objects.
11011      * @returns {Object} Returns `object`.
11012      * @example
11013      *
11014      * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
11015      * // => { 'user': 'barney', 'age': 36 }
11016      */
11017     var defaults = rest(function(args) {
11018       args.push(undefined, assignInDefaults);
11019       return apply(assignInWith, undefined, args);
11020     });
11021
11022     /**
11023      * This method is like `_.defaults` except that it recursively assigns
11024      * default properties.
11025      *
11026      * **Note:** This method mutates `object`.
11027      *
11028      * @static
11029      * @memberOf _
11030      * @category Object
11031      * @param {Object} object The destination object.
11032      * @param {...Object} [sources] The source objects.
11033      * @returns {Object} Returns `object`.
11034      * @example
11035      *
11036      * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
11037      * // => { 'user': { 'name': 'barney', 'age': 36 } }
11038      *
11039      */
11040     var defaultsDeep = rest(function(args) {
11041       args.push(undefined, mergeDefaults);
11042       return apply(mergeWith, undefined, args);
11043     });
11044
11045     /**
11046      * This method is like `_.find` except that it returns the key of the first
11047      * element `predicate` returns truthy for instead of the element itself.
11048      *
11049      * @static
11050      * @memberOf _
11051      * @category Object
11052      * @param {Object} object The object to search.
11053      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
11054      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
11055      * @example
11056      *
11057      * var users = {
11058      *   'barney':  { 'age': 36, 'active': true },
11059      *   'fred':    { 'age': 40, 'active': false },
11060      *   'pebbles': { 'age': 1,  'active': true }
11061      * };
11062      *
11063      * _.findKey(users, function(o) { return o.age < 40; });
11064      * // => 'barney' (iteration order is not guaranteed)
11065      *
11066      * // The `_.matches` iteratee shorthand.
11067      * _.findKey(users, { 'age': 1, 'active': true });
11068      * // => 'pebbles'
11069      *
11070      * // The `_.matchesProperty` iteratee shorthand.
11071      * _.findKey(users, ['active', false]);
11072      * // => 'fred'
11073      *
11074      * // The `_.property` iteratee shorthand.
11075      * _.findKey(users, 'active');
11076      * // => 'barney'
11077      */
11078     function findKey(object, predicate) {
11079       return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
11080     }
11081
11082     /**
11083      * This method is like `_.findKey` except that it iterates over elements of
11084      * a collection in the opposite order.
11085      *
11086      * @static
11087      * @memberOf _
11088      * @category Object
11089      * @param {Object} object The object to search.
11090      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
11091      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
11092      * @example
11093      *
11094      * var users = {
11095      *   'barney':  { 'age': 36, 'active': true },
11096      *   'fred':    { 'age': 40, 'active': false },
11097      *   'pebbles': { 'age': 1,  'active': true }
11098      * };
11099      *
11100      * _.findLastKey(users, function(o) { return o.age < 40; });
11101      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
11102      *
11103      * // The `_.matches` iteratee shorthand.
11104      * _.findLastKey(users, { 'age': 36, 'active': true });
11105      * // => 'barney'
11106      *
11107      * // The `_.matchesProperty` iteratee shorthand.
11108      * _.findLastKey(users, ['active', false]);
11109      * // => 'fred'
11110      *
11111      * // The `_.property` iteratee shorthand.
11112      * _.findLastKey(users, 'active');
11113      * // => 'pebbles'
11114      */
11115     function findLastKey(object, predicate) {
11116       return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
11117     }
11118
11119     /**
11120      * Iterates over own and inherited enumerable properties of an object invoking
11121      * `iteratee` for each property. The iteratee is invoked with three arguments:
11122      * (value, key, object). Iteratee functions may exit iteration early by explicitly
11123      * returning `false`.
11124      *
11125      * @static
11126      * @memberOf _
11127      * @category Object
11128      * @param {Object} object The object to iterate over.
11129      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11130      * @returns {Object} Returns `object`.
11131      * @example
11132      *
11133      * function Foo() {
11134      *   this.a = 1;
11135      *   this.b = 2;
11136      * }
11137      *
11138      * Foo.prototype.c = 3;
11139      *
11140      * _.forIn(new Foo, function(value, key) {
11141      *   console.log(key);
11142      * });
11143      * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
11144      */
11145     function forIn(object, iteratee) {
11146       return object == null
11147         ? object
11148         : baseFor(object, baseCastFunction(iteratee), keysIn);
11149     }
11150
11151     /**
11152      * This method is like `_.forIn` except that it iterates over properties of
11153      * `object` in the opposite order.
11154      *
11155      * @static
11156      * @memberOf _
11157      * @category Object
11158      * @param {Object} object The object to iterate over.
11159      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11160      * @returns {Object} Returns `object`.
11161      * @example
11162      *
11163      * function Foo() {
11164      *   this.a = 1;
11165      *   this.b = 2;
11166      * }
11167      *
11168      * Foo.prototype.c = 3;
11169      *
11170      * _.forInRight(new Foo, function(value, key) {
11171      *   console.log(key);
11172      * });
11173      * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
11174      */
11175     function forInRight(object, iteratee) {
11176       return object == null
11177         ? object
11178         : baseForRight(object, baseCastFunction(iteratee), keysIn);
11179     }
11180
11181     /**
11182      * Iterates over own enumerable properties of an object invoking `iteratee`
11183      * for each property. The iteratee is invoked with three arguments:
11184      * (value, key, object). Iteratee functions may exit iteration early by
11185      * explicitly returning `false`.
11186      *
11187      * @static
11188      * @memberOf _
11189      * @category Object
11190      * @param {Object} object The object to iterate over.
11191      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11192      * @returns {Object} Returns `object`.
11193      * @example
11194      *
11195      * function Foo() {
11196      *   this.a = 1;
11197      *   this.b = 2;
11198      * }
11199      *
11200      * Foo.prototype.c = 3;
11201      *
11202      * _.forOwn(new Foo, function(value, key) {
11203      *   console.log(key);
11204      * });
11205      * // => logs 'a' then 'b' (iteration order is not guaranteed)
11206      */
11207     function forOwn(object, iteratee) {
11208       return object && baseForOwn(object, baseCastFunction(iteratee));
11209     }
11210
11211     /**
11212      * This method is like `_.forOwn` except that it iterates over properties of
11213      * `object` in the opposite order.
11214      *
11215      * @static
11216      * @memberOf _
11217      * @category Object
11218      * @param {Object} object The object to iterate over.
11219      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11220      * @returns {Object} Returns `object`.
11221      * @example
11222      *
11223      * function Foo() {
11224      *   this.a = 1;
11225      *   this.b = 2;
11226      * }
11227      *
11228      * Foo.prototype.c = 3;
11229      *
11230      * _.forOwnRight(new Foo, function(value, key) {
11231      *   console.log(key);
11232      * });
11233      * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
11234      */
11235     function forOwnRight(object, iteratee) {
11236       return object && baseForOwnRight(object, baseCastFunction(iteratee));
11237     }
11238
11239     /**
11240      * Creates an array of function property names from own enumerable properties
11241      * of `object`.
11242      *
11243      * @static
11244      * @memberOf _
11245      * @category Object
11246      * @param {Object} object The object to inspect.
11247      * @returns {Array} Returns the new array of property names.
11248      * @example
11249      *
11250      * function Foo() {
11251      *   this.a = _.constant('a');
11252      *   this.b = _.constant('b');
11253      * }
11254      *
11255      * Foo.prototype.c = _.constant('c');
11256      *
11257      * _.functions(new Foo);
11258      * // => ['a', 'b']
11259      */
11260     function functions(object) {
11261       return object == null ? [] : baseFunctions(object, keys(object));
11262     }
11263
11264     /**
11265      * Creates an array of function property names from own and inherited
11266      * enumerable properties of `object`.
11267      *
11268      * @static
11269      * @memberOf _
11270      * @category Object
11271      * @param {Object} object The object to inspect.
11272      * @returns {Array} Returns the new array of property names.
11273      * @example
11274      *
11275      * function Foo() {
11276      *   this.a = _.constant('a');
11277      *   this.b = _.constant('b');
11278      * }
11279      *
11280      * Foo.prototype.c = _.constant('c');
11281      *
11282      * _.functionsIn(new Foo);
11283      * // => ['a', 'b', 'c']
11284      */
11285     function functionsIn(object) {
11286       return object == null ? [] : baseFunctions(object, keysIn(object));
11287     }
11288
11289     /**
11290      * Gets the value at `path` of `object`. If the resolved value is
11291      * `undefined` the `defaultValue` is used in its place.
11292      *
11293      * @static
11294      * @memberOf _
11295      * @category Object
11296      * @param {Object} object The object to query.
11297      * @param {Array|string} path The path of the property to get.
11298      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11299      * @returns {*} Returns the resolved value.
11300      * @example
11301      *
11302      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11303      *
11304      * _.get(object, 'a[0].b.c');
11305      * // => 3
11306      *
11307      * _.get(object, ['a', '0', 'b', 'c']);
11308      * // => 3
11309      *
11310      * _.get(object, 'a.b.c', 'default');
11311      * // => 'default'
11312      */
11313     function get(object, path, defaultValue) {
11314       var result = object == null ? undefined : baseGet(object, path);
11315       return result === undefined ? defaultValue : result;
11316     }
11317
11318     /**
11319      * Checks if `path` is a direct property of `object`.
11320      *
11321      * @static
11322      * @memberOf _
11323      * @category Object
11324      * @param {Object} object The object to query.
11325      * @param {Array|string} path The path to check.
11326      * @returns {boolean} Returns `true` if `path` exists, else `false`.
11327      * @example
11328      *
11329      * var object = { 'a': { 'b': { 'c': 3 } } };
11330      * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
11331      *
11332      * _.has(object, 'a');
11333      * // => true
11334      *
11335      * _.has(object, 'a.b.c');
11336      * // => true
11337      *
11338      * _.has(object, ['a', 'b', 'c']);
11339      * // => true
11340      *
11341      * _.has(other, 'a');
11342      * // => false
11343      */
11344     function has(object, path) {
11345       return hasPath(object, path, baseHas);
11346     }
11347
11348     /**
11349      * Checks if `path` is a direct or inherited property of `object`.
11350      *
11351      * @static
11352      * @memberOf _
11353      * @category Object
11354      * @param {Object} object The object to query.
11355      * @param {Array|string} path The path to check.
11356      * @returns {boolean} Returns `true` if `path` exists, else `false`.
11357      * @example
11358      *
11359      * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
11360      *
11361      * _.hasIn(object, 'a');
11362      * // => true
11363      *
11364      * _.hasIn(object, 'a.b.c');
11365      * // => true
11366      *
11367      * _.hasIn(object, ['a', 'b', 'c']);
11368      * // => true
11369      *
11370      * _.hasIn(object, 'b');
11371      * // => false
11372      */
11373     function hasIn(object, path) {
11374       return hasPath(object, path, baseHasIn);
11375     }
11376
11377     /**
11378      * Creates an object composed of the inverted keys and values of `object`.
11379      * If `object` contains duplicate values, subsequent values overwrite property
11380      * assignments of previous values.
11381      *
11382      * @static
11383      * @memberOf _
11384      * @category Object
11385      * @param {Object} object The object to invert.
11386      * @returns {Object} Returns the new inverted object.
11387      * @example
11388      *
11389      * var object = { 'a': 1, 'b': 2, 'c': 1 };
11390      *
11391      * _.invert(object);
11392      * // => { '1': 'c', '2': 'b' }
11393      */
11394     var invert = createInverter(function(result, value, key) {
11395       result[value] = key;
11396     }, constant(identity));
11397
11398     /**
11399      * This method is like `_.invert` except that the inverted object is generated
11400      * from the results of running each element of `object` through `iteratee`.
11401      * The corresponding inverted value of each inverted key is an array of keys
11402      * responsible for generating the inverted value. The iteratee is invoked
11403      * with one argument: (value).
11404      *
11405      * @static
11406      * @memberOf _
11407      * @category Object
11408      * @param {Object} object The object to invert.
11409      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
11410      * @returns {Object} Returns the new inverted object.
11411      * @example
11412      *
11413      * var object = { 'a': 1, 'b': 2, 'c': 1 };
11414      *
11415      * _.invertBy(object);
11416      * // => { '1': ['a', 'c'], '2': ['b'] }
11417      *
11418      * _.invertBy(object, function(value) {
11419      *   return 'group' + value;
11420      * });
11421      * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
11422      */
11423     var invertBy = createInverter(function(result, value, key) {
11424       if (hasOwnProperty.call(result, value)) {
11425         result[value].push(key);
11426       } else {
11427         result[value] = [key];
11428       }
11429     }, getIteratee);
11430
11431     /**
11432      * Invokes the method at `path` of `object`.
11433      *
11434      * @static
11435      * @memberOf _
11436      * @category Object
11437      * @param {Object} object The object to query.
11438      * @param {Array|string} path The path of the method to invoke.
11439      * @param {...*} [args] The arguments to invoke the method with.
11440      * @returns {*} Returns the result of the invoked method.
11441      * @example
11442      *
11443      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
11444      *
11445      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
11446      * // => [2, 3]
11447      */
11448     var invoke = rest(baseInvoke);
11449
11450     /**
11451      * Creates an array of the own enumerable property names of `object`.
11452      *
11453      * **Note:** Non-object values are coerced to objects. See the
11454      * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
11455      * for more details.
11456      *
11457      * @static
11458      * @memberOf _
11459      * @category Object
11460      * @param {Object} object The object to query.
11461      * @returns {Array} Returns the array of property names.
11462      * @example
11463      *
11464      * function Foo() {
11465      *   this.a = 1;
11466      *   this.b = 2;
11467      * }
11468      *
11469      * Foo.prototype.c = 3;
11470      *
11471      * _.keys(new Foo);
11472      * // => ['a', 'b'] (iteration order is not guaranteed)
11473      *
11474      * _.keys('hi');
11475      * // => ['0', '1']
11476      */
11477     function keys(object) {
11478       var isProto = isPrototype(object);
11479       if (!(isProto || isArrayLike(object))) {
11480         return baseKeys(object);
11481       }
11482       var indexes = indexKeys(object),
11483           skipIndexes = !!indexes,
11484           result = indexes || [],
11485           length = result.length;
11486
11487       for (var key in object) {
11488         if (baseHas(object, key) &&
11489             !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11490             !(isProto && key == 'constructor')) {
11491           result.push(key);
11492         }
11493       }
11494       return result;
11495     }
11496
11497     /**
11498      * Creates an array of the own and inherited enumerable property names of `object`.
11499      *
11500      * **Note:** Non-object values are coerced to objects.
11501      *
11502      * @static
11503      * @memberOf _
11504      * @category Object
11505      * @param {Object} object The object to query.
11506      * @returns {Array} Returns the array of property names.
11507      * @example
11508      *
11509      * function Foo() {
11510      *   this.a = 1;
11511      *   this.b = 2;
11512      * }
11513      *
11514      * Foo.prototype.c = 3;
11515      *
11516      * _.keysIn(new Foo);
11517      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
11518      */
11519     function keysIn(object) {
11520       var index = -1,
11521           isProto = isPrototype(object),
11522           props = baseKeysIn(object),
11523           propsLength = props.length,
11524           indexes = indexKeys(object),
11525           skipIndexes = !!indexes,
11526           result = indexes || [],
11527           length = result.length;
11528
11529       while (++index < propsLength) {
11530         var key = props[index];
11531         if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11532             !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
11533           result.push(key);
11534         }
11535       }
11536       return result;
11537     }
11538
11539     /**
11540      * The opposite of `_.mapValues`; this method creates an object with the
11541      * same values as `object` and keys generated by running each own enumerable
11542      * property of `object` through `iteratee`. The iteratee is invoked with
11543      * three arguments: (value, key, object).
11544      *
11545      * @static
11546      * @memberOf _
11547      * @category Object
11548      * @param {Object} object The object to iterate over.
11549      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11550      * @returns {Object} Returns the new mapped object.
11551      * @example
11552      *
11553      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
11554      *   return key + value;
11555      * });
11556      * // => { 'a1': 1, 'b2': 2 }
11557      */
11558     function mapKeys(object, iteratee) {
11559       var result = {};
11560       iteratee = getIteratee(iteratee, 3);
11561
11562       baseForOwn(object, function(value, key, object) {
11563         result[iteratee(value, key, object)] = value;
11564       });
11565       return result;
11566     }
11567
11568     /**
11569      * Creates an object with the same keys as `object` and values generated by
11570      * running each own enumerable property of `object` through `iteratee`. The
11571      * iteratee is invoked with three arguments: (value, key, object).
11572      *
11573      * @static
11574      * @memberOf _
11575      * @category Object
11576      * @param {Object} object The object to iterate over.
11577      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11578      * @returns {Object} Returns the new mapped object.
11579      * @example
11580      *
11581      * var users = {
11582      *   'fred':    { 'user': 'fred',    'age': 40 },
11583      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
11584      * };
11585      *
11586      * _.mapValues(users, function(o) { return o.age; });
11587      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11588      *
11589      * // The `_.property` iteratee shorthand.
11590      * _.mapValues(users, 'age');
11591      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11592      */
11593     function mapValues(object, iteratee) {
11594       var result = {};
11595       iteratee = getIteratee(iteratee, 3);
11596
11597       baseForOwn(object, function(value, key, object) {
11598         result[key] = iteratee(value, key, object);
11599       });
11600       return result;
11601     }
11602
11603     /**
11604      * Recursively merges own and inherited enumerable properties of source objects
11605      * into the destination object. Source properties that resolve to `undefined`
11606      * are skipped if a destination value exists. Array and plain object properties
11607      * are merged recursively. Other objects and value types are overridden by
11608      * assignment. Source objects are applied from left to right. Subsequent
11609      * sources overwrite property assignments of previous sources.
11610      *
11611      * **Note:** This method mutates `object`.
11612      *
11613      * @static
11614      * @memberOf _
11615      * @category Object
11616      * @param {Object} object The destination object.
11617      * @param {...Object} [sources] The source objects.
11618      * @returns {Object} Returns `object`.
11619      * @example
11620      *
11621      * var users = {
11622      *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
11623      * };
11624      *
11625      * var ages = {
11626      *   'data': [{ 'age': 36 }, { 'age': 40 }]
11627      * };
11628      *
11629      * _.merge(users, ages);
11630      * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
11631      */
11632     var merge = createAssigner(function(object, source, srcIndex) {
11633       baseMerge(object, source, srcIndex);
11634     });
11635
11636     /**
11637      * This method is like `_.merge` except that it accepts `customizer` which
11638      * is invoked to produce the merged values of the destination and source
11639      * properties. If `customizer` returns `undefined` merging is handled by the
11640      * method instead. The `customizer` is invoked with seven arguments:
11641      * (objValue, srcValue, key, object, source, stack).
11642      *
11643      * **Note:** This method mutates `object`.
11644      *
11645      * @static
11646      * @memberOf _
11647      * @category Object
11648      * @param {Object} object The destination object.
11649      * @param {...Object} sources The source objects.
11650      * @param {Function} customizer The function to customize assigned values.
11651      * @returns {Object} Returns `object`.
11652      * @example
11653      *
11654      * function customizer(objValue, srcValue) {
11655      *   if (_.isArray(objValue)) {
11656      *     return objValue.concat(srcValue);
11657      *   }
11658      * }
11659      *
11660      * var object = {
11661      *   'fruits': ['apple'],
11662      *   'vegetables': ['beet']
11663      * };
11664      *
11665      * var other = {
11666      *   'fruits': ['banana'],
11667      *   'vegetables': ['carrot']
11668      * };
11669      *
11670      * _.mergeWith(object, other, customizer);
11671      * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
11672      */
11673     var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
11674       baseMerge(object, source, srcIndex, customizer);
11675     });
11676
11677     /**
11678      * The opposite of `_.pick`; this method creates an object composed of the
11679      * own and inherited enumerable properties of `object` that are not omitted.
11680      *
11681      * @static
11682      * @memberOf _
11683      * @category Object
11684      * @param {Object} object The source object.
11685      * @param {...(string|string[])} [props] The property names to omit, specified
11686      *  individually or in arrays.
11687      * @returns {Object} Returns the new object.
11688      * @example
11689      *
11690      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11691      *
11692      * _.omit(object, ['a', 'c']);
11693      * // => { 'b': '2' }
11694      */
11695     var omit = rest(function(object, props) {
11696       if (object == null) {
11697         return {};
11698       }
11699       props = arrayMap(baseFlatten(props, 1), String);
11700       return basePick(object, baseDifference(keysIn(object), props));
11701     });
11702
11703     /**
11704      * The opposite of `_.pickBy`; this method creates an object composed of
11705      * the own and inherited enumerable properties of `object` that `predicate`
11706      * doesn't return truthy for. The predicate is invoked with two arguments:
11707      * (value, key).
11708      *
11709      * @static
11710      * @memberOf _
11711      * @category Object
11712      * @param {Object} object The source object.
11713      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11714      * @returns {Object} Returns the new object.
11715      * @example
11716      *
11717      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11718      *
11719      * _.omitBy(object, _.isNumber);
11720      * // => { 'b': '2' }
11721      */
11722     function omitBy(object, predicate) {
11723       predicate = getIteratee(predicate);
11724       return basePickBy(object, function(value, key) {
11725         return !predicate(value, key);
11726       });
11727     }
11728
11729     /**
11730      * Creates an object composed of the picked `object` properties.
11731      *
11732      * @static
11733      * @memberOf _
11734      * @category Object
11735      * @param {Object} object The source object.
11736      * @param {...(string|string[])} [props] The property names to pick, specified
11737      *  individually or in arrays.
11738      * @returns {Object} Returns the new object.
11739      * @example
11740      *
11741      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11742      *
11743      * _.pick(object, ['a', 'c']);
11744      * // => { 'a': 1, 'c': 3 }
11745      */
11746     var pick = rest(function(object, props) {
11747       return object == null ? {} : basePick(object, baseFlatten(props, 1));
11748     });
11749
11750     /**
11751      * Creates an object composed of the `object` properties `predicate` returns
11752      * truthy for. The predicate is invoked with two arguments: (value, key).
11753      *
11754      * @static
11755      * @memberOf _
11756      * @category Object
11757      * @param {Object} object The source object.
11758      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11759      * @returns {Object} Returns the new object.
11760      * @example
11761      *
11762      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11763      *
11764      * _.pickBy(object, _.isNumber);
11765      * // => { 'a': 1, 'c': 3 }
11766      */
11767     function pickBy(object, predicate) {
11768       return object == null ? {} : basePickBy(object, getIteratee(predicate));
11769     }
11770
11771     /**
11772      * This method is like `_.get` except that if the resolved value is a function
11773      * it's invoked with the `this` binding of its parent object and its result
11774      * is returned.
11775      *
11776      * @static
11777      * @memberOf _
11778      * @category Object
11779      * @param {Object} object The object to query.
11780      * @param {Array|string} path The path of the property to resolve.
11781      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11782      * @returns {*} Returns the resolved value.
11783      * @example
11784      *
11785      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
11786      *
11787      * _.result(object, 'a[0].b.c1');
11788      * // => 3
11789      *
11790      * _.result(object, 'a[0].b.c2');
11791      * // => 4
11792      *
11793      * _.result(object, 'a[0].b.c3', 'default');
11794      * // => 'default'
11795      *
11796      * _.result(object, 'a[0].b.c3', _.constant('default'));
11797      * // => 'default'
11798      */
11799     function result(object, path, defaultValue) {
11800       if (!isKey(path, object)) {
11801         path = baseCastPath(path);
11802         var result = get(object, path);
11803         object = parent(object, path);
11804       } else {
11805         result = object == null ? undefined : object[path];
11806       }
11807       if (result === undefined) {
11808         result = defaultValue;
11809       }
11810       return isFunction(result) ? result.call(object) : result;
11811     }
11812
11813     /**
11814      * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
11815      * it's created. Arrays are created for missing index properties while objects
11816      * are created for all other missing properties. Use `_.setWith` to customize
11817      * `path` creation.
11818      *
11819      * **Note:** This method mutates `object`.
11820      *
11821      * @static
11822      * @memberOf _
11823      * @category Object
11824      * @param {Object} object The object to modify.
11825      * @param {Array|string} path The path of the property to set.
11826      * @param {*} value The value to set.
11827      * @returns {Object} Returns `object`.
11828      * @example
11829      *
11830      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11831      *
11832      * _.set(object, 'a[0].b.c', 4);
11833      * console.log(object.a[0].b.c);
11834      * // => 4
11835      *
11836      * _.set(object, 'x[0].y.z', 5);
11837      * console.log(object.x[0].y.z);
11838      * // => 5
11839      */
11840     function set(object, path, value) {
11841       return object == null ? object : baseSet(object, path, value);
11842     }
11843
11844     /**
11845      * This method is like `_.set` except that it accepts `customizer` which is
11846      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
11847      * path creation is handled by the method instead. The `customizer` is invoked
11848      * with three arguments: (nsValue, key, nsObject).
11849      *
11850      * **Note:** This method mutates `object`.
11851      *
11852      * @static
11853      * @memberOf _
11854      * @category Object
11855      * @param {Object} object The object to modify.
11856      * @param {Array|string} path The path of the property to set.
11857      * @param {*} value The value to set.
11858      * @param {Function} [customizer] The function to customize assigned values.
11859      * @returns {Object} Returns `object`.
11860      * @example
11861      *
11862      * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
11863      * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
11864      */
11865     function setWith(object, path, value, customizer) {
11866       customizer = typeof customizer == 'function' ? customizer : undefined;
11867       return object == null ? object : baseSet(object, path, value, customizer);
11868     }
11869
11870     /**
11871      * Creates an array of own enumerable key-value pairs for `object` which
11872      * can be consumed by `_.fromPairs`.
11873      *
11874      * @static
11875      * @memberOf _
11876      * @category Object
11877      * @param {Object} object The object to query.
11878      * @returns {Array} Returns the new array of key-value pairs.
11879      * @example
11880      *
11881      * function Foo() {
11882      *   this.a = 1;
11883      *   this.b = 2;
11884      * }
11885      *
11886      * Foo.prototype.c = 3;
11887      *
11888      * _.toPairs(new Foo);
11889      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
11890      */
11891     function toPairs(object) {
11892       return baseToPairs(object, keys(object));
11893     }
11894
11895     /**
11896      * Creates an array of own and inherited enumerable key-value pairs for
11897      * `object` which can be consumed by `_.fromPairs`.
11898      *
11899      * @static
11900      * @memberOf _
11901      * @category Object
11902      * @param {Object} object The object to query.
11903      * @returns {Array} Returns the new array of key-value pairs.
11904      * @example
11905      *
11906      * function Foo() {
11907      *   this.a = 1;
11908      *   this.b = 2;
11909      * }
11910      *
11911      * Foo.prototype.c = 3;
11912      *
11913      * _.toPairsIn(new Foo);
11914      * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
11915      */
11916     function toPairsIn(object) {
11917       return baseToPairs(object, keysIn(object));
11918     }
11919
11920     /**
11921      * An alternative to `_.reduce`; this method transforms `object` to a new
11922      * `accumulator` object which is the result of running each of its own enumerable
11923      * properties through `iteratee`, with each invocation potentially mutating
11924      * the `accumulator` object. The iteratee is invoked with four arguments:
11925      * (accumulator, value, key, object). Iteratee functions may exit iteration
11926      * early by explicitly returning `false`.
11927      *
11928      * @static
11929      * @memberOf _
11930      * @category Object
11931      * @param {Array|Object} object The object to iterate over.
11932      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11933      * @param {*} [accumulator] The custom accumulator value.
11934      * @returns {*} Returns the accumulated value.
11935      * @example
11936      *
11937      * _.transform([2, 3, 4], function(result, n) {
11938      *   result.push(n *= n);
11939      *   return n % 2 == 0;
11940      * }, []);
11941      * // => [4, 9]
11942      *
11943      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
11944      *   (result[value] || (result[value] = [])).push(key);
11945      * }, {});
11946      * // => { '1': ['a', 'c'], '2': ['b'] }
11947      */
11948     function transform(object, iteratee, accumulator) {
11949       var isArr = isArray(object) || isTypedArray(object);
11950       iteratee = getIteratee(iteratee, 4);
11951
11952       if (accumulator == null) {
11953         if (isArr || isObject(object)) {
11954           var Ctor = object.constructor;
11955           if (isArr) {
11956             accumulator = isArray(object) ? new Ctor : [];
11957           } else {
11958             accumulator = isFunction(Ctor) ? baseCreate(getPrototypeOf(object)) : {};
11959           }
11960         } else {
11961           accumulator = {};
11962         }
11963       }
11964       (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
11965         return iteratee(accumulator, value, index, object);
11966       });
11967       return accumulator;
11968     }
11969
11970     /**
11971      * Removes the property at `path` of `object`.
11972      *
11973      * **Note:** This method mutates `object`.
11974      *
11975      * @static
11976      * @memberOf _
11977      * @category Object
11978      * @param {Object} object The object to modify.
11979      * @param {Array|string} path The path of the property to unset.
11980      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
11981      * @example
11982      *
11983      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
11984      * _.unset(object, 'a[0].b.c');
11985      * // => true
11986      *
11987      * console.log(object);
11988      * // => { 'a': [{ 'b': {} }] };
11989      *
11990      * _.unset(object, 'a[0].b.c');
11991      * // => true
11992      *
11993      * console.log(object);
11994      * // => { 'a': [{ 'b': {} }] };
11995      */
11996     function unset(object, path) {
11997       return object == null ? true : baseUnset(object, path);
11998     }
11999
12000     /**
12001      * Creates an array of the own enumerable property values of `object`.
12002      *
12003      * **Note:** Non-object values are coerced to objects.
12004      *
12005      * @static
12006      * @memberOf _
12007      * @category Object
12008      * @param {Object} object The object to query.
12009      * @returns {Array} Returns the array of property values.
12010      * @example
12011      *
12012      * function Foo() {
12013      *   this.a = 1;
12014      *   this.b = 2;
12015      * }
12016      *
12017      * Foo.prototype.c = 3;
12018      *
12019      * _.values(new Foo);
12020      * // => [1, 2] (iteration order is not guaranteed)
12021      *
12022      * _.values('hi');
12023      * // => ['h', 'i']
12024      */
12025     function values(object) {
12026       return object ? baseValues(object, keys(object)) : [];
12027     }
12028
12029     /**
12030      * Creates an array of the own and inherited enumerable property values of `object`.
12031      *
12032      * **Note:** Non-object values are coerced to objects.
12033      *
12034      * @static
12035      * @memberOf _
12036      * @category Object
12037      * @param {Object} object The object to query.
12038      * @returns {Array} Returns the array of property values.
12039      * @example
12040      *
12041      * function Foo() {
12042      *   this.a = 1;
12043      *   this.b = 2;
12044      * }
12045      *
12046      * Foo.prototype.c = 3;
12047      *
12048      * _.valuesIn(new Foo);
12049      * // => [1, 2, 3] (iteration order is not guaranteed)
12050      */
12051     function valuesIn(object) {
12052       return object == null ? [] : baseValues(object, keysIn(object));
12053     }
12054
12055     /*------------------------------------------------------------------------*/
12056
12057     /**
12058      * Clamps `number` within the inclusive `lower` and `upper` bounds.
12059      *
12060      * @static
12061      * @memberOf _
12062      * @category Number
12063      * @param {number} number The number to clamp.
12064      * @param {number} [lower] The lower bound.
12065      * @param {number} upper The upper bound.
12066      * @returns {number} Returns the clamped number.
12067      * @example
12068      *
12069      * _.clamp(-10, -5, 5);
12070      * // => -5
12071      *
12072      * _.clamp(10, -5, 5);
12073      * // => 5
12074      */
12075     function clamp(number, lower, upper) {
12076       if (upper === undefined) {
12077         upper = lower;
12078         lower = undefined;
12079       }
12080       if (upper !== undefined) {
12081         upper = toNumber(upper);
12082         upper = upper === upper ? upper : 0;
12083       }
12084       if (lower !== undefined) {
12085         lower = toNumber(lower);
12086         lower = lower === lower ? lower : 0;
12087       }
12088       return baseClamp(toNumber(number), lower, upper);
12089     }
12090
12091     /**
12092      * Checks if `n` is between `start` and up to but not including, `end`. If
12093      * `end` is not specified it's set to `start` with `start` then set to `0`.
12094      * If `start` is greater than `end` the params are swapped to support
12095      * negative ranges.
12096      *
12097      * @static
12098      * @memberOf _
12099      * @category Number
12100      * @param {number} number The number to check.
12101      * @param {number} [start=0] The start of the range.
12102      * @param {number} end The end of the range.
12103      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
12104      * @example
12105      *
12106      * _.inRange(3, 2, 4);
12107      * // => true
12108      *
12109      * _.inRange(4, 8);
12110      * // => true
12111      *
12112      * _.inRange(4, 2);
12113      * // => false
12114      *
12115      * _.inRange(2, 2);
12116      * // => false
12117      *
12118      * _.inRange(1.2, 2);
12119      * // => true
12120      *
12121      * _.inRange(5.2, 4);
12122      * // => false
12123      *
12124      * _.inRange(-3, -2, -6);
12125      * // => true
12126      */
12127     function inRange(number, start, end) {
12128       start = toNumber(start) || 0;
12129       if (end === undefined) {
12130         end = start;
12131         start = 0;
12132       } else {
12133         end = toNumber(end) || 0;
12134       }
12135       number = toNumber(number);
12136       return baseInRange(number, start, end);
12137     }
12138
12139     /**
12140      * Produces a random number between the inclusive `lower` and `upper` bounds.
12141      * If only one argument is provided a number between `0` and the given number
12142      * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
12143      * a floating-point number is returned instead of an integer.
12144      *
12145      * **Note:** JavaScript follows the IEEE-754 standard for resolving
12146      * floating-point values which can produce unexpected results.
12147      *
12148      * @static
12149      * @memberOf _
12150      * @category Number
12151      * @param {number} [lower=0] The lower bound.
12152      * @param {number} [upper=1] The upper bound.
12153      * @param {boolean} [floating] Specify returning a floating-point number.
12154      * @returns {number} Returns the random number.
12155      * @example
12156      *
12157      * _.random(0, 5);
12158      * // => an integer between 0 and 5
12159      *
12160      * _.random(5);
12161      * // => also an integer between 0 and 5
12162      *
12163      * _.random(5, true);
12164      * // => a floating-point number between 0 and 5
12165      *
12166      * _.random(1.2, 5.2);
12167      * // => a floating-point number between 1.2 and 5.2
12168      */
12169     function random(lower, upper, floating) {
12170       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
12171         upper = floating = undefined;
12172       }
12173       if (floating === undefined) {
12174         if (typeof upper == 'boolean') {
12175           floating = upper;
12176           upper = undefined;
12177         }
12178         else if (typeof lower == 'boolean') {
12179           floating = lower;
12180           lower = undefined;
12181         }
12182       }
12183       if (lower === undefined && upper === undefined) {
12184         lower = 0;
12185         upper = 1;
12186       }
12187       else {
12188         lower = toNumber(lower) || 0;
12189         if (upper === undefined) {
12190           upper = lower;
12191           lower = 0;
12192         } else {
12193           upper = toNumber(upper) || 0;
12194         }
12195       }
12196       if (lower > upper) {
12197         var temp = lower;
12198         lower = upper;
12199         upper = temp;
12200       }
12201       if (floating || lower % 1 || upper % 1) {
12202         var rand = nativeRandom();
12203         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
12204       }
12205       return baseRandom(lower, upper);
12206     }
12207
12208     /*------------------------------------------------------------------------*/
12209
12210     /**
12211      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
12212      *
12213      * @static
12214      * @memberOf _
12215      * @category String
12216      * @param {string} [string=''] The string to convert.
12217      * @returns {string} Returns the camel cased string.
12218      * @example
12219      *
12220      * _.camelCase('Foo Bar');
12221      * // => 'fooBar'
12222      *
12223      * _.camelCase('--foo-bar');
12224      * // => 'fooBar'
12225      *
12226      * _.camelCase('__foo_bar__');
12227      * // => 'fooBar'
12228      */
12229     var camelCase = createCompounder(function(result, word, index) {
12230       word = word.toLowerCase();
12231       return result + (index ? capitalize(word) : word);
12232     });
12233
12234     /**
12235      * Converts the first character of `string` to upper case and the remaining
12236      * to lower case.
12237      *
12238      * @static
12239      * @memberOf _
12240      * @category String
12241      * @param {string} [string=''] The string to capitalize.
12242      * @returns {string} Returns the capitalized string.
12243      * @example
12244      *
12245      * _.capitalize('FRED');
12246      * // => 'Fred'
12247      */
12248     function capitalize(string) {
12249       return upperFirst(toString(string).toLowerCase());
12250     }
12251
12252     /**
12253      * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
12254      * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
12255      *
12256      * @static
12257      * @memberOf _
12258      * @category String
12259      * @param {string} [string=''] The string to deburr.
12260      * @returns {string} Returns the deburred string.
12261      * @example
12262      *
12263      * _.deburr('déjà vu');
12264      * // => 'deja vu'
12265      */
12266     function deburr(string) {
12267       string = toString(string);
12268       return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
12269     }
12270
12271     /**
12272      * Checks if `string` ends with the given target string.
12273      *
12274      * @static
12275      * @memberOf _
12276      * @category String
12277      * @param {string} [string=''] The string to search.
12278      * @param {string} [target] The string to search for.
12279      * @param {number} [position=string.length] The position to search from.
12280      * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
12281      * @example
12282      *
12283      * _.endsWith('abc', 'c');
12284      * // => true
12285      *
12286      * _.endsWith('abc', 'b');
12287      * // => false
12288      *
12289      * _.endsWith('abc', 'b', 2);
12290      * // => true
12291      */
12292     function endsWith(string, target, position) {
12293       string = toString(string);
12294       target = typeof target == 'string' ? target : (target + '');
12295
12296       var length = string.length;
12297       position = position === undefined
12298         ? length
12299         : baseClamp(toInteger(position), 0, length);
12300
12301       position -= target.length;
12302       return position >= 0 && string.indexOf(target, position) == position;
12303     }
12304
12305     /**
12306      * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
12307      * their corresponding HTML entities.
12308      *
12309      * **Note:** No other characters are escaped. To escape additional
12310      * characters use a third-party library like [_he_](https://mths.be/he).
12311      *
12312      * Though the ">" character is escaped for symmetry, characters like
12313      * ">" and "/" don't need escaping in HTML and have no special meaning
12314      * unless they're part of a tag or unquoted attribute value.
12315      * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
12316      * (under "semi-related fun fact") for more details.
12317      *
12318      * Backticks are escaped because in IE < 9, they can break out of
12319      * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
12320      * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
12321      * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
12322      * for more details.
12323      *
12324      * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
12325      * to reduce XSS vectors.
12326      *
12327      * @static
12328      * @memberOf _
12329      * @category String
12330      * @param {string} [string=''] The string to escape.
12331      * @returns {string} Returns the escaped string.
12332      * @example
12333      *
12334      * _.escape('fred, barney, & pebbles');
12335      * // => 'fred, barney, &amp; pebbles'
12336      */
12337     function escape(string) {
12338       string = toString(string);
12339       return (string && reHasUnescapedHtml.test(string))
12340         ? string.replace(reUnescapedHtml, escapeHtmlChar)
12341         : string;
12342     }
12343
12344     /**
12345      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
12346      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
12347      *
12348      * @static
12349      * @memberOf _
12350      * @category String
12351      * @param {string} [string=''] The string to escape.
12352      * @returns {string} Returns the escaped string.
12353      * @example
12354      *
12355      * _.escapeRegExp('[lodash](https://lodash.com/)');
12356      * // => '\[lodash\]\(https://lodash\.com/\)'
12357      */
12358     function escapeRegExp(string) {
12359       string = toString(string);
12360       return (string && reHasRegExpChar.test(string))
12361         ? string.replace(reRegExpChar, '\\$&')
12362         : string;
12363     }
12364
12365     /**
12366      * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
12367      *
12368      * @static
12369      * @memberOf _
12370      * @category String
12371      * @param {string} [string=''] The string to convert.
12372      * @returns {string} Returns the kebab cased string.
12373      * @example
12374      *
12375      * _.kebabCase('Foo Bar');
12376      * // => 'foo-bar'
12377      *
12378      * _.kebabCase('fooBar');
12379      * // => 'foo-bar'
12380      *
12381      * _.kebabCase('__foo_bar__');
12382      * // => 'foo-bar'
12383      */
12384     var kebabCase = createCompounder(function(result, word, index) {
12385       return result + (index ? '-' : '') + word.toLowerCase();
12386     });
12387
12388     /**
12389      * Converts `string`, as space separated words, to lower case.
12390      *
12391      * @static
12392      * @memberOf _
12393      * @category String
12394      * @param {string} [string=''] The string to convert.
12395      * @returns {string} Returns the lower cased string.
12396      * @example
12397      *
12398      * _.lowerCase('--Foo-Bar');
12399      * // => 'foo bar'
12400      *
12401      * _.lowerCase('fooBar');
12402      * // => 'foo bar'
12403      *
12404      * _.lowerCase('__FOO_BAR__');
12405      * // => 'foo bar'
12406      */
12407     var lowerCase = createCompounder(function(result, word, index) {
12408       return result + (index ? ' ' : '') + word.toLowerCase();
12409     });
12410
12411     /**
12412      * Converts the first character of `string` to lower case.
12413      *
12414      * @static
12415      * @memberOf _
12416      * @category String
12417      * @param {string} [string=''] The string to convert.
12418      * @returns {string} Returns the converted string.
12419      * @example
12420      *
12421      * _.lowerFirst('Fred');
12422      * // => 'fred'
12423      *
12424      * _.lowerFirst('FRED');
12425      * // => 'fRED'
12426      */
12427     var lowerFirst = createCaseFirst('toLowerCase');
12428
12429     /**
12430      * Converts the first character of `string` to upper case.
12431      *
12432      * @static
12433      * @memberOf _
12434      * @category String
12435      * @param {string} [string=''] The string to convert.
12436      * @returns {string} Returns the converted string.
12437      * @example
12438      *
12439      * _.upperFirst('fred');
12440      * // => 'Fred'
12441      *
12442      * _.upperFirst('FRED');
12443      * // => 'FRED'
12444      */
12445     var upperFirst = createCaseFirst('toUpperCase');
12446
12447     /**
12448      * Pads `string` on the left and right sides if it's shorter than `length`.
12449      * Padding characters are truncated if they can't be evenly divided by `length`.
12450      *
12451      * @static
12452      * @memberOf _
12453      * @category String
12454      * @param {string} [string=''] The string to pad.
12455      * @param {number} [length=0] The padding length.
12456      * @param {string} [chars=' '] The string used as padding.
12457      * @returns {string} Returns the padded string.
12458      * @example
12459      *
12460      * _.pad('abc', 8);
12461      * // => '  abc   '
12462      *
12463      * _.pad('abc', 8, '_-');
12464      * // => '_-abc_-_'
12465      *
12466      * _.pad('abc', 3);
12467      * // => 'abc'
12468      */
12469     function pad(string, length, chars) {
12470       string = toString(string);
12471       length = toInteger(length);
12472
12473       var strLength = stringSize(string);
12474       if (!length || strLength >= length) {
12475         return string;
12476       }
12477       var mid = (length - strLength) / 2,
12478           leftLength = nativeFloor(mid),
12479           rightLength = nativeCeil(mid);
12480
12481       return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
12482     }
12483
12484     /**
12485      * Pads `string` on the right side if it's shorter than `length`. Padding
12486      * characters are truncated if they exceed `length`.
12487      *
12488      * @static
12489      * @memberOf _
12490      * @category String
12491      * @param {string} [string=''] The string to pad.
12492      * @param {number} [length=0] The padding length.
12493      * @param {string} [chars=' '] The string used as padding.
12494      * @returns {string} Returns the padded string.
12495      * @example
12496      *
12497      * _.padEnd('abc', 6);
12498      * // => 'abc   '
12499      *
12500      * _.padEnd('abc', 6, '_-');
12501      * // => 'abc_-_'
12502      *
12503      * _.padEnd('abc', 3);
12504      * // => 'abc'
12505      */
12506     function padEnd(string, length, chars) {
12507       string = toString(string);
12508       return string + createPadding(string, length, chars);
12509     }
12510
12511     /**
12512      * Pads `string` on the left side if it's shorter than `length`. Padding
12513      * characters are truncated if they exceed `length`.
12514      *
12515      * @static
12516      * @memberOf _
12517      * @category String
12518      * @param {string} [string=''] The string to pad.
12519      * @param {number} [length=0] The padding length.
12520      * @param {string} [chars=' '] The string used as padding.
12521      * @returns {string} Returns the padded string.
12522      * @example
12523      *
12524      * _.padStart('abc', 6);
12525      * // => '   abc'
12526      *
12527      * _.padStart('abc', 6, '_-');
12528      * // => '_-_abc'
12529      *
12530      * _.padStart('abc', 3);
12531      * // => 'abc'
12532      */
12533     function padStart(string, length, chars) {
12534       string = toString(string);
12535       return createPadding(string, length, chars) + string;
12536     }
12537
12538     /**
12539      * Converts `string` to an integer of the specified radix. If `radix` is
12540      * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
12541      * in which case a `radix` of `16` is used.
12542      *
12543      * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2)
12544      * of `parseInt`.
12545      *
12546      * @static
12547      * @memberOf _
12548      * @category String
12549      * @param {string} string The string to convert.
12550      * @param {number} [radix=10] The radix to interpret `value` by.
12551      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12552      * @returns {number} Returns the converted integer.
12553      * @example
12554      *
12555      * _.parseInt('08');
12556      * // => 8
12557      *
12558      * _.map(['6', '08', '10'], _.parseInt);
12559      * // => [6, 8, 10]
12560      */
12561     function parseInt(string, radix, guard) {
12562       // Chrome fails to trim leading <BOM> whitespace characters.
12563       // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
12564       if (guard || radix == null) {
12565         radix = 0;
12566       } else if (radix) {
12567         radix = +radix;
12568       }
12569       string = toString(string).replace(reTrim, '');
12570       return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
12571     }
12572
12573     /**
12574      * Repeats the given string `n` times.
12575      *
12576      * @static
12577      * @memberOf _
12578      * @category String
12579      * @param {string} [string=''] The string to repeat.
12580      * @param {number} [n=0] The number of times to repeat the string.
12581      * @returns {string} Returns the repeated string.
12582      * @example
12583      *
12584      * _.repeat('*', 3);
12585      * // => '***'
12586      *
12587      * _.repeat('abc', 2);
12588      * // => 'abcabc'
12589      *
12590      * _.repeat('abc', 0);
12591      * // => ''
12592      */
12593     function repeat(string, n) {
12594       string = toString(string);
12595       n = toInteger(n);
12596
12597       var result = '';
12598       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
12599         return result;
12600       }
12601       // Leverage the exponentiation by squaring algorithm for a faster repeat.
12602       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
12603       do {
12604         if (n % 2) {
12605           result += string;
12606         }
12607         n = nativeFloor(n / 2);
12608         string += string;
12609       } while (n);
12610
12611       return result;
12612     }
12613
12614     /**
12615      * Replaces matches for `pattern` in `string` with `replacement`.
12616      *
12617      * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
12618      *
12619      * @static
12620      * @memberOf _
12621      * @category String
12622      * @param {string} [string=''] The string to modify.
12623      * @param {RegExp|string} pattern The pattern to replace.
12624      * @param {Function|string} replacement The match replacement.
12625      * @returns {string} Returns the modified string.
12626      * @example
12627      *
12628      * _.replace('Hi Fred', 'Fred', 'Barney');
12629      * // => 'Hi Barney'
12630      */
12631     function replace() {
12632       var args = arguments,
12633           string = toString(args[0]);
12634
12635       return args.length < 3 ? string : string.replace(args[1], args[2]);
12636     }
12637
12638     /**
12639      * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
12640      *
12641      * @static
12642      * @memberOf _
12643      * @category String
12644      * @param {string} [string=''] The string to convert.
12645      * @returns {string} Returns the snake cased string.
12646      * @example
12647      *
12648      * _.snakeCase('Foo Bar');
12649      * // => 'foo_bar'
12650      *
12651      * _.snakeCase('fooBar');
12652      * // => 'foo_bar'
12653      *
12654      * _.snakeCase('--foo-bar');
12655      * // => 'foo_bar'
12656      */
12657     var snakeCase = createCompounder(function(result, word, index) {
12658       return result + (index ? '_' : '') + word.toLowerCase();
12659     });
12660
12661     /**
12662      * Splits `string` by `separator`.
12663      *
12664      * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
12665      *
12666      * @static
12667      * @memberOf _
12668      * @category String
12669      * @param {string} [string=''] The string to split.
12670      * @param {RegExp|string} separator The separator pattern to split by.
12671      * @param {number} [limit] The length to truncate results to.
12672      * @returns {Array} Returns the new array of string segments.
12673      * @example
12674      *
12675      * _.split('a-b-c', '-', 2);
12676      * // => ['a', 'b']
12677      */
12678     function split(string, separator, limit) {
12679       return toString(string).split(separator, limit);
12680     }
12681
12682     /**
12683      * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
12684      *
12685      * @static
12686      * @memberOf _
12687      * @category String
12688      * @param {string} [string=''] The string to convert.
12689      * @returns {string} Returns the start cased string.
12690      * @example
12691      *
12692      * _.startCase('--foo-bar');
12693      * // => 'Foo Bar'
12694      *
12695      * _.startCase('fooBar');
12696      * // => 'Foo Bar'
12697      *
12698      * _.startCase('__foo_bar__');
12699      * // => 'Foo Bar'
12700      */
12701     var startCase = createCompounder(function(result, word, index) {
12702       return result + (index ? ' ' : '') + capitalize(word);
12703     });
12704
12705     /**
12706      * Checks if `string` starts with the given target string.
12707      *
12708      * @static
12709      * @memberOf _
12710      * @category String
12711      * @param {string} [string=''] The string to search.
12712      * @param {string} [target] The string to search for.
12713      * @param {number} [position=0] The position to search from.
12714      * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
12715      * @example
12716      *
12717      * _.startsWith('abc', 'a');
12718      * // => true
12719      *
12720      * _.startsWith('abc', 'b');
12721      * // => false
12722      *
12723      * _.startsWith('abc', 'b', 1);
12724      * // => true
12725      */
12726     function startsWith(string, target, position) {
12727       string = toString(string);
12728       position = baseClamp(toInteger(position), 0, string.length);
12729       return string.lastIndexOf(target, position) == position;
12730     }
12731
12732     /**
12733      * Creates a compiled template function that can interpolate data properties
12734      * in "interpolate" delimiters, HTML-escape interpolated data properties in
12735      * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
12736      * properties may be accessed as free variables in the template. If a setting
12737      * object is given it takes precedence over `_.templateSettings` values.
12738      *
12739      * **Note:** In the development build `_.template` utilizes
12740      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
12741      * for easier debugging.
12742      *
12743      * For more information on precompiling templates see
12744      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
12745      *
12746      * For more information on Chrome extension sandboxes see
12747      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
12748      *
12749      * @static
12750      * @memberOf _
12751      * @category String
12752      * @param {string} [string=''] The template string.
12753      * @param {Object} [options] The options object.
12754      * @param {RegExp} [options.escape] The HTML "escape" delimiter.
12755      * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
12756      * @param {Object} [options.imports] An object to import into the template as free variables.
12757      * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
12758      * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
12759      * @param {string} [options.variable] The data object variable name.
12760      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12761      * @returns {Function} Returns the compiled template function.
12762      * @example
12763      *
12764      * // Use the "interpolate" delimiter to create a compiled template.
12765      * var compiled = _.template('hello <%= user %>!');
12766      * compiled({ 'user': 'fred' });
12767      * // => 'hello fred!'
12768      *
12769      * // Use the HTML "escape" delimiter to escape data property values.
12770      * var compiled = _.template('<b><%- value %></b>');
12771      * compiled({ 'value': '<script>' });
12772      * // => '<b>&lt;script&gt;</b>'
12773      *
12774      * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
12775      * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
12776      * compiled({ 'users': ['fred', 'barney'] });
12777      * // => '<li>fred</li><li>barney</li>'
12778      *
12779      * // Use the internal `print` function in "evaluate" delimiters.
12780      * var compiled = _.template('<% print("hello " + user); %>!');
12781      * compiled({ 'user': 'barney' });
12782      * // => 'hello barney!'
12783      *
12784      * // Use the ES delimiter as an alternative to the default "interpolate" delimiter.
12785      * var compiled = _.template('hello ${ user }!');
12786      * compiled({ 'user': 'pebbles' });
12787      * // => 'hello pebbles!'
12788      *
12789      * // Use custom template delimiters.
12790      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
12791      * var compiled = _.template('hello {{ user }}!');
12792      * compiled({ 'user': 'mustache' });
12793      * // => 'hello mustache!'
12794      *
12795      * // Use backslashes to treat delimiters as plain text.
12796      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
12797      * compiled({ 'value': 'ignored' });
12798      * // => '<%- value %>'
12799      *
12800      * // Use the `imports` option to import `jQuery` as `jq`.
12801      * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
12802      * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
12803      * compiled({ 'users': ['fred', 'barney'] });
12804      * // => '<li>fred</li><li>barney</li>'
12805      *
12806      * // Use the `sourceURL` option to specify a custom sourceURL for the template.
12807      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
12808      * compiled(data);
12809      * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
12810      *
12811      * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
12812      * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
12813      * compiled.source;
12814      * // => function(data) {
12815      * //   var __t, __p = '';
12816      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
12817      * //   return __p;
12818      * // }
12819      *
12820      * // Use the `source` property to inline compiled templates for meaningful
12821      * // line numbers in error messages and stack traces.
12822      * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
12823      *   var JST = {\
12824      *     "main": ' + _.template(mainText).source + '\
12825      *   };\
12826      * ');
12827      */
12828     function template(string, options, guard) {
12829       // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
12830       // and Laura Doktorova's doT.js (https://github.com/olado/doT).
12831       var settings = lodash.templateSettings;
12832
12833       if (guard && isIterateeCall(string, options, guard)) {
12834         options = undefined;
12835       }
12836       string = toString(string);
12837       options = assignInWith({}, options, settings, assignInDefaults);
12838
12839       var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
12840           importsKeys = keys(imports),
12841           importsValues = baseValues(imports, importsKeys);
12842
12843       var isEscaping,
12844           isEvaluating,
12845           index = 0,
12846           interpolate = options.interpolate || reNoMatch,
12847           source = "__p += '";
12848
12849       // Compile the regexp to match each delimiter.
12850       var reDelimiters = RegExp(
12851         (options.escape || reNoMatch).source + '|' +
12852         interpolate.source + '|' +
12853         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
12854         (options.evaluate || reNoMatch).source + '|$'
12855       , 'g');
12856
12857       // Use a sourceURL for easier debugging.
12858       var sourceURL = '//# sourceURL=' +
12859         ('sourceURL' in options
12860           ? options.sourceURL
12861           : ('lodash.templateSources[' + (++templateCounter) + ']')
12862         ) + '\n';
12863
12864       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
12865         interpolateValue || (interpolateValue = esTemplateValue);
12866
12867         // Escape characters that can't be included in string literals.
12868         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
12869
12870         // Replace delimiters with snippets.
12871         if (escapeValue) {
12872           isEscaping = true;
12873           source += "' +\n__e(" + escapeValue + ") +\n'";
12874         }
12875         if (evaluateValue) {
12876           isEvaluating = true;
12877           source += "';\n" + evaluateValue + ";\n__p += '";
12878         }
12879         if (interpolateValue) {
12880           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
12881         }
12882         index = offset + match.length;
12883
12884         // The JS engine embedded in Adobe products needs `match` returned in
12885         // order to produce the correct `offset` value.
12886         return match;
12887       });
12888
12889       source += "';\n";
12890
12891       // If `variable` is not specified wrap a with-statement around the generated
12892       // code to add the data object to the top of the scope chain.
12893       var variable = options.variable;
12894       if (!variable) {
12895         source = 'with (obj) {\n' + source + '\n}\n';
12896       }
12897       // Cleanup code by stripping empty strings.
12898       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
12899         .replace(reEmptyStringMiddle, '$1')
12900         .replace(reEmptyStringTrailing, '$1;');
12901
12902       // Frame code as the function body.
12903       source = 'function(' + (variable || 'obj') + ') {\n' +
12904         (variable
12905           ? ''
12906           : 'obj || (obj = {});\n'
12907         ) +
12908         "var __t, __p = ''" +
12909         (isEscaping
12910            ? ', __e = _.escape'
12911            : ''
12912         ) +
12913         (isEvaluating
12914           ? ', __j = Array.prototype.join;\n' +
12915             "function print() { __p += __j.call(arguments, '') }\n"
12916           : ';\n'
12917         ) +
12918         source +
12919         'return __p\n}';
12920
12921       var result = attempt(function() {
12922         return Function(importsKeys, sourceURL + 'return ' + source)
12923           .apply(undefined, importsValues);
12924       });
12925
12926       // Provide the compiled function's source by its `toString` method or
12927       // the `source` property as a convenience for inlining compiled templates.
12928       result.source = source;
12929       if (isError(result)) {
12930         throw result;
12931       }
12932       return result;
12933     }
12934
12935     /**
12936      * Converts `string`, as a whole, to lower case.
12937      *
12938      * @static
12939      * @memberOf _
12940      * @category String
12941      * @param {string} [string=''] The string to convert.
12942      * @returns {string} Returns the lower cased string.
12943      * @example
12944      *
12945      * _.toLower('--Foo-Bar');
12946      * // => '--foo-bar'
12947      *
12948      * _.toLower('fooBar');
12949      * // => 'foobar'
12950      *
12951      * _.toLower('__FOO_BAR__');
12952      * // => '__foo_bar__'
12953      */
12954     function toLower(value) {
12955       return toString(value).toLowerCase();
12956     }
12957
12958     /**
12959      * Converts `string`, as a whole, to upper case.
12960      *
12961      * @static
12962      * @memberOf _
12963      * @category String
12964      * @param {string} [string=''] The string to convert.
12965      * @returns {string} Returns the upper cased string.
12966      * @example
12967      *
12968      * _.toUpper('--foo-bar');
12969      * // => '--FOO-BAR'
12970      *
12971      * _.toUpper('fooBar');
12972      * // => 'FOOBAR'
12973      *
12974      * _.toUpper('__foo_bar__');
12975      * // => '__FOO_BAR__'
12976      */
12977     function toUpper(value) {
12978       return toString(value).toUpperCase();
12979     }
12980
12981     /**
12982      * Removes leading and trailing whitespace or specified characters from `string`.
12983      *
12984      * @static
12985      * @memberOf _
12986      * @category String
12987      * @param {string} [string=''] The string to trim.
12988      * @param {string} [chars=whitespace] The characters to trim.
12989      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12990      * @returns {string} Returns the trimmed string.
12991      * @example
12992      *
12993      * _.trim('  abc  ');
12994      * // => 'abc'
12995      *
12996      * _.trim('-_-abc-_-', '_-');
12997      * // => 'abc'
12998      *
12999      * _.map(['  foo  ', '  bar  '], _.trim);
13000      * // => ['foo', 'bar']
13001      */
13002     function trim(string, chars, guard) {
13003       string = toString(string);
13004       if (!string) {
13005         return string;
13006       }
13007       if (guard || chars === undefined) {
13008         return string.replace(reTrim, '');
13009       }
13010       chars = (chars + '');
13011       if (!chars) {
13012         return string;
13013       }
13014       var strSymbols = stringToArray(string),
13015           chrSymbols = stringToArray(chars);
13016
13017       return strSymbols
13018         .slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1)
13019         .join('');
13020     }
13021
13022     /**
13023      * Removes trailing whitespace or specified characters from `string`.
13024      *
13025      * @static
13026      * @memberOf _
13027      * @category String
13028      * @param {string} [string=''] The string to trim.
13029      * @param {string} [chars=whitespace] The characters to trim.
13030      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
13031      * @returns {string} Returns the trimmed string.
13032      * @example
13033      *
13034      * _.trimEnd('  abc  ');
13035      * // => '  abc'
13036      *
13037      * _.trimEnd('-_-abc-_-', '_-');
13038      * // => '-_-abc'
13039      */
13040     function trimEnd(string, chars, guard) {
13041       string = toString(string);
13042       if (!string) {
13043         return string;
13044       }
13045       if (guard || chars === undefined) {
13046         return string.replace(reTrimEnd, '');
13047       }
13048       chars = (chars + '');
13049       if (!chars) {
13050         return string;
13051       }
13052       var strSymbols = stringToArray(string);
13053       return strSymbols
13054         .slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1)
13055         .join('');
13056     }
13057
13058     /**
13059      * Removes leading whitespace or specified characters from `string`.
13060      *
13061      * @static
13062      * @memberOf _
13063      * @category String
13064      * @param {string} [string=''] The string to trim.
13065      * @param {string} [chars=whitespace] The characters to trim.
13066      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
13067      * @returns {string} Returns the trimmed string.
13068      * @example
13069      *
13070      * _.trimStart('  abc  ');
13071      * // => 'abc  '
13072      *
13073      * _.trimStart('-_-abc-_-', '_-');
13074      * // => 'abc-_-'
13075      */
13076     function trimStart(string, chars, guard) {
13077       string = toString(string);
13078       if (!string) {
13079         return string;
13080       }
13081       if (guard || chars === undefined) {
13082         return string.replace(reTrimStart, '');
13083       }
13084       chars = (chars + '');
13085       if (!chars) {
13086         return string;
13087       }
13088       var strSymbols = stringToArray(string);
13089       return strSymbols
13090         .slice(charsStartIndex(strSymbols, stringToArray(chars)))
13091         .join('');
13092     }
13093
13094     /**
13095      * Truncates `string` if it's longer than the given maximum string length.
13096      * The last characters of the truncated string are replaced with the omission
13097      * string which defaults to "...".
13098      *
13099      * @static
13100      * @memberOf _
13101      * @category String
13102      * @param {string} [string=''] The string to truncate.
13103      * @param {Object} [options=({})] The options object.
13104      * @param {number} [options.length=30] The maximum string length.
13105      * @param {string} [options.omission='...'] The string to indicate text is omitted.
13106      * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
13107      * @returns {string} Returns the truncated string.
13108      * @example
13109      *
13110      * _.truncate('hi-diddly-ho there, neighborino');
13111      * // => 'hi-diddly-ho there, neighbo...'
13112      *
13113      * _.truncate('hi-diddly-ho there, neighborino', {
13114      *   'length': 24,
13115      *   'separator': ' '
13116      * });
13117      * // => 'hi-diddly-ho there,...'
13118      *
13119      * _.truncate('hi-diddly-ho there, neighborino', {
13120      *   'length': 24,
13121      *   'separator': /,? +/
13122      * });
13123      * // => 'hi-diddly-ho there...'
13124      *
13125      * _.truncate('hi-diddly-ho there, neighborino', {
13126      *   'omission': ' [...]'
13127      * });
13128      * // => 'hi-diddly-ho there, neig [...]'
13129      */
13130     function truncate(string, options) {
13131       var length = DEFAULT_TRUNC_LENGTH,
13132           omission = DEFAULT_TRUNC_OMISSION;
13133
13134       if (isObject(options)) {
13135         var separator = 'separator' in options ? options.separator : separator;
13136         length = 'length' in options ? toInteger(options.length) : length;
13137         omission = 'omission' in options ? toString(options.omission) : omission;
13138       }
13139       string = toString(string);
13140
13141       var strLength = string.length;
13142       if (reHasComplexSymbol.test(string)) {
13143         var strSymbols = stringToArray(string);
13144         strLength = strSymbols.length;
13145       }
13146       if (length >= strLength) {
13147         return string;
13148       }
13149       var end = length - stringSize(omission);
13150       if (end < 1) {
13151         return omission;
13152       }
13153       var result = strSymbols
13154         ? strSymbols.slice(0, end).join('')
13155         : string.slice(0, end);
13156
13157       if (separator === undefined) {
13158         return result + omission;
13159       }
13160       if (strSymbols) {
13161         end += (result.length - end);
13162       }
13163       if (isRegExp(separator)) {
13164         if (string.slice(end).search(separator)) {
13165           var match,
13166               substring = result;
13167
13168           if (!separator.global) {
13169             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
13170           }
13171           separator.lastIndex = 0;
13172           while ((match = separator.exec(substring))) {
13173             var newEnd = match.index;
13174           }
13175           result = result.slice(0, newEnd === undefined ? end : newEnd);
13176         }
13177       } else if (string.indexOf(separator, end) != end) {
13178         var index = result.lastIndexOf(separator);
13179         if (index > -1) {
13180           result = result.slice(0, index);
13181         }
13182       }
13183       return result + omission;
13184     }
13185
13186     /**
13187      * The inverse of `_.escape`; this method converts the HTML entities
13188      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their
13189      * corresponding characters.
13190      *
13191      * **Note:** No other HTML entities are unescaped. To unescape additional HTML
13192      * entities use a third-party library like [_he_](https://mths.be/he).
13193      *
13194      * @static
13195      * @memberOf _
13196      * @category String
13197      * @param {string} [string=''] The string to unescape.
13198      * @returns {string} Returns the unescaped string.
13199      * @example
13200      *
13201      * _.unescape('fred, barney, &amp; pebbles');
13202      * // => 'fred, barney, & pebbles'
13203      */
13204     function unescape(string) {
13205       string = toString(string);
13206       return (string && reHasEscapedHtml.test(string))
13207         ? string.replace(reEscapedHtml, unescapeHtmlChar)
13208         : string;
13209     }
13210
13211     /**
13212      * Converts `string`, as space separated words, to upper case.
13213      *
13214      * @static
13215      * @memberOf _
13216      * @category String
13217      * @param {string} [string=''] The string to convert.
13218      * @returns {string} Returns the upper cased string.
13219      * @example
13220      *
13221      * _.upperCase('--foo-bar');
13222      * // => 'FOO BAR'
13223      *
13224      * _.upperCase('fooBar');
13225      * // => 'FOO BAR'
13226      *
13227      * _.upperCase('__foo_bar__');
13228      * // => 'FOO BAR'
13229      */
13230     var upperCase = createCompounder(function(result, word, index) {
13231       return result + (index ? ' ' : '') + word.toUpperCase();
13232     });
13233
13234     /**
13235      * Splits `string` into an array of its words.
13236      *
13237      * @static
13238      * @memberOf _
13239      * @category String
13240      * @param {string} [string=''] The string to inspect.
13241      * @param {RegExp|string} [pattern] The pattern to match words.
13242      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
13243      * @returns {Array} Returns the words of `string`.
13244      * @example
13245      *
13246      * _.words('fred, barney, & pebbles');
13247      * // => ['fred', 'barney', 'pebbles']
13248      *
13249      * _.words('fred, barney, & pebbles', /[^, ]+/g);
13250      * // => ['fred', 'barney', '&', 'pebbles']
13251      */
13252     function words(string, pattern, guard) {
13253       string = toString(string);
13254       pattern = guard ? undefined : pattern;
13255
13256       if (pattern === undefined) {
13257         pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
13258       }
13259       return string.match(pattern) || [];
13260     }
13261
13262     /*------------------------------------------------------------------------*/
13263
13264     /**
13265      * Attempts to invoke `func`, returning either the result or the caught error
13266      * object. Any additional arguments are provided to `func` when it's invoked.
13267      *
13268      * @static
13269      * @memberOf _
13270      * @category Util
13271      * @param {Function} func The function to attempt.
13272      * @returns {*} Returns the `func` result or error object.
13273      * @example
13274      *
13275      * // Avoid throwing errors for invalid selectors.
13276      * var elements = _.attempt(function(selector) {
13277      *   return document.querySelectorAll(selector);
13278      * }, '>_>');
13279      *
13280      * if (_.isError(elements)) {
13281      *   elements = [];
13282      * }
13283      */
13284     var attempt = rest(function(func, args) {
13285       try {
13286         return apply(func, undefined, args);
13287       } catch (e) {
13288         return isError(e) ? e : new Error(e);
13289       }
13290     });
13291
13292     /**
13293      * Binds methods of an object to the object itself, overwriting the existing
13294      * method.
13295      *
13296      * **Note:** This method doesn't set the "length" property of bound functions.
13297      *
13298      * @static
13299      * @memberOf _
13300      * @category Util
13301      * @param {Object} object The object to bind and assign the bound methods to.
13302      * @param {...(string|string[])} methodNames The object method names to bind,
13303      *  specified individually or in arrays.
13304      * @returns {Object} Returns `object`.
13305      * @example
13306      *
13307      * var view = {
13308      *   'label': 'docs',
13309      *   'onClick': function() {
13310      *     console.log('clicked ' + this.label);
13311      *   }
13312      * };
13313      *
13314      * _.bindAll(view, 'onClick');
13315      * jQuery(element).on('click', view.onClick);
13316      * // => logs 'clicked docs' when clicked
13317      */
13318     var bindAll = rest(function(object, methodNames) {
13319       arrayEach(baseFlatten(methodNames, 1), function(key) {
13320         object[key] = bind(object[key], object);
13321       });
13322       return object;
13323     });
13324
13325     /**
13326      * Creates a function that iterates over `pairs` invoking the corresponding
13327      * function of the first predicate to return truthy. The predicate-function
13328      * pairs are invoked with the `this` binding and arguments of the created
13329      * function.
13330      *
13331      * @static
13332      * @memberOf _
13333      * @category Util
13334      * @param {Array} pairs The predicate-function pairs.
13335      * @returns {Function} Returns the new function.
13336      * @example
13337      *
13338      * var func = _.cond([
13339      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
13340      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
13341      *   [_.constant(true),                _.constant('no match')]
13342      * ]);
13343      *
13344      * func({ 'a': 1, 'b': 2 });
13345      * // => 'matches A'
13346      *
13347      * func({ 'a': 0, 'b': 1 });
13348      * // => 'matches B'
13349      *
13350      * func({ 'a': '1', 'b': '2' });
13351      * // => 'no match'
13352      */
13353     function cond(pairs) {
13354       var length = pairs ? pairs.length : 0,
13355           toIteratee = getIteratee();
13356
13357       pairs = !length ? [] : arrayMap(pairs, function(pair) {
13358         if (typeof pair[1] != 'function') {
13359           throw new TypeError(FUNC_ERROR_TEXT);
13360         }
13361         return [toIteratee(pair[0]), pair[1]];
13362       });
13363
13364       return rest(function(args) {
13365         var index = -1;
13366         while (++index < length) {
13367           var pair = pairs[index];
13368           if (apply(pair[0], this, args)) {
13369             return apply(pair[1], this, args);
13370           }
13371         }
13372       });
13373     }
13374
13375     /**
13376      * Creates a function that invokes the predicate properties of `source` with
13377      * the corresponding property values of a given object, returning `true` if
13378      * all predicates return truthy, else `false`.
13379      *
13380      * @static
13381      * @memberOf _
13382      * @category Util
13383      * @param {Object} source The object of property predicates to conform to.
13384      * @returns {Function} Returns the new function.
13385      * @example
13386      *
13387      * var users = [
13388      *   { 'user': 'barney', 'age': 36 },
13389      *   { 'user': 'fred',   'age': 40 }
13390      * ];
13391      *
13392      * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
13393      * // => [{ 'user': 'fred', 'age': 40 }]
13394      */
13395     function conforms(source) {
13396       return baseConforms(baseClone(source, true));
13397     }
13398
13399     /**
13400      * Creates a function that returns `value`.
13401      *
13402      * @static
13403      * @memberOf _
13404      * @category Util
13405      * @param {*} value The value to return from the new function.
13406      * @returns {Function} Returns the new function.
13407      * @example
13408      *
13409      * var object = { 'user': 'fred' };
13410      * var getter = _.constant(object);
13411      *
13412      * getter() === object;
13413      * // => true
13414      */
13415     function constant(value) {
13416       return function() {
13417         return value;
13418       };
13419     }
13420
13421     /**
13422      * Creates a function that returns the result of invoking the given functions
13423      * with the `this` binding of the created function, where each successive
13424      * invocation is supplied the return value of the previous.
13425      *
13426      * @static
13427      * @memberOf _
13428      * @category Util
13429      * @param {...(Function|Function[])} [funcs] Functions to invoke.
13430      * @returns {Function} Returns the new function.
13431      * @example
13432      *
13433      * function square(n) {
13434      *   return n * n;
13435      * }
13436      *
13437      * var addSquare = _.flow(_.add, square);
13438      * addSquare(1, 2);
13439      * // => 9
13440      */
13441     var flow = createFlow();
13442
13443     /**
13444      * This method is like `_.flow` except that it creates a function that
13445      * invokes the given functions from right to left.
13446      *
13447      * @static
13448      * @memberOf _
13449      * @category Util
13450      * @param {...(Function|Function[])} [funcs] Functions to invoke.
13451      * @returns {Function} Returns the new function.
13452      * @example
13453      *
13454      * function square(n) {
13455      *   return n * n;
13456      * }
13457      *
13458      * var addSquare = _.flowRight(square, _.add);
13459      * addSquare(1, 2);
13460      * // => 9
13461      */
13462     var flowRight = createFlow(true);
13463
13464     /**
13465      * This method returns the first argument given to it.
13466      *
13467      * @static
13468      * @memberOf _
13469      * @category Util
13470      * @param {*} value Any value.
13471      * @returns {*} Returns `value`.
13472      * @example
13473      *
13474      * var object = { 'user': 'fred' };
13475      *
13476      * _.identity(object) === object;
13477      * // => true
13478      */
13479     function identity(value) {
13480       return value;
13481     }
13482
13483     /**
13484      * Creates a function that invokes `func` with the arguments of the created
13485      * function. If `func` is a property name the created callback returns the
13486      * property value for a given element. If `func` is an object the created
13487      * callback returns `true` for elements that contain the equivalent object
13488      * properties, otherwise it returns `false`.
13489      *
13490      * @static
13491      * @memberOf _
13492      * @category Util
13493      * @param {*} [func=_.identity] The value to convert to a callback.
13494      * @returns {Function} Returns the callback.
13495      * @example
13496      *
13497      * var users = [
13498      *   { 'user': 'barney', 'age': 36 },
13499      *   { 'user': 'fred',   'age': 40 }
13500      * ];
13501      *
13502      * // Create custom iteratee shorthands.
13503      * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
13504      *   var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
13505      *   return !p ? callback(func) : function(object) {
13506      *     return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
13507      *   };
13508      * });
13509      *
13510      * _.filter(users, 'age > 36');
13511      * // => [{ 'user': 'fred', 'age': 40 }]
13512      */
13513     function iteratee(func) {
13514       return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));
13515     }
13516
13517     /**
13518      * Creates a function that performs a partial deep comparison between a given
13519      * object and `source`, returning `true` if the given object has equivalent
13520      * property values, else `false`. The created function is equivalent to
13521      * `_.isMatch` with a `source` partially applied.
13522      *
13523      * **Note:** This method supports comparing the same values as `_.isEqual`.
13524      *
13525      * @static
13526      * @memberOf _
13527      * @category Util
13528      * @param {Object} source The object of property values to match.
13529      * @returns {Function} Returns the new function.
13530      * @example
13531      *
13532      * var users = [
13533      *   { 'user': 'barney', 'age': 36, 'active': true },
13534      *   { 'user': 'fred',   'age': 40, 'active': false }
13535      * ];
13536      *
13537      * _.filter(users, _.matches({ 'age': 40, 'active': false }));
13538      * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
13539      */
13540     function matches(source) {
13541       return baseMatches(baseClone(source, true));
13542     }
13543
13544     /**
13545      * Creates a function that performs a partial deep comparison between the
13546      * value at `path` of a given object to `srcValue`, returning `true` if the
13547      * object value is equivalent, else `false`.
13548      *
13549      * **Note:** This method supports comparing the same values as `_.isEqual`.
13550      *
13551      * @static
13552      * @memberOf _
13553      * @category Util
13554      * @param {Array|string} path The path of the property to get.
13555      * @param {*} srcValue The value to match.
13556      * @returns {Function} Returns the new function.
13557      * @example
13558      *
13559      * var users = [
13560      *   { 'user': 'barney' },
13561      *   { 'user': 'fred' }
13562      * ];
13563      *
13564      * _.find(users, _.matchesProperty('user', 'fred'));
13565      * // => { 'user': 'fred' }
13566      */
13567     function matchesProperty(path, srcValue) {
13568       return baseMatchesProperty(path, baseClone(srcValue, true));
13569     }
13570
13571     /**
13572      * Creates a function that invokes the method at `path` of a given object.
13573      * Any additional arguments are provided to the invoked method.
13574      *
13575      * @static
13576      * @memberOf _
13577      * @category Util
13578      * @param {Array|string} path The path of the method to invoke.
13579      * @param {...*} [args] The arguments to invoke the method with.
13580      * @returns {Function} Returns the new function.
13581      * @example
13582      *
13583      * var objects = [
13584      *   { 'a': { 'b': { 'c': _.constant(2) } } },
13585      *   { 'a': { 'b': { 'c': _.constant(1) } } }
13586      * ];
13587      *
13588      * _.map(objects, _.method('a.b.c'));
13589      * // => [2, 1]
13590      *
13591      * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
13592      * // => [1, 2]
13593      */
13594     var method = rest(function(path, args) {
13595       return function(object) {
13596         return baseInvoke(object, path, args);
13597       };
13598     });
13599
13600     /**
13601      * The opposite of `_.method`; this method creates a function that invokes
13602      * the method at a given path of `object`. Any additional arguments are
13603      * provided to the invoked method.
13604      *
13605      * @static
13606      * @memberOf _
13607      * @category Util
13608      * @param {Object} object The object to query.
13609      * @param {...*} [args] The arguments to invoke the method with.
13610      * @returns {Function} Returns the new function.
13611      * @example
13612      *
13613      * var array = _.times(3, _.constant),
13614      *     object = { 'a': array, 'b': array, 'c': array };
13615      *
13616      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
13617      * // => [2, 0]
13618      *
13619      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
13620      * // => [2, 0]
13621      */
13622     var methodOf = rest(function(object, args) {
13623       return function(path) {
13624         return baseInvoke(object, path, args);
13625       };
13626     });
13627
13628     /**
13629      * Adds all own enumerable function properties of a source object to the
13630      * destination object. If `object` is a function then methods are added to
13631      * its prototype as well.
13632      *
13633      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
13634      * avoid conflicts caused by modifying the original.
13635      *
13636      * @static
13637      * @memberOf _
13638      * @category Util
13639      * @param {Function|Object} [object=lodash] The destination object.
13640      * @param {Object} source The object of functions to add.
13641      * @param {Object} [options] The options object.
13642      * @param {boolean} [options.chain=true] Specify whether the functions added
13643      *  are chainable.
13644      * @returns {Function|Object} Returns `object`.
13645      * @example
13646      *
13647      * function vowels(string) {
13648      *   return _.filter(string, function(v) {
13649      *     return /[aeiou]/i.test(v);
13650      *   });
13651      * }
13652      *
13653      * _.mixin({ 'vowels': vowels });
13654      * _.vowels('fred');
13655      * // => ['e']
13656      *
13657      * _('fred').vowels().value();
13658      * // => ['e']
13659      *
13660      * _.mixin({ 'vowels': vowels }, { 'chain': false });
13661      * _('fred').vowels();
13662      * // => ['e']
13663      */
13664     function mixin(object, source, options) {
13665       var props = keys(source),
13666           methodNames = baseFunctions(source, props);
13667
13668       if (options == null &&
13669           !(isObject(source) && (methodNames.length || !props.length))) {
13670         options = source;
13671         source = object;
13672         object = this;
13673         methodNames = baseFunctions(source, keys(source));
13674       }
13675       var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
13676           isFunc = isFunction(object);
13677
13678       arrayEach(methodNames, function(methodName) {
13679         var func = source[methodName];
13680         object[methodName] = func;
13681         if (isFunc) {
13682           object.prototype[methodName] = function() {
13683             var chainAll = this.__chain__;
13684             if (chain || chainAll) {
13685               var result = object(this.__wrapped__),
13686                   actions = result.__actions__ = copyArray(this.__actions__);
13687
13688               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
13689               result.__chain__ = chainAll;
13690               return result;
13691             }
13692             return func.apply(object, arrayPush([this.value()], arguments));
13693           };
13694         }
13695       });
13696
13697       return object;
13698     }
13699
13700     /**
13701      * Reverts the `_` variable to its previous value and returns a reference to
13702      * the `lodash` function.
13703      *
13704      * @static
13705      * @memberOf _
13706      * @category Util
13707      * @returns {Function} Returns the `lodash` function.
13708      * @example
13709      *
13710      * var lodash = _.noConflict();
13711      */
13712     function noConflict() {
13713       if (root._ === this) {
13714         root._ = oldDash;
13715       }
13716       return this;
13717     }
13718
13719     /**
13720      * A no-operation function that returns `undefined` regardless of the
13721      * arguments it receives.
13722      *
13723      * @static
13724      * @memberOf _
13725      * @category Util
13726      * @example
13727      *
13728      * var object = { 'user': 'fred' };
13729      *
13730      * _.noop(object) === undefined;
13731      * // => true
13732      */
13733     function noop() {
13734       // No operation performed.
13735     }
13736
13737     /**
13738      * Creates a function that returns its nth argument.
13739      *
13740      * @static
13741      * @memberOf _
13742      * @category Util
13743      * @param {number} [n=0] The index of the argument to return.
13744      * @returns {Function} Returns the new function.
13745      * @example
13746      *
13747      * var func = _.nthArg(1);
13748      *
13749      * func('a', 'b', 'c');
13750      * // => 'b'
13751      */
13752     function nthArg(n) {
13753       n = toInteger(n);
13754       return function() {
13755         return arguments[n];
13756       };
13757     }
13758
13759     /**
13760      * Creates a function that invokes `iteratees` with the arguments provided
13761      * to the created function and returns their results.
13762      *
13763      * @static
13764      * @memberOf _
13765      * @category Util
13766      * @param {...(Function|Function[])} iteratees The iteratees to invoke.
13767      * @returns {Function} Returns the new function.
13768      * @example
13769      *
13770      * var func = _.over(Math.max, Math.min);
13771      *
13772      * func(1, 2, 3, 4);
13773      * // => [4, 1]
13774      */
13775     var over = createOver(arrayMap);
13776
13777     /**
13778      * Creates a function that checks if **all** of the `predicates` return
13779      * truthy when invoked with the arguments provided to the created function.
13780      *
13781      * @static
13782      * @memberOf _
13783      * @category Util
13784      * @param {...(Function|Function[])} predicates The predicates to check.
13785      * @returns {Function} Returns the new function.
13786      * @example
13787      *
13788      * var func = _.overEvery(Boolean, isFinite);
13789      *
13790      * func('1');
13791      * // => true
13792      *
13793      * func(null);
13794      * // => false
13795      *
13796      * func(NaN);
13797      * // => false
13798      */
13799     var overEvery = createOver(arrayEvery);
13800
13801     /**
13802      * Creates a function that checks if **any** of the `predicates` return
13803      * truthy when invoked with the arguments provided to the created function.
13804      *
13805      * @static
13806      * @memberOf _
13807      * @category Util
13808      * @param {...(Function|Function[])} predicates The predicates to check.
13809      * @returns {Function} Returns the new function.
13810      * @example
13811      *
13812      * var func = _.overSome(Boolean, isFinite);
13813      *
13814      * func('1');
13815      * // => true
13816      *
13817      * func(null);
13818      * // => true
13819      *
13820      * func(NaN);
13821      * // => false
13822      */
13823     var overSome = createOver(arraySome);
13824
13825     /**
13826      * Creates a function that returns the value at `path` of a given object.
13827      *
13828      * @static
13829      * @memberOf _
13830      * @category Util
13831      * @param {Array|string} path The path of the property to get.
13832      * @returns {Function} Returns the new function.
13833      * @example
13834      *
13835      * var objects = [
13836      *   { 'a': { 'b': { 'c': 2 } } },
13837      *   { 'a': { 'b': { 'c': 1 } } }
13838      * ];
13839      *
13840      * _.map(objects, _.property('a.b.c'));
13841      * // => [2, 1]
13842      *
13843      * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
13844      * // => [1, 2]
13845      */
13846     function property(path) {
13847       return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
13848     }
13849
13850     /**
13851      * The opposite of `_.property`; this method creates a function that returns
13852      * the value at a given path of `object`.
13853      *
13854      * @static
13855      * @memberOf _
13856      * @category Util
13857      * @param {Object} object The object to query.
13858      * @returns {Function} Returns the new function.
13859      * @example
13860      *
13861      * var array = [0, 1, 2],
13862      *     object = { 'a': array, 'b': array, 'c': array };
13863      *
13864      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
13865      * // => [2, 0]
13866      *
13867      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
13868      * // => [2, 0]
13869      */
13870     function propertyOf(object) {
13871       return function(path) {
13872         return object == null ? undefined : baseGet(object, path);
13873       };
13874     }
13875
13876     /**
13877      * Creates an array of numbers (positive and/or negative) progressing from
13878      * `start` up to, but not including, `end`. A step of `-1` is used if a negative
13879      * `start` is specified without an `end` or `step`. If `end` is not specified
13880      * it's set to `start` with `start` then set to `0`.
13881      *
13882      * **Note:** JavaScript follows the IEEE-754 standard for resolving
13883      * floating-point values which can produce unexpected results.
13884      *
13885      * @static
13886      * @memberOf _
13887      * @category Util
13888      * @param {number} [start=0] The start of the range.
13889      * @param {number} end The end of the range.
13890      * @param {number} [step=1] The value to increment or decrement by.
13891      * @returns {Array} Returns the new array of numbers.
13892      * @example
13893      *
13894      * _.range(4);
13895      * // => [0, 1, 2, 3]
13896      *
13897      * _.range(-4);
13898      * // => [0, -1, -2, -3]
13899      *
13900      * _.range(1, 5);
13901      * // => [1, 2, 3, 4]
13902      *
13903      * _.range(0, 20, 5);
13904      * // => [0, 5, 10, 15]
13905      *
13906      * _.range(0, -4, -1);
13907      * // => [0, -1, -2, -3]
13908      *
13909      * _.range(1, 4, 0);
13910      * // => [1, 1, 1]
13911      *
13912      * _.range(0);
13913      * // => []
13914      */
13915     var range = createRange();
13916
13917     /**
13918      * This method is like `_.range` except that it populates values in
13919      * descending order.
13920      *
13921      * @static
13922      * @memberOf _
13923      * @category Util
13924      * @param {number} [start=0] The start of the range.
13925      * @param {number} end The end of the range.
13926      * @param {number} [step=1] The value to increment or decrement by.
13927      * @returns {Array} Returns the new array of numbers.
13928      * @example
13929      *
13930      * _.rangeRight(4);
13931      * // => [3, 2, 1, 0]
13932      *
13933      * _.rangeRight(-4);
13934      * // => [-3, -2, -1, 0]
13935      *
13936      * _.rangeRight(1, 5);
13937      * // => [4, 3, 2, 1]
13938      *
13939      * _.rangeRight(0, 20, 5);
13940      * // => [15, 10, 5, 0]
13941      *
13942      * _.rangeRight(0, -4, -1);
13943      * // => [-3, -2, -1, 0]
13944      *
13945      * _.rangeRight(1, 4, 0);
13946      * // => [1, 1, 1]
13947      *
13948      * _.rangeRight(0);
13949      * // => []
13950      */
13951     var rangeRight = createRange(true);
13952
13953     /**
13954      * Invokes the iteratee `n` times, returning an array of the results of
13955      * each invocation. The iteratee is invoked with one argument; (index).
13956      *
13957      * @static
13958      * @memberOf _
13959      * @category Util
13960      * @param {number} n The number of times to invoke `iteratee`.
13961      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13962      * @returns {Array} Returns the array of results.
13963      * @example
13964      *
13965      * _.times(3, String);
13966      * // => ['0', '1', '2']
13967      *
13968      *  _.times(4, _.constant(true));
13969      * // => [true, true, true, true]
13970      */
13971     function times(n, iteratee) {
13972       n = toInteger(n);
13973       if (n < 1 || n > MAX_SAFE_INTEGER) {
13974         return [];
13975       }
13976       var index = MAX_ARRAY_LENGTH,
13977           length = nativeMin(n, MAX_ARRAY_LENGTH);
13978
13979       iteratee = baseCastFunction(iteratee);
13980       n -= MAX_ARRAY_LENGTH;
13981
13982       var result = baseTimes(length, iteratee);
13983       while (++index < n) {
13984         iteratee(index);
13985       }
13986       return result;
13987     }
13988
13989     /**
13990      * Converts `value` to a property path array.
13991      *
13992      * @static
13993      * @memberOf _
13994      * @category Util
13995      * @param {*} value The value to convert.
13996      * @returns {Array} Returns the new property path array.
13997      * @example
13998      *
13999      * _.toPath('a.b.c');
14000      * // => ['a', 'b', 'c']
14001      *
14002      * _.toPath('a[0].b.c');
14003      * // => ['a', '0', 'b', 'c']
14004      *
14005      * var path = ['a', 'b', 'c'],
14006      *     newPath = _.toPath(path);
14007      *
14008      * console.log(newPath);
14009      * // => ['a', 'b', 'c']
14010      *
14011      * console.log(path === newPath);
14012      * // => false
14013      */
14014     function toPath(value) {
14015       return isArray(value) ? arrayMap(value, String) : stringToPath(value);
14016     }
14017
14018     /**
14019      * Generates a unique ID. If `prefix` is given the ID is appended to it.
14020      *
14021      * @static
14022      * @memberOf _
14023      * @category Util
14024      * @param {string} [prefix=''] The value to prefix the ID with.
14025      * @returns {string} Returns the unique ID.
14026      * @example
14027      *
14028      * _.uniqueId('contact_');
14029      * // => 'contact_104'
14030      *
14031      * _.uniqueId();
14032      * // => '105'
14033      */
14034     function uniqueId(prefix) {
14035       var id = ++idCounter;
14036       return toString(prefix) + id;
14037     }
14038
14039     /*------------------------------------------------------------------------*/
14040
14041     /**
14042      * Adds two numbers.
14043      *
14044      * @static
14045      * @memberOf _
14046      * @category Math
14047      * @param {number} augend The first number in an addition.
14048      * @param {number} addend The second number in an addition.
14049      * @returns {number} Returns the total.
14050      * @example
14051      *
14052      * _.add(6, 4);
14053      * // => 10
14054      */
14055     function add(augend, addend) {
14056       var result;
14057       if (augend === undefined && addend === undefined) {
14058         return 0;
14059       }
14060       if (augend !== undefined) {
14061         result = augend;
14062       }
14063       if (addend !== undefined) {
14064         result = result === undefined ? addend : (result + addend);
14065       }
14066       return result;
14067     }
14068
14069     /**
14070      * Computes `number` rounded up to `precision`.
14071      *
14072      * @static
14073      * @memberOf _
14074      * @category Math
14075      * @param {number} number The number to round up.
14076      * @param {number} [precision=0] The precision to round up to.
14077      * @returns {number} Returns the rounded up number.
14078      * @example
14079      *
14080      * _.ceil(4.006);
14081      * // => 5
14082      *
14083      * _.ceil(6.004, 2);
14084      * // => 6.01
14085      *
14086      * _.ceil(6040, -2);
14087      * // => 6100
14088      */
14089     var ceil = createRound('ceil');
14090
14091     /**
14092      * Computes `number` rounded down to `precision`.
14093      *
14094      * @static
14095      * @memberOf _
14096      * @category Math
14097      * @param {number} number The number to round down.
14098      * @param {number} [precision=0] The precision to round down to.
14099      * @returns {number} Returns the rounded down number.
14100      * @example
14101      *
14102      * _.floor(4.006);
14103      * // => 4
14104      *
14105      * _.floor(0.046, 2);
14106      * // => 0.04
14107      *
14108      * _.floor(4060, -2);
14109      * // => 4000
14110      */
14111     var floor = createRound('floor');
14112
14113     /**
14114      * Computes the maximum value of `array`. If `array` is empty or falsey
14115      * `undefined` is returned.
14116      *
14117      * @static
14118      * @memberOf _
14119      * @category Math
14120      * @param {Array} array The array to iterate over.
14121      * @returns {*} Returns the maximum value.
14122      * @example
14123      *
14124      * _.max([4, 2, 8, 6]);
14125      * // => 8
14126      *
14127      * _.max([]);
14128      * // => undefined
14129      */
14130     function max(array) {
14131       return (array && array.length)
14132         ? baseExtremum(array, identity, gt)
14133         : undefined;
14134     }
14135
14136     /**
14137      * This method is like `_.max` except that it accepts `iteratee` which is
14138      * invoked for each element in `array` to generate the criterion by which
14139      * the value is ranked. The iteratee is invoked with one argument: (value).
14140      *
14141      * @static
14142      * @memberOf _
14143      * @category Math
14144      * @param {Array} array The array to iterate over.
14145      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14146      * @returns {*} Returns the maximum value.
14147      * @example
14148      *
14149      * var objects = [{ 'n': 1 }, { 'n': 2 }];
14150      *
14151      * _.maxBy(objects, function(o) { return o.n; });
14152      * // => { 'n': 2 }
14153      *
14154      * // The `_.property` iteratee shorthand.
14155      * _.maxBy(objects, 'n');
14156      * // => { 'n': 2 }
14157      */
14158     function maxBy(array, iteratee) {
14159       return (array && array.length)
14160         ? baseExtremum(array, getIteratee(iteratee), gt)
14161         : undefined;
14162     }
14163
14164     /**
14165      * Computes the mean of the values in `array`.
14166      *
14167      * @static
14168      * @memberOf _
14169      * @category Math
14170      * @param {Array} array The array to iterate over.
14171      * @returns {number} Returns the mean.
14172      * @example
14173      *
14174      * _.mean([4, 2, 8, 6]);
14175      * // => 5
14176      */
14177     function mean(array) {
14178       return sum(array) / (array ? array.length : 0);
14179     }
14180
14181     /**
14182      * Computes the minimum value of `array`. If `array` is empty or falsey
14183      * `undefined` is returned.
14184      *
14185      * @static
14186      * @memberOf _
14187      * @category Math
14188      * @param {Array} array The array to iterate over.
14189      * @returns {*} Returns the minimum value.
14190      * @example
14191      *
14192      * _.min([4, 2, 8, 6]);
14193      * // => 2
14194      *
14195      * _.min([]);
14196      * // => undefined
14197      */
14198     function min(array) {
14199       return (array && array.length)
14200         ? baseExtremum(array, identity, lt)
14201         : undefined;
14202     }
14203
14204     /**
14205      * This method is like `_.min` except that it accepts `iteratee` which is
14206      * invoked for each element in `array` to generate the criterion by which
14207      * the value is ranked. The iteratee is invoked with one argument: (value).
14208      *
14209      * @static
14210      * @memberOf _
14211      * @category Math
14212      * @param {Array} array The array to iterate over.
14213      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14214      * @returns {*} Returns the minimum value.
14215      * @example
14216      *
14217      * var objects = [{ 'n': 1 }, { 'n': 2 }];
14218      *
14219      * _.minBy(objects, function(o) { return o.n; });
14220      * // => { 'n': 1 }
14221      *
14222      * // The `_.property` iteratee shorthand.
14223      * _.minBy(objects, 'n');
14224      * // => { 'n': 1 }
14225      */
14226     function minBy(array, iteratee) {
14227       return (array && array.length)
14228         ? baseExtremum(array, getIteratee(iteratee), lt)
14229         : undefined;
14230     }
14231
14232     /**
14233      * Computes `number` rounded to `precision`.
14234      *
14235      * @static
14236      * @memberOf _
14237      * @category Math
14238      * @param {number} number The number to round.
14239      * @param {number} [precision=0] The precision to round to.
14240      * @returns {number} Returns the rounded number.
14241      * @example
14242      *
14243      * _.round(4.006);
14244      * // => 4
14245      *
14246      * _.round(4.006, 2);
14247      * // => 4.01
14248      *
14249      * _.round(4060, -2);
14250      * // => 4100
14251      */
14252     var round = createRound('round');
14253
14254     /**
14255      * Subtract two numbers.
14256      *
14257      * @static
14258      * @memberOf _
14259      * @category Math
14260      * @param {number} minuend The first number in a subtraction.
14261      * @param {number} subtrahend The second number in a subtraction.
14262      * @returns {number} Returns the difference.
14263      * @example
14264      *
14265      * _.subtract(6, 4);
14266      * // => 2
14267      */
14268     function subtract(minuend, subtrahend) {
14269       var result;
14270       if (minuend === undefined && subtrahend === undefined) {
14271         return 0;
14272       }
14273       if (minuend !== undefined) {
14274         result = minuend;
14275       }
14276       if (subtrahend !== undefined) {
14277         result = result === undefined ? subtrahend : (result - subtrahend);
14278       }
14279       return result;
14280     }
14281
14282     /**
14283      * Computes the sum of the values in `array`.
14284      *
14285      * @static
14286      * @memberOf _
14287      * @category Math
14288      * @param {Array} array The array to iterate over.
14289      * @returns {number} Returns the sum.
14290      * @example
14291      *
14292      * _.sum([4, 2, 8, 6]);
14293      * // => 20
14294      */
14295     function sum(array) {
14296       return (array && array.length)
14297         ? baseSum(array, identity)
14298         : 0;
14299     }
14300
14301     /**
14302      * This method is like `_.sum` except that it accepts `iteratee` which is
14303      * invoked for each element in `array` to generate the value to be summed.
14304      * The iteratee is invoked with one argument: (value).
14305      *
14306      * @static
14307      * @memberOf _
14308      * @category Math
14309      * @param {Array} array The array to iterate over.
14310      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14311      * @returns {number} Returns the sum.
14312      * @example
14313      *
14314      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
14315      *
14316      * _.sumBy(objects, function(o) { return o.n; });
14317      * // => 20
14318      *
14319      * // The `_.property` iteratee shorthand.
14320      * _.sumBy(objects, 'n');
14321      * // => 20
14322      */
14323     function sumBy(array, iteratee) {
14324       return (array && array.length)
14325         ? baseSum(array, getIteratee(iteratee))
14326         : 0;
14327     }
14328
14329     /*------------------------------------------------------------------------*/
14330
14331     // Ensure wrappers are instances of `baseLodash`.
14332     lodash.prototype = baseLodash.prototype;
14333
14334     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
14335     LodashWrapper.prototype.constructor = LodashWrapper;
14336
14337     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
14338     LazyWrapper.prototype.constructor = LazyWrapper;
14339
14340     // Avoid inheriting from `Object.prototype` when possible.
14341     Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
14342
14343     // Add functions to the `MapCache`.
14344     MapCache.prototype.clear = mapClear;
14345     MapCache.prototype['delete'] = mapDelete;
14346     MapCache.prototype.get = mapGet;
14347     MapCache.prototype.has = mapHas;
14348     MapCache.prototype.set = mapSet;
14349
14350     // Add functions to the `SetCache`.
14351     SetCache.prototype.push = cachePush;
14352
14353     // Add functions to the `Stack` cache.
14354     Stack.prototype.clear = stackClear;
14355     Stack.prototype['delete'] = stackDelete;
14356     Stack.prototype.get = stackGet;
14357     Stack.prototype.has = stackHas;
14358     Stack.prototype.set = stackSet;
14359
14360     // Assign cache to `_.memoize`.
14361     memoize.Cache = MapCache;
14362
14363     // Add functions that return wrapped values when chaining.
14364     lodash.after = after;
14365     lodash.ary = ary;
14366     lodash.assign = assign;
14367     lodash.assignIn = assignIn;
14368     lodash.assignInWith = assignInWith;
14369     lodash.assignWith = assignWith;
14370     lodash.at = at;
14371     lodash.before = before;
14372     lodash.bind = bind;
14373     lodash.bindAll = bindAll;
14374     lodash.bindKey = bindKey;
14375     lodash.castArray = castArray;
14376     lodash.chain = chain;
14377     lodash.chunk = chunk;
14378     lodash.compact = compact;
14379     lodash.concat = concat;
14380     lodash.cond = cond;
14381     lodash.conforms = conforms;
14382     lodash.constant = constant;
14383     lodash.countBy = countBy;
14384     lodash.create = create;
14385     lodash.curry = curry;
14386     lodash.curryRight = curryRight;
14387     lodash.debounce = debounce;
14388     lodash.defaults = defaults;
14389     lodash.defaultsDeep = defaultsDeep;
14390     lodash.defer = defer;
14391     lodash.delay = delay;
14392     lodash.difference = difference;
14393     lodash.differenceBy = differenceBy;
14394     lodash.differenceWith = differenceWith;
14395     lodash.drop = drop;
14396     lodash.dropRight = dropRight;
14397     lodash.dropRightWhile = dropRightWhile;
14398     lodash.dropWhile = dropWhile;
14399     lodash.fill = fill;
14400     lodash.filter = filter;
14401     lodash.flatMap = flatMap;
14402     lodash.flatten = flatten;
14403     lodash.flattenDeep = flattenDeep;
14404     lodash.flattenDepth = flattenDepth;
14405     lodash.flip = flip;
14406     lodash.flow = flow;
14407     lodash.flowRight = flowRight;
14408     lodash.fromPairs = fromPairs;
14409     lodash.functions = functions;
14410     lodash.functionsIn = functionsIn;
14411     lodash.groupBy = groupBy;
14412     lodash.initial = initial;
14413     lodash.intersection = intersection;
14414     lodash.intersectionBy = intersectionBy;
14415     lodash.intersectionWith = intersectionWith;
14416     lodash.invert = invert;
14417     lodash.invertBy = invertBy;
14418     lodash.invokeMap = invokeMap;
14419     lodash.iteratee = iteratee;
14420     lodash.keyBy = keyBy;
14421     lodash.keys = keys;
14422     lodash.keysIn = keysIn;
14423     lodash.map = map;
14424     lodash.mapKeys = mapKeys;
14425     lodash.mapValues = mapValues;
14426     lodash.matches = matches;
14427     lodash.matchesProperty = matchesProperty;
14428     lodash.memoize = memoize;
14429     lodash.merge = merge;
14430     lodash.mergeWith = mergeWith;
14431     lodash.method = method;
14432     lodash.methodOf = methodOf;
14433     lodash.mixin = mixin;
14434     lodash.negate = negate;
14435     lodash.nthArg = nthArg;
14436     lodash.omit = omit;
14437     lodash.omitBy = omitBy;
14438     lodash.once = once;
14439     lodash.orderBy = orderBy;
14440     lodash.over = over;
14441     lodash.overArgs = overArgs;
14442     lodash.overEvery = overEvery;
14443     lodash.overSome = overSome;
14444     lodash.partial = partial;
14445     lodash.partialRight = partialRight;
14446     lodash.partition = partition;
14447     lodash.pick = pick;
14448     lodash.pickBy = pickBy;
14449     lodash.property = property;
14450     lodash.propertyOf = propertyOf;
14451     lodash.pull = pull;
14452     lodash.pullAll = pullAll;
14453     lodash.pullAllBy = pullAllBy;
14454     lodash.pullAt = pullAt;
14455     lodash.range = range;
14456     lodash.rangeRight = rangeRight;
14457     lodash.rearg = rearg;
14458     lodash.reject = reject;
14459     lodash.remove = remove;
14460     lodash.rest = rest;
14461     lodash.reverse = reverse;
14462     lodash.sampleSize = sampleSize;
14463     lodash.set = set;
14464     lodash.setWith = setWith;
14465     lodash.shuffle = shuffle;
14466     lodash.slice = slice;
14467     lodash.sortBy = sortBy;
14468     lodash.sortedUniq = sortedUniq;
14469     lodash.sortedUniqBy = sortedUniqBy;
14470     lodash.split = split;
14471     lodash.spread = spread;
14472     lodash.tail = tail;
14473     lodash.take = take;
14474     lodash.takeRight = takeRight;
14475     lodash.takeRightWhile = takeRightWhile;
14476     lodash.takeWhile = takeWhile;
14477     lodash.tap = tap;
14478     lodash.throttle = throttle;
14479     lodash.thru = thru;
14480     lodash.toArray = toArray;
14481     lodash.toPairs = toPairs;
14482     lodash.toPairsIn = toPairsIn;
14483     lodash.toPath = toPath;
14484     lodash.toPlainObject = toPlainObject;
14485     lodash.transform = transform;
14486     lodash.unary = unary;
14487     lodash.union = union;
14488     lodash.unionBy = unionBy;
14489     lodash.unionWith = unionWith;
14490     lodash.uniq = uniq;
14491     lodash.uniqBy = uniqBy;
14492     lodash.uniqWith = uniqWith;
14493     lodash.unset = unset;
14494     lodash.unzip = unzip;
14495     lodash.unzipWith = unzipWith;
14496     lodash.values = values;
14497     lodash.valuesIn = valuesIn;
14498     lodash.without = without;
14499     lodash.words = words;
14500     lodash.wrap = wrap;
14501     lodash.xor = xor;
14502     lodash.xorBy = xorBy;
14503     lodash.xorWith = xorWith;
14504     lodash.zip = zip;
14505     lodash.zipObject = zipObject;
14506     lodash.zipObjectDeep = zipObjectDeep;
14507     lodash.zipWith = zipWith;
14508
14509     // Add aliases.
14510     lodash.extend = assignIn;
14511     lodash.extendWith = assignInWith;
14512
14513     // Add functions to `lodash.prototype`.
14514     mixin(lodash, lodash);
14515
14516     /*------------------------------------------------------------------------*/
14517
14518     // Add functions that return unwrapped values when chaining.
14519     lodash.add = add;
14520     lodash.attempt = attempt;
14521     lodash.camelCase = camelCase;
14522     lodash.capitalize = capitalize;
14523     lodash.ceil = ceil;
14524     lodash.clamp = clamp;
14525     lodash.clone = clone;
14526     lodash.cloneDeep = cloneDeep;
14527     lodash.cloneDeepWith = cloneDeepWith;
14528     lodash.cloneWith = cloneWith;
14529     lodash.deburr = deburr;
14530     lodash.endsWith = endsWith;
14531     lodash.eq = eq;
14532     lodash.escape = escape;
14533     lodash.escapeRegExp = escapeRegExp;
14534     lodash.every = every;
14535     lodash.find = find;
14536     lodash.findIndex = findIndex;
14537     lodash.findKey = findKey;
14538     lodash.findLast = findLast;
14539     lodash.findLastIndex = findLastIndex;
14540     lodash.findLastKey = findLastKey;
14541     lodash.floor = floor;
14542     lodash.forEach = forEach;
14543     lodash.forEachRight = forEachRight;
14544     lodash.forIn = forIn;
14545     lodash.forInRight = forInRight;
14546     lodash.forOwn = forOwn;
14547     lodash.forOwnRight = forOwnRight;
14548     lodash.get = get;
14549     lodash.gt = gt;
14550     lodash.gte = gte;
14551     lodash.has = has;
14552     lodash.hasIn = hasIn;
14553     lodash.head = head;
14554     lodash.identity = identity;
14555     lodash.includes = includes;
14556     lodash.indexOf = indexOf;
14557     lodash.inRange = inRange;
14558     lodash.invoke = invoke;
14559     lodash.isArguments = isArguments;
14560     lodash.isArray = isArray;
14561     lodash.isArrayBuffer = isArrayBuffer;
14562     lodash.isArrayLike = isArrayLike;
14563     lodash.isArrayLikeObject = isArrayLikeObject;
14564     lodash.isBoolean = isBoolean;
14565     lodash.isBuffer = isBuffer;
14566     lodash.isDate = isDate;
14567     lodash.isElement = isElement;
14568     lodash.isEmpty = isEmpty;
14569     lodash.isEqual = isEqual;
14570     lodash.isEqualWith = isEqualWith;
14571     lodash.isError = isError;
14572     lodash.isFinite = isFinite;
14573     lodash.isFunction = isFunction;
14574     lodash.isInteger = isInteger;
14575     lodash.isLength = isLength;
14576     lodash.isMap = isMap;
14577     lodash.isMatch = isMatch;
14578     lodash.isMatchWith = isMatchWith;
14579     lodash.isNaN = isNaN;
14580     lodash.isNative = isNative;
14581     lodash.isNil = isNil;
14582     lodash.isNull = isNull;
14583     lodash.isNumber = isNumber;
14584     lodash.isObject = isObject;
14585     lodash.isObjectLike = isObjectLike;
14586     lodash.isPlainObject = isPlainObject;
14587     lodash.isRegExp = isRegExp;
14588     lodash.isSafeInteger = isSafeInteger;
14589     lodash.isSet = isSet;
14590     lodash.isString = isString;
14591     lodash.isSymbol = isSymbol;
14592     lodash.isTypedArray = isTypedArray;
14593     lodash.isUndefined = isUndefined;
14594     lodash.isWeakMap = isWeakMap;
14595     lodash.isWeakSet = isWeakSet;
14596     lodash.join = join;
14597     lodash.kebabCase = kebabCase;
14598     lodash.last = last;
14599     lodash.lastIndexOf = lastIndexOf;
14600     lodash.lowerCase = lowerCase;
14601     lodash.lowerFirst = lowerFirst;
14602     lodash.lt = lt;
14603     lodash.lte = lte;
14604     lodash.max = max;
14605     lodash.maxBy = maxBy;
14606     lodash.mean = mean;
14607     lodash.min = min;
14608     lodash.minBy = minBy;
14609     lodash.noConflict = noConflict;
14610     lodash.noop = noop;
14611     lodash.now = now;
14612     lodash.pad = pad;
14613     lodash.padEnd = padEnd;
14614     lodash.padStart = padStart;
14615     lodash.parseInt = parseInt;
14616     lodash.random = random;
14617     lodash.reduce = reduce;
14618     lodash.reduceRight = reduceRight;
14619     lodash.repeat = repeat;
14620     lodash.replace = replace;
14621     lodash.result = result;
14622     lodash.round = round;
14623     lodash.runInContext = runInContext;
14624     lodash.sample = sample;
14625     lodash.size = size;
14626     lodash.snakeCase = snakeCase;
14627     lodash.some = some;
14628     lodash.sortedIndex = sortedIndex;
14629     lodash.sortedIndexBy = sortedIndexBy;
14630     lodash.sortedIndexOf = sortedIndexOf;
14631     lodash.sortedLastIndex = sortedLastIndex;
14632     lodash.sortedLastIndexBy = sortedLastIndexBy;
14633     lodash.sortedLastIndexOf = sortedLastIndexOf;
14634     lodash.startCase = startCase;
14635     lodash.startsWith = startsWith;
14636     lodash.subtract = subtract;
14637     lodash.sum = sum;
14638     lodash.sumBy = sumBy;
14639     lodash.template = template;
14640     lodash.times = times;
14641     lodash.toInteger = toInteger;
14642     lodash.toLength = toLength;
14643     lodash.toLower = toLower;
14644     lodash.toNumber = toNumber;
14645     lodash.toSafeInteger = toSafeInteger;
14646     lodash.toString = toString;
14647     lodash.toUpper = toUpper;
14648     lodash.trim = trim;
14649     lodash.trimEnd = trimEnd;
14650     lodash.trimStart = trimStart;
14651     lodash.truncate = truncate;
14652     lodash.unescape = unescape;
14653     lodash.uniqueId = uniqueId;
14654     lodash.upperCase = upperCase;
14655     lodash.upperFirst = upperFirst;
14656
14657     // Add aliases.
14658     lodash.each = forEach;
14659     lodash.eachRight = forEachRight;
14660     lodash.first = head;
14661
14662     mixin(lodash, (function() {
14663       var source = {};
14664       baseForOwn(lodash, function(func, methodName) {
14665         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
14666           source[methodName] = func;
14667         }
14668       });
14669       return source;
14670     }()), { 'chain': false });
14671
14672     /*------------------------------------------------------------------------*/
14673
14674     /**
14675      * The semantic version number.
14676      *
14677      * @static
14678      * @memberOf _
14679      * @type {string}
14680      */
14681     lodash.VERSION = VERSION;
14682
14683     // Assign default placeholders.
14684     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
14685       lodash[methodName].placeholder = lodash;
14686     });
14687
14688     // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
14689     arrayEach(['drop', 'take'], function(methodName, index) {
14690       LazyWrapper.prototype[methodName] = function(n) {
14691         var filtered = this.__filtered__;
14692         if (filtered && !index) {
14693           return new LazyWrapper(this);
14694         }
14695         n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
14696
14697         var result = this.clone();
14698         if (filtered) {
14699           result.__takeCount__ = nativeMin(n, result.__takeCount__);
14700         } else {
14701           result.__views__.push({
14702             'size': nativeMin(n, MAX_ARRAY_LENGTH),
14703             'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
14704           });
14705         }
14706         return result;
14707       };
14708
14709       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
14710         return this.reverse()[methodName](n).reverse();
14711       };
14712     });
14713
14714     // Add `LazyWrapper` methods that accept an `iteratee` value.
14715     arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
14716       var type = index + 1,
14717           isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
14718
14719       LazyWrapper.prototype[methodName] = function(iteratee) {
14720         var result = this.clone();
14721         result.__iteratees__.push({
14722           'iteratee': getIteratee(iteratee, 3),
14723           'type': type
14724         });
14725         result.__filtered__ = result.__filtered__ || isFilter;
14726         return result;
14727       };
14728     });
14729
14730     // Add `LazyWrapper` methods for `_.head` and `_.last`.
14731     arrayEach(['head', 'last'], function(methodName, index) {
14732       var takeName = 'take' + (index ? 'Right' : '');
14733
14734       LazyWrapper.prototype[methodName] = function() {
14735         return this[takeName](1).value()[0];
14736       };
14737     });
14738
14739     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
14740     arrayEach(['initial', 'tail'], function(methodName, index) {
14741       var dropName = 'drop' + (index ? '' : 'Right');
14742
14743       LazyWrapper.prototype[methodName] = function() {
14744         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
14745       };
14746     });
14747
14748     LazyWrapper.prototype.compact = function() {
14749       return this.filter(identity);
14750     };
14751
14752     LazyWrapper.prototype.find = function(predicate) {
14753       return this.filter(predicate).head();
14754     };
14755
14756     LazyWrapper.prototype.findLast = function(predicate) {
14757       return this.reverse().find(predicate);
14758     };
14759
14760     LazyWrapper.prototype.invokeMap = rest(function(path, args) {
14761       if (typeof path == 'function') {
14762         return new LazyWrapper(this);
14763       }
14764       return this.map(function(value) {
14765         return baseInvoke(value, path, args);
14766       });
14767     });
14768
14769     LazyWrapper.prototype.reject = function(predicate) {
14770       predicate = getIteratee(predicate, 3);
14771       return this.filter(function(value) {
14772         return !predicate(value);
14773       });
14774     };
14775
14776     LazyWrapper.prototype.slice = function(start, end) {
14777       start = toInteger(start);
14778
14779       var result = this;
14780       if (result.__filtered__ && (start > 0 || end < 0)) {
14781         return new LazyWrapper(result);
14782       }
14783       if (start < 0) {
14784         result = result.takeRight(-start);
14785       } else if (start) {
14786         result = result.drop(start);
14787       }
14788       if (end !== undefined) {
14789         end = toInteger(end);
14790         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
14791       }
14792       return result;
14793     };
14794
14795     LazyWrapper.prototype.takeRightWhile = function(predicate) {
14796       return this.reverse().takeWhile(predicate).reverse();
14797     };
14798
14799     LazyWrapper.prototype.toArray = function() {
14800       return this.take(MAX_ARRAY_LENGTH);
14801     };
14802
14803     // Add `LazyWrapper` methods to `lodash.prototype`.
14804     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14805       var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
14806           isTaker = /^(?:head|last)$/.test(methodName),
14807           lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
14808           retUnwrapped = isTaker || /^find/.test(methodName);
14809
14810       if (!lodashFunc) {
14811         return;
14812       }
14813       lodash.prototype[methodName] = function() {
14814         var value = this.__wrapped__,
14815             args = isTaker ? [1] : arguments,
14816             isLazy = value instanceof LazyWrapper,
14817             iteratee = args[0],
14818             useLazy = isLazy || isArray(value);
14819
14820         var interceptor = function(value) {
14821           var result = lodashFunc.apply(lodash, arrayPush([value], args));
14822           return (isTaker && chainAll) ? result[0] : result;
14823         };
14824
14825         if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
14826           // Avoid lazy use if the iteratee has a "length" value other than `1`.
14827           isLazy = useLazy = false;
14828         }
14829         var chainAll = this.__chain__,
14830             isHybrid = !!this.__actions__.length,
14831             isUnwrapped = retUnwrapped && !chainAll,
14832             onlyLazy = isLazy && !isHybrid;
14833
14834         if (!retUnwrapped && useLazy) {
14835           value = onlyLazy ? value : new LazyWrapper(this);
14836           var result = func.apply(value, args);
14837           result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
14838           return new LodashWrapper(result, chainAll);
14839         }
14840         if (isUnwrapped && onlyLazy) {
14841           return func.apply(this, args);
14842         }
14843         result = this.thru(interceptor);
14844         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
14845       };
14846     });
14847
14848     // Add `Array` and `String` methods to `lodash.prototype`.
14849     arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
14850       var func = arrayProto[methodName],
14851           chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
14852           retUnwrapped = /^(?:pop|shift)$/.test(methodName);
14853
14854       lodash.prototype[methodName] = function() {
14855         var args = arguments;
14856         if (retUnwrapped && !this.__chain__) {
14857           return func.apply(this.value(), args);
14858         }
14859         return this[chainName](function(value) {
14860           return func.apply(value, args);
14861         });
14862       };
14863     });
14864
14865     // Map minified function names to their real names.
14866     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14867       var lodashFunc = lodash[methodName];
14868       if (lodashFunc) {
14869         var key = (lodashFunc.name + ''),
14870             names = realNames[key] || (realNames[key] = []);
14871
14872         names.push({ 'name': methodName, 'func': lodashFunc });
14873       }
14874     });
14875
14876     realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{
14877       'name': 'wrapper',
14878       'func': undefined
14879     }];
14880
14881     // Add functions to the lazy wrapper.
14882     LazyWrapper.prototype.clone = lazyClone;
14883     LazyWrapper.prototype.reverse = lazyReverse;
14884     LazyWrapper.prototype.value = lazyValue;
14885
14886     // Add chaining functions to the `lodash` wrapper.
14887     lodash.prototype.at = wrapperAt;
14888     lodash.prototype.chain = wrapperChain;
14889     lodash.prototype.commit = wrapperCommit;
14890     lodash.prototype.flatMap = wrapperFlatMap;
14891     lodash.prototype.next = wrapperNext;
14892     lodash.prototype.plant = wrapperPlant;
14893     lodash.prototype.reverse = wrapperReverse;
14894     lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
14895
14896     if (iteratorSymbol) {
14897       lodash.prototype[iteratorSymbol] = wrapperToIterator;
14898     }
14899     return lodash;
14900   }
14901
14902   /*--------------------------------------------------------------------------*/
14903
14904   // Export lodash.
14905   var _ = runInContext();
14906
14907   // Expose lodash on the free variable `window` or `self` when available. This
14908   // prevents errors in cases where lodash is loaded by a script tag in the presence
14909   // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
14910   (freeWindow || freeSelf || {})._ = _;
14911
14912   // Some AMD build optimizers like r.js check for condition patterns like the following:
14913   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
14914     // Define as an anonymous module so, through path mapping, it can be
14915     // referenced as the "underscore" module.
14916     define(function() {
14917       return _;
14918     });
14919   }
14920   // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
14921   else if (freeExports && freeModule) {
14922     // Export for Node.js.
14923     if (moduleExports) {
14924       (freeModule.exports = _)._ = _;
14925     }
14926     // Export for CommonJS support.
14927     freeExports._ = _;
14928   }
14929   else {
14930     // Export to the global object.
14931     root._ = _;
14932   }
14933 }.call(this));