Built motion from commit 1038d87.|0.0.141
[motion.git] / public / bower_components / lodash / lodash.js
1 /**
2  * @license
3  * lodash 4.5.1 <https://lodash.com/>
4  * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
5  * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6  * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7  * Available under MIT license <https://lodash.com/license>
8  */
9 ;(function() {
10
11   /** Used as a safe reference for `undefined` in pre-ES5 environments. */
12   var undefined;
13
14   /** Used as the semantic version number. */
15   var VERSION = '4.5.1';
16
17   /** Used to compose bitmasks for wrapper metadata. */
18   var BIND_FLAG = 1,
19       BIND_KEY_FLAG = 2,
20       CURRY_BOUND_FLAG = 4,
21       CURRY_FLAG = 8,
22       CURRY_RIGHT_FLAG = 16,
23       PARTIAL_FLAG = 32,
24       PARTIAL_RIGHT_FLAG = 64,
25       ARY_FLAG = 128,
26       REARG_FLAG = 256,
27       FLIP_FLAG = 512;
28
29   /** Used to compose bitmasks for comparison styles. */
30   var UNORDERED_COMPARE_FLAG = 1,
31       PARTIAL_COMPARE_FLAG = 2;
32
33   /** Used as default options for `_.truncate`. */
34   var DEFAULT_TRUNC_LENGTH = 30,
35       DEFAULT_TRUNC_OMISSION = '...';
36
37   /** Used to detect hot functions by number of calls within a span of milliseconds. */
38   var HOT_COUNT = 150,
39       HOT_SPAN = 16;
40
41   /** Used as the size to enable large array optimizations. */
42   var LARGE_ARRAY_SIZE = 200;
43
44   /** Used to indicate the type of lazy iteratees. */
45   var LAZY_FILTER_FLAG = 1,
46       LAZY_MAP_FLAG = 2,
47       LAZY_WHILE_FLAG = 3;
48
49   /** Used as the `TypeError` message for "Functions" methods. */
50   var FUNC_ERROR_TEXT = 'Expected a function';
51
52   /** Used to stand-in for `undefined` hash values. */
53   var HASH_UNDEFINED = '__lodash_hash_undefined__';
54
55   /** Used as references for various `Number` constants. */
56   var INFINITY = 1 / 0,
57       MAX_SAFE_INTEGER = 9007199254740991,
58       MAX_INTEGER = 1.7976931348623157e+308,
59       NAN = 0 / 0;
60
61   /** Used as references for the maximum length and index of an array. */
62   var MAX_ARRAY_LENGTH = 4294967295,
63       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
64       HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
65
66   /** Used as the internal argument placeholder. */
67   var PLACEHOLDER = '__lodash_placeholder__';
68
69   /** `Object#toString` result references. */
70   var argsTag = '[object Arguments]',
71       arrayTag = '[object Array]',
72       boolTag = '[object Boolean]',
73       dateTag = '[object Date]',
74       errorTag = '[object Error]',
75       funcTag = '[object Function]',
76       genTag = '[object GeneratorFunction]',
77       mapTag = '[object Map]',
78       numberTag = '[object Number]',
79       objectTag = '[object Object]',
80       regexpTag = '[object RegExp]',
81       setTag = '[object Set]',
82       stringTag = '[object String]',
83       symbolTag = '[object Symbol]',
84       weakMapTag = '[object WeakMap]',
85       weakSetTag = '[object WeakSet]';
86
87   var arrayBufferTag = '[object ArrayBuffer]',
88       float32Tag = '[object Float32Array]',
89       float64Tag = '[object Float64Array]',
90       int8Tag = '[object Int8Array]',
91       int16Tag = '[object Int16Array]',
92       int32Tag = '[object Int32Array]',
93       uint8Tag = '[object Uint8Array]',
94       uint8ClampedTag = '[object Uint8ClampedArray]',
95       uint16Tag = '[object Uint16Array]',
96       uint32Tag = '[object Uint32Array]';
97
98   /** Used to match empty string literals in compiled template source. */
99   var reEmptyStringLeading = /\b__p \+= '';/g,
100       reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
101       reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
102
103   /** Used to match HTML entities and HTML characters. */
104   var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
105       reUnescapedHtml = /[&<>"'`]/g,
106       reHasEscapedHtml = RegExp(reEscapedHtml.source),
107       reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
108
109   /** Used to match template delimiters. */
110   var reEscape = /<%-([\s\S]+?)%>/g,
111       reEvaluate = /<%([\s\S]+?)%>/g,
112       reInterpolate = /<%=([\s\S]+?)%>/g;
113
114   /** Used to match property names within property paths. */
115   var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
116       reIsPlainProp = /^\w*$/,
117       rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
118
119   /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
120   var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
121       reHasRegExpChar = RegExp(reRegExpChar.source);
122
123   /** Used to match leading and trailing whitespace. */
124   var reTrim = /^\s+|\s+$/g,
125       reTrimStart = /^\s+/,
126       reTrimEnd = /\s+$/;
127
128   /** Used to match backslashes in property paths. */
129   var reEscapeChar = /\\(\\)?/g;
130
131   /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
132   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
133
134   /** Used to match `RegExp` flags from their coerced string values. */
135   var reFlags = /\w*$/;
136
137   /** Used to detect hexadecimal string values. */
138   var reHasHexPrefix = /^0x/i;
139
140   /** Used to detect bad signed hexadecimal string values. */
141   var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
142
143   /** Used to detect binary string values. */
144   var reIsBinary = /^0b[01]+$/i;
145
146   /** Used to detect host constructors (Safari > 5). */
147   var reIsHostCtor = /^\[object .+?Constructor\]$/;
148
149   /** Used to detect octal string values. */
150   var reIsOctal = /^0o[0-7]+$/i;
151
152   /** Used to detect unsigned integer values. */
153   var reIsUint = /^(?:0|[1-9]\d*)$/;
154
155   /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
156   var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
157
158   /** Used to ensure capturing order of template delimiters. */
159   var reNoMatch = /($^)/;
160
161   /** Used to match unescaped characters in compiled string literals. */
162   var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
163
164   /** Used to compose unicode character classes. */
165   var rsAstralRange = '\\ud800-\\udfff',
166       rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
167       rsComboSymbolsRange = '\\u20d0-\\u20f0',
168       rsDingbatRange = '\\u2700-\\u27bf',
169       rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
170       rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
171       rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
172       rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
173       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',
174       rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
175       rsVarRange = '\\ufe0e\\ufe0f',
176       rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
177
178   /** Used to compose unicode capture groups. */
179   var rsAstral = '[' + rsAstralRange + ']',
180       rsBreak = '[' + rsBreakRange + ']',
181       rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
182       rsDigits = '\\d+',
183       rsDingbat = '[' + rsDingbatRange + ']',
184       rsLower = '[' + rsLowerRange + ']',
185       rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
186       rsFitz = '\\ud83c[\\udffb-\\udfff]',
187       rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
188       rsNonAstral = '[^' + rsAstralRange + ']',
189       rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
190       rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
191       rsUpper = '[' + rsUpperRange + ']',
192       rsZWJ = '\\u200d';
193
194   /** Used to compose unicode regexes. */
195   var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
196       rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
197       reOptMod = rsModifier + '?',
198       rsOptVar = '[' + rsVarRange + ']?',
199       rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
200       rsSeq = rsOptVar + reOptMod + rsOptJoin,
201       rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
202       rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
203
204   /**
205    * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
206    * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
207    */
208   var reComboMark = RegExp(rsCombo, 'g');
209
210   /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
211   var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
212
213   /** 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/). */
214   var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
215
216   /** Used to match non-compound words composed of alphanumeric characters. */
217   var reBasicWord = /[a-zA-Z0-9]+/g;
218
219   /** Used to match complex or compound words. */
220   var reComplexWord = RegExp([
221     rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
222     rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
223     rsUpper + '?' + rsLowerMisc + '+',
224     rsUpper + '+',
225     rsDigits,
226     rsEmoji
227   ].join('|'), 'g');
228
229   /** Used to detect strings that need a more robust regexp to match words. */
230   var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
231
232   /** Used to assign default `context` object properties. */
233   var contextProps = [
234     'Array', 'Buffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
235     'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
236     'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
237     'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
238     'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
239   ];
240
241   /** Used to make template sourceURLs easier to identify. */
242   var templateCounter = -1;
243
244   /** Used to identify `toStringTag` values of typed arrays. */
245   var typedArrayTags = {};
246   typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
247   typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
248   typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
249   typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
250   typedArrayTags[uint32Tag] = true;
251   typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
252   typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
253   typedArrayTags[dateTag] = typedArrayTags[errorTag] =
254   typedArrayTags[funcTag] = typedArrayTags[mapTag] =
255   typedArrayTags[numberTag] = typedArrayTags[objectTag] =
256   typedArrayTags[regexpTag] = typedArrayTags[setTag] =
257   typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
258
259   /** Used to identify `toStringTag` values supported by `_.clone`. */
260   var cloneableTags = {};
261   cloneableTags[argsTag] = cloneableTags[arrayTag] =
262   cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
263   cloneableTags[dateTag] = cloneableTags[float32Tag] =
264   cloneableTags[float64Tag] = cloneableTags[int8Tag] =
265   cloneableTags[int16Tag] = cloneableTags[int32Tag] =
266   cloneableTags[mapTag] = cloneableTags[numberTag] =
267   cloneableTags[objectTag] = cloneableTags[regexpTag] =
268   cloneableTags[setTag] = cloneableTags[stringTag] =
269   cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
270   cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
271   cloneableTags[uint32Tag] = true;
272   cloneableTags[errorTag] = cloneableTags[funcTag] =
273   cloneableTags[weakMapTag] = false;
274
275   /** Used to map latin-1 supplementary letters to basic latin letters. */
276   var deburredLetters = {
277     '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
278     '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
279     '\xc7': 'C',  '\xe7': 'c',
280     '\xd0': 'D',  '\xf0': 'd',
281     '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
282     '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
283     '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
284     '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
285     '\xd1': 'N',  '\xf1': 'n',
286     '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
287     '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
288     '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
289     '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
290     '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
291     '\xc6': 'Ae', '\xe6': 'ae',
292     '\xde': 'Th', '\xfe': 'th',
293     '\xdf': 'ss'
294   };
295
296   /** Used to map characters to HTML entities. */
297   var htmlEscapes = {
298     '&': '&amp;',
299     '<': '&lt;',
300     '>': '&gt;',
301     '"': '&quot;',
302     "'": '&#39;',
303     '`': '&#96;'
304   };
305
306   /** Used to map HTML entities to characters. */
307   var htmlUnescapes = {
308     '&amp;': '&',
309     '&lt;': '<',
310     '&gt;': '>',
311     '&quot;': '"',
312     '&#39;': "'",
313     '&#96;': '`'
314   };
315
316   /** Used to determine if values are of the language type `Object`. */
317   var objectTypes = {
318     'function': true,
319     'object': true
320   };
321
322   /** Used to escape characters for inclusion in compiled string literals. */
323   var stringEscapes = {
324     '\\': '\\',
325     "'": "'",
326     '\n': 'n',
327     '\r': 'r',
328     '\u2028': 'u2028',
329     '\u2029': 'u2029'
330   };
331
332   /** Built-in method references without a dependency on `root`. */
333   var freeParseFloat = parseFloat,
334       freeParseInt = parseInt;
335
336   /** Detect free variable `exports`. */
337   var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
338     ? exports
339     : undefined;
340
341   /** Detect free variable `module`. */
342   var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
343     ? module
344     : undefined;
345
346   /** Detect the popular CommonJS extension `module.exports`. */
347   var moduleExports = (freeModule && freeModule.exports === freeExports)
348     ? freeExports
349     : undefined;
350
351   /** Detect free variable `global` from Node.js. */
352   var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
353
354   /** Detect free variable `self`. */
355   var freeSelf = checkGlobal(objectTypes[typeof self] && self);
356
357   /** Detect free variable `window`. */
358   var freeWindow = checkGlobal(objectTypes[typeof window] && window);
359
360   /** Detect `this` as the global object. */
361   var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
362
363   /**
364    * Used as a reference to the global object.
365    *
366    * The `this` value is used if it's the global object to avoid Greasemonkey's
367    * restricted `window` object, otherwise the `window` object is used.
368    */
369   var root = freeGlobal ||
370     ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
371       freeSelf || thisGlobal || Function('return this')();
372
373   /*--------------------------------------------------------------------------*/
374
375   /**
376    * Adds the key-value `pair` to `map`.
377    *
378    * @private
379    * @param {Object} map The map to modify.
380    * @param {Array} pair The key-value pair to add.
381    * @returns {Object} Returns `map`.
382    */
383   function addMapEntry(map, pair) {
384     map.set(pair[0], pair[1]);
385     return map;
386   }
387
388   /**
389    * Adds `value` to `set`.
390    *
391    * @private
392    * @param {Object} set The set to modify.
393    * @param {*} value The value to add.
394    * @returns {Object} Returns `set`.
395    */
396   function addSetEntry(set, value) {
397     set.add(value);
398     return set;
399   }
400
401   /**
402    * A faster alternative to `Function#apply`, this function invokes `func`
403    * with the `this` binding of `thisArg` and the arguments of `args`.
404    *
405    * @private
406    * @param {Function} func The function to invoke.
407    * @param {*} thisArg The `this` binding of `func`.
408    * @param {...*} args The arguments to invoke `func` with.
409    * @returns {*} Returns the result of `func`.
410    */
411   function apply(func, thisArg, args) {
412     var length = args.length;
413     switch (length) {
414       case 0: return func.call(thisArg);
415       case 1: return func.call(thisArg, args[0]);
416       case 2: return func.call(thisArg, args[0], args[1]);
417       case 3: return func.call(thisArg, args[0], args[1], args[2]);
418     }
419     return func.apply(thisArg, args);
420   }
421
422   /**
423    * A specialized version of `baseAggregator` for arrays.
424    *
425    * @private
426    * @param {Array} array The array to iterate over.
427    * @param {Function} setter The function to set `accumulator` values.
428    * @param {Function} iteratee The iteratee to transform keys.
429    * @param {Object} accumulator The initial aggregated object.
430    * @returns {Function} Returns `accumulator`.
431    */
432   function arrayAggregator(array, setter, iteratee, accumulator) {
433     var index = -1,
434         length = array.length;
435
436     while (++index < length) {
437       var value = array[index];
438       setter(accumulator, value, iteratee(value), array);
439     }
440     return accumulator;
441   }
442
443   /**
444    * Creates a new array concatenating `array` with `other`.
445    *
446    * @private
447    * @param {Array} array The first array to concatenate.
448    * @param {Array} other The second array to concatenate.
449    * @returns {Array} Returns the new concatenated array.
450    */
451   function arrayConcat(array, other) {
452     var index = -1,
453         length = array.length,
454         othIndex = -1,
455         othLength = other.length,
456         result = Array(length + othLength);
457
458     while (++index < length) {
459       result[index] = array[index];
460     }
461     while (++othIndex < othLength) {
462       result[index++] = other[othIndex];
463     }
464     return result;
465   }
466
467   /**
468    * A specialized version of `_.forEach` for arrays without support for
469    * iteratee shorthands.
470    *
471    * @private
472    * @param {Array} array The array to iterate over.
473    * @param {Function} iteratee The function invoked per iteration.
474    * @returns {Array} Returns `array`.
475    */
476   function arrayEach(array, iteratee) {
477     var index = -1,
478         length = array.length;
479
480     while (++index < length) {
481       if (iteratee(array[index], index, array) === false) {
482         break;
483       }
484     }
485     return array;
486   }
487
488   /**
489    * A specialized version of `_.forEachRight` for arrays without support for
490    * iteratee shorthands.
491    *
492    * @private
493    * @param {Array} array The array to iterate over.
494    * @param {Function} iteratee The function invoked per iteration.
495    * @returns {Array} Returns `array`.
496    */
497   function arrayEachRight(array, iteratee) {
498     var length = array.length;
499
500     while (length--) {
501       if (iteratee(array[length], length, array) === false) {
502         break;
503       }
504     }
505     return array;
506   }
507
508   /**
509    * A specialized version of `_.every` for arrays without support for
510    * iteratee shorthands.
511    *
512    * @private
513    * @param {Array} array The array to iterate over.
514    * @param {Function} predicate The function invoked per iteration.
515    * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
516    */
517   function arrayEvery(array, predicate) {
518     var index = -1,
519         length = array.length;
520
521     while (++index < length) {
522       if (!predicate(array[index], index, array)) {
523         return false;
524       }
525     }
526     return true;
527   }
528
529   /**
530    * A specialized version of `_.filter` for arrays without support for
531    * iteratee shorthands.
532    *
533    * @private
534    * @param {Array} array The array to iterate over.
535    * @param {Function} predicate The function invoked per iteration.
536    * @returns {Array} Returns the new filtered array.
537    */
538   function arrayFilter(array, predicate) {
539     var index = -1,
540         length = array.length,
541         resIndex = -1,
542         result = [];
543
544     while (++index < length) {
545       var value = array[index];
546       if (predicate(value, index, array)) {
547         result[++resIndex] = value;
548       }
549     }
550     return result;
551   }
552
553   /**
554    * A specialized version of `_.includes` for arrays without support for
555    * specifying an index to search from.
556    *
557    * @private
558    * @param {Array} array The array to search.
559    * @param {*} target The value to search for.
560    * @returns {boolean} Returns `true` if `target` is found, else `false`.
561    */
562   function arrayIncludes(array, value) {
563     return !!array.length && baseIndexOf(array, value, 0) > -1;
564   }
565
566   /**
567    * A specialized version of `_.includesWith` for arrays without support for
568    * specifying an index to search from.
569    *
570    * @private
571    * @param {Array} array The array to search.
572    * @param {*} target The value to search for.
573    * @param {Function} comparator The comparator invoked per element.
574    * @returns {boolean} Returns `true` if `target` is found, else `false`.
575    */
576   function arrayIncludesWith(array, value, comparator) {
577     var index = -1,
578         length = array.length;
579
580     while (++index < length) {
581       if (comparator(value, array[index])) {
582         return true;
583       }
584     }
585     return false;
586   }
587
588   /**
589    * A specialized version of `_.map` for arrays without support for iteratee
590    * shorthands.
591    *
592    * @private
593    * @param {Array} array The array to iterate over.
594    * @param {Function} iteratee The function invoked per iteration.
595    * @returns {Array} Returns the new mapped array.
596    */
597   function arrayMap(array, iteratee) {
598     var index = -1,
599         length = array.length,
600         result = Array(length);
601
602     while (++index < length) {
603       result[index] = iteratee(array[index], index, array);
604     }
605     return result;
606   }
607
608   /**
609    * Appends the elements of `values` to `array`.
610    *
611    * @private
612    * @param {Array} array The array to modify.
613    * @param {Array} values The values to append.
614    * @returns {Array} Returns `array`.
615    */
616   function arrayPush(array, values) {
617     var index = -1,
618         length = values.length,
619         offset = array.length;
620
621     while (++index < length) {
622       array[offset + index] = values[index];
623     }
624     return array;
625   }
626
627   /**
628    * A specialized version of `_.reduce` for arrays without support for
629    * iteratee shorthands.
630    *
631    * @private
632    * @param {Array} array The array to iterate over.
633    * @param {Function} iteratee The function invoked per iteration.
634    * @param {*} [accumulator] The initial value.
635    * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
636    * @returns {*} Returns the accumulated value.
637    */
638   function arrayReduce(array, iteratee, accumulator, initAccum) {
639     var index = -1,
640         length = array.length;
641
642     if (initAccum && length) {
643       accumulator = array[++index];
644     }
645     while (++index < length) {
646       accumulator = iteratee(accumulator, array[index], index, array);
647     }
648     return accumulator;
649   }
650
651   /**
652    * A specialized version of `_.reduceRight` for arrays without support for
653    * iteratee shorthands.
654    *
655    * @private
656    * @param {Array} array The array to iterate over.
657    * @param {Function} iteratee The function invoked per iteration.
658    * @param {*} [accumulator] The initial value.
659    * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value.
660    * @returns {*} Returns the accumulated value.
661    */
662   function arrayReduceRight(array, iteratee, accumulator, initAccum) {
663     var length = array.length;
664     if (initAccum && length) {
665       accumulator = array[--length];
666     }
667     while (length--) {
668       accumulator = iteratee(accumulator, array[length], length, array);
669     }
670     return accumulator;
671   }
672
673   /**
674    * A specialized version of `_.some` for arrays without support for iteratee
675    * shorthands.
676    *
677    * @private
678    * @param {Array} array The array to iterate over.
679    * @param {Function} predicate The function invoked per iteration.
680    * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
681    */
682   function arraySome(array, predicate) {
683     var index = -1,
684         length = array.length;
685
686     while (++index < length) {
687       if (predicate(array[index], index, array)) {
688         return true;
689       }
690     }
691     return false;
692   }
693
694   /**
695    * The base implementation of methods like `_.max` and `_.min` which accepts a
696    * `comparator` to determine the extremum value.
697    *
698    * @private
699    * @param {Array} array The array to iterate over.
700    * @param {Function} iteratee The iteratee invoked per iteration.
701    * @param {Function} comparator The comparator used to compare values.
702    * @returns {*} Returns the extremum value.
703    */
704   function baseExtremum(array, iteratee, comparator) {
705     var index = -1,
706         length = array.length;
707
708     while (++index < length) {
709       var value = array[index],
710           current = iteratee(value);
711
712       if (current != null && (computed === undefined
713             ? current === current
714             : comparator(current, computed)
715           )) {
716         var computed = current,
717             result = value;
718       }
719     }
720     return result;
721   }
722
723   /**
724    * The base implementation of methods like `_.find` and `_.findKey`, without
725    * support for iteratee shorthands, which iterates over `collection` using
726    * `eachFunc`.
727    *
728    * @private
729    * @param {Array|Object} collection The collection to search.
730    * @param {Function} predicate The function invoked per iteration.
731    * @param {Function} eachFunc The function to iterate over `collection`.
732    * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
733    * @returns {*} Returns the found element or its key, else `undefined`.
734    */
735   function baseFind(collection, predicate, eachFunc, retKey) {
736     var result;
737     eachFunc(collection, function(value, key, collection) {
738       if (predicate(value, key, collection)) {
739         result = retKey ? key : value;
740         return false;
741       }
742     });
743     return result;
744   }
745
746   /**
747    * The base implementation of `_.findIndex` and `_.findLastIndex` without
748    * support for iteratee shorthands.
749    *
750    * @private
751    * @param {Array} array The array to search.
752    * @param {Function} predicate The function invoked per iteration.
753    * @param {boolean} [fromRight] Specify iterating from right to left.
754    * @returns {number} Returns the index of the matched value, else `-1`.
755    */
756   function baseFindIndex(array, predicate, fromRight) {
757     var length = array.length,
758         index = fromRight ? length : -1;
759
760     while ((fromRight ? index-- : ++index < length)) {
761       if (predicate(array[index], index, array)) {
762         return index;
763       }
764     }
765     return -1;
766   }
767
768   /**
769    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
770    *
771    * @private
772    * @param {Array} array The array to search.
773    * @param {*} value The value to search for.
774    * @param {number} fromIndex The index to search from.
775    * @returns {number} Returns the index of the matched value, else `-1`.
776    */
777   function baseIndexOf(array, value, fromIndex) {
778     if (value !== value) {
779       return indexOfNaN(array, fromIndex);
780     }
781     var index = fromIndex - 1,
782         length = array.length;
783
784     while (++index < length) {
785       if (array[index] === value) {
786         return index;
787       }
788     }
789     return -1;
790   }
791
792   /**
793    * The base implementation of `_.reduce` and `_.reduceRight`, without support
794    * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
795    *
796    * @private
797    * @param {Array|Object} collection The collection to iterate over.
798    * @param {Function} iteratee The function invoked per iteration.
799    * @param {*} accumulator The initial value.
800    * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
801    * @param {Function} eachFunc The function to iterate over `collection`.
802    * @returns {*} Returns the accumulated value.
803    */
804   function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
805     eachFunc(collection, function(value, index, collection) {
806       accumulator = initAccum
807         ? (initAccum = false, value)
808         : iteratee(accumulator, value, index, collection);
809     });
810     return accumulator;
811   }
812
813   /**
814    * The base implementation of `_.sortBy` which uses `comparer` to define
815    * the sort order of `array` and replaces criteria objects with their
816    * corresponding values.
817    *
818    * @private
819    * @param {Array} array The array to sort.
820    * @param {Function} comparer The function to define sort order.
821    * @returns {Array} Returns `array`.
822    */
823   function baseSortBy(array, comparer) {
824     var length = array.length;
825
826     array.sort(comparer);
827     while (length--) {
828       array[length] = array[length].value;
829     }
830     return array;
831   }
832
833   /**
834    * The base implementation of `_.sum` without support for iteratee shorthands.
835    *
836    * @private
837    * @param {Array} array The array to iterate over.
838    * @param {Function} iteratee The function invoked per iteration.
839    * @returns {number} Returns the sum.
840    */
841   function baseSum(array, iteratee) {
842     var result,
843         index = -1,
844         length = array.length;
845
846     while (++index < length) {
847       var current = iteratee(array[index]);
848       if (current !== undefined) {
849         result = result === undefined ? current : (result + current);
850       }
851     }
852     return result;
853   }
854
855   /**
856    * The base implementation of `_.times` without support for iteratee shorthands
857    * or max array length checks.
858    *
859    * @private
860    * @param {number} n The number of times to invoke `iteratee`.
861    * @param {Function} iteratee The function invoked per iteration.
862    * @returns {Array} Returns the array of results.
863    */
864   function baseTimes(n, iteratee) {
865     var index = -1,
866         result = Array(n);
867
868     while (++index < n) {
869       result[index] = iteratee(index);
870     }
871     return result;
872   }
873
874   /**
875    * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
876    * of key-value pairs for `object` corresponding to the property names of `props`.
877    *
878    * @private
879    * @param {Object} object The object to query.
880    * @param {Array} props The property names to get values for.
881    * @returns {Object} Returns the new array of key-value pairs.
882    */
883   function baseToPairs(object, props) {
884     return arrayMap(props, function(key) {
885       return [key, object[key]];
886     });
887   }
888
889   /**
890    * The base implementation of `_.unary` without support for storing wrapper metadata.
891    *
892    * @private
893    * @param {Function} func The function to cap arguments for.
894    * @returns {Function} Returns the new function.
895    */
896   function baseUnary(func) {
897     return function(value) {
898       return func(value);
899     };
900   }
901
902   /**
903    * The base implementation of `_.values` and `_.valuesIn` which creates an
904    * array of `object` property values corresponding to the property names
905    * of `props`.
906    *
907    * @private
908    * @param {Object} object The object to query.
909    * @param {Array} props The property names to get values for.
910    * @returns {Object} Returns the array of property values.
911    */
912   function baseValues(object, props) {
913     return arrayMap(props, function(key) {
914       return object[key];
915     });
916   }
917
918   /**
919    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
920    * that is not found in the character symbols.
921    *
922    * @private
923    * @param {Array} strSymbols The string symbols to inspect.
924    * @param {Array} chrSymbols The character symbols to find.
925    * @returns {number} Returns the index of the first unmatched string symbol.
926    */
927   function charsStartIndex(strSymbols, chrSymbols) {
928     var index = -1,
929         length = strSymbols.length;
930
931     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
932     return index;
933   }
934
935   /**
936    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
937    * that is not found in the character symbols.
938    *
939    * @private
940    * @param {Array} strSymbols The string symbols to inspect.
941    * @param {Array} chrSymbols The character symbols to find.
942    * @returns {number} Returns the index of the last unmatched string symbol.
943    */
944   function charsEndIndex(strSymbols, chrSymbols) {
945     var index = strSymbols.length;
946
947     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
948     return index;
949   }
950
951   /**
952    * Checks if `value` is a global object.
953    *
954    * @private
955    * @param {*} value The value to check.
956    * @returns {null|Object} Returns `value` if it's a global object, else `null`.
957    */
958   function checkGlobal(value) {
959     return (value && value.Object === Object) ? value : null;
960   }
961
962   /**
963    * Compares values to sort them in ascending order.
964    *
965    * @private
966    * @param {*} value The value to compare.
967    * @param {*} other The other value to compare.
968    * @returns {number} Returns the sort order indicator for `value`.
969    */
970   function compareAscending(value, other) {
971     if (value !== other) {
972       var valIsNull = value === null,
973           valIsUndef = value === undefined,
974           valIsReflexive = value === value;
975
976       var othIsNull = other === null,
977           othIsUndef = other === undefined,
978           othIsReflexive = other === other;
979
980       if ((value > other && !othIsNull) || !valIsReflexive ||
981           (valIsNull && !othIsUndef && othIsReflexive) ||
982           (valIsUndef && othIsReflexive)) {
983         return 1;
984       }
985       if ((value < other && !valIsNull) || !othIsReflexive ||
986           (othIsNull && !valIsUndef && valIsReflexive) ||
987           (othIsUndef && valIsReflexive)) {
988         return -1;
989       }
990     }
991     return 0;
992   }
993
994   /**
995    * Used by `_.orderBy` to compare multiple properties of a value to another
996    * and stable sort them.
997    *
998    * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
999    * specify an order of "desc" for descending or "asc" for ascending sort order
1000    * of corresponding values.
1001    *
1002    * @private
1003    * @param {Object} object The object to compare.
1004    * @param {Object} other The other object to compare.
1005    * @param {boolean[]|string[]} orders The order to sort by for each property.
1006    * @returns {number} Returns the sort order indicator for `object`.
1007    */
1008   function compareMultiple(object, other, orders) {
1009     var index = -1,
1010         objCriteria = object.criteria,
1011         othCriteria = other.criteria,
1012         length = objCriteria.length,
1013         ordersLength = orders.length;
1014
1015     while (++index < length) {
1016       var result = compareAscending(objCriteria[index], othCriteria[index]);
1017       if (result) {
1018         if (index >= ordersLength) {
1019           return result;
1020         }
1021         var order = orders[index];
1022         return result * (order == 'desc' ? -1 : 1);
1023       }
1024     }
1025     // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
1026     // that causes it, under certain circumstances, to provide the same value for
1027     // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
1028     // for more details.
1029     //
1030     // This also ensures a stable sort in V8 and other engines.
1031     // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
1032     return object.index - other.index;
1033   }
1034
1035   /**
1036    * Gets the number of `placeholder` occurrences in `array`.
1037    *
1038    * @private
1039    * @param {Array} array The array to inspect.
1040    * @param {*} placeholder The placeholder to search for.
1041    * @returns {number} Returns the placeholder count.
1042    */
1043   function countHolders(array, placeholder) {
1044     var length = array.length,
1045         result = 0;
1046
1047     while (length--) {
1048       if (array[length] === placeholder) {
1049         result++;
1050       }
1051     }
1052     return result;
1053   }
1054
1055   /**
1056    * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
1057    *
1058    * @private
1059    * @param {string} letter The matched letter to deburr.
1060    * @returns {string} Returns the deburred letter.
1061    */
1062   function deburrLetter(letter) {
1063     return deburredLetters[letter];
1064   }
1065
1066   /**
1067    * Used by `_.escape` to convert characters to HTML entities.
1068    *
1069    * @private
1070    * @param {string} chr The matched character to escape.
1071    * @returns {string} Returns the escaped character.
1072    */
1073   function escapeHtmlChar(chr) {
1074     return htmlEscapes[chr];
1075   }
1076
1077   /**
1078    * Used by `_.template` to escape characters for inclusion in compiled string literals.
1079    *
1080    * @private
1081    * @param {string} chr The matched character to escape.
1082    * @returns {string} Returns the escaped character.
1083    */
1084   function escapeStringChar(chr) {
1085     return '\\' + stringEscapes[chr];
1086   }
1087
1088   /**
1089    * Gets the index at which the first occurrence of `NaN` is found in `array`.
1090    *
1091    * @private
1092    * @param {Array} array The array to search.
1093    * @param {number} fromIndex The index to search from.
1094    * @param {boolean} [fromRight] Specify iterating from right to left.
1095    * @returns {number} Returns the index of the matched `NaN`, else `-1`.
1096    */
1097   function indexOfNaN(array, fromIndex, fromRight) {
1098     var length = array.length,
1099         index = fromIndex + (fromRight ? 0 : -1);
1100
1101     while ((fromRight ? index-- : ++index < length)) {
1102       var other = array[index];
1103       if (other !== other) {
1104         return index;
1105       }
1106     }
1107     return -1;
1108   }
1109
1110   /**
1111    * Checks if `value` is a host object in IE < 9.
1112    *
1113    * @private
1114    * @param {*} value The value to check.
1115    * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
1116    */
1117   function isHostObject(value) {
1118     // Many host objects are `Object` objects that can coerce to strings
1119     // despite having improperly defined `toString` methods.
1120     var result = false;
1121     if (value != null && typeof value.toString != 'function') {
1122       try {
1123         result = !!(value + '');
1124       } catch (e) {}
1125     }
1126     return result;
1127   }
1128
1129   /**
1130    * Checks if `value` is a valid array-like index.
1131    *
1132    * @private
1133    * @param {*} value The value to check.
1134    * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
1135    * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
1136    */
1137   function isIndex(value, length) {
1138     value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
1139     length = length == null ? MAX_SAFE_INTEGER : length;
1140     return value > -1 && value % 1 == 0 && value < length;
1141   }
1142
1143   /**
1144    * Converts `iterator` to an array.
1145    *
1146    * @private
1147    * @param {Object} iterator The iterator to convert.
1148    * @returns {Array} Returns the converted array.
1149    */
1150   function iteratorToArray(iterator) {
1151     var data,
1152         result = [];
1153
1154     while (!(data = iterator.next()).done) {
1155       result.push(data.value);
1156     }
1157     return result;
1158   }
1159
1160   /**
1161    * Converts `map` to an array.
1162    *
1163    * @private
1164    * @param {Object} map The map to convert.
1165    * @returns {Array} Returns the converted array.
1166    */
1167   function mapToArray(map) {
1168     var index = -1,
1169         result = Array(map.size);
1170
1171     map.forEach(function(value, key) {
1172       result[++index] = [key, value];
1173     });
1174     return result;
1175   }
1176
1177   /**
1178    * Replaces all `placeholder` elements in `array` with an internal placeholder
1179    * and returns an array of their indexes.
1180    *
1181    * @private
1182    * @param {Array} array The array to modify.
1183    * @param {*} placeholder The placeholder to replace.
1184    * @returns {Array} Returns the new array of placeholder indexes.
1185    */
1186   function replaceHolders(array, placeholder) {
1187     var index = -1,
1188         length = array.length,
1189         resIndex = -1,
1190         result = [];
1191
1192     while (++index < length) {
1193       var value = array[index];
1194       if (value === placeholder || value === PLACEHOLDER) {
1195         array[index] = PLACEHOLDER;
1196         result[++resIndex] = index;
1197       }
1198     }
1199     return result;
1200   }
1201
1202   /**
1203    * Converts `set` to an array.
1204    *
1205    * @private
1206    * @param {Object} set The set to convert.
1207    * @returns {Array} Returns the converted array.
1208    */
1209   function setToArray(set) {
1210     var index = -1,
1211         result = Array(set.size);
1212
1213     set.forEach(function(value) {
1214       result[++index] = value;
1215     });
1216     return result;
1217   }
1218
1219   /**
1220    * Gets the number of symbols in `string`.
1221    *
1222    * @private
1223    * @param {string} string The string to inspect.
1224    * @returns {number} Returns the string size.
1225    */
1226   function stringSize(string) {
1227     if (!(string && reHasComplexSymbol.test(string))) {
1228       return string.length;
1229     }
1230     var result = reComplexSymbol.lastIndex = 0;
1231     while (reComplexSymbol.test(string)) {
1232       result++;
1233     }
1234     return result;
1235   }
1236
1237   /**
1238    * Converts `string` to an array.
1239    *
1240    * @private
1241    * @param {string} string The string to convert.
1242    * @returns {Array} Returns the converted array.
1243    */
1244   function stringToArray(string) {
1245     return string.match(reComplexSymbol);
1246   }
1247
1248   /**
1249    * Used by `_.unescape` to convert HTML entities to characters.
1250    *
1251    * @private
1252    * @param {string} chr The matched character to unescape.
1253    * @returns {string} Returns the unescaped character.
1254    */
1255   function unescapeHtmlChar(chr) {
1256     return htmlUnescapes[chr];
1257   }
1258
1259   /*--------------------------------------------------------------------------*/
1260
1261   /**
1262    * Create a new pristine `lodash` function using the `context` object.
1263    *
1264    * @static
1265    * @memberOf _
1266    * @category Util
1267    * @param {Object} [context=root] The context object.
1268    * @returns {Function} Returns a new `lodash` function.
1269    * @example
1270    *
1271    * _.mixin({ 'foo': _.constant('foo') });
1272    *
1273    * var lodash = _.runInContext();
1274    * lodash.mixin({ 'bar': lodash.constant('bar') });
1275    *
1276    * _.isFunction(_.foo);
1277    * // => true
1278    * _.isFunction(_.bar);
1279    * // => false
1280    *
1281    * lodash.isFunction(lodash.foo);
1282    * // => false
1283    * lodash.isFunction(lodash.bar);
1284    * // => true
1285    *
1286    * // Use `context` to mock `Date#getTime` use in `_.now`.
1287    * var mock = _.runInContext({
1288    *   'Date': function() {
1289    *     return { 'getTime': getTimeMock };
1290    *   }
1291    * });
1292    *
1293    * // Create a suped-up `defer` in Node.js.
1294    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1295    */
1296   function runInContext(context) {
1297     context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
1298
1299     /** Built-in constructor references. */
1300     var Date = context.Date,
1301         Error = context.Error,
1302         Math = context.Math,
1303         RegExp = context.RegExp,
1304         TypeError = context.TypeError;
1305
1306     /** Used for built-in method references. */
1307     var arrayProto = context.Array.prototype,
1308         objectProto = context.Object.prototype;
1309
1310     /** Used to resolve the decompiled source of functions. */
1311     var funcToString = context.Function.prototype.toString;
1312
1313     /** Used to check objects for own properties. */
1314     var hasOwnProperty = objectProto.hasOwnProperty;
1315
1316     /** Used to generate unique IDs. */
1317     var idCounter = 0;
1318
1319     /** Used to infer the `Object` constructor. */
1320     var objectCtorString = funcToString.call(Object);
1321
1322     /**
1323      * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1324      * of values.
1325      */
1326     var objectToString = objectProto.toString;
1327
1328     /** Used to restore the original `_` reference in `_.noConflict`. */
1329     var oldDash = root._;
1330
1331     /** Used to detect if a method is native. */
1332     var reIsNative = RegExp('^' +
1333       funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1334       .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1335     );
1336
1337     /** Built-in value references. */
1338     var Buffer = moduleExports ? context.Buffer : undefined,
1339         Reflect = context.Reflect,
1340         Symbol = context.Symbol,
1341         Uint8Array = context.Uint8Array,
1342         clearTimeout = context.clearTimeout,
1343         enumerate = Reflect ? Reflect.enumerate : undefined,
1344         getPrototypeOf = Object.getPrototypeOf,
1345         getOwnPropertySymbols = Object.getOwnPropertySymbols,
1346         iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
1347         objectCreate = Object.create,
1348         propertyIsEnumerable = objectProto.propertyIsEnumerable,
1349         setTimeout = context.setTimeout,
1350         splice = arrayProto.splice;
1351
1352     /* Built-in method references for those with the same name as other `lodash` methods. */
1353     var nativeCeil = Math.ceil,
1354         nativeFloor = Math.floor,
1355         nativeIsFinite = context.isFinite,
1356         nativeJoin = arrayProto.join,
1357         nativeKeys = Object.keys,
1358         nativeMax = Math.max,
1359         nativeMin = Math.min,
1360         nativeParseInt = context.parseInt,
1361         nativeRandom = Math.random,
1362         nativeReverse = arrayProto.reverse;
1363
1364     /* Built-in method references that are verified to be native. */
1365     var Map = getNative(context, 'Map'),
1366         Set = getNative(context, 'Set'),
1367         WeakMap = getNative(context, 'WeakMap'),
1368         nativeCreate = getNative(Object, 'create');
1369
1370     /** Used to store function metadata. */
1371     var metaMap = WeakMap && new WeakMap;
1372
1373     /** Used to detect maps, sets, and weakmaps. */
1374     var mapCtorString = Map ? funcToString.call(Map) : '',
1375         setCtorString = Set ? funcToString.call(Set) : '',
1376         weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : '';
1377
1378     /** Used to convert symbols to primitives and strings. */
1379     var symbolProto = Symbol ? Symbol.prototype : undefined,
1380         symbolValueOf = Symbol ? symbolProto.valueOf : undefined,
1381         symbolToString = Symbol ? symbolProto.toString : undefined;
1382
1383     /** Used to lookup unminified function names. */
1384     var realNames = {};
1385
1386     /*------------------------------------------------------------------------*/
1387
1388     /**
1389      * Creates a `lodash` object which wraps `value` to enable implicit method
1390      * chaining. Methods that operate on and return arrays, collections, and
1391      * functions can be chained together. Methods that retrieve a single value or
1392      * may return a primitive value will automatically end the chain sequence and
1393      * return the unwrapped value. Otherwise, the value must be unwrapped with
1394      * `_#value`.
1395      *
1396      * Explicit chaining, which must be unwrapped with `_#value` in all cases,
1397      * may be enabled using `_.chain`.
1398      *
1399      * The execution of chained methods is lazy, that is, it's deferred until
1400      * `_#value` is implicitly or explicitly called.
1401      *
1402      * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
1403      * fusion is an optimization to merge iteratee calls; this avoids the creation
1404      * of intermediate arrays and can greatly reduce the number of iteratee executions.
1405      * Sections of a chain sequence qualify for shortcut fusion if the section is
1406      * applied to an array of at least two hundred elements and any iteratees
1407      * accept only one argument. The heuristic for whether a section qualifies
1408      * for shortcut fusion is subject to change.
1409      *
1410      * Chaining is supported in custom builds as long as the `_#value` method is
1411      * directly or indirectly included in the build.
1412      *
1413      * In addition to lodash methods, wrappers have `Array` and `String` methods.
1414      *
1415      * The wrapper `Array` methods are:
1416      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1417      *
1418      * The wrapper `String` methods are:
1419      * `replace` and `split`
1420      *
1421      * The wrapper methods that support shortcut fusion are:
1422      * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1423      * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1424      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1425      *
1426      * The chainable wrapper methods are:
1427      * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1428      * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1429      * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1430      * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
1431      * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
1432      * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`,
1433      * `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`,
1434      * `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`,
1435      * `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`,
1436      * `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`,
1437      * `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`,
1438      * `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`,
1439      * `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`,
1440      * `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`,
1441      * `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`,
1442      * `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`,
1443      * `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`,
1444      * `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`,
1445      * `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`,
1446      * `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`,
1447      * `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`,
1448      * `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith`
1449      *
1450      * The wrapper methods that are **not** chainable by default are:
1451      * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1452      * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
1453      * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
1454      * `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`, `forIn`,
1455      * `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`,
1456      * `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`,
1457      * `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
1458      * `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`,
1459      * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`,
1460      * `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
1461      * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
1462      * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`,
1463      * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`,
1464      * `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`,
1465      * `now`, `pad`, `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`,
1466      * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `sample`,
1467      * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`,
1468      * `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`,
1469      * `sum`, `sumBy`, `template`, `times`, `toLower`, `toInteger`, `toLength`,
1470      * `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`,
1471      * `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`,
1472      * `value`, and `words`
1473      *
1474      * @name _
1475      * @constructor
1476      * @category Seq
1477      * @param {*} value The value to wrap in a `lodash` instance.
1478      * @returns {Object} Returns the new `lodash` wrapper instance.
1479      * @example
1480      *
1481      * function square(n) {
1482      *   return n * n;
1483      * }
1484      *
1485      * var wrapped = _([1, 2, 3]);
1486      *
1487      * // Returns an unwrapped value.
1488      * wrapped.reduce(_.add);
1489      * // => 6
1490      *
1491      * // Returns a wrapped value.
1492      * var squares = wrapped.map(square);
1493      *
1494      * _.isArray(squares);
1495      * // => false
1496      *
1497      * _.isArray(squares.value());
1498      * // => true
1499      */
1500     function lodash(value) {
1501       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1502         if (value instanceof LodashWrapper) {
1503           return value;
1504         }
1505         if (hasOwnProperty.call(value, '__wrapped__')) {
1506           return wrapperClone(value);
1507         }
1508       }
1509       return new LodashWrapper(value);
1510     }
1511
1512     /**
1513      * The function whose prototype all chaining wrappers inherit from.
1514      *
1515      * @private
1516      */
1517     function baseLodash() {
1518       // No operation performed.
1519     }
1520
1521     /**
1522      * The base constructor for creating `lodash` wrapper objects.
1523      *
1524      * @private
1525      * @param {*} value The value to wrap.
1526      * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
1527      */
1528     function LodashWrapper(value, chainAll) {
1529       this.__wrapped__ = value;
1530       this.__actions__ = [];
1531       this.__chain__ = !!chainAll;
1532       this.__index__ = 0;
1533       this.__values__ = undefined;
1534     }
1535
1536     /**
1537      * By default, the template delimiters used by lodash are like those in
1538      * embedded Ruby (ERB). Change the following template settings to use
1539      * alternative delimiters.
1540      *
1541      * @static
1542      * @memberOf _
1543      * @type {Object}
1544      */
1545     lodash.templateSettings = {
1546
1547       /**
1548        * Used to detect `data` property values to be HTML-escaped.
1549        *
1550        * @memberOf _.templateSettings
1551        * @type {RegExp}
1552        */
1553       'escape': reEscape,
1554
1555       /**
1556        * Used to detect code to be evaluated.
1557        *
1558        * @memberOf _.templateSettings
1559        * @type {RegExp}
1560        */
1561       'evaluate': reEvaluate,
1562
1563       /**
1564        * Used to detect `data` property values to inject.
1565        *
1566        * @memberOf _.templateSettings
1567        * @type {RegExp}
1568        */
1569       'interpolate': reInterpolate,
1570
1571       /**
1572        * Used to reference the data object in the template text.
1573        *
1574        * @memberOf _.templateSettings
1575        * @type {string}
1576        */
1577       'variable': '',
1578
1579       /**
1580        * Used to import variables into the compiled template.
1581        *
1582        * @memberOf _.templateSettings
1583        * @type {Object}
1584        */
1585       'imports': {
1586
1587         /**
1588          * A reference to the `lodash` function.
1589          *
1590          * @memberOf _.templateSettings.imports
1591          * @type {Function}
1592          */
1593         '_': lodash
1594       }
1595     };
1596
1597     /*------------------------------------------------------------------------*/
1598
1599     /**
1600      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1601      *
1602      * @private
1603      * @constructor
1604      * @param {*} value The value to wrap.
1605      */
1606     function LazyWrapper(value) {
1607       this.__wrapped__ = value;
1608       this.__actions__ = [];
1609       this.__dir__ = 1;
1610       this.__filtered__ = false;
1611       this.__iteratees__ = [];
1612       this.__takeCount__ = MAX_ARRAY_LENGTH;
1613       this.__views__ = [];
1614     }
1615
1616     /**
1617      * Creates a clone of the lazy wrapper object.
1618      *
1619      * @private
1620      * @name clone
1621      * @memberOf LazyWrapper
1622      * @returns {Object} Returns the cloned `LazyWrapper` object.
1623      */
1624     function lazyClone() {
1625       var result = new LazyWrapper(this.__wrapped__);
1626       result.__actions__ = copyArray(this.__actions__);
1627       result.__dir__ = this.__dir__;
1628       result.__filtered__ = this.__filtered__;
1629       result.__iteratees__ = copyArray(this.__iteratees__);
1630       result.__takeCount__ = this.__takeCount__;
1631       result.__views__ = copyArray(this.__views__);
1632       return result;
1633     }
1634
1635     /**
1636      * Reverses the direction of lazy iteration.
1637      *
1638      * @private
1639      * @name reverse
1640      * @memberOf LazyWrapper
1641      * @returns {Object} Returns the new reversed `LazyWrapper` object.
1642      */
1643     function lazyReverse() {
1644       if (this.__filtered__) {
1645         var result = new LazyWrapper(this);
1646         result.__dir__ = -1;
1647         result.__filtered__ = true;
1648       } else {
1649         result = this.clone();
1650         result.__dir__ *= -1;
1651       }
1652       return result;
1653     }
1654
1655     /**
1656      * Extracts the unwrapped value from its lazy wrapper.
1657      *
1658      * @private
1659      * @name value
1660      * @memberOf LazyWrapper
1661      * @returns {*} Returns the unwrapped value.
1662      */
1663     function lazyValue() {
1664       var array = this.__wrapped__.value(),
1665           dir = this.__dir__,
1666           isArr = isArray(array),
1667           isRight = dir < 0,
1668           arrLength = isArr ? array.length : 0,
1669           view = getView(0, arrLength, this.__views__),
1670           start = view.start,
1671           end = view.end,
1672           length = end - start,
1673           index = isRight ? end : (start - 1),
1674           iteratees = this.__iteratees__,
1675           iterLength = iteratees.length,
1676           resIndex = 0,
1677           takeCount = nativeMin(length, this.__takeCount__);
1678
1679       if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
1680           (arrLength == length && takeCount == length)) {
1681         return baseWrapperValue(array, this.__actions__);
1682       }
1683       var result = [];
1684
1685       outer:
1686       while (length-- && resIndex < takeCount) {
1687         index += dir;
1688
1689         var iterIndex = -1,
1690             value = array[index];
1691
1692         while (++iterIndex < iterLength) {
1693           var data = iteratees[iterIndex],
1694               iteratee = data.iteratee,
1695               type = data.type,
1696               computed = iteratee(value);
1697
1698           if (type == LAZY_MAP_FLAG) {
1699             value = computed;
1700           } else if (!computed) {
1701             if (type == LAZY_FILTER_FLAG) {
1702               continue outer;
1703             } else {
1704               break outer;
1705             }
1706           }
1707         }
1708         result[resIndex++] = value;
1709       }
1710       return result;
1711     }
1712
1713     /*------------------------------------------------------------------------*/
1714
1715     /**
1716      * Creates an hash object.
1717      *
1718      * @private
1719      * @constructor
1720      * @returns {Object} Returns the new hash object.
1721      */
1722     function Hash() {}
1723
1724     /**
1725      * Removes `key` and its value from the hash.
1726      *
1727      * @private
1728      * @param {Object} hash The hash to modify.
1729      * @param {string} key The key of the value to remove.
1730      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1731      */
1732     function hashDelete(hash, key) {
1733       return hashHas(hash, key) && delete hash[key];
1734     }
1735
1736     /**
1737      * Gets the hash value for `key`.
1738      *
1739      * @private
1740      * @param {Object} hash The hash to query.
1741      * @param {string} key The key of the value to get.
1742      * @returns {*} Returns the entry value.
1743      */
1744     function hashGet(hash, key) {
1745       if (nativeCreate) {
1746         var result = hash[key];
1747         return result === HASH_UNDEFINED ? undefined : result;
1748       }
1749       return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
1750     }
1751
1752     /**
1753      * Checks if a hash value for `key` exists.
1754      *
1755      * @private
1756      * @param {Object} hash The hash to query.
1757      * @param {string} key The key of the entry to check.
1758      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1759      */
1760     function hashHas(hash, key) {
1761       return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
1762     }
1763
1764     /**
1765      * Sets the hash `key` to `value`.
1766      *
1767      * @private
1768      * @param {Object} hash The hash to modify.
1769      * @param {string} key The key of the value to set.
1770      * @param {*} value The value to set.
1771      */
1772     function hashSet(hash, key, value) {
1773       hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1774     }
1775
1776     /*------------------------------------------------------------------------*/
1777
1778     /**
1779      * Creates a map cache object to store key-value pairs.
1780      *
1781      * @private
1782      * @constructor
1783      * @param {Array} [values] The values to cache.
1784      */
1785     function MapCache(values) {
1786       var index = -1,
1787           length = values ? values.length : 0;
1788
1789       this.clear();
1790       while (++index < length) {
1791         var entry = values[index];
1792         this.set(entry[0], entry[1]);
1793       }
1794     }
1795
1796     /**
1797      * Removes all key-value entries from the map.
1798      *
1799      * @private
1800      * @name clear
1801      * @memberOf MapCache
1802      */
1803     function mapClear() {
1804       this.__data__ = {
1805         'hash': new Hash,
1806         'map': Map ? new Map : [],
1807         'string': new Hash
1808       };
1809     }
1810
1811     /**
1812      * Removes `key` and its value from the map.
1813      *
1814      * @private
1815      * @name delete
1816      * @memberOf MapCache
1817      * @param {string} key The key of the value to remove.
1818      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1819      */
1820     function mapDelete(key) {
1821       var data = this.__data__;
1822       if (isKeyable(key)) {
1823         return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
1824       }
1825       return Map ? data.map['delete'](key) : assocDelete(data.map, key);
1826     }
1827
1828     /**
1829      * Gets the map value for `key`.
1830      *
1831      * @private
1832      * @name get
1833      * @memberOf MapCache
1834      * @param {string} key The key of the value to get.
1835      * @returns {*} Returns the entry value.
1836      */
1837     function mapGet(key) {
1838       var data = this.__data__;
1839       if (isKeyable(key)) {
1840         return hashGet(typeof key == 'string' ? data.string : data.hash, key);
1841       }
1842       return Map ? data.map.get(key) : assocGet(data.map, key);
1843     }
1844
1845     /**
1846      * Checks if a map value for `key` exists.
1847      *
1848      * @private
1849      * @name has
1850      * @memberOf MapCache
1851      * @param {string} key The key of the entry to check.
1852      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1853      */
1854     function mapHas(key) {
1855       var data = this.__data__;
1856       if (isKeyable(key)) {
1857         return hashHas(typeof key == 'string' ? data.string : data.hash, key);
1858       }
1859       return Map ? data.map.has(key) : assocHas(data.map, key);
1860     }
1861
1862     /**
1863      * Sets the map `key` to `value`.
1864      *
1865      * @private
1866      * @name set
1867      * @memberOf MapCache
1868      * @param {string} key The key of the value to set.
1869      * @param {*} value The value to set.
1870      * @returns {Object} Returns the map cache object.
1871      */
1872     function mapSet(key, value) {
1873       var data = this.__data__;
1874       if (isKeyable(key)) {
1875         hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
1876       } else if (Map) {
1877         data.map.set(key, value);
1878       } else {
1879         assocSet(data.map, key, value);
1880       }
1881       return this;
1882     }
1883
1884     /*------------------------------------------------------------------------*/
1885
1886     /**
1887      *
1888      * Creates a set cache object to store unique values.
1889      *
1890      * @private
1891      * @constructor
1892      * @param {Array} [values] The values to cache.
1893      */
1894     function SetCache(values) {
1895       var index = -1,
1896           length = values ? values.length : 0;
1897
1898       this.__data__ = new MapCache;
1899       while (++index < length) {
1900         this.push(values[index]);
1901       }
1902     }
1903
1904     /**
1905      * Checks if `value` is in `cache`.
1906      *
1907      * @private
1908      * @param {Object} cache The set cache to search.
1909      * @param {*} value The value to search for.
1910      * @returns {number} Returns `true` if `value` is found, else `false`.
1911      */
1912     function cacheHas(cache, value) {
1913       var map = cache.__data__;
1914       if (isKeyable(value)) {
1915         var data = map.__data__,
1916             hash = typeof value == 'string' ? data.string : data.hash;
1917
1918         return hash[value] === HASH_UNDEFINED;
1919       }
1920       return map.has(value);
1921     }
1922
1923     /**
1924      * Adds `value` to the set cache.
1925      *
1926      * @private
1927      * @name push
1928      * @memberOf SetCache
1929      * @param {*} value The value to cache.
1930      */
1931     function cachePush(value) {
1932       var map = this.__data__;
1933       if (isKeyable(value)) {
1934         var data = map.__data__,
1935             hash = typeof value == 'string' ? data.string : data.hash;
1936
1937         hash[value] = HASH_UNDEFINED;
1938       }
1939       else {
1940         map.set(value, HASH_UNDEFINED);
1941       }
1942     }
1943
1944     /*------------------------------------------------------------------------*/
1945
1946     /**
1947      * Creates a stack cache object to store key-value pairs.
1948      *
1949      * @private
1950      * @constructor
1951      * @param {Array} [values] The values to cache.
1952      */
1953     function Stack(values) {
1954       var index = -1,
1955           length = values ? values.length : 0;
1956
1957       this.clear();
1958       while (++index < length) {
1959         var entry = values[index];
1960         this.set(entry[0], entry[1]);
1961       }
1962     }
1963
1964     /**
1965      * Removes all key-value entries from the stack.
1966      *
1967      * @private
1968      * @name clear
1969      * @memberOf Stack
1970      */
1971     function stackClear() {
1972       this.__data__ = { 'array': [], 'map': null };
1973     }
1974
1975     /**
1976      * Removes `key` and its value from the stack.
1977      *
1978      * @private
1979      * @name delete
1980      * @memberOf Stack
1981      * @param {string} key The key of the value to remove.
1982      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1983      */
1984     function stackDelete(key) {
1985       var data = this.__data__,
1986           array = data.array;
1987
1988       return array ? assocDelete(array, key) : data.map['delete'](key);
1989     }
1990
1991     /**
1992      * Gets the stack value for `key`.
1993      *
1994      * @private
1995      * @name get
1996      * @memberOf Stack
1997      * @param {string} key The key of the value to get.
1998      * @returns {*} Returns the entry value.
1999      */
2000     function stackGet(key) {
2001       var data = this.__data__,
2002           array = data.array;
2003
2004       return array ? assocGet(array, key) : data.map.get(key);
2005     }
2006
2007     /**
2008      * Checks if a stack value for `key` exists.
2009      *
2010      * @private
2011      * @name has
2012      * @memberOf Stack
2013      * @param {string} key The key of the entry to check.
2014      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2015      */
2016     function stackHas(key) {
2017       var data = this.__data__,
2018           array = data.array;
2019
2020       return array ? assocHas(array, key) : data.map.has(key);
2021     }
2022
2023     /**
2024      * Sets the stack `key` to `value`.
2025      *
2026      * @private
2027      * @name set
2028      * @memberOf Stack
2029      * @param {string} key The key of the value to set.
2030      * @param {*} value The value to set.
2031      * @returns {Object} Returns the stack cache object.
2032      */
2033     function stackSet(key, value) {
2034       var data = this.__data__,
2035           array = data.array;
2036
2037       if (array) {
2038         if (array.length < (LARGE_ARRAY_SIZE - 1)) {
2039           assocSet(array, key, value);
2040         } else {
2041           data.array = null;
2042           data.map = new MapCache(array);
2043         }
2044       }
2045       var map = data.map;
2046       if (map) {
2047         map.set(key, value);
2048       }
2049       return this;
2050     }
2051
2052     /*------------------------------------------------------------------------*/
2053
2054     /**
2055      * Removes `key` and its value from the associative array.
2056      *
2057      * @private
2058      * @param {Array} array The array to query.
2059      * @param {string} key The key of the value to remove.
2060      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2061      */
2062     function assocDelete(array, key) {
2063       var index = assocIndexOf(array, key);
2064       if (index < 0) {
2065         return false;
2066       }
2067       var lastIndex = array.length - 1;
2068       if (index == lastIndex) {
2069         array.pop();
2070       } else {
2071         splice.call(array, index, 1);
2072       }
2073       return true;
2074     }
2075
2076     /**
2077      * Gets the associative array value for `key`.
2078      *
2079      * @private
2080      * @param {Array} array The array to query.
2081      * @param {string} key The key of the value to get.
2082      * @returns {*} Returns the entry value.
2083      */
2084     function assocGet(array, key) {
2085       var index = assocIndexOf(array, key);
2086       return index < 0 ? undefined : array[index][1];
2087     }
2088
2089     /**
2090      * Checks if an associative array value for `key` exists.
2091      *
2092      * @private
2093      * @param {Array} array The array to query.
2094      * @param {string} key The key of the entry to check.
2095      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2096      */
2097     function assocHas(array, key) {
2098       return assocIndexOf(array, key) > -1;
2099     }
2100
2101     /**
2102      * Gets the index at which the first occurrence of `key` is found in `array`
2103      * of key-value pairs.
2104      *
2105      * @private
2106      * @param {Array} array The array to search.
2107      * @param {*} key The key to search for.
2108      * @returns {number} Returns the index of the matched value, else `-1`.
2109      */
2110     function assocIndexOf(array, key) {
2111       var length = array.length;
2112       while (length--) {
2113         if (eq(array[length][0], key)) {
2114           return length;
2115         }
2116       }
2117       return -1;
2118     }
2119
2120     /**
2121      * Sets the associative array `key` to `value`.
2122      *
2123      * @private
2124      * @param {Array} array The array to modify.
2125      * @param {string} key The key of the value to set.
2126      * @param {*} value The value to set.
2127      */
2128     function assocSet(array, key, value) {
2129       var index = assocIndexOf(array, key);
2130       if (index < 0) {
2131         array.push([key, value]);
2132       } else {
2133         array[index][1] = value;
2134       }
2135     }
2136
2137     /*------------------------------------------------------------------------*/
2138
2139     /**
2140      * Used by `_.defaults` to customize its `_.assignIn` use.
2141      *
2142      * @private
2143      * @param {*} objValue The destination value.
2144      * @param {*} srcValue The source value.
2145      * @param {string} key The key of the property to assign.
2146      * @param {Object} object The parent object of `objValue`.
2147      * @returns {*} Returns the value to assign.
2148      */
2149     function assignInDefaults(objValue, srcValue, key, object) {
2150       if (objValue === undefined ||
2151           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2152         return srcValue;
2153       }
2154       return objValue;
2155     }
2156
2157     /**
2158      * This function is like `assignValue` except that it doesn't assign `undefined` values.
2159      *
2160      * @private
2161      * @param {Object} object The object to modify.
2162      * @param {string} key The key of the property to assign.
2163      * @param {*} value The value to assign.
2164      */
2165     function assignMergeValue(object, key, value) {
2166       if ((value !== undefined && !eq(object[key], value)) ||
2167           (typeof key == 'number' && value === undefined && !(key in object))) {
2168         object[key] = value;
2169       }
2170     }
2171
2172     /**
2173      * Assigns `value` to `key` of `object` if the existing value is not equivalent
2174      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
2175      * for equality comparisons.
2176      *
2177      * @private
2178      * @param {Object} object The object to modify.
2179      * @param {string} key The key of the property to assign.
2180      * @param {*} value The value to assign.
2181      */
2182     function assignValue(object, key, value) {
2183       var objValue = object[key];
2184       if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2185           (value === undefined && !(key in object))) {
2186         object[key] = value;
2187       }
2188     }
2189
2190     /**
2191      * Aggregates elements of `collection` on `accumulator` with keys transformed
2192      * by `iteratee` and values set by `setter`.
2193      *
2194      * @private
2195      * @param {Array|Object} collection The collection to iterate over.
2196      * @param {Function} setter The function to set `accumulator` values.
2197      * @param {Function} iteratee The iteratee to transform keys.
2198      * @param {Object} accumulator The initial aggregated object.
2199      * @returns {Function} Returns `accumulator`.
2200      */
2201     function baseAggregator(collection, setter, iteratee, accumulator) {
2202       baseEach(collection, function(value, key, collection) {
2203         setter(accumulator, value, iteratee(value), collection);
2204       });
2205       return accumulator;
2206     }
2207
2208     /**
2209      * The base implementation of `_.assign` without support for multiple sources
2210      * or `customizer` functions.
2211      *
2212      * @private
2213      * @param {Object} object The destination object.
2214      * @param {Object} source The source object.
2215      * @returns {Object} Returns `object`.
2216      */
2217     function baseAssign(object, source) {
2218       return object && copyObject(source, keys(source), object);
2219     }
2220
2221     /**
2222      * The base implementation of `_.at` without support for individual paths.
2223      *
2224      * @private
2225      * @param {Object} object The object to iterate over.
2226      * @param {string[]} paths The property paths of elements to pick.
2227      * @returns {Array} Returns the new array of picked elements.
2228      */
2229     function baseAt(object, paths) {
2230       var index = -1,
2231           isNil = object == null,
2232           length = paths.length,
2233           result = Array(length);
2234
2235       while (++index < length) {
2236         result[index] = isNil ? undefined : get(object, paths[index]);
2237       }
2238       return result;
2239     }
2240
2241     /**
2242      * Casts `value` to an empty array if it's not an array like object.
2243      *
2244      * @private
2245      * @param {*} value The value to inspect.
2246      * @returns {Array} Returns the array-like object.
2247      */
2248     function baseCastArrayLikeObject(value) {
2249       return isArrayLikeObject(value) ? value : [];
2250     }
2251
2252     /**
2253      * Casts `value` to `identity` if it's not a function.
2254      *
2255      * @private
2256      * @param {*} value The value to inspect.
2257      * @returns {Array} Returns the array-like object.
2258      */
2259     function baseCastFunction(value) {
2260       return typeof value == 'function' ? value : identity;
2261     }
2262
2263     /**
2264      * Casts `value` to a path array if it's not one.
2265      *
2266      * @private
2267      * @param {*} value The value to inspect.
2268      * @returns {Array} Returns the cast property path array.
2269      */
2270     function baseCastPath(value) {
2271       return isArray(value) ? value : stringToPath(value);
2272     }
2273
2274     /**
2275      * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
2276      *
2277      * @private
2278      * @param {number} number The number to clamp.
2279      * @param {number} [lower] The lower bound.
2280      * @param {number} upper The upper bound.
2281      * @returns {number} Returns the clamped number.
2282      */
2283     function baseClamp(number, lower, upper) {
2284       if (number === number) {
2285         if (upper !== undefined) {
2286           number = number <= upper ? number : upper;
2287         }
2288         if (lower !== undefined) {
2289           number = number >= lower ? number : lower;
2290         }
2291       }
2292       return number;
2293     }
2294
2295     /**
2296      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2297      * traversed objects.
2298      *
2299      * @private
2300      * @param {*} value The value to clone.
2301      * @param {boolean} [isDeep] Specify a deep clone.
2302      * @param {Function} [customizer] The function to customize cloning.
2303      * @param {string} [key] The key of `value`.
2304      * @param {Object} [object] The parent object of `value`.
2305      * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2306      * @returns {*} Returns the cloned value.
2307      */
2308     function baseClone(value, isDeep, customizer, key, object, stack) {
2309       var result;
2310       if (customizer) {
2311         result = object ? customizer(value, key, object, stack) : customizer(value);
2312       }
2313       if (result !== undefined) {
2314         return result;
2315       }
2316       if (!isObject(value)) {
2317         return value;
2318       }
2319       var isArr = isArray(value);
2320       if (isArr) {
2321         result = initCloneArray(value);
2322         if (!isDeep) {
2323           return copyArray(value, result);
2324         }
2325       } else {
2326         var tag = getTag(value),
2327             isFunc = tag == funcTag || tag == genTag;
2328
2329         if (isBuffer(value)) {
2330           return cloneBuffer(value, isDeep);
2331         }
2332         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2333           if (isHostObject(value)) {
2334             return object ? value : {};
2335           }
2336           result = initCloneObject(isFunc ? {} : value);
2337           if (!isDeep) {
2338             return copySymbols(value, baseAssign(result, value));
2339           }
2340         } else {
2341           if (!cloneableTags[tag]) {
2342             return object ? value : {};
2343           }
2344           result = initCloneByTag(value, tag, isDeep);
2345         }
2346       }
2347       // Check for circular references and return its corresponding clone.
2348       stack || (stack = new Stack);
2349       var stacked = stack.get(value);
2350       if (stacked) {
2351         return stacked;
2352       }
2353       stack.set(value, result);
2354
2355       // Recursively populate clone (susceptible to call stack limits).
2356       (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
2357         assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
2358       });
2359       return isArr ? result : copySymbols(value, result);
2360     }
2361
2362     /**
2363      * The base implementation of `_.conforms` which doesn't clone `source`.
2364      *
2365      * @private
2366      * @param {Object} source The object of property predicates to conform to.
2367      * @returns {Function} Returns the new function.
2368      */
2369     function baseConforms(source) {
2370       var props = keys(source),
2371           length = props.length;
2372
2373       return function(object) {
2374         if (object == null) {
2375           return !length;
2376         }
2377         var index = length;
2378         while (index--) {
2379           var key = props[index],
2380               predicate = source[key],
2381               value = object[key];
2382
2383           if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
2384             return false;
2385           }
2386         }
2387         return true;
2388       };
2389     }
2390
2391     /**
2392      * The base implementation of `_.create` without support for assigning
2393      * properties to the created object.
2394      *
2395      * @private
2396      * @param {Object} prototype The object to inherit from.
2397      * @returns {Object} Returns the new object.
2398      */
2399     function baseCreate(proto) {
2400       return isObject(proto) ? objectCreate(proto) : {};
2401     }
2402
2403     /**
2404      * The base implementation of `_.delay` and `_.defer` which accepts an array
2405      * of `func` arguments.
2406      *
2407      * @private
2408      * @param {Function} func The function to delay.
2409      * @param {number} wait The number of milliseconds to delay invocation.
2410      * @param {Object} args The arguments to provide to `func`.
2411      * @returns {number} Returns the timer id.
2412      */
2413     function baseDelay(func, wait, args) {
2414       if (typeof func != 'function') {
2415         throw new TypeError(FUNC_ERROR_TEXT);
2416       }
2417       return setTimeout(function() { func.apply(undefined, args); }, wait);
2418     }
2419
2420     /**
2421      * The base implementation of methods like `_.difference` without support for
2422      * excluding multiple arrays or iteratee shorthands.
2423      *
2424      * @private
2425      * @param {Array} array The array to inspect.
2426      * @param {Array} values The values to exclude.
2427      * @param {Function} [iteratee] The iteratee invoked per element.
2428      * @param {Function} [comparator] The comparator invoked per element.
2429      * @returns {Array} Returns the new array of filtered values.
2430      */
2431     function baseDifference(array, values, iteratee, comparator) {
2432       var index = -1,
2433           includes = arrayIncludes,
2434           isCommon = true,
2435           length = array.length,
2436           result = [],
2437           valuesLength = values.length;
2438
2439       if (!length) {
2440         return result;
2441       }
2442       if (iteratee) {
2443         values = arrayMap(values, baseUnary(iteratee));
2444       }
2445       if (comparator) {
2446         includes = arrayIncludesWith;
2447         isCommon = false;
2448       }
2449       else if (values.length >= LARGE_ARRAY_SIZE) {
2450         includes = cacheHas;
2451         isCommon = false;
2452         values = new SetCache(values);
2453       }
2454       outer:
2455       while (++index < length) {
2456         var value = array[index],
2457             computed = iteratee ? iteratee(value) : value;
2458
2459         if (isCommon && computed === computed) {
2460           var valuesIndex = valuesLength;
2461           while (valuesIndex--) {
2462             if (values[valuesIndex] === computed) {
2463               continue outer;
2464             }
2465           }
2466           result.push(value);
2467         }
2468         else if (!includes(values, computed, comparator)) {
2469           result.push(value);
2470         }
2471       }
2472       return result;
2473     }
2474
2475     /**
2476      * The base implementation of `_.forEach` without support for iteratee shorthands.
2477      *
2478      * @private
2479      * @param {Array|Object} collection The collection to iterate over.
2480      * @param {Function} iteratee The function invoked per iteration.
2481      * @returns {Array|Object} Returns `collection`.
2482      */
2483     var baseEach = createBaseEach(baseForOwn);
2484
2485     /**
2486      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2487      *
2488      * @private
2489      * @param {Array|Object} collection The collection to iterate over.
2490      * @param {Function} iteratee The function invoked per iteration.
2491      * @returns {Array|Object} Returns `collection`.
2492      */
2493     var baseEachRight = createBaseEach(baseForOwnRight, true);
2494
2495     /**
2496      * The base implementation of `_.every` without support for iteratee shorthands.
2497      *
2498      * @private
2499      * @param {Array|Object} collection The collection to iterate over.
2500      * @param {Function} predicate The function invoked per iteration.
2501      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
2502      */
2503     function baseEvery(collection, predicate) {
2504       var result = true;
2505       baseEach(collection, function(value, index, collection) {
2506         result = !!predicate(value, index, collection);
2507         return result;
2508       });
2509       return result;
2510     }
2511
2512     /**
2513      * The base implementation of `_.fill` without an iteratee call guard.
2514      *
2515      * @private
2516      * @param {Array} array The array to fill.
2517      * @param {*} value The value to fill `array` with.
2518      * @param {number} [start=0] The start position.
2519      * @param {number} [end=array.length] The end position.
2520      * @returns {Array} Returns `array`.
2521      */
2522     function baseFill(array, value, start, end) {
2523       var length = array.length;
2524
2525       start = toInteger(start);
2526       if (start < 0) {
2527         start = -start > length ? 0 : (length + start);
2528       }
2529       end = (end === undefined || end > length) ? length : toInteger(end);
2530       if (end < 0) {
2531         end += length;
2532       }
2533       end = start > end ? 0 : toLength(end);
2534       while (start < end) {
2535         array[start++] = value;
2536       }
2537       return array;
2538     }
2539
2540     /**
2541      * The base implementation of `_.filter` without support for iteratee shorthands.
2542      *
2543      * @private
2544      * @param {Array|Object} collection The collection to iterate over.
2545      * @param {Function} predicate The function invoked per iteration.
2546      * @returns {Array} Returns the new filtered array.
2547      */
2548     function baseFilter(collection, predicate) {
2549       var result = [];
2550       baseEach(collection, function(value, index, collection) {
2551         if (predicate(value, index, collection)) {
2552           result.push(value);
2553         }
2554       });
2555       return result;
2556     }
2557
2558     /**
2559      * The base implementation of `_.flatten` with support for restricting flattening.
2560      *
2561      * @private
2562      * @param {Array} array The array to flatten.
2563      * @param {number} depth The maximum recursion depth.
2564      * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
2565      * @param {Array} [result=[]] The initial result value.
2566      * @returns {Array} Returns the new flattened array.
2567      */
2568     function baseFlatten(array, depth, isStrict, result) {
2569       result || (result = []);
2570
2571       var index = -1,
2572           length = array.length;
2573
2574       while (++index < length) {
2575         var value = array[index];
2576         if (depth > 0 && isArrayLikeObject(value) &&
2577             (isStrict || isArray(value) || isArguments(value))) {
2578           if (depth > 1) {
2579             // Recursively flatten arrays (susceptible to call stack limits).
2580             baseFlatten(value, depth - 1, isStrict, result);
2581           } else {
2582             arrayPush(result, value);
2583           }
2584         } else if (!isStrict) {
2585           result[result.length] = value;
2586         }
2587       }
2588       return result;
2589     }
2590
2591     /**
2592      * The base implementation of `baseForIn` and `baseForOwn` which iterates
2593      * over `object` properties returned by `keysFunc` invoking `iteratee` for
2594      * each property. Iteratee functions may exit iteration early by explicitly
2595      * returning `false`.
2596      *
2597      * @private
2598      * @param {Object} object The object to iterate over.
2599      * @param {Function} iteratee The function invoked per iteration.
2600      * @param {Function} keysFunc The function to get the keys of `object`.
2601      * @returns {Object} Returns `object`.
2602      */
2603     var baseFor = createBaseFor();
2604
2605     /**
2606      * This function is like `baseFor` except that it iterates over properties
2607      * in the opposite order.
2608      *
2609      * @private
2610      * @param {Object} object The object to iterate over.
2611      * @param {Function} iteratee The function invoked per iteration.
2612      * @param {Function} keysFunc The function to get the keys of `object`.
2613      * @returns {Object} Returns `object`.
2614      */
2615     var baseForRight = createBaseFor(true);
2616
2617     /**
2618      * The base implementation of `_.forIn` without support for iteratee shorthands.
2619      *
2620      * @private
2621      * @param {Object} object The object to iterate over.
2622      * @param {Function} iteratee The function invoked per iteration.
2623      * @returns {Object} Returns `object`.
2624      */
2625     function baseForIn(object, iteratee) {
2626       return object == null ? object : baseFor(object, iteratee, keysIn);
2627     }
2628
2629     /**
2630      * The base implementation of `_.forOwn` without support for iteratee shorthands.
2631      *
2632      * @private
2633      * @param {Object} object The object to iterate over.
2634      * @param {Function} iteratee The function invoked per iteration.
2635      * @returns {Object} Returns `object`.
2636      */
2637     function baseForOwn(object, iteratee) {
2638       return object && baseFor(object, iteratee, keys);
2639     }
2640
2641     /**
2642      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2643      *
2644      * @private
2645      * @param {Object} object The object to iterate over.
2646      * @param {Function} iteratee The function invoked per iteration.
2647      * @returns {Object} Returns `object`.
2648      */
2649     function baseForOwnRight(object, iteratee) {
2650       return object && baseForRight(object, iteratee, keys);
2651     }
2652
2653     /**
2654      * The base implementation of `_.functions` which creates an array of
2655      * `object` function property names filtered from `props`.
2656      *
2657      * @private
2658      * @param {Object} object The object to inspect.
2659      * @param {Array} props The property names to filter.
2660      * @returns {Array} Returns the new array of filtered property names.
2661      */
2662     function baseFunctions(object, props) {
2663       return arrayFilter(props, function(key) {
2664         return isFunction(object[key]);
2665       });
2666     }
2667
2668     /**
2669      * The base implementation of `_.get` without support for default values.
2670      *
2671      * @private
2672      * @param {Object} object The object to query.
2673      * @param {Array|string} path The path of the property to get.
2674      * @returns {*} Returns the resolved value.
2675      */
2676     function baseGet(object, path) {
2677       path = isKey(path, object) ? [path + ''] : baseCastPath(path);
2678
2679       var index = 0,
2680           length = path.length;
2681
2682       while (object != null && index < length) {
2683         object = object[path[index++]];
2684       }
2685       return (index && index == length) ? object : undefined;
2686     }
2687
2688     /**
2689      * The base implementation of `_.has` without support for deep paths.
2690      *
2691      * @private
2692      * @param {Object} object The object to query.
2693      * @param {Array|string} key The key to check.
2694      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2695      */
2696     function baseHas(object, key) {
2697       // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
2698       // that are composed entirely of index properties, return `false` for
2699       // `hasOwnProperty` checks of them.
2700       return hasOwnProperty.call(object, key) ||
2701         (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
2702     }
2703
2704     /**
2705      * The base implementation of `_.hasIn` without support for deep paths.
2706      *
2707      * @private
2708      * @param {Object} object The object to query.
2709      * @param {Array|string} key The key to check.
2710      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2711      */
2712     function baseHasIn(object, key) {
2713       return key in Object(object);
2714     }
2715
2716     /**
2717      * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
2718      *
2719      * @private
2720      * @param {number} number The number to check.
2721      * @param {number} start The start of the range.
2722      * @param {number} end The end of the range.
2723      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
2724      */
2725     function baseInRange(number, start, end) {
2726       return number >= nativeMin(start, end) && number < nativeMax(start, end);
2727     }
2728
2729     /**
2730      * The base implementation of methods like `_.intersection`, without support
2731      * for iteratee shorthands, that accepts an array of arrays to inspect.
2732      *
2733      * @private
2734      * @param {Array} arrays The arrays to inspect.
2735      * @param {Function} [iteratee] The iteratee invoked per element.
2736      * @param {Function} [comparator] The comparator invoked per element.
2737      * @returns {Array} Returns the new array of shared values.
2738      */
2739     function baseIntersection(arrays, iteratee, comparator) {
2740       var includes = comparator ? arrayIncludesWith : arrayIncludes,
2741           othLength = arrays.length,
2742           othIndex = othLength,
2743           caches = Array(othLength),
2744           result = [];
2745
2746       while (othIndex--) {
2747         var array = arrays[othIndex];
2748         if (othIndex && iteratee) {
2749           array = arrayMap(array, baseUnary(iteratee));
2750         }
2751         caches[othIndex] = !comparator && (iteratee || array.length >= 120)
2752           ? new SetCache(othIndex && array)
2753           : undefined;
2754       }
2755       array = arrays[0];
2756
2757       var index = -1,
2758           length = array.length,
2759           seen = caches[0];
2760
2761       outer:
2762       while (++index < length) {
2763         var value = array[index],
2764             computed = iteratee ? iteratee(value) : value;
2765
2766         if (!(seen
2767               ? cacheHas(seen, computed)
2768               : includes(result, computed, comparator)
2769             )) {
2770           var othIndex = othLength;
2771           while (--othIndex) {
2772             var cache = caches[othIndex];
2773             if (!(cache
2774                   ? cacheHas(cache, computed)
2775                   : includes(arrays[othIndex], computed, comparator))
2776                 ) {
2777               continue outer;
2778             }
2779           }
2780           if (seen) {
2781             seen.push(computed);
2782           }
2783           result.push(value);
2784         }
2785       }
2786       return result;
2787     }
2788
2789     /**
2790      * The base implementation of `_.invert` and `_.invertBy` which inverts
2791      * `object` with values transformed by `iteratee` and set by `setter`.
2792      *
2793      * @private
2794      * @param {Object} object The object to iterate over.
2795      * @param {Function} setter The function to set `accumulator` values.
2796      * @param {Function} iteratee The iteratee to transform values.
2797      * @param {Object} accumulator The initial inverted object.
2798      * @returns {Function} Returns `accumulator`.
2799      */
2800     function baseInverter(object, setter, iteratee, accumulator) {
2801       baseForOwn(object, function(value, key, object) {
2802         setter(accumulator, iteratee(value), key, object);
2803       });
2804       return accumulator;
2805     }
2806
2807     /**
2808      * The base implementation of `_.invoke` without support for individual
2809      * method arguments.
2810      *
2811      * @private
2812      * @param {Object} object The object to query.
2813      * @param {Array|string} path The path of the method to invoke.
2814      * @param {Array} args The arguments to invoke the method with.
2815      * @returns {*} Returns the result of the invoked method.
2816      */
2817     function baseInvoke(object, path, args) {
2818       if (!isKey(path, object)) {
2819         path = baseCastPath(path);
2820         object = parent(object, path);
2821         path = last(path);
2822       }
2823       var func = object == null ? object : object[path];
2824       return func == null ? undefined : apply(func, object, args);
2825     }
2826
2827     /**
2828      * The base implementation of `_.isEqual` which supports partial comparisons
2829      * and tracks traversed objects.
2830      *
2831      * @private
2832      * @param {*} value The value to compare.
2833      * @param {*} other The other value to compare.
2834      * @param {Function} [customizer] The function to customize comparisons.
2835      * @param {boolean} [bitmask] The bitmask of comparison flags.
2836      *  The bitmask may be composed of the following flags:
2837      *     1 - Unordered comparison
2838      *     2 - Partial comparison
2839      * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2840      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2841      */
2842     function baseIsEqual(value, other, customizer, bitmask, stack) {
2843       if (value === other) {
2844         return true;
2845       }
2846       if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
2847         return value !== value && other !== other;
2848       }
2849       return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
2850     }
2851
2852     /**
2853      * A specialized version of `baseIsEqual` for arrays and objects which performs
2854      * deep comparisons and tracks traversed objects enabling objects with circular
2855      * references to be compared.
2856      *
2857      * @private
2858      * @param {Object} object The object to compare.
2859      * @param {Object} other The other object to compare.
2860      * @param {Function} equalFunc The function to determine equivalents of values.
2861      * @param {Function} [customizer] The function to customize comparisons.
2862      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
2863      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2864      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2865      */
2866     function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
2867       var objIsArr = isArray(object),
2868           othIsArr = isArray(other),
2869           objTag = arrayTag,
2870           othTag = arrayTag;
2871
2872       if (!objIsArr) {
2873         objTag = getTag(object);
2874         if (objTag == argsTag) {
2875           objTag = objectTag;
2876         } else if (objTag != objectTag) {
2877           objIsArr = isTypedArray(object);
2878         }
2879       }
2880       if (!othIsArr) {
2881         othTag = getTag(other);
2882         if (othTag == argsTag) {
2883           othTag = objectTag;
2884         } else if (othTag != objectTag) {
2885           othIsArr = isTypedArray(other);
2886         }
2887       }
2888       var objIsObj = objTag == objectTag && !isHostObject(object),
2889           othIsObj = othTag == objectTag && !isHostObject(other),
2890           isSameTag = objTag == othTag;
2891
2892       if (isSameTag && !(objIsArr || objIsObj)) {
2893         return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
2894       }
2895       var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
2896       if (!isPartial) {
2897         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2898             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2899
2900         if (objIsWrapped || othIsWrapped) {
2901           return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
2902         }
2903       }
2904       if (!isSameTag) {
2905         return false;
2906       }
2907       stack || (stack = new Stack);
2908       return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
2909     }
2910
2911     /**
2912      * The base implementation of `_.isMatch` without support for iteratee shorthands.
2913      *
2914      * @private
2915      * @param {Object} object The object to inspect.
2916      * @param {Object} source The object of property values to match.
2917      * @param {Array} matchData The property names, values, and compare flags to match.
2918      * @param {Function} [customizer] The function to customize comparisons.
2919      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
2920      */
2921     function baseIsMatch(object, source, matchData, customizer) {
2922       var index = matchData.length,
2923           length = index,
2924           noCustomizer = !customizer;
2925
2926       if (object == null) {
2927         return !length;
2928       }
2929       object = Object(object);
2930       while (index--) {
2931         var data = matchData[index];
2932         if ((noCustomizer && data[2])
2933               ? data[1] !== object[data[0]]
2934               : !(data[0] in object)
2935             ) {
2936           return false;
2937         }
2938       }
2939       while (++index < length) {
2940         data = matchData[index];
2941         var key = data[0],
2942             objValue = object[key],
2943             srcValue = data[1];
2944
2945         if (noCustomizer && data[2]) {
2946           if (objValue === undefined && !(key in object)) {
2947             return false;
2948           }
2949         } else {
2950           var stack = new Stack,
2951               result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
2952
2953           if (!(result === undefined
2954                 ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
2955                 : result
2956               )) {
2957             return false;
2958           }
2959         }
2960       }
2961       return true;
2962     }
2963
2964     /**
2965      * The base implementation of `_.iteratee`.
2966      *
2967      * @private
2968      * @param {*} [value=_.identity] The value to convert to an iteratee.
2969      * @returns {Function} Returns the iteratee.
2970      */
2971     function baseIteratee(value) {
2972       var type = typeof value;
2973       if (type == 'function') {
2974         return value;
2975       }
2976       if (value == null) {
2977         return identity;
2978       }
2979       if (type == 'object') {
2980         return isArray(value)
2981           ? baseMatchesProperty(value[0], value[1])
2982           : baseMatches(value);
2983       }
2984       return property(value);
2985     }
2986
2987     /**
2988      * The base implementation of `_.keys` which doesn't skip the constructor
2989      * property of prototypes or treat sparse arrays as dense.
2990      *
2991      * @private
2992      * @param {Object} object The object to query.
2993      * @returns {Array} Returns the array of property names.
2994      */
2995     function baseKeys(object) {
2996       return nativeKeys(Object(object));
2997     }
2998
2999     /**
3000      * The base implementation of `_.keysIn` which doesn't skip the constructor
3001      * property of prototypes or treat sparse arrays as dense.
3002      *
3003      * @private
3004      * @param {Object} object The object to query.
3005      * @returns {Array} Returns the array of property names.
3006      */
3007     function baseKeysIn(object) {
3008       object = object == null ? object : Object(object);
3009
3010       var result = [];
3011       for (var key in object) {
3012         result.push(key);
3013       }
3014       return result;
3015     }
3016
3017     // Fallback for IE < 9 with es6-shim.
3018     if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
3019       baseKeysIn = function(object) {
3020         return iteratorToArray(enumerate(object));
3021       };
3022     }
3023
3024     /**
3025      * The base implementation of `_.map` without support for iteratee shorthands.
3026      *
3027      * @private
3028      * @param {Array|Object} collection The collection to iterate over.
3029      * @param {Function} iteratee The function invoked per iteration.
3030      * @returns {Array} Returns the new mapped array.
3031      */
3032     function baseMap(collection, iteratee) {
3033       var index = -1,
3034           result = isArrayLike(collection) ? Array(collection.length) : [];
3035
3036       baseEach(collection, function(value, key, collection) {
3037         result[++index] = iteratee(value, key, collection);
3038       });
3039       return result;
3040     }
3041
3042     /**
3043      * The base implementation of `_.matches` which doesn't clone `source`.
3044      *
3045      * @private
3046      * @param {Object} source The object of property values to match.
3047      * @returns {Function} Returns the new function.
3048      */
3049     function baseMatches(source) {
3050       var matchData = getMatchData(source);
3051       if (matchData.length == 1 && matchData[0][2]) {
3052         var key = matchData[0][0],
3053             value = matchData[0][1];
3054
3055         return function(object) {
3056           if (object == null) {
3057             return false;
3058           }
3059           return object[key] === value &&
3060             (value !== undefined || (key in Object(object)));
3061         };
3062       }
3063       return function(object) {
3064         return object === source || baseIsMatch(object, source, matchData);
3065       };
3066     }
3067
3068     /**
3069      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3070      *
3071      * @private
3072      * @param {string} path The path of the property to get.
3073      * @param {*} srcValue The value to match.
3074      * @returns {Function} Returns the new function.
3075      */
3076     function baseMatchesProperty(path, srcValue) {
3077       return function(object) {
3078         var objValue = get(object, path);
3079         return (objValue === undefined && objValue === srcValue)
3080           ? hasIn(object, path)
3081           : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
3082       };
3083     }
3084
3085     /**
3086      * The base implementation of `_.merge` without support for multiple sources.
3087      *
3088      * @private
3089      * @param {Object} object The destination object.
3090      * @param {Object} source The source object.
3091      * @param {number} srcIndex The index of `source`.
3092      * @param {Function} [customizer] The function to customize merged values.
3093      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
3094      */
3095     function baseMerge(object, source, srcIndex, customizer, stack) {
3096       if (object === source) {
3097         return;
3098       }
3099       var props = (isArray(source) || isTypedArray(source))
3100         ? undefined
3101         : keysIn(source);
3102
3103       arrayEach(props || source, function(srcValue, key) {
3104         if (props) {
3105           key = srcValue;
3106           srcValue = source[key];
3107         }
3108         if (isObject(srcValue)) {
3109           stack || (stack = new Stack);
3110           baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3111         }
3112         else {
3113           var newValue = customizer
3114             ? customizer(object[key], srcValue, (key + ''), object, source, stack)
3115             : undefined;
3116
3117           if (newValue === undefined) {
3118             newValue = srcValue;
3119           }
3120           assignMergeValue(object, key, newValue);
3121         }
3122       });
3123     }
3124
3125     /**
3126      * A specialized version of `baseMerge` for arrays and objects which performs
3127      * deep merges and tracks traversed objects enabling objects with circular
3128      * references to be merged.
3129      *
3130      * @private
3131      * @param {Object} object The destination object.
3132      * @param {Object} source The source object.
3133      * @param {string} key The key of the value to merge.
3134      * @param {number} srcIndex The index of `source`.
3135      * @param {Function} mergeFunc The function to merge values.
3136      * @param {Function} [customizer] The function to customize assigned values.
3137      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
3138      */
3139     function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3140       var objValue = object[key],
3141           srcValue = source[key],
3142           stacked = stack.get(srcValue);
3143
3144       if (stacked) {
3145         assignMergeValue(object, key, stacked);
3146         return;
3147       }
3148       var newValue = customizer
3149         ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3150         : undefined;
3151
3152       var isCommon = newValue === undefined;
3153
3154       if (isCommon) {
3155         newValue = srcValue;
3156         if (isArray(srcValue) || isTypedArray(srcValue)) {
3157           if (isArray(objValue)) {
3158             newValue = objValue;
3159           }
3160           else if (isArrayLikeObject(objValue)) {
3161             newValue = copyArray(objValue);
3162           }
3163           else {
3164             isCommon = false;
3165             newValue = baseClone(srcValue, true);
3166           }
3167         }
3168         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3169           if (isArguments(objValue)) {
3170             newValue = toPlainObject(objValue);
3171           }
3172           else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3173             isCommon = false;
3174             newValue = baseClone(srcValue, true);
3175           }
3176           else {
3177             newValue = objValue;
3178           }
3179         }
3180         else {
3181           isCommon = false;
3182         }
3183       }
3184       stack.set(srcValue, newValue);
3185
3186       if (isCommon) {
3187         // Recursively merge objects and arrays (susceptible to call stack limits).
3188         mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3189       }
3190       assignMergeValue(object, key, newValue);
3191     }
3192
3193     /**
3194      * The base implementation of `_.orderBy` without param guards.
3195      *
3196      * @private
3197      * @param {Array|Object} collection The collection to iterate over.
3198      * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3199      * @param {string[]} orders The sort orders of `iteratees`.
3200      * @returns {Array} Returns the new sorted array.
3201      */
3202     function baseOrderBy(collection, iteratees, orders) {
3203       var index = -1,
3204           toIteratee = getIteratee();
3205
3206       iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
3207         return toIteratee(iteratee);
3208       });
3209
3210       var result = baseMap(collection, function(value, key, collection) {
3211         var criteria = arrayMap(iteratees, function(iteratee) {
3212           return iteratee(value);
3213         });
3214         return { 'criteria': criteria, 'index': ++index, 'value': value };
3215       });
3216
3217       return baseSortBy(result, function(object, other) {
3218         return compareMultiple(object, other, orders);
3219       });
3220     }
3221
3222     /**
3223      * The base implementation of `_.pick` without support for individual
3224      * property names.
3225      *
3226      * @private
3227      * @param {Object} object The source object.
3228      * @param {string[]} props The property names to pick.
3229      * @returns {Object} Returns the new object.
3230      */
3231     function basePick(object, props) {
3232       object = Object(object);
3233       return arrayReduce(props, function(result, key) {
3234         if (key in object) {
3235           result[key] = object[key];
3236         }
3237         return result;
3238       }, {});
3239     }
3240
3241     /**
3242      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3243      *
3244      * @private
3245      * @param {Object} object The source object.
3246      * @param {Function} predicate The function invoked per property.
3247      * @returns {Object} Returns the new object.
3248      */
3249     function basePickBy(object, predicate) {
3250       var result = {};
3251       baseForIn(object, function(value, key) {
3252         if (predicate(value, key)) {
3253           result[key] = value;
3254         }
3255       });
3256       return result;
3257     }
3258
3259     /**
3260      * The base implementation of `_.property` without support for deep paths.
3261      *
3262      * @private
3263      * @param {string} key The key of the property to get.
3264      * @returns {Function} Returns the new function.
3265      */
3266     function baseProperty(key) {
3267       return function(object) {
3268         return object == null ? undefined : object[key];
3269       };
3270     }
3271
3272     /**
3273      * A specialized version of `baseProperty` which supports deep paths.
3274      *
3275      * @private
3276      * @param {Array|string} path The path of the property to get.
3277      * @returns {Function} Returns the new function.
3278      */
3279     function basePropertyDeep(path) {
3280       return function(object) {
3281         return baseGet(object, path);
3282       };
3283     }
3284
3285     /**
3286      * The base implementation of `_.pullAll`.
3287      *
3288      * @private
3289      * @param {Array} array The array to modify.
3290      * @param {Array} values The values to remove.
3291      * @returns {Array} Returns `array`.
3292      */
3293     function basePullAll(array, values) {
3294       return basePullAllBy(array, values);
3295     }
3296
3297     /**
3298      * The base implementation of `_.pullAllBy` without support for iteratee
3299      * shorthands.
3300      *
3301      * @private
3302      * @param {Array} array The array to modify.
3303      * @param {Array} values The values to remove.
3304      * @param {Function} [iteratee] The iteratee invoked per element.
3305      * @returns {Array} Returns `array`.
3306      */
3307     function basePullAllBy(array, values, iteratee) {
3308       var index = -1,
3309           length = values.length,
3310           seen = array;
3311
3312       if (iteratee) {
3313         seen = arrayMap(array, function(value) { return iteratee(value); });
3314       }
3315       while (++index < length) {
3316         var fromIndex = 0,
3317             value = values[index],
3318             computed = iteratee ? iteratee(value) : value;
3319
3320         while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
3321           if (seen !== array) {
3322             splice.call(seen, fromIndex, 1);
3323           }
3324           splice.call(array, fromIndex, 1);
3325         }
3326       }
3327       return array;
3328     }
3329
3330     /**
3331      * The base implementation of `_.pullAt` without support for individual
3332      * indexes or capturing the removed elements.
3333      *
3334      * @private
3335      * @param {Array} array The array to modify.
3336      * @param {number[]} indexes The indexes of elements to remove.
3337      * @returns {Array} Returns `array`.
3338      */
3339     function basePullAt(array, indexes) {
3340       var length = array ? indexes.length : 0,
3341           lastIndex = length - 1;
3342
3343       while (length--) {
3344         var index = indexes[length];
3345         if (lastIndex == length || index != previous) {
3346           var previous = index;
3347           if (isIndex(index)) {
3348             splice.call(array, index, 1);
3349           }
3350           else if (!isKey(index, array)) {
3351             var path = baseCastPath(index),
3352                 object = parent(array, path);
3353
3354             if (object != null) {
3355               delete object[last(path)];
3356             }
3357           }
3358           else {
3359             delete array[index];
3360           }
3361         }
3362       }
3363       return array;
3364     }
3365
3366     /**
3367      * The base implementation of `_.random` without support for returning
3368      * floating-point numbers.
3369      *
3370      * @private
3371      * @param {number} lower The lower bound.
3372      * @param {number} upper The upper bound.
3373      * @returns {number} Returns the random number.
3374      */
3375     function baseRandom(lower, upper) {
3376       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3377     }
3378
3379     /**
3380      * The base implementation of `_.range` and `_.rangeRight` which doesn't
3381      * coerce arguments to numbers.
3382      *
3383      * @private
3384      * @param {number} start The start of the range.
3385      * @param {number} end The end of the range.
3386      * @param {number} step The value to increment or decrement by.
3387      * @param {boolean} [fromRight] Specify iterating from right to left.
3388      * @returns {Array} Returns the new array of numbers.
3389      */
3390     function baseRange(start, end, step, fromRight) {
3391       var index = -1,
3392           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3393           result = Array(length);
3394
3395       while (length--) {
3396         result[fromRight ? length : ++index] = start;
3397         start += step;
3398       }
3399       return result;
3400     }
3401
3402     /**
3403      * The base implementation of `_.set`.
3404      *
3405      * @private
3406      * @param {Object} object The object to query.
3407      * @param {Array|string} path The path of the property to set.
3408      * @param {*} value The value to set.
3409      * @param {Function} [customizer] The function to customize path creation.
3410      * @returns {Object} Returns `object`.
3411      */
3412     function baseSet(object, path, value, customizer) {
3413       path = isKey(path, object) ? [path + ''] : baseCastPath(path);
3414
3415       var index = -1,
3416           length = path.length,
3417           lastIndex = length - 1,
3418           nested = object;
3419
3420       while (nested != null && ++index < length) {
3421         var key = path[index];
3422         if (isObject(nested)) {
3423           var newValue = value;
3424           if (index != lastIndex) {
3425             var objValue = nested[key];
3426             newValue = customizer ? customizer(objValue, key, nested) : undefined;
3427             if (newValue === undefined) {
3428               newValue = objValue == null
3429                 ? (isIndex(path[index + 1]) ? [] : {})
3430                 : objValue;
3431             }
3432           }
3433           assignValue(nested, key, newValue);
3434         }
3435         nested = nested[key];
3436       }
3437       return object;
3438     }
3439
3440     /**
3441      * The base implementation of `setData` without support for hot loop detection.
3442      *
3443      * @private
3444      * @param {Function} func The function to associate metadata with.
3445      * @param {*} data The metadata.
3446      * @returns {Function} Returns `func`.
3447      */
3448     var baseSetData = !metaMap ? identity : function(func, data) {
3449       metaMap.set(func, data);
3450       return func;
3451     };
3452
3453     /**
3454      * The base implementation of `_.slice` without an iteratee call guard.
3455      *
3456      * @private
3457      * @param {Array} array The array to slice.
3458      * @param {number} [start=0] The start position.
3459      * @param {number} [end=array.length] The end position.
3460      * @returns {Array} Returns the slice of `array`.
3461      */
3462     function baseSlice(array, start, end) {
3463       var index = -1,
3464           length = array.length;
3465
3466       if (start < 0) {
3467         start = -start > length ? 0 : (length + start);
3468       }
3469       end = end > length ? length : end;
3470       if (end < 0) {
3471         end += length;
3472       }
3473       length = start > end ? 0 : ((end - start) >>> 0);
3474       start >>>= 0;
3475
3476       var result = Array(length);
3477       while (++index < length) {
3478         result[index] = array[index + start];
3479       }
3480       return result;
3481     }
3482
3483     /**
3484      * The base implementation of `_.some` without support for iteratee shorthands.
3485      *
3486      * @private
3487      * @param {Array|Object} collection The collection to iterate over.
3488      * @param {Function} predicate The function invoked per iteration.
3489      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
3490      */
3491     function baseSome(collection, predicate) {
3492       var result;
3493
3494       baseEach(collection, function(value, index, collection) {
3495         result = predicate(value, index, collection);
3496         return !result;
3497       });
3498       return !!result;
3499     }
3500
3501     /**
3502      * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
3503      * performs a binary search of `array` to determine the index at which `value`
3504      * should be inserted into `array` in order to maintain its sort order.
3505      *
3506      * @private
3507      * @param {Array} array The sorted array to inspect.
3508      * @param {*} value The value to evaluate.
3509      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3510      * @returns {number} Returns the index at which `value` should be inserted
3511      *  into `array`.
3512      */
3513     function baseSortedIndex(array, value, retHighest) {
3514       var low = 0,
3515           high = array ? array.length : low;
3516
3517       if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
3518         while (low < high) {
3519           var mid = (low + high) >>> 1,
3520               computed = array[mid];
3521
3522           if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
3523             low = mid + 1;
3524           } else {
3525             high = mid;
3526           }
3527         }
3528         return high;
3529       }
3530       return baseSortedIndexBy(array, value, identity, retHighest);
3531     }
3532
3533     /**
3534      * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
3535      * which invokes `iteratee` for `value` and each element of `array` to compute
3536      * their sort ranking. The iteratee is invoked with one argument; (value).
3537      *
3538      * @private
3539      * @param {Array} array The sorted array to inspect.
3540      * @param {*} value The value to evaluate.
3541      * @param {Function} iteratee The iteratee invoked per element.
3542      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3543      * @returns {number} Returns the index at which `value` should be inserted into `array`.
3544      */
3545     function baseSortedIndexBy(array, value, iteratee, retHighest) {
3546       value = iteratee(value);
3547
3548       var low = 0,
3549           high = array ? array.length : 0,
3550           valIsNaN = value !== value,
3551           valIsNull = value === null,
3552           valIsUndef = value === undefined;
3553
3554       while (low < high) {
3555         var mid = nativeFloor((low + high) / 2),
3556             computed = iteratee(array[mid]),
3557             isDef = computed !== undefined,
3558             isReflexive = computed === computed;
3559
3560         if (valIsNaN) {
3561           var setLow = isReflexive || retHighest;
3562         } else if (valIsNull) {
3563           setLow = isReflexive && isDef && (retHighest || computed != null);
3564         } else if (valIsUndef) {
3565           setLow = isReflexive && (retHighest || isDef);
3566         } else if (computed == null) {
3567           setLow = false;
3568         } else {
3569           setLow = retHighest ? (computed <= value) : (computed < value);
3570         }
3571         if (setLow) {
3572           low = mid + 1;
3573         } else {
3574           high = mid;
3575         }
3576       }
3577       return nativeMin(high, MAX_ARRAY_INDEX);
3578     }
3579
3580     /**
3581      * The base implementation of `_.sortedUniq`.
3582      *
3583      * @private
3584      * @param {Array} array The array to inspect.
3585      * @returns {Array} Returns the new duplicate free array.
3586      */
3587     function baseSortedUniq(array) {
3588       return baseSortedUniqBy(array);
3589     }
3590
3591     /**
3592      * The base implementation of `_.sortedUniqBy` without support for iteratee
3593      * shorthands.
3594      *
3595      * @private
3596      * @param {Array} array The array to inspect.
3597      * @param {Function} [iteratee] The iteratee invoked per element.
3598      * @returns {Array} Returns the new duplicate free array.
3599      */
3600     function baseSortedUniqBy(array, iteratee) {
3601       var index = 0,
3602           length = array.length,
3603           value = array[0],
3604           computed = iteratee ? iteratee(value) : value,
3605           seen = computed,
3606           resIndex = 0,
3607           result = [value];
3608
3609       while (++index < length) {
3610         value = array[index],
3611         computed = iteratee ? iteratee(value) : value;
3612
3613         if (!eq(computed, seen)) {
3614           seen = computed;
3615           result[++resIndex] = value;
3616         }
3617       }
3618       return result;
3619     }
3620
3621     /**
3622      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
3623      *
3624      * @private
3625      * @param {Array} array The array to inspect.
3626      * @param {Function} [iteratee] The iteratee invoked per element.
3627      * @param {Function} [comparator] The comparator invoked per element.
3628      * @returns {Array} Returns the new duplicate free array.
3629      */
3630     function baseUniq(array, iteratee, comparator) {
3631       var index = -1,
3632           includes = arrayIncludes,
3633           length = array.length,
3634           isCommon = true,
3635           result = [],
3636           seen = result;
3637
3638       if (comparator) {
3639         isCommon = false;
3640         includes = arrayIncludesWith;
3641       }
3642       else if (length >= LARGE_ARRAY_SIZE) {
3643         var set = iteratee ? null : createSet(array);
3644         if (set) {
3645           return setToArray(set);
3646         }
3647         isCommon = false;
3648         includes = cacheHas;
3649         seen = new SetCache;
3650       }
3651       else {
3652         seen = iteratee ? [] : result;
3653       }
3654       outer:
3655       while (++index < length) {
3656         var value = array[index],
3657             computed = iteratee ? iteratee(value) : value;
3658
3659         if (isCommon && computed === computed) {
3660           var seenIndex = seen.length;
3661           while (seenIndex--) {
3662             if (seen[seenIndex] === computed) {
3663               continue outer;
3664             }
3665           }
3666           if (iteratee) {
3667             seen.push(computed);
3668           }
3669           result.push(value);
3670         }
3671         else if (!includes(seen, computed, comparator)) {
3672           if (seen !== result) {
3673             seen.push(computed);
3674           }
3675           result.push(value);
3676         }
3677       }
3678       return result;
3679     }
3680
3681     /**
3682      * The base implementation of `_.unset`.
3683      *
3684      * @private
3685      * @param {Object} object The object to modify.
3686      * @param {Array|string} path The path of the property to unset.
3687      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
3688      */
3689     function baseUnset(object, path) {
3690       path = isKey(path, object) ? [path + ''] : baseCastPath(path);
3691       object = parent(object, path);
3692       var key = last(path);
3693       return (object != null && has(object, key)) ? delete object[key] : true;
3694     }
3695
3696     /**
3697      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
3698      * without support for iteratee shorthands.
3699      *
3700      * @private
3701      * @param {Array} array The array to query.
3702      * @param {Function} predicate The function invoked per iteration.
3703      * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
3704      * @param {boolean} [fromRight] Specify iterating from right to left.
3705      * @returns {Array} Returns the slice of `array`.
3706      */
3707     function baseWhile(array, predicate, isDrop, fromRight) {
3708       var length = array.length,
3709           index = fromRight ? length : -1;
3710
3711       while ((fromRight ? index-- : ++index < length) &&
3712         predicate(array[index], index, array)) {}
3713
3714       return isDrop
3715         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
3716         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
3717     }
3718
3719     /**
3720      * The base implementation of `wrapperValue` which returns the result of
3721      * performing a sequence of actions on the unwrapped `value`, where each
3722      * successive action is supplied the return value of the previous.
3723      *
3724      * @private
3725      * @param {*} value The unwrapped value.
3726      * @param {Array} actions Actions to perform to resolve the unwrapped value.
3727      * @returns {*} Returns the resolved value.
3728      */
3729     function baseWrapperValue(value, actions) {
3730       var result = value;
3731       if (result instanceof LazyWrapper) {
3732         result = result.value();
3733       }
3734       return arrayReduce(actions, function(result, action) {
3735         return action.func.apply(action.thisArg, arrayPush([result], action.args));
3736       }, result);
3737     }
3738
3739     /**
3740      * The base implementation of methods like `_.xor`, without support for
3741      * iteratee shorthands, that accepts an array of arrays to inspect.
3742      *
3743      * @private
3744      * @param {Array} arrays The arrays to inspect.
3745      * @param {Function} [iteratee] The iteratee invoked per element.
3746      * @param {Function} [comparator] The comparator invoked per element.
3747      * @returns {Array} Returns the new array of values.
3748      */
3749     function baseXor(arrays, iteratee, comparator) {
3750       var index = -1,
3751           length = arrays.length;
3752
3753       while (++index < length) {
3754         var result = result
3755           ? arrayPush(
3756               baseDifference(result, arrays[index], iteratee, comparator),
3757               baseDifference(arrays[index], result, iteratee, comparator)
3758             )
3759           : arrays[index];
3760       }
3761       return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
3762     }
3763
3764     /**
3765      * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
3766      *
3767      * @private
3768      * @param {Array} props The property names.
3769      * @param {Array} values The property values.
3770      * @param {Function} assignFunc The function to assign values.
3771      * @returns {Object} Returns the new object.
3772      */
3773     function baseZipObject(props, values, assignFunc) {
3774       var index = -1,
3775           length = props.length,
3776           valsLength = values.length,
3777           result = {};
3778
3779       while (++index < length) {
3780         assignFunc(result, props[index], index < valsLength ? values[index] : undefined);
3781       }
3782       return result;
3783     }
3784
3785     /**
3786      * Creates a clone of  `buffer`.
3787      *
3788      * @private
3789      * @param {Buffer} buffer The buffer to clone.
3790      * @param {boolean} [isDeep] Specify a deep clone.
3791      * @returns {Buffer} Returns the cloned buffer.
3792      */
3793     function cloneBuffer(buffer, isDeep) {
3794       if (isDeep) {
3795         return buffer.slice();
3796       }
3797       var Ctor = buffer.constructor,
3798           result = new Ctor(buffer.length);
3799
3800       buffer.copy(result);
3801       return result;
3802     }
3803
3804     /**
3805      * Creates a clone of `arrayBuffer`.
3806      *
3807      * @private
3808      * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
3809      * @returns {ArrayBuffer} Returns the cloned array buffer.
3810      */
3811     function cloneArrayBuffer(arrayBuffer) {
3812       var Ctor = arrayBuffer.constructor,
3813           result = new Ctor(arrayBuffer.byteLength),
3814           view = new Uint8Array(result);
3815
3816       view.set(new Uint8Array(arrayBuffer));
3817       return result;
3818     }
3819
3820     /**
3821      * Creates a clone of `map`.
3822      *
3823      * @private
3824      * @param {Object} map The map to clone.
3825      * @returns {Object} Returns the cloned map.
3826      */
3827     function cloneMap(map) {
3828       var Ctor = map.constructor;
3829       return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
3830     }
3831
3832     /**
3833      * Creates a clone of `regexp`.
3834      *
3835      * @private
3836      * @param {Object} regexp The regexp to clone.
3837      * @returns {Object} Returns the cloned regexp.
3838      */
3839     function cloneRegExp(regexp) {
3840       var Ctor = regexp.constructor,
3841           result = new Ctor(regexp.source, reFlags.exec(regexp));
3842
3843       result.lastIndex = regexp.lastIndex;
3844       return result;
3845     }
3846
3847     /**
3848      * Creates a clone of `set`.
3849      *
3850      * @private
3851      * @param {Object} set The set to clone.
3852      * @returns {Object} Returns the cloned set.
3853      */
3854     function cloneSet(set) {
3855       var Ctor = set.constructor;
3856       return arrayReduce(setToArray(set), addSetEntry, new Ctor);
3857     }
3858
3859     /**
3860      * Creates a clone of the `symbol` object.
3861      *
3862      * @private
3863      * @param {Object} symbol The symbol object to clone.
3864      * @returns {Object} Returns the cloned symbol object.
3865      */
3866     function cloneSymbol(symbol) {
3867       return Symbol ? Object(symbolValueOf.call(symbol)) : {};
3868     }
3869
3870     /**
3871      * Creates a clone of `typedArray`.
3872      *
3873      * @private
3874      * @param {Object} typedArray The typed array to clone.
3875      * @param {boolean} [isDeep] Specify a deep clone.
3876      * @returns {Object} Returns the cloned typed array.
3877      */
3878     function cloneTypedArray(typedArray, isDeep) {
3879       var arrayBuffer = typedArray.buffer,
3880           buffer = isDeep ? cloneArrayBuffer(arrayBuffer) : arrayBuffer,
3881           Ctor = typedArray.constructor;
3882
3883       return new Ctor(buffer, typedArray.byteOffset, typedArray.length);
3884     }
3885
3886     /**
3887      * Creates an array that is the composition of partially applied arguments,
3888      * placeholders, and provided arguments into a single array of arguments.
3889      *
3890      * @private
3891      * @param {Array|Object} args The provided arguments.
3892      * @param {Array} partials The arguments to prepend to those provided.
3893      * @param {Array} holders The `partials` placeholder indexes.
3894      * @params {boolean} [isCurried] Specify composing for a curried function.
3895      * @returns {Array} Returns the new array of composed arguments.
3896      */
3897     function composeArgs(args, partials, holders, isCurried) {
3898       var argsIndex = -1,
3899           argsLength = args.length,
3900           holdersLength = holders.length,
3901           leftIndex = -1,
3902           leftLength = partials.length,
3903           rangeLength = nativeMax(argsLength - holdersLength, 0),
3904           result = Array(leftLength + rangeLength),
3905           isUncurried = !isCurried;
3906
3907       while (++leftIndex < leftLength) {
3908         result[leftIndex] = partials[leftIndex];
3909       }
3910       while (++argsIndex < holdersLength) {
3911         if (isUncurried || argsIndex < argsLength) {
3912           result[holders[argsIndex]] = args[argsIndex];
3913         }
3914       }
3915       while (rangeLength--) {
3916         result[leftIndex++] = args[argsIndex++];
3917       }
3918       return result;
3919     }
3920
3921     /**
3922      * This function is like `composeArgs` except that the arguments composition
3923      * is tailored for `_.partialRight`.
3924      *
3925      * @private
3926      * @param {Array|Object} args The provided arguments.
3927      * @param {Array} partials The arguments to append to those provided.
3928      * @param {Array} holders The `partials` placeholder indexes.
3929      * @params {boolean} [isCurried] Specify composing for a curried function.
3930      * @returns {Array} Returns the new array of composed arguments.
3931      */
3932     function composeArgsRight(args, partials, holders, isCurried) {
3933       var argsIndex = -1,
3934           argsLength = args.length,
3935           holdersIndex = -1,
3936           holdersLength = holders.length,
3937           rightIndex = -1,
3938           rightLength = partials.length,
3939           rangeLength = nativeMax(argsLength - holdersLength, 0),
3940           result = Array(rangeLength + rightLength),
3941           isUncurried = !isCurried;
3942
3943       while (++argsIndex < rangeLength) {
3944         result[argsIndex] = args[argsIndex];
3945       }
3946       var offset = argsIndex;
3947       while (++rightIndex < rightLength) {
3948         result[offset + rightIndex] = partials[rightIndex];
3949       }
3950       while (++holdersIndex < holdersLength) {
3951         if (isUncurried || argsIndex < argsLength) {
3952           result[offset + holders[holdersIndex]] = args[argsIndex++];
3953         }
3954       }
3955       return result;
3956     }
3957
3958     /**
3959      * Copies the values of `source` to `array`.
3960      *
3961      * @private
3962      * @param {Array} source The array to copy values from.
3963      * @param {Array} [array=[]] The array to copy values to.
3964      * @returns {Array} Returns `array`.
3965      */
3966     function copyArray(source, array) {
3967       var index = -1,
3968           length = source.length;
3969
3970       array || (array = Array(length));
3971       while (++index < length) {
3972         array[index] = source[index];
3973       }
3974       return array;
3975     }
3976
3977     /**
3978      * Copies properties of `source` to `object`.
3979      *
3980      * @private
3981      * @param {Object} source The object to copy properties from.
3982      * @param {Array} props The property names to copy.
3983      * @param {Object} [object={}] The object to copy properties to.
3984      * @returns {Object} Returns `object`.
3985      */
3986     function copyObject(source, props, object) {
3987       return copyObjectWith(source, props, object);
3988     }
3989
3990     /**
3991      * This function is like `copyObject` except that it accepts a function to
3992      * customize copied values.
3993      *
3994      * @private
3995      * @param {Object} source The object to copy properties from.
3996      * @param {Array} props The property names to copy.
3997      * @param {Object} [object={}] The object to copy properties to.
3998      * @param {Function} [customizer] The function to customize copied values.
3999      * @returns {Object} Returns `object`.
4000      */
4001     function copyObjectWith(source, props, object, customizer) {
4002       object || (object = {});
4003
4004       var index = -1,
4005           length = props.length;
4006
4007       while (++index < length) {
4008         var key = props[index];
4009
4010         var newValue = customizer
4011           ? customizer(object[key], source[key], key, object, source)
4012           : source[key];
4013
4014         assignValue(object, key, newValue);
4015       }
4016       return object;
4017     }
4018
4019     /**
4020      * Copies own symbol properties of `source` to `object`.
4021      *
4022      * @private
4023      * @param {Object} source The object to copy symbols from.
4024      * @param {Object} [object={}] The object to copy symbols to.
4025      * @returns {Object} Returns `object`.
4026      */
4027     function copySymbols(source, object) {
4028       return copyObject(source, getSymbols(source), object);
4029     }
4030
4031     /**
4032      * Creates a function like `_.groupBy`.
4033      *
4034      * @private
4035      * @param {Function} setter The function to set accumulator values.
4036      * @param {Function} [initializer] The accumulator object initializer.
4037      * @returns {Function} Returns the new aggregator function.
4038      */
4039     function createAggregator(setter, initializer) {
4040       return function(collection, iteratee) {
4041         var func = isArray(collection) ? arrayAggregator : baseAggregator,
4042             accumulator = initializer ? initializer() : {};
4043
4044         return func(collection, setter, getIteratee(iteratee), accumulator);
4045       };
4046     }
4047
4048     /**
4049      * Creates a function like `_.assign`.
4050      *
4051      * @private
4052      * @param {Function} assigner The function to assign values.
4053      * @returns {Function} Returns the new assigner function.
4054      */
4055     function createAssigner(assigner) {
4056       return rest(function(object, sources) {
4057         var index = -1,
4058             length = sources.length,
4059             customizer = length > 1 ? sources[length - 1] : undefined,
4060             guard = length > 2 ? sources[2] : undefined;
4061
4062         customizer = typeof customizer == 'function'
4063           ? (length--, customizer)
4064           : undefined;
4065
4066         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4067           customizer = length < 3 ? undefined : customizer;
4068           length = 1;
4069         }
4070         object = Object(object);
4071         while (++index < length) {
4072           var source = sources[index];
4073           if (source) {
4074             assigner(object, source, index, customizer);
4075           }
4076         }
4077         return object;
4078       });
4079     }
4080
4081     /**
4082      * Creates a `baseEach` or `baseEachRight` function.
4083      *
4084      * @private
4085      * @param {Function} eachFunc The function to iterate over a collection.
4086      * @param {boolean} [fromRight] Specify iterating from right to left.
4087      * @returns {Function} Returns the new base function.
4088      */
4089     function createBaseEach(eachFunc, fromRight) {
4090       return function(collection, iteratee) {
4091         if (collection == null) {
4092           return collection;
4093         }
4094         if (!isArrayLike(collection)) {
4095           return eachFunc(collection, iteratee);
4096         }
4097         var length = collection.length,
4098             index = fromRight ? length : -1,
4099             iterable = Object(collection);
4100
4101         while ((fromRight ? index-- : ++index < length)) {
4102           if (iteratee(iterable[index], index, iterable) === false) {
4103             break;
4104           }
4105         }
4106         return collection;
4107       };
4108     }
4109
4110     /**
4111      * Creates a base function for methods like `_.forIn`.
4112      *
4113      * @private
4114      * @param {boolean} [fromRight] Specify iterating from right to left.
4115      * @returns {Function} Returns the new base function.
4116      */
4117     function createBaseFor(fromRight) {
4118       return function(object, iteratee, keysFunc) {
4119         var index = -1,
4120             iterable = Object(object),
4121             props = keysFunc(object),
4122             length = props.length;
4123
4124         while (length--) {
4125           var key = props[fromRight ? length : ++index];
4126           if (iteratee(iterable[key], key, iterable) === false) {
4127             break;
4128           }
4129         }
4130         return object;
4131       };
4132     }
4133
4134     /**
4135      * Creates a function that wraps `func` to invoke it with the optional `this`
4136      * binding of `thisArg`.
4137      *
4138      * @private
4139      * @param {Function} func The function to wrap.
4140      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4141      * @param {*} [thisArg] The `this` binding of `func`.
4142      * @returns {Function} Returns the new wrapped function.
4143      */
4144     function createBaseWrapper(func, bitmask, thisArg) {
4145       var isBind = bitmask & BIND_FLAG,
4146           Ctor = createCtorWrapper(func);
4147
4148       function wrapper() {
4149         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4150         return fn.apply(isBind ? thisArg : this, arguments);
4151       }
4152       return wrapper;
4153     }
4154
4155     /**
4156      * Creates a function like `_.lowerFirst`.
4157      *
4158      * @private
4159      * @param {string} methodName The name of the `String` case method to use.
4160      * @returns {Function} Returns the new function.
4161      */
4162     function createCaseFirst(methodName) {
4163       return function(string) {
4164         string = toString(string);
4165
4166         var strSymbols = reHasComplexSymbol.test(string)
4167           ? stringToArray(string)
4168           : undefined;
4169
4170         var chr = strSymbols ? strSymbols[0] : string.charAt(0),
4171             trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
4172
4173         return chr[methodName]() + trailing;
4174       };
4175     }
4176
4177     /**
4178      * Creates a function like `_.camelCase`.
4179      *
4180      * @private
4181      * @param {Function} callback The function to combine each word.
4182      * @returns {Function} Returns the new compounder function.
4183      */
4184     function createCompounder(callback) {
4185       return function(string) {
4186         return arrayReduce(words(deburr(string)), callback, '');
4187       };
4188     }
4189
4190     /**
4191      * Creates a function that produces an instance of `Ctor` regardless of
4192      * whether it was invoked as part of a `new` expression or by `call` or `apply`.
4193      *
4194      * @private
4195      * @param {Function} Ctor The constructor to wrap.
4196      * @returns {Function} Returns the new wrapped function.
4197      */
4198     function createCtorWrapper(Ctor) {
4199       return function() {
4200         // Use a `switch` statement to work with class constructors.
4201         // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
4202         // for more details.
4203         var args = arguments;
4204         switch (args.length) {
4205           case 0: return new Ctor;
4206           case 1: return new Ctor(args[0]);
4207           case 2: return new Ctor(args[0], args[1]);
4208           case 3: return new Ctor(args[0], args[1], args[2]);
4209           case 4: return new Ctor(args[0], args[1], args[2], args[3]);
4210           case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
4211           case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
4212           case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
4213         }
4214         var thisBinding = baseCreate(Ctor.prototype),
4215             result = Ctor.apply(thisBinding, args);
4216
4217         // Mimic the constructor's `return` behavior.
4218         // See https://es5.github.io/#x13.2.2 for more details.
4219         return isObject(result) ? result : thisBinding;
4220       };
4221     }
4222
4223     /**
4224      * Creates a function that wraps `func` to enable currying.
4225      *
4226      * @private
4227      * @param {Function} func The function to wrap.
4228      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4229      * @param {number} arity The arity of `func`.
4230      * @returns {Function} Returns the new wrapped function.
4231      */
4232     function createCurryWrapper(func, bitmask, arity) {
4233       var Ctor = createCtorWrapper(func);
4234
4235       function wrapper() {
4236         var length = arguments.length,
4237             args = Array(length),
4238             index = length,
4239             placeholder = getPlaceholder(wrapper);
4240
4241         while (index--) {
4242           args[index] = arguments[index];
4243         }
4244         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
4245           ? []
4246           : replaceHolders(args, placeholder);
4247
4248         length -= holders.length;
4249         if (length < arity) {
4250           return createRecurryWrapper(
4251             func, bitmask, createHybridWrapper, wrapper.placeholder, undefined,
4252             args, holders, undefined, undefined, arity - length);
4253         }
4254         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4255         return apply(fn, this, args);
4256       }
4257       return wrapper;
4258     }
4259
4260     /**
4261      * Creates a `_.flow` or `_.flowRight` function.
4262      *
4263      * @private
4264      * @param {boolean} [fromRight] Specify iterating from right to left.
4265      * @returns {Function} Returns the new flow function.
4266      */
4267     function createFlow(fromRight) {
4268       return rest(function(funcs) {
4269         funcs = baseFlatten(funcs, 1);
4270
4271         var length = funcs.length,
4272             index = length,
4273             prereq = LodashWrapper.prototype.thru;
4274
4275         if (fromRight) {
4276           funcs.reverse();
4277         }
4278         while (index--) {
4279           var func = funcs[index];
4280           if (typeof func != 'function') {
4281             throw new TypeError(FUNC_ERROR_TEXT);
4282           }
4283           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
4284             var wrapper = new LodashWrapper([], true);
4285           }
4286         }
4287         index = wrapper ? index : length;
4288         while (++index < length) {
4289           func = funcs[index];
4290
4291           var funcName = getFuncName(func),
4292               data = funcName == 'wrapper' ? getData(func) : undefined;
4293
4294           if (data && isLaziable(data[0]) &&
4295                 data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) &&
4296                 !data[4].length && data[9] == 1
4297               ) {
4298             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
4299           } else {
4300             wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
4301           }
4302         }
4303         return function() {
4304           var args = arguments,
4305               value = args[0];
4306
4307           if (wrapper && args.length == 1 &&
4308               isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
4309             return wrapper.plant(value).value();
4310           }
4311           var index = 0,
4312               result = length ? funcs[index].apply(this, args) : value;
4313
4314           while (++index < length) {
4315             result = funcs[index].call(this, result);
4316           }
4317           return result;
4318         };
4319       });
4320     }
4321
4322     /**
4323      * Creates a function that wraps `func` to invoke it with optional `this`
4324      * binding of `thisArg`, partial application, and currying.
4325      *
4326      * @private
4327      * @param {Function|string} func The function or method name to wrap.
4328      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4329      * @param {*} [thisArg] The `this` binding of `func`.
4330      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4331      * @param {Array} [holders] The `partials` placeholder indexes.
4332      * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
4333      * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
4334      * @param {Array} [argPos] The argument positions of the new function.
4335      * @param {number} [ary] The arity cap of `func`.
4336      * @param {number} [arity] The arity of `func`.
4337      * @returns {Function} Returns the new wrapped function.
4338      */
4339     function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
4340       var isAry = bitmask & ARY_FLAG,
4341           isBind = bitmask & BIND_FLAG,
4342           isBindKey = bitmask & BIND_KEY_FLAG,
4343           isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
4344           isFlip = bitmask & FLIP_FLAG,
4345           Ctor = isBindKey ? undefined : createCtorWrapper(func);
4346
4347       function wrapper() {
4348         var length = arguments.length,
4349             index = length,
4350             args = Array(length);
4351
4352         while (index--) {
4353           args[index] = arguments[index];
4354         }
4355         if (isCurried) {
4356           var placeholder = getPlaceholder(wrapper),
4357               holdersCount = countHolders(args, placeholder);
4358         }
4359         if (partials) {
4360           args = composeArgs(args, partials, holders, isCurried);
4361         }
4362         if (partialsRight) {
4363           args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
4364         }
4365         length -= holdersCount;
4366         if (isCurried && length < arity) {
4367           var newHolders = replaceHolders(args, placeholder);
4368           return createRecurryWrapper(
4369             func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg,
4370             args, newHolders, argPos, ary, arity - length
4371           );
4372         }
4373         var thisBinding = isBind ? thisArg : this,
4374             fn = isBindKey ? thisBinding[func] : func;
4375
4376         length = args.length;
4377         if (argPos) {
4378           args = reorder(args, argPos);
4379         } else if (isFlip && length > 1) {
4380           args.reverse();
4381         }
4382         if (isAry && ary < length) {
4383           args.length = ary;
4384         }
4385         if (this && this !== root && this instanceof wrapper) {
4386           fn = Ctor || createCtorWrapper(fn);
4387         }
4388         return fn.apply(thisBinding, args);
4389       }
4390       return wrapper;
4391     }
4392
4393     /**
4394      * Creates a function like `_.invertBy`.
4395      *
4396      * @private
4397      * @param {Function} setter The function to set accumulator values.
4398      * @param {Function} toIteratee The function to resolve iteratees.
4399      * @returns {Function} Returns the new inverter function.
4400      */
4401     function createInverter(setter, toIteratee) {
4402       return function(object, iteratee) {
4403         return baseInverter(object, setter, toIteratee(iteratee), {});
4404       };
4405     }
4406
4407     /**
4408      * Creates a function like `_.over`.
4409      *
4410      * @private
4411      * @param {Function} arrayFunc The function to iterate over iteratees.
4412      * @returns {Function} Returns the new invoker function.
4413      */
4414     function createOver(arrayFunc) {
4415       return rest(function(iteratees) {
4416         iteratees = arrayMap(baseFlatten(iteratees, 1), getIteratee());
4417         return rest(function(args) {
4418           var thisArg = this;
4419           return arrayFunc(iteratees, function(iteratee) {
4420             return apply(iteratee, thisArg, args);
4421           });
4422         });
4423       });
4424     }
4425
4426     /**
4427      * Creates the padding for `string` based on `length`. The `chars` string
4428      * is truncated if the number of characters exceeds `length`.
4429      *
4430      * @private
4431      * @param {string} string The string to create padding for.
4432      * @param {number} [length=0] The padding length.
4433      * @param {string} [chars=' '] The string used as padding.
4434      * @returns {string} Returns the padding for `string`.
4435      */
4436     function createPadding(string, length, chars) {
4437       length = toInteger(length);
4438
4439       var strLength = stringSize(string);
4440       if (!length || strLength >= length) {
4441         return '';
4442       }
4443       var padLength = length - strLength;
4444       chars = chars === undefined ? ' ' : (chars + '');
4445
4446       var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
4447       return reHasComplexSymbol.test(chars)
4448         ? stringToArray(result).slice(0, padLength).join('')
4449         : result.slice(0, padLength);
4450     }
4451
4452     /**
4453      * Creates a function that wraps `func` to invoke it with the optional `this`
4454      * binding of `thisArg` and the `partials` prepended to those provided to
4455      * the wrapper.
4456      *
4457      * @private
4458      * @param {Function} func The function to wrap.
4459      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4460      * @param {*} thisArg The `this` binding of `func`.
4461      * @param {Array} partials The arguments to prepend to those provided to the new function.
4462      * @returns {Function} Returns the new wrapped function.
4463      */
4464     function createPartialWrapper(func, bitmask, thisArg, partials) {
4465       var isBind = bitmask & BIND_FLAG,
4466           Ctor = createCtorWrapper(func);
4467
4468       function wrapper() {
4469         var argsIndex = -1,
4470             argsLength = arguments.length,
4471             leftIndex = -1,
4472             leftLength = partials.length,
4473             args = Array(leftLength + argsLength),
4474             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4475
4476         while (++leftIndex < leftLength) {
4477           args[leftIndex] = partials[leftIndex];
4478         }
4479         while (argsLength--) {
4480           args[leftIndex++] = arguments[++argsIndex];
4481         }
4482         return apply(fn, isBind ? thisArg : this, args);
4483       }
4484       return wrapper;
4485     }
4486
4487     /**
4488      * Creates a `_.range` or `_.rangeRight` function.
4489      *
4490      * @private
4491      * @param {boolean} [fromRight] Specify iterating from right to left.
4492      * @returns {Function} Returns the new range function.
4493      */
4494     function createRange(fromRight) {
4495       return function(start, end, step) {
4496         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
4497           end = step = undefined;
4498         }
4499         // Ensure the sign of `-0` is preserved.
4500         start = toNumber(start);
4501         start = start === start ? start : 0;
4502         if (end === undefined) {
4503           end = start;
4504           start = 0;
4505         } else {
4506           end = toNumber(end) || 0;
4507         }
4508         step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
4509         return baseRange(start, end, step, fromRight);
4510       };
4511     }
4512
4513     /**
4514      * Creates a function that wraps `func` to continue currying.
4515      *
4516      * @private
4517      * @param {Function} func The function to wrap.
4518      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4519      * @param {Function} wrapFunc The function to create the `func` wrapper.
4520      * @param {*} placeholder The placeholder value.
4521      * @param {*} [thisArg] The `this` binding of `func`.
4522      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4523      * @param {Array} [holders] The `partials` placeholder indexes.
4524      * @param {Array} [argPos] The argument positions of the new function.
4525      * @param {number} [ary] The arity cap of `func`.
4526      * @param {number} [arity] The arity of `func`.
4527      * @returns {Function} Returns the new wrapped function.
4528      */
4529     function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
4530       var isCurry = bitmask & CURRY_FLAG,
4531           newArgPos = argPos ? copyArray(argPos) : undefined,
4532           newHolders = isCurry ? holders : undefined,
4533           newHoldersRight = isCurry ? undefined : holders,
4534           newPartials = isCurry ? partials : undefined,
4535           newPartialsRight = isCurry ? undefined : partials;
4536
4537       bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
4538       bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
4539
4540       if (!(bitmask & CURRY_BOUND_FLAG)) {
4541         bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
4542       }
4543       var newData = [
4544         func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
4545         newHoldersRight, newArgPos, ary, arity
4546       ];
4547
4548       var result = wrapFunc.apply(undefined, newData);
4549       if (isLaziable(func)) {
4550         setData(result, newData);
4551       }
4552       result.placeholder = placeholder;
4553       return result;
4554     }
4555
4556     /**
4557      * Creates a function like `_.round`.
4558      *
4559      * @private
4560      * @param {string} methodName The name of the `Math` method to use when rounding.
4561      * @returns {Function} Returns the new round function.
4562      */
4563     function createRound(methodName) {
4564       var func = Math[methodName];
4565       return function(number, precision) {
4566         number = toNumber(number);
4567         precision = toInteger(precision);
4568         if (precision) {
4569           // Shift with exponential notation to avoid floating-point issues.
4570           // See [MDN](https://mdn.io/round#Examples) for more details.
4571           var pair = (toString(number) + 'e').split('e'),
4572               value = func(pair[0] + 'e' + (+pair[1] + precision));
4573
4574           pair = (toString(value) + 'e').split('e');
4575           return +(pair[0] + 'e' + (+pair[1] - precision));
4576         }
4577         return func(number);
4578       };
4579     }
4580
4581     /**
4582      * Creates a set of `values`.
4583      *
4584      * @private
4585      * @param {Array} values The values to add to the set.
4586      * @returns {Object} Returns the new set.
4587      */
4588     var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
4589       return new Set(values);
4590     };
4591
4592     /**
4593      * Creates a function that either curries or invokes `func` with optional
4594      * `this` binding and partially applied arguments.
4595      *
4596      * @private
4597      * @param {Function|string} func The function or method name to wrap.
4598      * @param {number} bitmask The bitmask of wrapper flags.
4599      *  The bitmask may be composed of the following flags:
4600      *     1 - `_.bind`
4601      *     2 - `_.bindKey`
4602      *     4 - `_.curry` or `_.curryRight` of a bound function
4603      *     8 - `_.curry`
4604      *    16 - `_.curryRight`
4605      *    32 - `_.partial`
4606      *    64 - `_.partialRight`
4607      *   128 - `_.rearg`
4608      *   256 - `_.ary`
4609      * @param {*} [thisArg] The `this` binding of `func`.
4610      * @param {Array} [partials] The arguments to be partially applied.
4611      * @param {Array} [holders] The `partials` placeholder indexes.
4612      * @param {Array} [argPos] The argument positions of the new function.
4613      * @param {number} [ary] The arity cap of `func`.
4614      * @param {number} [arity] The arity of `func`.
4615      * @returns {Function} Returns the new wrapped function.
4616      */
4617     function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
4618       var isBindKey = bitmask & BIND_KEY_FLAG;
4619       if (!isBindKey && typeof func != 'function') {
4620         throw new TypeError(FUNC_ERROR_TEXT);
4621       }
4622       var length = partials ? partials.length : 0;
4623       if (!length) {
4624         bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
4625         partials = holders = undefined;
4626       }
4627       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
4628       arity = arity === undefined ? arity : toInteger(arity);
4629       length -= holders ? holders.length : 0;
4630
4631       if (bitmask & PARTIAL_RIGHT_FLAG) {
4632         var partialsRight = partials,
4633             holdersRight = holders;
4634
4635         partials = holders = undefined;
4636       }
4637       var data = isBindKey ? undefined : getData(func);
4638
4639       var newData = [
4640         func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
4641         argPos, ary, arity
4642       ];
4643
4644       if (data) {
4645         mergeData(newData, data);
4646       }
4647       func = newData[0];
4648       bitmask = newData[1];
4649       thisArg = newData[2];
4650       partials = newData[3];
4651       holders = newData[4];
4652       arity = newData[9] = newData[9] == null
4653         ? (isBindKey ? 0 : func.length)
4654         : nativeMax(newData[9] - length, 0);
4655
4656       if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
4657         bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
4658       }
4659       if (!bitmask || bitmask == BIND_FLAG) {
4660         var result = createBaseWrapper(func, bitmask, thisArg);
4661       } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
4662         result = createCurryWrapper(func, bitmask, arity);
4663       } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
4664         result = createPartialWrapper(func, bitmask, thisArg, partials);
4665       } else {
4666         result = createHybridWrapper.apply(undefined, newData);
4667       }
4668       var setter = data ? baseSetData : setData;
4669       return setter(result, newData);
4670     }
4671
4672     /**
4673      * A specialized version of `baseIsEqualDeep` for arrays with support for
4674      * partial deep comparisons.
4675      *
4676      * @private
4677      * @param {Array} array The array to compare.
4678      * @param {Array} other The other array to compare.
4679      * @param {Function} equalFunc The function to determine equivalents of values.
4680      * @param {Function} [customizer] The function to customize comparisons.
4681      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4682      * @param {Object} [stack] Tracks traversed `array` and `other` objects.
4683      * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
4684      */
4685     function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
4686       var index = -1,
4687           isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4688           isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
4689           arrLength = array.length,
4690           othLength = other.length;
4691
4692       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
4693         return false;
4694       }
4695       // Assume cyclic values are equal.
4696       var stacked = stack.get(array);
4697       if (stacked) {
4698         return stacked == other;
4699       }
4700       var result = true;
4701       stack.set(array, other);
4702
4703       // Ignore non-index properties.
4704       while (++index < arrLength) {
4705         var arrValue = array[index],
4706             othValue = other[index];
4707
4708         if (customizer) {
4709           var compared = isPartial
4710             ? customizer(othValue, arrValue, index, other, array, stack)
4711             : customizer(arrValue, othValue, index, array, other, stack);
4712         }
4713         if (compared !== undefined) {
4714           if (compared) {
4715             continue;
4716           }
4717           result = false;
4718           break;
4719         }
4720         // Recursively compare arrays (susceptible to call stack limits).
4721         if (isUnordered) {
4722           if (!arraySome(other, function(othValue) {
4723                 return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
4724               })) {
4725             result = false;
4726             break;
4727           }
4728         } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
4729           result = false;
4730           break;
4731         }
4732       }
4733       stack['delete'](array);
4734       return result;
4735     }
4736
4737     /**
4738      * A specialized version of `baseIsEqualDeep` for comparing objects of
4739      * the same `toStringTag`.
4740      *
4741      * **Note:** This function only supports comparing values with tags of
4742      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4743      *
4744      * @private
4745      * @param {Object} object The object to compare.
4746      * @param {Object} other The other object to compare.
4747      * @param {string} tag The `toStringTag` of the objects to compare.
4748      * @param {Function} equalFunc The function to determine equivalents of values.
4749      * @param {Function} [customizer] The function to customize comparisons.
4750      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4751      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4752      */
4753     function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
4754       switch (tag) {
4755         case arrayBufferTag:
4756           if ((object.byteLength != other.byteLength) ||
4757               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
4758             return false;
4759           }
4760           return true;
4761
4762         case boolTag:
4763         case dateTag:
4764           // Coerce dates and booleans to numbers, dates to milliseconds and booleans
4765           // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
4766           return +object == +other;
4767
4768         case errorTag:
4769           return object.name == other.name && object.message == other.message;
4770
4771         case numberTag:
4772           // Treat `NaN` vs. `NaN` as equal.
4773           return (object != +object) ? other != +other : object == +other;
4774
4775         case regexpTag:
4776         case stringTag:
4777           // Coerce regexes to strings and treat strings primitives and string
4778           // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
4779           return object == (other + '');
4780
4781         case mapTag:
4782           var convert = mapToArray;
4783
4784         case setTag:
4785           var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
4786           convert || (convert = setToArray);
4787
4788           // Recursively compare objects (susceptible to call stack limits).
4789           return (isPartial || object.size == other.size) &&
4790             equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
4791
4792         case symbolTag:
4793           return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
4794       }
4795       return false;
4796     }
4797
4798     /**
4799      * A specialized version of `baseIsEqualDeep` for objects with support for
4800      * partial deep comparisons.
4801      *
4802      * @private
4803      * @param {Object} object The object to compare.
4804      * @param {Object} other The other object to compare.
4805      * @param {Function} equalFunc The function to determine equivalents of values.
4806      * @param {Function} [customizer] The function to customize comparisons.
4807      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4808      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
4809      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4810      */
4811     function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
4812       var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4813           objProps = keys(object),
4814           objLength = objProps.length,
4815           othProps = keys(other),
4816           othLength = othProps.length;
4817
4818       if (objLength != othLength && !isPartial) {
4819         return false;
4820       }
4821       var index = objLength;
4822       while (index--) {
4823         var key = objProps[index];
4824         if (!(isPartial ? key in other : baseHas(other, key))) {
4825           return false;
4826         }
4827       }
4828       // Assume cyclic values are equal.
4829       var stacked = stack.get(object);
4830       if (stacked) {
4831         return stacked == other;
4832       }
4833       var result = true;
4834       stack.set(object, other);
4835
4836       var skipCtor = isPartial;
4837       while (++index < objLength) {
4838         key = objProps[index];
4839         var objValue = object[key],
4840             othValue = other[key];
4841
4842         if (customizer) {
4843           var compared = isPartial
4844             ? customizer(othValue, objValue, key, other, object, stack)
4845             : customizer(objValue, othValue, key, object, other, stack);
4846         }
4847         // Recursively compare objects (susceptible to call stack limits).
4848         if (!(compared === undefined
4849               ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
4850               : compared
4851             )) {
4852           result = false;
4853           break;
4854         }
4855         skipCtor || (skipCtor = key == 'constructor');
4856       }
4857       if (result && !skipCtor) {
4858         var objCtor = object.constructor,
4859             othCtor = other.constructor;
4860
4861         // Non `Object` object instances with different constructors are not equal.
4862         if (objCtor != othCtor &&
4863             ('constructor' in object && 'constructor' in other) &&
4864             !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
4865               typeof othCtor == 'function' && othCtor instanceof othCtor)) {
4866           result = false;
4867         }
4868       }
4869       stack['delete'](object);
4870       return result;
4871     }
4872
4873     /**
4874      * Gets metadata for `func`.
4875      *
4876      * @private
4877      * @param {Function} func The function to query.
4878      * @returns {*} Returns the metadata for `func`.
4879      */
4880     var getData = !metaMap ? noop : function(func) {
4881       return metaMap.get(func);
4882     };
4883
4884     /**
4885      * Gets the name of `func`.
4886      *
4887      * @private
4888      * @param {Function} func The function to query.
4889      * @returns {string} Returns the function name.
4890      */
4891     function getFuncName(func) {
4892       var result = (func.name + ''),
4893           array = realNames[result],
4894           length = hasOwnProperty.call(realNames, result) ? array.length : 0;
4895
4896       while (length--) {
4897         var data = array[length],
4898             otherFunc = data.func;
4899         if (otherFunc == null || otherFunc == func) {
4900           return data.name;
4901         }
4902       }
4903       return result;
4904     }
4905
4906     /**
4907      * Gets the appropriate "iteratee" function. If the `_.iteratee` method is
4908      * customized this function returns the custom method, otherwise it returns
4909      * `baseIteratee`. If arguments are provided the chosen function is invoked
4910      * with them and its result is returned.
4911      *
4912      * @private
4913      * @param {*} [value] The value to convert to an iteratee.
4914      * @param {number} [arity] The arity of the created iteratee.
4915      * @returns {Function} Returns the chosen function or its result.
4916      */
4917     function getIteratee() {
4918       var result = lodash.iteratee || iteratee;
4919       result = result === iteratee ? baseIteratee : result;
4920       return arguments.length ? result(arguments[0], arguments[1]) : result;
4921     }
4922
4923     /**
4924      * Gets the "length" property value of `object`.
4925      *
4926      * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
4927      * that affects Safari on at least iOS 8.1-8.3 ARM64.
4928      *
4929      * @private
4930      * @param {Object} object The object to query.
4931      * @returns {*} Returns the "length" value.
4932      */
4933     var getLength = baseProperty('length');
4934
4935     /**
4936      * Gets the property names, values, and compare flags of `object`.
4937      *
4938      * @private
4939      * @param {Object} object The object to query.
4940      * @returns {Array} Returns the match data of `object`.
4941      */
4942     function getMatchData(object) {
4943       var result = toPairs(object),
4944           length = result.length;
4945
4946       while (length--) {
4947         result[length][2] = isStrictComparable(result[length][1]);
4948       }
4949       return result;
4950     }
4951
4952     /**
4953      * Gets the native function at `key` of `object`.
4954      *
4955      * @private
4956      * @param {Object} object The object to query.
4957      * @param {string} key The key of the method to get.
4958      * @returns {*} Returns the function if it's native, else `undefined`.
4959      */
4960     function getNative(object, key) {
4961       var value = object == null ? undefined : object[key];
4962       return isNative(value) ? value : undefined;
4963     }
4964
4965     /**
4966      * Gets the argument placeholder value for `func`.
4967      *
4968      * @private
4969      * @param {Function} func The function to inspect.
4970      * @returns {*} Returns the placeholder value.
4971      */
4972     function getPlaceholder(func) {
4973       var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
4974       return object.placeholder;
4975     }
4976
4977     /**
4978      * Creates an array of the own symbol properties of `object`.
4979      *
4980      * @private
4981      * @param {Object} object The object to query.
4982      * @returns {Array} Returns the array of symbols.
4983      */
4984     var getSymbols = getOwnPropertySymbols || function() {
4985       return [];
4986     };
4987
4988     /**
4989      * Gets the `toStringTag` of `value`.
4990      *
4991      * @private
4992      * @param {*} value The value to query.
4993      * @returns {string} Returns the `toStringTag`.
4994      */
4995     function getTag(value) {
4996       return objectToString.call(value);
4997     }
4998
4999     // Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps.
5000     if ((Map && getTag(new Map) != mapTag) ||
5001         (Set && getTag(new Set) != setTag) ||
5002         (WeakMap && getTag(new WeakMap) != weakMapTag)) {
5003       getTag = function(value) {
5004         var result = objectToString.call(value),
5005             Ctor = result == objectTag ? value.constructor : null,
5006             ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
5007
5008         if (ctorString) {
5009           switch (ctorString) {
5010             case mapCtorString: return mapTag;
5011             case setCtorString: return setTag;
5012             case weakMapCtorString: return weakMapTag;
5013           }
5014         }
5015         return result;
5016       };
5017     }
5018
5019     /**
5020      * Gets the view, applying any `transforms` to the `start` and `end` positions.
5021      *
5022      * @private
5023      * @param {number} start The start of the view.
5024      * @param {number} end The end of the view.
5025      * @param {Array} transforms The transformations to apply to the view.
5026      * @returns {Object} Returns an object containing the `start` and `end`
5027      *  positions of the view.
5028      */
5029     function getView(start, end, transforms) {
5030       var index = -1,
5031           length = transforms.length;
5032
5033       while (++index < length) {
5034         var data = transforms[index],
5035             size = data.size;
5036
5037         switch (data.type) {
5038           case 'drop':      start += size; break;
5039           case 'dropRight': end -= size; break;
5040           case 'take':      end = nativeMin(end, start + size); break;
5041           case 'takeRight': start = nativeMax(start, end - size); break;
5042         }
5043       }
5044       return { 'start': start, 'end': end };
5045     }
5046
5047     /**
5048      * Checks if `path` exists on `object`.
5049      *
5050      * @private
5051      * @param {Object} object The object to query.
5052      * @param {Array|string} path The path to check.
5053      * @param {Function} hasFunc The function to check properties.
5054      * @returns {boolean} Returns `true` if `path` exists, else `false`.
5055      */
5056     function hasPath(object, path, hasFunc) {
5057       if (object == null) {
5058         return false;
5059       }
5060       var result = hasFunc(object, path);
5061       if (!result && !isKey(path)) {
5062         path = baseCastPath(path);
5063         object = parent(object, path);
5064         if (object != null) {
5065           path = last(path);
5066           result = hasFunc(object, path);
5067         }
5068       }
5069       var length = object ? object.length : undefined;
5070       return result || (
5071         !!length && isLength(length) && isIndex(path, length) &&
5072         (isArray(object) || isString(object) || isArguments(object))
5073       );
5074     }
5075
5076     /**
5077      * Initializes an array clone.
5078      *
5079      * @private
5080      * @param {Array} array The array to clone.
5081      * @returns {Array} Returns the initialized clone.
5082      */
5083     function initCloneArray(array) {
5084       var length = array.length,
5085           result = array.constructor(length);
5086
5087       // Add properties assigned by `RegExp#exec`.
5088       if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
5089         result.index = array.index;
5090         result.input = array.input;
5091       }
5092       return result;
5093     }
5094
5095     /**
5096      * Initializes an object clone.
5097      *
5098      * @private
5099      * @param {Object} object The object to clone.
5100      * @returns {Object} Returns the initialized clone.
5101      */
5102     function initCloneObject(object) {
5103       return (isFunction(object.constructor) && !isPrototype(object))
5104         ? baseCreate(getPrototypeOf(object))
5105         : {};
5106     }
5107
5108     /**
5109      * Initializes an object clone based on its `toStringTag`.
5110      *
5111      * **Note:** This function only supports cloning values with tags of
5112      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5113      *
5114      * @private
5115      * @param {Object} object The object to clone.
5116      * @param {string} tag The `toStringTag` of the object to clone.
5117      * @param {boolean} [isDeep] Specify a deep clone.
5118      * @returns {Object} Returns the initialized clone.
5119      */
5120     function initCloneByTag(object, tag, isDeep) {
5121       var Ctor = object.constructor;
5122       switch (tag) {
5123         case arrayBufferTag:
5124           return cloneArrayBuffer(object);
5125
5126         case boolTag:
5127         case dateTag:
5128           return new Ctor(+object);
5129
5130         case float32Tag: case float64Tag:
5131         case int8Tag: case int16Tag: case int32Tag:
5132         case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
5133           return cloneTypedArray(object, isDeep);
5134
5135         case mapTag:
5136           return cloneMap(object);
5137
5138         case numberTag:
5139         case stringTag:
5140           return new Ctor(object);
5141
5142         case regexpTag:
5143           return cloneRegExp(object);
5144
5145         case setTag:
5146           return cloneSet(object);
5147
5148         case symbolTag:
5149           return cloneSymbol(object);
5150       }
5151     }
5152
5153     /**
5154      * Creates an array of index keys for `object` values of arrays,
5155      * `arguments` objects, and strings, otherwise `null` is returned.
5156      *
5157      * @private
5158      * @param {Object} object The object to query.
5159      * @returns {Array|null} Returns index keys, else `null`.
5160      */
5161     function indexKeys(object) {
5162       var length = object ? object.length : undefined;
5163       if (isLength(length) &&
5164           (isArray(object) || isString(object) || isArguments(object))) {
5165         return baseTimes(length, String);
5166       }
5167       return null;
5168     }
5169
5170     /**
5171      * Checks if the given arguments are from an iteratee call.
5172      *
5173      * @private
5174      * @param {*} value The potential iteratee value argument.
5175      * @param {*} index The potential iteratee index or key argument.
5176      * @param {*} object The potential iteratee object argument.
5177      * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
5178      */
5179     function isIterateeCall(value, index, object) {
5180       if (!isObject(object)) {
5181         return false;
5182       }
5183       var type = typeof index;
5184       if (type == 'number'
5185           ? (isArrayLike(object) && isIndex(index, object.length))
5186           : (type == 'string' && index in object)) {
5187         return eq(object[index], value);
5188       }
5189       return false;
5190     }
5191
5192     /**
5193      * Checks if `value` is a property name and not a property path.
5194      *
5195      * @private
5196      * @param {*} value The value to check.
5197      * @param {Object} [object] The object to query keys on.
5198      * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
5199      */
5200     function isKey(value, object) {
5201       if (typeof value == 'number') {
5202         return true;
5203       }
5204       return !isArray(value) &&
5205         (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
5206           (object != null && value in Object(object)));
5207     }
5208
5209     /**
5210      * Checks if `value` is suitable for use as unique object key.
5211      *
5212      * @private
5213      * @param {*} value The value to check.
5214      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
5215      */
5216     function isKeyable(value) {
5217       var type = typeof value;
5218       return type == 'number' || type == 'boolean' ||
5219         (type == 'string' && value != '__proto__') || value == null;
5220     }
5221
5222     /**
5223      * Checks if `func` has a lazy counterpart.
5224      *
5225      * @private
5226      * @param {Function} func The function to check.
5227      * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
5228      */
5229     function isLaziable(func) {
5230       var funcName = getFuncName(func),
5231           other = lodash[funcName];
5232
5233       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
5234         return false;
5235       }
5236       if (func === other) {
5237         return true;
5238       }
5239       var data = getData(other);
5240       return !!data && func === data[0];
5241     }
5242
5243     /**
5244      * Checks if `value` is likely a prototype object.
5245      *
5246      * @private
5247      * @param {*} value The value to check.
5248      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
5249      */
5250     function isPrototype(value) {
5251       var Ctor = value && value.constructor,
5252           proto = (isFunction(Ctor) && Ctor.prototype) || objectProto;
5253
5254       return value === proto;
5255     }
5256
5257     /**
5258      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
5259      *
5260      * @private
5261      * @param {*} value The value to check.
5262      * @returns {boolean} Returns `true` if `value` if suitable for strict
5263      *  equality comparisons, else `false`.
5264      */
5265     function isStrictComparable(value) {
5266       return value === value && !isObject(value);
5267     }
5268
5269     /**
5270      * Merges the function metadata of `source` into `data`.
5271      *
5272      * Merging metadata reduces the number of wrappers used to invoke a function.
5273      * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
5274      * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
5275      * modify function arguments, making the order in which they are executed important,
5276      * preventing the merging of metadata. However, we make an exception for a safe
5277      * combined case where curried functions have `_.ary` and or `_.rearg` applied.
5278      *
5279      * @private
5280      * @param {Array} data The destination metadata.
5281      * @param {Array} source The source metadata.
5282      * @returns {Array} Returns `data`.
5283      */
5284     function mergeData(data, source) {
5285       var bitmask = data[1],
5286           srcBitmask = source[1],
5287           newBitmask = bitmask | srcBitmask,
5288           isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
5289
5290       var isCombo =
5291         ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) ||
5292         ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
5293         ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
5294
5295       // Exit early if metadata can't be merged.
5296       if (!(isCommon || isCombo)) {
5297         return data;
5298       }
5299       // Use source `thisArg` if available.
5300       if (srcBitmask & BIND_FLAG) {
5301         data[2] = source[2];
5302         // Set when currying a bound function.
5303         newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG;
5304       }
5305       // Compose partial arguments.
5306       var value = source[3];
5307       if (value) {
5308         var partials = data[3];
5309         data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
5310         data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
5311       }
5312       // Compose partial right arguments.
5313       value = source[5];
5314       if (value) {
5315         partials = data[5];
5316         data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
5317         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
5318       }
5319       // Use source `argPos` if available.
5320       value = source[7];
5321       if (value) {
5322         data[7] = copyArray(value);
5323       }
5324       // Use source `ary` if it's smaller.
5325       if (srcBitmask & ARY_FLAG) {
5326         data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
5327       }
5328       // Use source `arity` if one is not provided.
5329       if (data[9] == null) {
5330         data[9] = source[9];
5331       }
5332       // Use source `func` and merge bitmasks.
5333       data[0] = source[0];
5334       data[1] = newBitmask;
5335
5336       return data;
5337     }
5338
5339     /**
5340      * Used by `_.defaultsDeep` to customize its `_.merge` use.
5341      *
5342      * @private
5343      * @param {*} objValue The destination value.
5344      * @param {*} srcValue The source value.
5345      * @param {string} key The key of the property to merge.
5346      * @param {Object} object The parent object of `objValue`.
5347      * @param {Object} source The parent object of `srcValue`.
5348      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
5349      * @returns {*} Returns the value to assign.
5350      */
5351     function mergeDefaults(objValue, srcValue, key, object, source, stack) {
5352       if (isObject(objValue) && isObject(srcValue)) {
5353         stack.set(srcValue, objValue);
5354         baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
5355       }
5356       return objValue;
5357     }
5358
5359     /**
5360      * Gets the parent value at `path` of `object`.
5361      *
5362      * @private
5363      * @param {Object} object The object to query.
5364      * @param {Array} path The path to get the parent value of.
5365      * @returns {*} Returns the parent value.
5366      */
5367     function parent(object, path) {
5368       return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
5369     }
5370
5371     /**
5372      * Reorder `array` according to the specified indexes where the element at
5373      * the first index is assigned as the first element, the element at
5374      * the second index is assigned as the second element, and so on.
5375      *
5376      * @private
5377      * @param {Array} array The array to reorder.
5378      * @param {Array} indexes The arranged array indexes.
5379      * @returns {Array} Returns `array`.
5380      */
5381     function reorder(array, indexes) {
5382       var arrLength = array.length,
5383           length = nativeMin(indexes.length, arrLength),
5384           oldArray = copyArray(array);
5385
5386       while (length--) {
5387         var index = indexes[length];
5388         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5389       }
5390       return array;
5391     }
5392
5393     /**
5394      * Sets metadata for `func`.
5395      *
5396      * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
5397      * period of time, it will trip its breaker and transition to an identity function
5398      * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
5399      * for more details.
5400      *
5401      * @private
5402      * @param {Function} func The function to associate metadata with.
5403      * @param {*} data The metadata.
5404      * @returns {Function} Returns `func`.
5405      */
5406     var setData = (function() {
5407       var count = 0,
5408           lastCalled = 0;
5409
5410       return function(key, value) {
5411         var stamp = now(),
5412             remaining = HOT_SPAN - (stamp - lastCalled);
5413
5414         lastCalled = stamp;
5415         if (remaining > 0) {
5416           if (++count >= HOT_COUNT) {
5417             return key;
5418           }
5419         } else {
5420           count = 0;
5421         }
5422         return baseSetData(key, value);
5423       };
5424     }());
5425
5426     /**
5427      * Converts `string` to a property path array.
5428      *
5429      * @private
5430      * @param {string} string The string to convert.
5431      * @returns {Array} Returns the property path array.
5432      */
5433     function stringToPath(string) {
5434       var result = [];
5435       toString(string).replace(rePropName, function(match, number, quote, string) {
5436         result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
5437       });
5438       return result;
5439     }
5440
5441     /**
5442      * Creates a clone of `wrapper`.
5443      *
5444      * @private
5445      * @param {Object} wrapper The wrapper to clone.
5446      * @returns {Object} Returns the cloned wrapper.
5447      */
5448     function wrapperClone(wrapper) {
5449       if (wrapper instanceof LazyWrapper) {
5450         return wrapper.clone();
5451       }
5452       var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
5453       result.__actions__ = copyArray(wrapper.__actions__);
5454       result.__index__  = wrapper.__index__;
5455       result.__values__ = wrapper.__values__;
5456       return result;
5457     }
5458
5459     /*------------------------------------------------------------------------*/
5460
5461     /**
5462      * Creates an array of elements split into groups the length of `size`.
5463      * If `array` can't be split evenly, the final chunk will be the remaining
5464      * elements.
5465      *
5466      * @static
5467      * @memberOf _
5468      * @category Array
5469      * @param {Array} array The array to process.
5470      * @param {number} [size=0] The length of each chunk.
5471      * @returns {Array} Returns the new array containing chunks.
5472      * @example
5473      *
5474      * _.chunk(['a', 'b', 'c', 'd'], 2);
5475      * // => [['a', 'b'], ['c', 'd']]
5476      *
5477      * _.chunk(['a', 'b', 'c', 'd'], 3);
5478      * // => [['a', 'b', 'c'], ['d']]
5479      */
5480     function chunk(array, size) {
5481       size = nativeMax(toInteger(size), 0);
5482
5483       var length = array ? array.length : 0;
5484       if (!length || size < 1) {
5485         return [];
5486       }
5487       var index = 0,
5488           resIndex = -1,
5489           result = Array(nativeCeil(length / size));
5490
5491       while (index < length) {
5492         result[++resIndex] = baseSlice(array, index, (index += size));
5493       }
5494       return result;
5495     }
5496
5497     /**
5498      * Creates an array with all falsey values removed. The values `false`, `null`,
5499      * `0`, `""`, `undefined`, and `NaN` are falsey.
5500      *
5501      * @static
5502      * @memberOf _
5503      * @category Array
5504      * @param {Array} array The array to compact.
5505      * @returns {Array} Returns the new array of filtered values.
5506      * @example
5507      *
5508      * _.compact([0, 1, false, 2, '', 3]);
5509      * // => [1, 2, 3]
5510      */
5511     function compact(array) {
5512       var index = -1,
5513           length = array ? array.length : 0,
5514           resIndex = -1,
5515           result = [];
5516
5517       while (++index < length) {
5518         var value = array[index];
5519         if (value) {
5520           result[++resIndex] = value;
5521         }
5522       }
5523       return result;
5524     }
5525
5526     /**
5527      * Creates a new array concatenating `array` with any additional arrays
5528      * and/or values.
5529      *
5530      * @static
5531      * @memberOf _
5532      * @category Array
5533      * @param {Array} array The array to concatenate.
5534      * @param {...*} [values] The values to concatenate.
5535      * @returns {Array} Returns the new concatenated array.
5536      * @example
5537      *
5538      * var array = [1];
5539      * var other = _.concat(array, 2, [3], [[4]]);
5540      *
5541      * console.log(other);
5542      * // => [1, 2, 3, [4]]
5543      *
5544      * console.log(array);
5545      * // => [1]
5546      */
5547     var concat = rest(function(array, values) {
5548       if (!isArray(array)) {
5549         array = array == null ? [] : [Object(array)];
5550       }
5551       values = baseFlatten(values, 1);
5552       return arrayConcat(array, values);
5553     });
5554
5555     /**
5556      * Creates an array of unique `array` values not included in the other
5557      * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5558      * for equality comparisons.
5559      *
5560      * @static
5561      * @memberOf _
5562      * @category Array
5563      * @param {Array} array The array to inspect.
5564      * @param {...Array} [values] The values to exclude.
5565      * @returns {Array} Returns the new array of filtered values.
5566      * @example
5567      *
5568      * _.difference([3, 2, 1], [4, 2]);
5569      * // => [3, 1]
5570      */
5571     var difference = rest(function(array, values) {
5572       return isArrayLikeObject(array)
5573         ? baseDifference(array, baseFlatten(values, 1, true))
5574         : [];
5575     });
5576
5577     /**
5578      * This method is like `_.difference` except that it accepts `iteratee` which
5579      * is invoked for each element of `array` and `values` to generate the criterion
5580      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5581      *
5582      * @static
5583      * @memberOf _
5584      * @category Array
5585      * @param {Array} array The array to inspect.
5586      * @param {...Array} [values] The values to exclude.
5587      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5588      * @returns {Array} Returns the new array of filtered values.
5589      * @example
5590      *
5591      * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
5592      * // => [3.1, 1.3]
5593      *
5594      * // The `_.property` iteratee shorthand.
5595      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
5596      * // => [{ 'x': 2 }]
5597      */
5598     var differenceBy = rest(function(array, values) {
5599       var iteratee = last(values);
5600       if (isArrayLikeObject(iteratee)) {
5601         iteratee = undefined;
5602       }
5603       return isArrayLikeObject(array)
5604         ? baseDifference(array, baseFlatten(values, 1, true), getIteratee(iteratee))
5605         : [];
5606     });
5607
5608     /**
5609      * This method is like `_.difference` except that it accepts `comparator`
5610      * which is invoked to compare elements of `array` to `values`. The comparator
5611      * is invoked with two arguments: (arrVal, othVal).
5612      *
5613      * @static
5614      * @memberOf _
5615      * @category Array
5616      * @param {Array} array The array to inspect.
5617      * @param {...Array} [values] The values to exclude.
5618      * @param {Function} [comparator] The comparator invoked per element.
5619      * @returns {Array} Returns the new array of filtered values.
5620      * @example
5621      *
5622      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5623      *
5624      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
5625      * // => [{ 'x': 2, 'y': 1 }]
5626      */
5627     var differenceWith = rest(function(array, values) {
5628       var comparator = last(values);
5629       if (isArrayLikeObject(comparator)) {
5630         comparator = undefined;
5631       }
5632       return isArrayLikeObject(array)
5633         ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator)
5634         : [];
5635     });
5636
5637     /**
5638      * Creates a slice of `array` with `n` elements dropped from the beginning.
5639      *
5640      * @static
5641      * @memberOf _
5642      * @category Array
5643      * @param {Array} array The array to query.
5644      * @param {number} [n=1] The number of elements to drop.
5645      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5646      * @returns {Array} Returns the slice of `array`.
5647      * @example
5648      *
5649      * _.drop([1, 2, 3]);
5650      * // => [2, 3]
5651      *
5652      * _.drop([1, 2, 3], 2);
5653      * // => [3]
5654      *
5655      * _.drop([1, 2, 3], 5);
5656      * // => []
5657      *
5658      * _.drop([1, 2, 3], 0);
5659      * // => [1, 2, 3]
5660      */
5661     function drop(array, n, guard) {
5662       var length = array ? array.length : 0;
5663       if (!length) {
5664         return [];
5665       }
5666       n = (guard || n === undefined) ? 1 : toInteger(n);
5667       return baseSlice(array, n < 0 ? 0 : n, length);
5668     }
5669
5670     /**
5671      * Creates a slice of `array` with `n` elements dropped from the end.
5672      *
5673      * @static
5674      * @memberOf _
5675      * @category Array
5676      * @param {Array} array The array to query.
5677      * @param {number} [n=1] The number of elements to drop.
5678      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5679      * @returns {Array} Returns the slice of `array`.
5680      * @example
5681      *
5682      * _.dropRight([1, 2, 3]);
5683      * // => [1, 2]
5684      *
5685      * _.dropRight([1, 2, 3], 2);
5686      * // => [1]
5687      *
5688      * _.dropRight([1, 2, 3], 5);
5689      * // => []
5690      *
5691      * _.dropRight([1, 2, 3], 0);
5692      * // => [1, 2, 3]
5693      */
5694     function dropRight(array, n, guard) {
5695       var length = array ? array.length : 0;
5696       if (!length) {
5697         return [];
5698       }
5699       n = (guard || n === undefined) ? 1 : toInteger(n);
5700       n = length - n;
5701       return baseSlice(array, 0, n < 0 ? 0 : n);
5702     }
5703
5704     /**
5705      * Creates a slice of `array` excluding elements dropped from the end.
5706      * Elements are dropped until `predicate` returns falsey. The predicate is
5707      * invoked with three arguments: (value, index, array).
5708      *
5709      * @static
5710      * @memberOf _
5711      * @category Array
5712      * @param {Array} array The array to query.
5713      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5714      * @returns {Array} Returns the slice of `array`.
5715      * @example
5716      *
5717      * var users = [
5718      *   { 'user': 'barney',  'active': true },
5719      *   { 'user': 'fred',    'active': false },
5720      *   { 'user': 'pebbles', 'active': false }
5721      * ];
5722      *
5723      * _.dropRightWhile(users, function(o) { return !o.active; });
5724      * // => objects for ['barney']
5725      *
5726      * // The `_.matches` iteratee shorthand.
5727      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
5728      * // => objects for ['barney', 'fred']
5729      *
5730      * // The `_.matchesProperty` iteratee shorthand.
5731      * _.dropRightWhile(users, ['active', false]);
5732      * // => objects for ['barney']
5733      *
5734      * // The `_.property` iteratee shorthand.
5735      * _.dropRightWhile(users, 'active');
5736      * // => objects for ['barney', 'fred', 'pebbles']
5737      */
5738     function dropRightWhile(array, predicate) {
5739       return (array && array.length)
5740         ? baseWhile(array, getIteratee(predicate, 3), true, true)
5741         : [];
5742     }
5743
5744     /**
5745      * Creates a slice of `array` excluding elements dropped from the beginning.
5746      * Elements are dropped until `predicate` returns falsey. The predicate is
5747      * invoked with three arguments: (value, index, array).
5748      *
5749      * @static
5750      * @memberOf _
5751      * @category Array
5752      * @param {Array} array The array to query.
5753      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5754      * @returns {Array} Returns the slice of `array`.
5755      * @example
5756      *
5757      * var users = [
5758      *   { 'user': 'barney',  'active': false },
5759      *   { 'user': 'fred',    'active': false },
5760      *   { 'user': 'pebbles', 'active': true }
5761      * ];
5762      *
5763      * _.dropWhile(users, function(o) { return !o.active; });
5764      * // => objects for ['pebbles']
5765      *
5766      * // The `_.matches` iteratee shorthand.
5767      * _.dropWhile(users, { 'user': 'barney', 'active': false });
5768      * // => objects for ['fred', 'pebbles']
5769      *
5770      * // The `_.matchesProperty` iteratee shorthand.
5771      * _.dropWhile(users, ['active', false]);
5772      * // => objects for ['pebbles']
5773      *
5774      * // The `_.property` iteratee shorthand.
5775      * _.dropWhile(users, 'active');
5776      * // => objects for ['barney', 'fred', 'pebbles']
5777      */
5778     function dropWhile(array, predicate) {
5779       return (array && array.length)
5780         ? baseWhile(array, getIteratee(predicate, 3), true)
5781         : [];
5782     }
5783
5784     /**
5785      * Fills elements of `array` with `value` from `start` up to, but not
5786      * including, `end`.
5787      *
5788      * **Note:** This method mutates `array`.
5789      *
5790      * @static
5791      * @memberOf _
5792      * @category Array
5793      * @param {Array} array The array to fill.
5794      * @param {*} value The value to fill `array` with.
5795      * @param {number} [start=0] The start position.
5796      * @param {number} [end=array.length] The end position.
5797      * @returns {Array} Returns `array`.
5798      * @example
5799      *
5800      * var array = [1, 2, 3];
5801      *
5802      * _.fill(array, 'a');
5803      * console.log(array);
5804      * // => ['a', 'a', 'a']
5805      *
5806      * _.fill(Array(3), 2);
5807      * // => [2, 2, 2]
5808      *
5809      * _.fill([4, 6, 8, 10], '*', 1, 3);
5810      * // => [4, '*', '*', 10]
5811      */
5812     function fill(array, value, start, end) {
5813       var length = array ? array.length : 0;
5814       if (!length) {
5815         return [];
5816       }
5817       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
5818         start = 0;
5819         end = length;
5820       }
5821       return baseFill(array, value, start, end);
5822     }
5823
5824     /**
5825      * This method is like `_.find` except that it returns the index of the first
5826      * element `predicate` returns truthy for instead of the element itself.
5827      *
5828      * @static
5829      * @memberOf _
5830      * @category Array
5831      * @param {Array} array The array to search.
5832      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5833      * @returns {number} Returns the index of the found element, else `-1`.
5834      * @example
5835      *
5836      * var users = [
5837      *   { 'user': 'barney',  'active': false },
5838      *   { 'user': 'fred',    'active': false },
5839      *   { 'user': 'pebbles', 'active': true }
5840      * ];
5841      *
5842      * _.findIndex(users, function(o) { return o.user == 'barney'; });
5843      * // => 0
5844      *
5845      * // The `_.matches` iteratee shorthand.
5846      * _.findIndex(users, { 'user': 'fred', 'active': false });
5847      * // => 1
5848      *
5849      * // The `_.matchesProperty` iteratee shorthand.
5850      * _.findIndex(users, ['active', false]);
5851      * // => 0
5852      *
5853      * // The `_.property` iteratee shorthand.
5854      * _.findIndex(users, 'active');
5855      * // => 2
5856      */
5857     function findIndex(array, predicate) {
5858       return (array && array.length)
5859         ? baseFindIndex(array, getIteratee(predicate, 3))
5860         : -1;
5861     }
5862
5863     /**
5864      * This method is like `_.findIndex` except that it iterates over elements
5865      * of `collection` from right to left.
5866      *
5867      * @static
5868      * @memberOf _
5869      * @category Array
5870      * @param {Array} array The array to search.
5871      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5872      * @returns {number} Returns the index of the found element, else `-1`.
5873      * @example
5874      *
5875      * var users = [
5876      *   { 'user': 'barney',  'active': true },
5877      *   { 'user': 'fred',    'active': false },
5878      *   { 'user': 'pebbles', 'active': false }
5879      * ];
5880      *
5881      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
5882      * // => 2
5883      *
5884      * // The `_.matches` iteratee shorthand.
5885      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
5886      * // => 0
5887      *
5888      * // The `_.matchesProperty` iteratee shorthand.
5889      * _.findLastIndex(users, ['active', false]);
5890      * // => 2
5891      *
5892      * // The `_.property` iteratee shorthand.
5893      * _.findLastIndex(users, 'active');
5894      * // => 0
5895      */
5896     function findLastIndex(array, predicate) {
5897       return (array && array.length)
5898         ? baseFindIndex(array, getIteratee(predicate, 3), true)
5899         : -1;
5900     }
5901
5902     /**
5903      * Flattens `array` a single level deep.
5904      *
5905      * @static
5906      * @memberOf _
5907      * @category Array
5908      * @param {Array} array The array to flatten.
5909      * @returns {Array} Returns the new flattened array.
5910      * @example
5911      *
5912      * _.flatten([1, [2, [3, [4]], 5]]);
5913      * // => [1, 2, [3, [4]], 5]
5914      */
5915     function flatten(array) {
5916       var length = array ? array.length : 0;
5917       return length ? baseFlatten(array, 1) : [];
5918     }
5919
5920     /**
5921      * Recursively flattens `array`.
5922      *
5923      * @static
5924      * @memberOf _
5925      * @category Array
5926      * @param {Array} array The array to flatten.
5927      * @returns {Array} Returns the new flattened array.
5928      * @example
5929      *
5930      * _.flattenDeep([1, [2, [3, [4]], 5]]);
5931      * // => [1, 2, 3, 4, 5]
5932      */
5933     function flattenDeep(array) {
5934       var length = array ? array.length : 0;
5935       return length ? baseFlatten(array, INFINITY) : [];
5936     }
5937
5938     /**
5939      * Recursively flatten `array` up to `depth` times.
5940      *
5941      * @static
5942      * @memberOf _
5943      * @category Array
5944      * @param {Array} array The array to flatten.
5945      * @param {number} [depth=1] The maximum recursion depth.
5946      * @returns {Array} Returns the new flattened array.
5947      * @example
5948      *
5949      * var array = [1, [2, [3, [4]], 5]];
5950      *
5951      * _.flattenDepth(array, 1);
5952      * // => [1, 2, [3, [4]], 5]
5953      *
5954      * _.flattenDepth(array, 2);
5955      * // => [1, 2, 3, [4], 5]
5956      */
5957     function flattenDepth(array, depth) {
5958       var length = array ? array.length : 0;
5959       if (!length) {
5960         return [];
5961       }
5962       depth = depth === undefined ? 1 : toInteger(depth);
5963       return baseFlatten(array, depth);
5964     }
5965
5966     /**
5967      * The inverse of `_.toPairs`; this method returns an object composed
5968      * from key-value `pairs`.
5969      *
5970      * @static
5971      * @memberOf _
5972      * @category Array
5973      * @param {Array} pairs The key-value pairs.
5974      * @returns {Object} Returns the new object.
5975      * @example
5976      *
5977      * _.fromPairs([['fred', 30], ['barney', 40]]);
5978      * // => { 'fred': 30, 'barney': 40 }
5979      */
5980     function fromPairs(pairs) {
5981       var index = -1,
5982           length = pairs ? pairs.length : 0,
5983           result = {};
5984
5985       while (++index < length) {
5986         var pair = pairs[index];
5987         result[pair[0]] = pair[1];
5988       }
5989       return result;
5990     }
5991
5992     /**
5993      * Gets the first element of `array`.
5994      *
5995      * @static
5996      * @memberOf _
5997      * @alias first
5998      * @category Array
5999      * @param {Array} array The array to query.
6000      * @returns {*} Returns the first element of `array`.
6001      * @example
6002      *
6003      * _.head([1, 2, 3]);
6004      * // => 1
6005      *
6006      * _.head([]);
6007      * // => undefined
6008      */
6009     function head(array) {
6010       return array ? array[0] : undefined;
6011     }
6012
6013     /**
6014      * Gets the index at which the first occurrence of `value` is found in `array`
6015      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6016      * for equality comparisons. If `fromIndex` is negative, it's used as the offset
6017      * from the end of `array`.
6018      *
6019      * @static
6020      * @memberOf _
6021      * @category Array
6022      * @param {Array} array The array to search.
6023      * @param {*} value The value to search for.
6024      * @param {number} [fromIndex=0] The index to search from.
6025      * @returns {number} Returns the index of the matched value, else `-1`.
6026      * @example
6027      *
6028      * _.indexOf([1, 2, 1, 2], 2);
6029      * // => 1
6030      *
6031      * // Search from the `fromIndex`.
6032      * _.indexOf([1, 2, 1, 2], 2, 2);
6033      * // => 3
6034      */
6035     function indexOf(array, value, fromIndex) {
6036       var length = array ? array.length : 0;
6037       if (!length) {
6038         return -1;
6039       }
6040       fromIndex = toInteger(fromIndex);
6041       if (fromIndex < 0) {
6042         fromIndex = nativeMax(length + fromIndex, 0);
6043       }
6044       return baseIndexOf(array, value, fromIndex);
6045     }
6046
6047     /**
6048      * Gets all but the last element of `array`.
6049      *
6050      * @static
6051      * @memberOf _
6052      * @category Array
6053      * @param {Array} array The array to query.
6054      * @returns {Array} Returns the slice of `array`.
6055      * @example
6056      *
6057      * _.initial([1, 2, 3]);
6058      * // => [1, 2]
6059      */
6060     function initial(array) {
6061       return dropRight(array, 1);
6062     }
6063
6064     /**
6065      * Creates an array of unique values that are included in all given arrays
6066      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6067      * for equality comparisons.
6068      *
6069      * @static
6070      * @memberOf _
6071      * @category Array
6072      * @param {...Array} [arrays] The arrays to inspect.
6073      * @returns {Array} Returns the new array of shared values.
6074      * @example
6075      *
6076      * _.intersection([2, 1], [4, 2], [1, 2]);
6077      * // => [2]
6078      */
6079     var intersection = rest(function(arrays) {
6080       var mapped = arrayMap(arrays, baseCastArrayLikeObject);
6081       return (mapped.length && mapped[0] === arrays[0])
6082         ? baseIntersection(mapped)
6083         : [];
6084     });
6085
6086     /**
6087      * This method is like `_.intersection` except that it accepts `iteratee`
6088      * which is invoked for each element of each `arrays` to generate the criterion
6089      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
6090      *
6091      * @static
6092      * @memberOf _
6093      * @category Array
6094      * @param {...Array} [arrays] The arrays to inspect.
6095      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6096      * @returns {Array} Returns the new array of shared values.
6097      * @example
6098      *
6099      * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6100      * // => [2.1]
6101      *
6102      * // The `_.property` iteratee shorthand.
6103      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6104      * // => [{ 'x': 1 }]
6105      */
6106     var intersectionBy = rest(function(arrays) {
6107       var iteratee = last(arrays),
6108           mapped = arrayMap(arrays, baseCastArrayLikeObject);
6109
6110       if (iteratee === last(mapped)) {
6111         iteratee = undefined;
6112       } else {
6113         mapped.pop();
6114       }
6115       return (mapped.length && mapped[0] === arrays[0])
6116         ? baseIntersection(mapped, getIteratee(iteratee))
6117         : [];
6118     });
6119
6120     /**
6121      * This method is like `_.intersection` except that it accepts `comparator`
6122      * which is invoked to compare elements of `arrays`. The comparator is invoked
6123      * with two arguments: (arrVal, othVal).
6124      *
6125      * @static
6126      * @memberOf _
6127      * @category Array
6128      * @param {...Array} [arrays] The arrays to inspect.
6129      * @param {Function} [comparator] The comparator invoked per element.
6130      * @returns {Array} Returns the new array of shared values.
6131      * @example
6132      *
6133      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6134      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6135      *
6136      * _.intersectionWith(objects, others, _.isEqual);
6137      * // => [{ 'x': 1, 'y': 2 }]
6138      */
6139     var intersectionWith = rest(function(arrays) {
6140       var comparator = last(arrays),
6141           mapped = arrayMap(arrays, baseCastArrayLikeObject);
6142
6143       if (comparator === last(mapped)) {
6144         comparator = undefined;
6145       } else {
6146         mapped.pop();
6147       }
6148       return (mapped.length && mapped[0] === arrays[0])
6149         ? baseIntersection(mapped, undefined, comparator)
6150         : [];
6151     });
6152
6153     /**
6154      * Converts all elements in `array` into a string separated by `separator`.
6155      *
6156      * @static
6157      * @memberOf _
6158      * @category Array
6159      * @param {Array} array The array to convert.
6160      * @param {string} [separator=','] The element separator.
6161      * @returns {string} Returns the joined string.
6162      * @example
6163      *
6164      * _.join(['a', 'b', 'c'], '~');
6165      * // => 'a~b~c'
6166      */
6167     function join(array, separator) {
6168       return array ? nativeJoin.call(array, separator) : '';
6169     }
6170
6171     /**
6172      * Gets the last element of `array`.
6173      *
6174      * @static
6175      * @memberOf _
6176      * @category Array
6177      * @param {Array} array The array to query.
6178      * @returns {*} Returns the last element of `array`.
6179      * @example
6180      *
6181      * _.last([1, 2, 3]);
6182      * // => 3
6183      */
6184     function last(array) {
6185       var length = array ? array.length : 0;
6186       return length ? array[length - 1] : undefined;
6187     }
6188
6189     /**
6190      * This method is like `_.indexOf` except that it iterates over elements of
6191      * `array` from right to left.
6192      *
6193      * @static
6194      * @memberOf _
6195      * @category Array
6196      * @param {Array} array The array to search.
6197      * @param {*} value The value to search for.
6198      * @param {number} [fromIndex=array.length-1] The index to search from.
6199      * @returns {number} Returns the index of the matched value, else `-1`.
6200      * @example
6201      *
6202      * _.lastIndexOf([1, 2, 1, 2], 2);
6203      * // => 3
6204      *
6205      * // Search from the `fromIndex`.
6206      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
6207      * // => 1
6208      */
6209     function lastIndexOf(array, value, fromIndex) {
6210       var length = array ? array.length : 0;
6211       if (!length) {
6212         return -1;
6213       }
6214       var index = length;
6215       if (fromIndex !== undefined) {
6216         index = toInteger(fromIndex);
6217         index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
6218       }
6219       if (value !== value) {
6220         return indexOfNaN(array, index, true);
6221       }
6222       while (index--) {
6223         if (array[index] === value) {
6224           return index;
6225         }
6226       }
6227       return -1;
6228     }
6229
6230     /**
6231      * Removes all given values from `array` using
6232      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6233      * for equality comparisons.
6234      *
6235      * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
6236      * to remove elements from an array by predicate.
6237      *
6238      * @static
6239      * @memberOf _
6240      * @category Array
6241      * @param {Array} array The array to modify.
6242      * @param {...*} [values] The values to remove.
6243      * @returns {Array} Returns `array`.
6244      * @example
6245      *
6246      * var array = [1, 2, 3, 1, 2, 3];
6247      *
6248      * _.pull(array, 2, 3);
6249      * console.log(array);
6250      * // => [1, 1]
6251      */
6252     var pull = rest(pullAll);
6253
6254     /**
6255      * This method is like `_.pull` except that it accepts an array of values to remove.
6256      *
6257      * **Note:** Unlike `_.difference`, this method mutates `array`.
6258      *
6259      * @static
6260      * @memberOf _
6261      * @category Array
6262      * @param {Array} array The array to modify.
6263      * @param {Array} values The values to remove.
6264      * @returns {Array} Returns `array`.
6265      * @example
6266      *
6267      * var array = [1, 2, 3, 1, 2, 3];
6268      *
6269      * _.pullAll(array, [2, 3]);
6270      * console.log(array);
6271      * // => [1, 1]
6272      */
6273     function pullAll(array, values) {
6274       return (array && array.length && values && values.length)
6275         ? basePullAll(array, values)
6276         : array;
6277     }
6278
6279     /**
6280      * This method is like `_.pullAll` except that it accepts `iteratee` which is
6281      * invoked for each element of `array` and `values` to generate the criterion
6282      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
6283      *
6284      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
6285      *
6286      * @static
6287      * @memberOf _
6288      * @category Array
6289      * @param {Array} array The array to modify.
6290      * @param {Array} values The values to remove.
6291      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6292      * @returns {Array} Returns `array`.
6293      * @example
6294      *
6295      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
6296      *
6297      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
6298      * console.log(array);
6299      * // => [{ 'x': 2 }]
6300      */
6301     function pullAllBy(array, values, iteratee) {
6302       return (array && array.length && values && values.length)
6303         ? basePullAllBy(array, values, getIteratee(iteratee))
6304         : array;
6305     }
6306
6307     /**
6308      * Removes elements from `array` corresponding to `indexes` and returns an
6309      * array of removed elements.
6310      *
6311      * **Note:** Unlike `_.at`, this method mutates `array`.
6312      *
6313      * @static
6314      * @memberOf _
6315      * @category Array
6316      * @param {Array} array The array to modify.
6317      * @param {...(number|number[])} [indexes] The indexes of elements to remove,
6318      *  specified individually or in arrays.
6319      * @returns {Array} Returns the new array of removed elements.
6320      * @example
6321      *
6322      * var array = [5, 10, 15, 20];
6323      * var evens = _.pullAt(array, 1, 3);
6324      *
6325      * console.log(array);
6326      * // => [5, 15]
6327      *
6328      * console.log(evens);
6329      * // => [10, 20]
6330      */
6331     var pullAt = rest(function(array, indexes) {
6332       indexes = arrayMap(baseFlatten(indexes, 1), String);
6333
6334       var result = baseAt(array, indexes);
6335       basePullAt(array, indexes.sort(compareAscending));
6336       return result;
6337     });
6338
6339     /**
6340      * Removes all elements from `array` that `predicate` returns truthy for
6341      * and returns an array of the removed elements. The predicate is invoked
6342      * with three arguments: (value, index, array).
6343      *
6344      * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
6345      * to pull elements from an array by value.
6346      *
6347      * @static
6348      * @memberOf _
6349      * @category Array
6350      * @param {Array} array The array to modify.
6351      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6352      * @returns {Array} Returns the new array of removed elements.
6353      * @example
6354      *
6355      * var array = [1, 2, 3, 4];
6356      * var evens = _.remove(array, function(n) {
6357      *   return n % 2 == 0;
6358      * });
6359      *
6360      * console.log(array);
6361      * // => [1, 3]
6362      *
6363      * console.log(evens);
6364      * // => [2, 4]
6365      */
6366     function remove(array, predicate) {
6367       var result = [];
6368       if (!(array && array.length)) {
6369         return result;
6370       }
6371       var index = -1,
6372           indexes = [],
6373           length = array.length;
6374
6375       predicate = getIteratee(predicate, 3);
6376       while (++index < length) {
6377         var value = array[index];
6378         if (predicate(value, index, array)) {
6379           result.push(value);
6380           indexes.push(index);
6381         }
6382       }
6383       basePullAt(array, indexes);
6384       return result;
6385     }
6386
6387     /**
6388      * Reverses `array` so that the first element becomes the last, the second
6389      * element becomes the second to last, and so on.
6390      *
6391      * **Note:** This method mutates `array` and is based on
6392      * [`Array#reverse`](https://mdn.io/Array/reverse).
6393      *
6394      * @static
6395      * @memberOf _
6396      * @category Array
6397      * @returns {Array} Returns `array`.
6398      * @example
6399      *
6400      * var array = [1, 2, 3];
6401      *
6402      * _.reverse(array);
6403      * // => [3, 2, 1]
6404      *
6405      * console.log(array);
6406      * // => [3, 2, 1]
6407      */
6408     function reverse(array) {
6409       return array ? nativeReverse.call(array) : array;
6410     }
6411
6412     /**
6413      * Creates a slice of `array` from `start` up to, but not including, `end`.
6414      *
6415      * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
6416      * to ensure dense arrays are returned.
6417      *
6418      * @static
6419      * @memberOf _
6420      * @category Array
6421      * @param {Array} array The array to slice.
6422      * @param {number} [start=0] The start position.
6423      * @param {number} [end=array.length] The end position.
6424      * @returns {Array} Returns the slice of `array`.
6425      */
6426     function slice(array, start, end) {
6427       var length = array ? array.length : 0;
6428       if (!length) {
6429         return [];
6430       }
6431       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
6432         start = 0;
6433         end = length;
6434       }
6435       else {
6436         start = start == null ? 0 : toInteger(start);
6437         end = end === undefined ? length : toInteger(end);
6438       }
6439       return baseSlice(array, start, end);
6440     }
6441
6442     /**
6443      * Uses a binary search to determine the lowest index at which `value` should
6444      * be inserted into `array` in order to maintain its sort order.
6445      *
6446      * @static
6447      * @memberOf _
6448      * @category Array
6449      * @param {Array} array The sorted array to inspect.
6450      * @param {*} value The value to evaluate.
6451      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6452      * @example
6453      *
6454      * _.sortedIndex([30, 50], 40);
6455      * // => 1
6456      *
6457      * _.sortedIndex([4, 5], 4);
6458      * // => 0
6459      */
6460     function sortedIndex(array, value) {
6461       return baseSortedIndex(array, value);
6462     }
6463
6464     /**
6465      * This method is like `_.sortedIndex` except that it accepts `iteratee`
6466      * which is invoked for `value` and each element of `array` to compute their
6467      * sort ranking. The iteratee is invoked with one argument: (value).
6468      *
6469      * @static
6470      * @memberOf _
6471      * @category Array
6472      * @param {Array} array The sorted array to inspect.
6473      * @param {*} value The value to evaluate.
6474      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6475      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6476      * @example
6477      *
6478      * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
6479      *
6480      * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
6481      * // => 1
6482      *
6483      * // The `_.property` iteratee shorthand.
6484      * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6485      * // => 0
6486      */
6487     function sortedIndexBy(array, value, iteratee) {
6488       return baseSortedIndexBy(array, value, getIteratee(iteratee));
6489     }
6490
6491     /**
6492      * This method is like `_.indexOf` except that it performs a binary
6493      * search on a sorted `array`.
6494      *
6495      * @static
6496      * @memberOf _
6497      * @category Array
6498      * @param {Array} array The array to search.
6499      * @param {*} value The value to search for.
6500      * @returns {number} Returns the index of the matched value, else `-1`.
6501      * @example
6502      *
6503      * _.sortedIndexOf([1, 1, 2, 2], 2);
6504      * // => 2
6505      */
6506     function sortedIndexOf(array, value) {
6507       var length = array ? array.length : 0;
6508       if (length) {
6509         var index = baseSortedIndex(array, value);
6510         if (index < length && eq(array[index], value)) {
6511           return index;
6512         }
6513       }
6514       return -1;
6515     }
6516
6517     /**
6518      * This method is like `_.sortedIndex` except that it returns the highest
6519      * index at which `value` should be inserted into `array` in order to
6520      * maintain its sort order.
6521      *
6522      * @static
6523      * @memberOf _
6524      * @category Array
6525      * @param {Array} array The sorted array to inspect.
6526      * @param {*} value The value to evaluate.
6527      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6528      * @example
6529      *
6530      * _.sortedLastIndex([4, 5], 4);
6531      * // => 1
6532      */
6533     function sortedLastIndex(array, value) {
6534       return baseSortedIndex(array, value, true);
6535     }
6536
6537     /**
6538      * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
6539      * which is invoked for `value` and each element of `array` to compute their
6540      * sort ranking. The iteratee is invoked with one argument: (value).
6541      *
6542      * @static
6543      * @memberOf _
6544      * @category Array
6545      * @param {Array} array The sorted array to inspect.
6546      * @param {*} value The value to evaluate.
6547      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6548      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6549      * @example
6550      *
6551      * // The `_.property` iteratee shorthand.
6552      * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6553      * // => 1
6554      */
6555     function sortedLastIndexBy(array, value, iteratee) {
6556       return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
6557     }
6558
6559     /**
6560      * This method is like `_.lastIndexOf` except that it performs a binary
6561      * search on a sorted `array`.
6562      *
6563      * @static
6564      * @memberOf _
6565      * @category Array
6566      * @param {Array} array The array to search.
6567      * @param {*} value The value to search for.
6568      * @returns {number} Returns the index of the matched value, else `-1`.
6569      * @example
6570      *
6571      * _.sortedLastIndexOf([1, 1, 2, 2], 2);
6572      * // => 3
6573      */
6574     function sortedLastIndexOf(array, value) {
6575       var length = array ? array.length : 0;
6576       if (length) {
6577         var index = baseSortedIndex(array, value, true) - 1;
6578         if (eq(array[index], value)) {
6579           return index;
6580         }
6581       }
6582       return -1;
6583     }
6584
6585     /**
6586      * This method is like `_.uniq` except that it's designed and optimized
6587      * for sorted arrays.
6588      *
6589      * @static
6590      * @memberOf _
6591      * @category Array
6592      * @param {Array} array The array to inspect.
6593      * @returns {Array} Returns the new duplicate free array.
6594      * @example
6595      *
6596      * _.sortedUniq([1, 1, 2]);
6597      * // => [1, 2]
6598      */
6599     function sortedUniq(array) {
6600       return (array && array.length)
6601         ? baseSortedUniq(array)
6602         : [];
6603     }
6604
6605     /**
6606      * This method is like `_.uniqBy` except that it's designed and optimized
6607      * for sorted arrays.
6608      *
6609      * @static
6610      * @memberOf _
6611      * @category Array
6612      * @param {Array} array The array to inspect.
6613      * @param {Function} [iteratee] The iteratee invoked per element.
6614      * @returns {Array} Returns the new duplicate free array.
6615      * @example
6616      *
6617      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
6618      * // => [1.1, 2.3]
6619      */
6620     function sortedUniqBy(array, iteratee) {
6621       return (array && array.length)
6622         ? baseSortedUniqBy(array, getIteratee(iteratee))
6623         : [];
6624     }
6625
6626     /**
6627      * Gets all but the first element of `array`.
6628      *
6629      * @static
6630      * @memberOf _
6631      * @category Array
6632      * @param {Array} array The array to query.
6633      * @returns {Array} Returns the slice of `array`.
6634      * @example
6635      *
6636      * _.tail([1, 2, 3]);
6637      * // => [2, 3]
6638      */
6639     function tail(array) {
6640       return drop(array, 1);
6641     }
6642
6643     /**
6644      * Creates a slice of `array` with `n` elements taken from the beginning.
6645      *
6646      * @static
6647      * @memberOf _
6648      * @category Array
6649      * @param {Array} array The array to query.
6650      * @param {number} [n=1] The number of elements to take.
6651      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6652      * @returns {Array} Returns the slice of `array`.
6653      * @example
6654      *
6655      * _.take([1, 2, 3]);
6656      * // => [1]
6657      *
6658      * _.take([1, 2, 3], 2);
6659      * // => [1, 2]
6660      *
6661      * _.take([1, 2, 3], 5);
6662      * // => [1, 2, 3]
6663      *
6664      * _.take([1, 2, 3], 0);
6665      * // => []
6666      */
6667     function take(array, n, guard) {
6668       if (!(array && array.length)) {
6669         return [];
6670       }
6671       n = (guard || n === undefined) ? 1 : toInteger(n);
6672       return baseSlice(array, 0, n < 0 ? 0 : n);
6673     }
6674
6675     /**
6676      * Creates a slice of `array` with `n` elements taken from the end.
6677      *
6678      * @static
6679      * @memberOf _
6680      * @category Array
6681      * @param {Array} array The array to query.
6682      * @param {number} [n=1] The number of elements to take.
6683      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6684      * @returns {Array} Returns the slice of `array`.
6685      * @example
6686      *
6687      * _.takeRight([1, 2, 3]);
6688      * // => [3]
6689      *
6690      * _.takeRight([1, 2, 3], 2);
6691      * // => [2, 3]
6692      *
6693      * _.takeRight([1, 2, 3], 5);
6694      * // => [1, 2, 3]
6695      *
6696      * _.takeRight([1, 2, 3], 0);
6697      * // => []
6698      */
6699     function takeRight(array, n, guard) {
6700       var length = array ? array.length : 0;
6701       if (!length) {
6702         return [];
6703       }
6704       n = (guard || n === undefined) ? 1 : toInteger(n);
6705       n = length - n;
6706       return baseSlice(array, n < 0 ? 0 : n, length);
6707     }
6708
6709     /**
6710      * Creates a slice of `array` with elements taken from the end. Elements are
6711      * taken until `predicate` returns falsey. The predicate is invoked with three
6712      * arguments: (value, index, array).
6713      *
6714      * @static
6715      * @memberOf _
6716      * @category Array
6717      * @param {Array} array The array to query.
6718      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6719      * @returns {Array} Returns the slice of `array`.
6720      * @example
6721      *
6722      * var users = [
6723      *   { 'user': 'barney',  'active': true },
6724      *   { 'user': 'fred',    'active': false },
6725      *   { 'user': 'pebbles', 'active': false }
6726      * ];
6727      *
6728      * _.takeRightWhile(users, function(o) { return !o.active; });
6729      * // => objects for ['fred', 'pebbles']
6730      *
6731      * // The `_.matches` iteratee shorthand.
6732      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
6733      * // => objects for ['pebbles']
6734      *
6735      * // The `_.matchesProperty` iteratee shorthand.
6736      * _.takeRightWhile(users, ['active', false]);
6737      * // => objects for ['fred', 'pebbles']
6738      *
6739      * // The `_.property` iteratee shorthand.
6740      * _.takeRightWhile(users, 'active');
6741      * // => []
6742      */
6743     function takeRightWhile(array, predicate) {
6744       return (array && array.length)
6745         ? baseWhile(array, getIteratee(predicate, 3), false, true)
6746         : [];
6747     }
6748
6749     /**
6750      * Creates a slice of `array` with elements taken from the beginning. Elements
6751      * are taken until `predicate` returns falsey. The predicate is invoked with
6752      * three arguments: (value, index, array).
6753      *
6754      * @static
6755      * @memberOf _
6756      * @category Array
6757      * @param {Array} array The array to query.
6758      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6759      * @returns {Array} Returns the slice of `array`.
6760      * @example
6761      *
6762      * var users = [
6763      *   { 'user': 'barney',  'active': false },
6764      *   { 'user': 'fred',    'active': false},
6765      *   { 'user': 'pebbles', 'active': true }
6766      * ];
6767      *
6768      * _.takeWhile(users, function(o) { return !o.active; });
6769      * // => objects for ['barney', 'fred']
6770      *
6771      * // The `_.matches` iteratee shorthand.
6772      * _.takeWhile(users, { 'user': 'barney', 'active': false });
6773      * // => objects for ['barney']
6774      *
6775      * // The `_.matchesProperty` iteratee shorthand.
6776      * _.takeWhile(users, ['active', false]);
6777      * // => objects for ['barney', 'fred']
6778      *
6779      * // The `_.property` iteratee shorthand.
6780      * _.takeWhile(users, 'active');
6781      * // => []
6782      */
6783     function takeWhile(array, predicate) {
6784       return (array && array.length)
6785         ? baseWhile(array, getIteratee(predicate, 3))
6786         : [];
6787     }
6788
6789     /**
6790      * Creates an array of unique values, in order, from all given arrays using
6791      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6792      * for equality comparisons.
6793      *
6794      * @static
6795      * @memberOf _
6796      * @category Array
6797      * @param {...Array} [arrays] The arrays to inspect.
6798      * @returns {Array} Returns the new array of combined values.
6799      * @example
6800      *
6801      * _.union([2, 1], [4, 2], [1, 2]);
6802      * // => [2, 1, 4]
6803      */
6804     var union = rest(function(arrays) {
6805       return baseUniq(baseFlatten(arrays, 1, true));
6806     });
6807
6808     /**
6809      * This method is like `_.union` except that it accepts `iteratee` which is
6810      * invoked for each element of each `arrays` to generate the criterion by which
6811      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6812      *
6813      * @static
6814      * @memberOf _
6815      * @category Array
6816      * @param {...Array} [arrays] The arrays to inspect.
6817      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6818      * @returns {Array} Returns the new array of combined values.
6819      * @example
6820      *
6821      * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6822      * // => [2.1, 1.2, 4.3]
6823      *
6824      * // The `_.property` iteratee shorthand.
6825      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6826      * // => [{ 'x': 1 }, { 'x': 2 }]
6827      */
6828     var unionBy = rest(function(arrays) {
6829       var iteratee = last(arrays);
6830       if (isArrayLikeObject(iteratee)) {
6831         iteratee = undefined;
6832       }
6833       return baseUniq(baseFlatten(arrays, 1, true), getIteratee(iteratee));
6834     });
6835
6836     /**
6837      * This method is like `_.union` except that it accepts `comparator` which
6838      * is invoked to compare elements of `arrays`. The comparator is invoked
6839      * with two arguments: (arrVal, othVal).
6840      *
6841      * @static
6842      * @memberOf _
6843      * @category Array
6844      * @param {...Array} [arrays] The arrays to inspect.
6845      * @param {Function} [comparator] The comparator invoked per element.
6846      * @returns {Array} Returns the new array of combined values.
6847      * @example
6848      *
6849      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6850      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6851      *
6852      * _.unionWith(objects, others, _.isEqual);
6853      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6854      */
6855     var unionWith = rest(function(arrays) {
6856       var comparator = last(arrays);
6857       if (isArrayLikeObject(comparator)) {
6858         comparator = undefined;
6859       }
6860       return baseUniq(baseFlatten(arrays, 1, true), undefined, comparator);
6861     });
6862
6863     /**
6864      * Creates a duplicate-free version of an array, using
6865      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6866      * for equality comparisons, in which only the first occurrence of each element
6867      * is kept.
6868      *
6869      * @static
6870      * @memberOf _
6871      * @category Array
6872      * @param {Array} array The array to inspect.
6873      * @returns {Array} Returns the new duplicate free array.
6874      * @example
6875      *
6876      * _.uniq([2, 1, 2]);
6877      * // => [2, 1]
6878      */
6879     function uniq(array) {
6880       return (array && array.length)
6881         ? baseUniq(array)
6882         : [];
6883     }
6884
6885     /**
6886      * This method is like `_.uniq` except that it accepts `iteratee` which is
6887      * invoked for each element in `array` to generate the criterion by which
6888      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6889      *
6890      * @static
6891      * @memberOf _
6892      * @category Array
6893      * @param {Array} array The array to inspect.
6894      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6895      * @returns {Array} Returns the new duplicate free array.
6896      * @example
6897      *
6898      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
6899      * // => [2.1, 1.2]
6900      *
6901      * // The `_.property` iteratee shorthand.
6902      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
6903      * // => [{ 'x': 1 }, { 'x': 2 }]
6904      */
6905     function uniqBy(array, iteratee) {
6906       return (array && array.length)
6907         ? baseUniq(array, getIteratee(iteratee))
6908         : [];
6909     }
6910
6911     /**
6912      * This method is like `_.uniq` except that it accepts `comparator` which
6913      * is invoked to compare elements of `array`. The comparator is invoked with
6914      * two arguments: (arrVal, othVal).
6915      *
6916      * @static
6917      * @memberOf _
6918      * @category Array
6919      * @param {Array} array The array to inspect.
6920      * @param {Function} [comparator] The comparator invoked per element.
6921      * @returns {Array} Returns the new duplicate free array.
6922      * @example
6923      *
6924      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
6925      *
6926      * _.uniqWith(objects, _.isEqual);
6927      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
6928      */
6929     function uniqWith(array, comparator) {
6930       return (array && array.length)
6931         ? baseUniq(array, undefined, comparator)
6932         : [];
6933     }
6934
6935     /**
6936      * This method is like `_.zip` except that it accepts an array of grouped
6937      * elements and creates an array regrouping the elements to their pre-zip
6938      * configuration.
6939      *
6940      * @static
6941      * @memberOf _
6942      * @category Array
6943      * @param {Array} array The array of grouped elements to process.
6944      * @returns {Array} Returns the new array of regrouped elements.
6945      * @example
6946      *
6947      * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
6948      * // => [['fred', 30, true], ['barney', 40, false]]
6949      *
6950      * _.unzip(zipped);
6951      * // => [['fred', 'barney'], [30, 40], [true, false]]
6952      */
6953     function unzip(array) {
6954       if (!(array && array.length)) {
6955         return [];
6956       }
6957       var length = 0;
6958       array = arrayFilter(array, function(group) {
6959         if (isArrayLikeObject(group)) {
6960           length = nativeMax(group.length, length);
6961           return true;
6962         }
6963       });
6964       return baseTimes(length, function(index) {
6965         return arrayMap(array, baseProperty(index));
6966       });
6967     }
6968
6969     /**
6970      * This method is like `_.unzip` except that it accepts `iteratee` to specify
6971      * how regrouped values should be combined. The iteratee is invoked with the
6972      * elements of each group: (...group).
6973      *
6974      * @static
6975      * @memberOf _
6976      * @category Array
6977      * @param {Array} array The array of grouped elements to process.
6978      * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
6979      * @returns {Array} Returns the new array of regrouped elements.
6980      * @example
6981      *
6982      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
6983      * // => [[1, 10, 100], [2, 20, 200]]
6984      *
6985      * _.unzipWith(zipped, _.add);
6986      * // => [3, 30, 300]
6987      */
6988     function unzipWith(array, iteratee) {
6989       if (!(array && array.length)) {
6990         return [];
6991       }
6992       var result = unzip(array);
6993       if (iteratee == null) {
6994         return result;
6995       }
6996       return arrayMap(result, function(group) {
6997         return apply(iteratee, undefined, group);
6998       });
6999     }
7000
7001     /**
7002      * Creates an array excluding all given values using
7003      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7004      * for equality comparisons.
7005      *
7006      * @static
7007      * @memberOf _
7008      * @category Array
7009      * @param {Array} array The array to filter.
7010      * @param {...*} [values] The values to exclude.
7011      * @returns {Array} Returns the new array of filtered values.
7012      * @example
7013      *
7014      * _.without([1, 2, 1, 3], 1, 2);
7015      * // => [3]
7016      */
7017     var without = rest(function(array, values) {
7018       return isArrayLikeObject(array)
7019         ? baseDifference(array, values)
7020         : [];
7021     });
7022
7023     /**
7024      * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
7025      * of the given arrays.
7026      *
7027      * @static
7028      * @memberOf _
7029      * @category Array
7030      * @param {...Array} [arrays] The arrays to inspect.
7031      * @returns {Array} Returns the new array of values.
7032      * @example
7033      *
7034      * _.xor([2, 1], [4, 2]);
7035      * // => [1, 4]
7036      */
7037     var xor = rest(function(arrays) {
7038       return baseXor(arrayFilter(arrays, isArrayLikeObject));
7039     });
7040
7041     /**
7042      * This method is like `_.xor` except that it accepts `iteratee` which is
7043      * invoked for each element of each `arrays` to generate the criterion by which
7044      * uniqueness is computed. The iteratee is invoked with one argument: (value).
7045      *
7046      * @static
7047      * @memberOf _
7048      * @category Array
7049      * @param {...Array} [arrays] The arrays to inspect.
7050      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
7051      * @returns {Array} Returns the new array of values.
7052      * @example
7053      *
7054      * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
7055      * // => [1.2, 4.3]
7056      *
7057      * // The `_.property` iteratee shorthand.
7058      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7059      * // => [{ 'x': 2 }]
7060      */
7061     var xorBy = rest(function(arrays) {
7062       var iteratee = last(arrays);
7063       if (isArrayLikeObject(iteratee)) {
7064         iteratee = undefined;
7065       }
7066       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
7067     });
7068
7069     /**
7070      * This method is like `_.xor` except that it accepts `comparator` which is
7071      * invoked to compare elements of `arrays`. The comparator is invoked with
7072      * two arguments: (arrVal, othVal).
7073      *
7074      * @static
7075      * @memberOf _
7076      * @category Array
7077      * @param {...Array} [arrays] The arrays to inspect.
7078      * @param {Function} [comparator] The comparator invoked per element.
7079      * @returns {Array} Returns the new array of values.
7080      * @example
7081      *
7082      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7083      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7084      *
7085      * _.xorWith(objects, others, _.isEqual);
7086      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
7087      */
7088     var xorWith = rest(function(arrays) {
7089       var comparator = last(arrays);
7090       if (isArrayLikeObject(comparator)) {
7091         comparator = undefined;
7092       }
7093       return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
7094     });
7095
7096     /**
7097      * Creates an array of grouped elements, the first of which contains the first
7098      * elements of the given arrays, the second of which contains the second elements
7099      * of the given arrays, and so on.
7100      *
7101      * @static
7102      * @memberOf _
7103      * @category Array
7104      * @param {...Array} [arrays] The arrays to process.
7105      * @returns {Array} Returns the new array of grouped elements.
7106      * @example
7107      *
7108      * _.zip(['fred', 'barney'], [30, 40], [true, false]);
7109      * // => [['fred', 30, true], ['barney', 40, false]]
7110      */
7111     var zip = rest(unzip);
7112
7113     /**
7114      * This method is like `_.fromPairs` except that it accepts two arrays,
7115      * one of property names and one of corresponding values.
7116      *
7117      * @static
7118      * @memberOf _
7119      * @category Array
7120      * @param {Array} [props=[]] The property names.
7121      * @param {Array} [values=[]] The property values.
7122      * @returns {Object} Returns the new object.
7123      * @example
7124      *
7125      * _.zipObject(['a', 'b'], [1, 2]);
7126      * // => { 'a': 1, 'b': 2 }
7127      */
7128     function zipObject(props, values) {
7129       return baseZipObject(props || [], values || [], assignValue);
7130     }
7131
7132     /**
7133      * This method is like `_.zipObject` except that it supports property paths.
7134      *
7135      * @static
7136      * @memberOf _
7137      * @category Array
7138      * @param {Array} [props=[]] The property names.
7139      * @param {Array} [values=[]] The property values.
7140      * @returns {Object} Returns the new object.
7141      * @example
7142      *
7143      * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
7144      * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
7145      */
7146     function zipObjectDeep(props, values) {
7147       return baseZipObject(props || [], values || [], baseSet);
7148     }
7149
7150     /**
7151      * This method is like `_.zip` except that it accepts `iteratee` to specify
7152      * how grouped values should be combined. The iteratee is invoked with the
7153      * elements of each group: (...group).
7154      *
7155      * @static
7156      * @memberOf _
7157      * @category Array
7158      * @param {...Array} [arrays] The arrays to process.
7159      * @param {Function} [iteratee=_.identity] The function to combine grouped values.
7160      * @returns {Array} Returns the new array of grouped elements.
7161      * @example
7162      *
7163      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
7164      *   return a + b + c;
7165      * });
7166      * // => [111, 222]
7167      */
7168     var zipWith = rest(function(arrays) {
7169       var length = arrays.length,
7170           iteratee = length > 1 ? arrays[length - 1] : undefined;
7171
7172       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
7173       return unzipWith(arrays, iteratee);
7174     });
7175
7176     /*------------------------------------------------------------------------*/
7177
7178     /**
7179      * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
7180      * The result of such method chaining must be unwrapped with `_#value`.
7181      *
7182      * @static
7183      * @memberOf _
7184      * @category Seq
7185      * @param {*} value The value to wrap.
7186      * @returns {Object} Returns the new `lodash` wrapper instance.
7187      * @example
7188      *
7189      * var users = [
7190      *   { 'user': 'barney',  'age': 36 },
7191      *   { 'user': 'fred',    'age': 40 },
7192      *   { 'user': 'pebbles', 'age': 1 }
7193      * ];
7194      *
7195      * var youngest = _
7196      *   .chain(users)
7197      *   .sortBy('age')
7198      *   .map(function(o) {
7199      *     return o.user + ' is ' + o.age;
7200      *   })
7201      *   .head()
7202      *   .value();
7203      * // => 'pebbles is 1'
7204      */
7205     function chain(value) {
7206       var result = lodash(value);
7207       result.__chain__ = true;
7208       return result;
7209     }
7210
7211     /**
7212      * This method invokes `interceptor` and returns `value`. The interceptor
7213      * is invoked with one argument; (value). The purpose of this method is to
7214      * "tap into" a method chain in order to modify intermediate results.
7215      *
7216      * @static
7217      * @memberOf _
7218      * @category Seq
7219      * @param {*} value The value to provide to `interceptor`.
7220      * @param {Function} interceptor The function to invoke.
7221      * @returns {*} Returns `value`.
7222      * @example
7223      *
7224      * _([1, 2, 3])
7225      *  .tap(function(array) {
7226      *    // Mutate input array.
7227      *    array.pop();
7228      *  })
7229      *  .reverse()
7230      *  .value();
7231      * // => [2, 1]
7232      */
7233     function tap(value, interceptor) {
7234       interceptor(value);
7235       return value;
7236     }
7237
7238     /**
7239      * This method is like `_.tap` except that it returns the result of `interceptor`.
7240      * The purpose of this method is to "pass thru" values replacing intermediate
7241      * results in a method chain.
7242      *
7243      * @static
7244      * @memberOf _
7245      * @category Seq
7246      * @param {*} value The value to provide to `interceptor`.
7247      * @param {Function} interceptor The function to invoke.
7248      * @returns {*} Returns the result of `interceptor`.
7249      * @example
7250      *
7251      * _('  abc  ')
7252      *  .chain()
7253      *  .trim()
7254      *  .thru(function(value) {
7255      *    return [value];
7256      *  })
7257      *  .value();
7258      * // => ['abc']
7259      */
7260     function thru(value, interceptor) {
7261       return interceptor(value);
7262     }
7263
7264     /**
7265      * This method is the wrapper version of `_.at`.
7266      *
7267      * @name at
7268      * @memberOf _
7269      * @category Seq
7270      * @param {...(string|string[])} [paths] The property paths of elements to pick,
7271      *  specified individually or in arrays.
7272      * @returns {Object} Returns the new `lodash` wrapper instance.
7273      * @example
7274      *
7275      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
7276      *
7277      * _(object).at(['a[0].b.c', 'a[1]']).value();
7278      * // => [3, 4]
7279      *
7280      * _(['a', 'b', 'c']).at(0, 2).value();
7281      * // => ['a', 'c']
7282      */
7283     var wrapperAt = rest(function(paths) {
7284       paths = baseFlatten(paths, 1);
7285       var length = paths.length,
7286           start = length ? paths[0] : 0,
7287           value = this.__wrapped__,
7288           interceptor = function(object) { return baseAt(object, paths); };
7289
7290       if (length > 1 || this.__actions__.length ||
7291           !(value instanceof LazyWrapper) || !isIndex(start)) {
7292         return this.thru(interceptor);
7293       }
7294       value = value.slice(start, +start + (length ? 1 : 0));
7295       value.__actions__.push({
7296         'func': thru,
7297         'args': [interceptor],
7298         'thisArg': undefined
7299       });
7300       return new LodashWrapper(value, this.__chain__).thru(function(array) {
7301         if (length && !array.length) {
7302           array.push(undefined);
7303         }
7304         return array;
7305       });
7306     });
7307
7308     /**
7309      * Enables explicit method chaining on the wrapper object.
7310      *
7311      * @name chain
7312      * @memberOf _
7313      * @category Seq
7314      * @returns {Object} Returns the new `lodash` wrapper instance.
7315      * @example
7316      *
7317      * var users = [
7318      *   { 'user': 'barney', 'age': 36 },
7319      *   { 'user': 'fred',   'age': 40 }
7320      * ];
7321      *
7322      * // A sequence without explicit chaining.
7323      * _(users).head();
7324      * // => { 'user': 'barney', 'age': 36 }
7325      *
7326      * // A sequence with explicit chaining.
7327      * _(users)
7328      *   .chain()
7329      *   .head()
7330      *   .pick('user')
7331      *   .value();
7332      * // => { 'user': 'barney' }
7333      */
7334     function wrapperChain() {
7335       return chain(this);
7336     }
7337
7338     /**
7339      * Executes the chained sequence and returns the wrapped result.
7340      *
7341      * @name commit
7342      * @memberOf _
7343      * @category Seq
7344      * @returns {Object} Returns the new `lodash` wrapper instance.
7345      * @example
7346      *
7347      * var array = [1, 2];
7348      * var wrapped = _(array).push(3);
7349      *
7350      * console.log(array);
7351      * // => [1, 2]
7352      *
7353      * wrapped = wrapped.commit();
7354      * console.log(array);
7355      * // => [1, 2, 3]
7356      *
7357      * wrapped.last();
7358      * // => 3
7359      *
7360      * console.log(array);
7361      * // => [1, 2, 3]
7362      */
7363     function wrapperCommit() {
7364       return new LodashWrapper(this.value(), this.__chain__);
7365     }
7366
7367     /**
7368      * This method is the wrapper version of `_.flatMap`.
7369      *
7370      * @name flatMap
7371      * @memberOf _
7372      * @category Seq
7373      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7374      * @returns {Object} Returns the new `lodash` wrapper instance.
7375      * @example
7376      *
7377      * function duplicate(n) {
7378      *   return [n, n];
7379      * }
7380      *
7381      * _([1, 2]).flatMap(duplicate).value();
7382      * // => [1, 1, 2, 2]
7383      */
7384     function wrapperFlatMap(iteratee) {
7385       return this.map(iteratee).flatten();
7386     }
7387
7388     /**
7389      * Gets the next value on a wrapped object following the
7390      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
7391      *
7392      * @name next
7393      * @memberOf _
7394      * @category Seq
7395      * @returns {Object} Returns the next iterator value.
7396      * @example
7397      *
7398      * var wrapped = _([1, 2]);
7399      *
7400      * wrapped.next();
7401      * // => { 'done': false, 'value': 1 }
7402      *
7403      * wrapped.next();
7404      * // => { 'done': false, 'value': 2 }
7405      *
7406      * wrapped.next();
7407      * // => { 'done': true, 'value': undefined }
7408      */
7409     function wrapperNext() {
7410       if (this.__values__ === undefined) {
7411         this.__values__ = toArray(this.value());
7412       }
7413       var done = this.__index__ >= this.__values__.length,
7414           value = done ? undefined : this.__values__[this.__index__++];
7415
7416       return { 'done': done, 'value': value };
7417     }
7418
7419     /**
7420      * Enables the wrapper to be iterable.
7421      *
7422      * @name Symbol.iterator
7423      * @memberOf _
7424      * @category Seq
7425      * @returns {Object} Returns the wrapper object.
7426      * @example
7427      *
7428      * var wrapped = _([1, 2]);
7429      *
7430      * wrapped[Symbol.iterator]() === wrapped;
7431      * // => true
7432      *
7433      * Array.from(wrapped);
7434      * // => [1, 2]
7435      */
7436     function wrapperToIterator() {
7437       return this;
7438     }
7439
7440     /**
7441      * Creates a clone of the chained sequence planting `value` as the wrapped value.
7442      *
7443      * @name plant
7444      * @memberOf _
7445      * @category Seq
7446      * @param {*} value The value to plant.
7447      * @returns {Object} Returns the new `lodash` wrapper instance.
7448      * @example
7449      *
7450      * function square(n) {
7451      *   return n * n;
7452      * }
7453      *
7454      * var wrapped = _([1, 2]).map(square);
7455      * var other = wrapped.plant([3, 4]);
7456      *
7457      * other.value();
7458      * // => [9, 16]
7459      *
7460      * wrapped.value();
7461      * // => [1, 4]
7462      */
7463     function wrapperPlant(value) {
7464       var result,
7465           parent = this;
7466
7467       while (parent instanceof baseLodash) {
7468         var clone = wrapperClone(parent);
7469         clone.__index__ = 0;
7470         clone.__values__ = undefined;
7471         if (result) {
7472           previous.__wrapped__ = clone;
7473         } else {
7474           result = clone;
7475         }
7476         var previous = clone;
7477         parent = parent.__wrapped__;
7478       }
7479       previous.__wrapped__ = value;
7480       return result;
7481     }
7482
7483     /**
7484      * This method is the wrapper version of `_.reverse`.
7485      *
7486      * **Note:** This method mutates the wrapped array.
7487      *
7488      * @name reverse
7489      * @memberOf _
7490      * @category Seq
7491      * @returns {Object} Returns the new `lodash` wrapper instance.
7492      * @example
7493      *
7494      * var array = [1, 2, 3];
7495      *
7496      * _(array).reverse().value()
7497      * // => [3, 2, 1]
7498      *
7499      * console.log(array);
7500      * // => [3, 2, 1]
7501      */
7502     function wrapperReverse() {
7503       var value = this.__wrapped__;
7504       if (value instanceof LazyWrapper) {
7505         var wrapped = value;
7506         if (this.__actions__.length) {
7507           wrapped = new LazyWrapper(this);
7508         }
7509         wrapped = wrapped.reverse();
7510         wrapped.__actions__.push({
7511           'func': thru,
7512           'args': [reverse],
7513           'thisArg': undefined
7514         });
7515         return new LodashWrapper(wrapped, this.__chain__);
7516       }
7517       return this.thru(reverse);
7518     }
7519
7520     /**
7521      * Executes the chained sequence to extract the unwrapped value.
7522      *
7523      * @name value
7524      * @memberOf _
7525      * @alias toJSON, valueOf
7526      * @category Seq
7527      * @returns {*} Returns the resolved unwrapped value.
7528      * @example
7529      *
7530      * _([1, 2, 3]).value();
7531      * // => [1, 2, 3]
7532      */
7533     function wrapperValue() {
7534       return baseWrapperValue(this.__wrapped__, this.__actions__);
7535     }
7536
7537     /*------------------------------------------------------------------------*/
7538
7539     /**
7540      * Creates an object composed of keys generated from the results of running
7541      * each element of `collection` through `iteratee`. The corresponding value
7542      * of each key is the number of times the key was returned by `iteratee`.
7543      * The iteratee is invoked with one argument: (value).
7544      *
7545      * @static
7546      * @memberOf _
7547      * @category Collection
7548      * @param {Array|Object} collection The collection to iterate over.
7549      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7550      * @returns {Object} Returns the composed aggregate object.
7551      * @example
7552      *
7553      * _.countBy([6.1, 4.2, 6.3], Math.floor);
7554      * // => { '4': 1, '6': 2 }
7555      *
7556      * _.countBy(['one', 'two', 'three'], 'length');
7557      * // => { '3': 2, '5': 1 }
7558      */
7559     var countBy = createAggregator(function(result, value, key) {
7560       hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
7561     });
7562
7563     /**
7564      * Checks if `predicate` returns truthy for **all** elements of `collection`.
7565      * Iteration is stopped once `predicate` returns falsey. The predicate is
7566      * invoked with three arguments: (value, index|key, collection).
7567      *
7568      * @static
7569      * @memberOf _
7570      * @category Collection
7571      * @param {Array|Object} collection The collection to iterate over.
7572      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7573      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
7574      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
7575      * @example
7576      *
7577      * _.every([true, 1, null, 'yes'], Boolean);
7578      * // => false
7579      *
7580      * var users = [
7581      *   { 'user': 'barney', 'active': false },
7582      *   { 'user': 'fred',   'active': false }
7583      * ];
7584      *
7585      * // The `_.matches` iteratee shorthand.
7586      * _.every(users, { 'user': 'barney', 'active': false });
7587      * // => false
7588      *
7589      * // The `_.matchesProperty` iteratee shorthand.
7590      * _.every(users, ['active', false]);
7591      * // => true
7592      *
7593      * // The `_.property` iteratee shorthand.
7594      * _.every(users, 'active');
7595      * // => false
7596      */
7597     function every(collection, predicate, guard) {
7598       var func = isArray(collection) ? arrayEvery : baseEvery;
7599       if (guard && isIterateeCall(collection, predicate, guard)) {
7600         predicate = undefined;
7601       }
7602       return func(collection, getIteratee(predicate, 3));
7603     }
7604
7605     /**
7606      * Iterates over elements of `collection`, returning an array of all elements
7607      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7608      * (value, index|key, collection).
7609      *
7610      * @static
7611      * @memberOf _
7612      * @category Collection
7613      * @param {Array|Object} collection The collection to iterate over.
7614      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7615      * @returns {Array} Returns the new filtered array.
7616      * @example
7617      *
7618      * var users = [
7619      *   { 'user': 'barney', 'age': 36, 'active': true },
7620      *   { 'user': 'fred',   'age': 40, 'active': false }
7621      * ];
7622      *
7623      * _.filter(users, function(o) { return !o.active; });
7624      * // => objects for ['fred']
7625      *
7626      * // The `_.matches` iteratee shorthand.
7627      * _.filter(users, { 'age': 36, 'active': true });
7628      * // => objects for ['barney']
7629      *
7630      * // The `_.matchesProperty` iteratee shorthand.
7631      * _.filter(users, ['active', false]);
7632      * // => objects for ['fred']
7633      *
7634      * // The `_.property` iteratee shorthand.
7635      * _.filter(users, 'active');
7636      * // => objects for ['barney']
7637      */
7638     function filter(collection, predicate) {
7639       var func = isArray(collection) ? arrayFilter : baseFilter;
7640       return func(collection, getIteratee(predicate, 3));
7641     }
7642
7643     /**
7644      * Iterates over elements of `collection`, returning the first element
7645      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7646      * (value, index|key, collection).
7647      *
7648      * @static
7649      * @memberOf _
7650      * @category Collection
7651      * @param {Array|Object} collection The collection to search.
7652      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7653      * @returns {*} Returns the matched element, else `undefined`.
7654      * @example
7655      *
7656      * var users = [
7657      *   { 'user': 'barney',  'age': 36, 'active': true },
7658      *   { 'user': 'fred',    'age': 40, 'active': false },
7659      *   { 'user': 'pebbles', 'age': 1,  'active': true }
7660      * ];
7661      *
7662      * _.find(users, function(o) { return o.age < 40; });
7663      * // => object for 'barney'
7664      *
7665      * // The `_.matches` iteratee shorthand.
7666      * _.find(users, { 'age': 1, 'active': true });
7667      * // => object for 'pebbles'
7668      *
7669      * // The `_.matchesProperty` iteratee shorthand.
7670      * _.find(users, ['active', false]);
7671      * // => object for 'fred'
7672      *
7673      * // The `_.property` iteratee shorthand.
7674      * _.find(users, 'active');
7675      * // => object for 'barney'
7676      */
7677     function find(collection, predicate) {
7678       predicate = getIteratee(predicate, 3);
7679       if (isArray(collection)) {
7680         var index = baseFindIndex(collection, predicate);
7681         return index > -1 ? collection[index] : undefined;
7682       }
7683       return baseFind(collection, predicate, baseEach);
7684     }
7685
7686     /**
7687      * This method is like `_.find` except that it iterates over elements of
7688      * `collection` from right to left.
7689      *
7690      * @static
7691      * @memberOf _
7692      * @category Collection
7693      * @param {Array|Object} collection The collection to search.
7694      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7695      * @returns {*} Returns the matched element, else `undefined`.
7696      * @example
7697      *
7698      * _.findLast([1, 2, 3, 4], function(n) {
7699      *   return n % 2 == 1;
7700      * });
7701      * // => 3
7702      */
7703     function findLast(collection, predicate) {
7704       predicate = getIteratee(predicate, 3);
7705       if (isArray(collection)) {
7706         var index = baseFindIndex(collection, predicate, true);
7707         return index > -1 ? collection[index] : undefined;
7708       }
7709       return baseFind(collection, predicate, baseEachRight);
7710     }
7711
7712     /**
7713      * Creates an array of flattened values by running each element in `collection`
7714      * through `iteratee` and concating its result to the other mapped values.
7715      * The iteratee is invoked with three arguments: (value, index|key, collection).
7716      *
7717      * @static
7718      * @memberOf _
7719      * @category Collection
7720      * @param {Array|Object} collection The collection to iterate over.
7721      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7722      * @returns {Array} Returns the new flattened array.
7723      * @example
7724      *
7725      * function duplicate(n) {
7726      *   return [n, n];
7727      * }
7728      *
7729      * _.flatMap([1, 2], duplicate);
7730      * // => [1, 1, 2, 2]
7731      */
7732     function flatMap(collection, iteratee) {
7733       return baseFlatten(map(collection, iteratee), 1);
7734     }
7735
7736     /**
7737      * Iterates over elements of `collection` invoking `iteratee` for each element.
7738      * The iteratee is invoked with three arguments: (value, index|key, collection).
7739      * Iteratee functions may exit iteration early by explicitly returning `false`.
7740      *
7741      * **Note:** As with other "Collections" methods, objects with a "length" property
7742      * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
7743      * for object iteration.
7744      *
7745      * @static
7746      * @memberOf _
7747      * @alias each
7748      * @category Collection
7749      * @param {Array|Object} collection The collection to iterate over.
7750      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7751      * @returns {Array|Object} Returns `collection`.
7752      * @example
7753      *
7754      * _([1, 2]).forEach(function(value) {
7755      *   console.log(value);
7756      * });
7757      * // => logs `1` then `2`
7758      *
7759      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
7760      *   console.log(key);
7761      * });
7762      * // => logs 'a' then 'b' (iteration order is not guaranteed)
7763      */
7764     function forEach(collection, iteratee) {
7765       return (typeof iteratee == 'function' && isArray(collection))
7766         ? arrayEach(collection, iteratee)
7767         : baseEach(collection, baseCastFunction(iteratee));
7768     }
7769
7770     /**
7771      * This method is like `_.forEach` except that it iterates over elements of
7772      * `collection` from right to left.
7773      *
7774      * @static
7775      * @memberOf _
7776      * @alias eachRight
7777      * @category Collection
7778      * @param {Array|Object} collection The collection to iterate over.
7779      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7780      * @returns {Array|Object} Returns `collection`.
7781      * @example
7782      *
7783      * _.forEachRight([1, 2], function(value) {
7784      *   console.log(value);
7785      * });
7786      * // => logs `2` then `1`
7787      */
7788     function forEachRight(collection, iteratee) {
7789       return (typeof iteratee == 'function' && isArray(collection))
7790         ? arrayEachRight(collection, iteratee)
7791         : baseEachRight(collection, baseCastFunction(iteratee));
7792     }
7793
7794     /**
7795      * Creates an object composed of keys generated from the results of running
7796      * each element of `collection` through `iteratee`. The corresponding value
7797      * of each key is an array of elements responsible for generating the key.
7798      * The iteratee is invoked with one argument: (value).
7799      *
7800      * @static
7801      * @memberOf _
7802      * @category Collection
7803      * @param {Array|Object} collection The collection to iterate over.
7804      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7805      * @returns {Object} Returns the composed aggregate object.
7806      * @example
7807      *
7808      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
7809      * // => { '4': [4.2], '6': [6.1, 6.3] }
7810      *
7811      * // The `_.property` iteratee shorthand.
7812      * _.groupBy(['one', 'two', 'three'], 'length');
7813      * // => { '3': ['one', 'two'], '5': ['three'] }
7814      */
7815     var groupBy = createAggregator(function(result, value, key) {
7816       if (hasOwnProperty.call(result, key)) {
7817         result[key].push(value);
7818       } else {
7819         result[key] = [value];
7820       }
7821     });
7822
7823     /**
7824      * Checks if `value` is in `collection`. If `collection` is a string it's checked
7825      * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7826      * is used for equality comparisons. If `fromIndex` is negative, it's used as
7827      * the offset from the end of `collection`.
7828      *
7829      * @static
7830      * @memberOf _
7831      * @category Collection
7832      * @param {Array|Object|string} collection The collection to search.
7833      * @param {*} value The value to search for.
7834      * @param {number} [fromIndex=0] The index to search from.
7835      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7836      * @returns {boolean} Returns `true` if `value` is found, else `false`.
7837      * @example
7838      *
7839      * _.includes([1, 2, 3], 1);
7840      * // => true
7841      *
7842      * _.includes([1, 2, 3], 1, 2);
7843      * // => false
7844      *
7845      * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
7846      * // => true
7847      *
7848      * _.includes('pebbles', 'eb');
7849      * // => true
7850      */
7851     function includes(collection, value, fromIndex, guard) {
7852       collection = isArrayLike(collection) ? collection : values(collection);
7853       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
7854
7855       var length = collection.length;
7856       if (fromIndex < 0) {
7857         fromIndex = nativeMax(length + fromIndex, 0);
7858       }
7859       return isString(collection)
7860         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
7861         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
7862     }
7863
7864     /**
7865      * Invokes the method at `path` of each element in `collection`, returning
7866      * an array of the results of each invoked method. Any additional arguments
7867      * are provided to each invoked method. If `methodName` is a function it's
7868      * invoked for, and `this` bound to, each element in `collection`.
7869      *
7870      * @static
7871      * @memberOf _
7872      * @category Collection
7873      * @param {Array|Object} collection The collection to iterate over.
7874      * @param {Array|Function|string} path The path of the method to invoke or
7875      *  the function invoked per iteration.
7876      * @param {...*} [args] The arguments to invoke each method with.
7877      * @returns {Array} Returns the array of results.
7878      * @example
7879      *
7880      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
7881      * // => [[1, 5, 7], [1, 2, 3]]
7882      *
7883      * _.invokeMap([123, 456], String.prototype.split, '');
7884      * // => [['1', '2', '3'], ['4', '5', '6']]
7885      */
7886     var invokeMap = rest(function(collection, path, args) {
7887       var index = -1,
7888           isFunc = typeof path == 'function',
7889           isProp = isKey(path),
7890           result = isArrayLike(collection) ? Array(collection.length) : [];
7891
7892       baseEach(collection, function(value) {
7893         var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
7894         result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
7895       });
7896       return result;
7897     });
7898
7899     /**
7900      * Creates an object composed of keys generated from the results of running
7901      * each element of `collection` through `iteratee`. The corresponding value
7902      * of each key is the last element responsible for generating the key. The
7903      * iteratee is invoked with one argument: (value).
7904      *
7905      * @static
7906      * @memberOf _
7907      * @category Collection
7908      * @param {Array|Object} collection The collection to iterate over.
7909      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7910      * @returns {Object} Returns the composed aggregate object.
7911      * @example
7912      *
7913      * var array = [
7914      *   { 'dir': 'left', 'code': 97 },
7915      *   { 'dir': 'right', 'code': 100 }
7916      * ];
7917      *
7918      * _.keyBy(array, function(o) {
7919      *   return String.fromCharCode(o.code);
7920      * });
7921      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
7922      *
7923      * _.keyBy(array, 'dir');
7924      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
7925      */
7926     var keyBy = createAggregator(function(result, value, key) {
7927       result[key] = value;
7928     });
7929
7930     /**
7931      * Creates an array of values by running each element in `collection` through
7932      * `iteratee`. The iteratee is invoked with three arguments:
7933      * (value, index|key, collection).
7934      *
7935      * Many lodash methods are guarded to work as iteratees for methods like
7936      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
7937      *
7938      * The guarded methods are:
7939      * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
7940      * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
7941      * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
7942      * and `words`
7943      *
7944      * @static
7945      * @memberOf _
7946      * @category Collection
7947      * @param {Array|Object} collection The collection to iterate over.
7948      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7949      * @returns {Array} Returns the new mapped array.
7950      * @example
7951      *
7952      * function square(n) {
7953      *   return n * n;
7954      * }
7955      *
7956      * _.map([4, 8], square);
7957      * // => [16, 64]
7958      *
7959      * _.map({ 'a': 4, 'b': 8 }, square);
7960      * // => [16, 64] (iteration order is not guaranteed)
7961      *
7962      * var users = [
7963      *   { 'user': 'barney' },
7964      *   { 'user': 'fred' }
7965      * ];
7966      *
7967      * // The `_.property` iteratee shorthand.
7968      * _.map(users, 'user');
7969      * // => ['barney', 'fred']
7970      */
7971     function map(collection, iteratee) {
7972       var func = isArray(collection) ? arrayMap : baseMap;
7973       return func(collection, getIteratee(iteratee, 3));
7974     }
7975
7976     /**
7977      * This method is like `_.sortBy` except that it allows specifying the sort
7978      * orders of the iteratees to sort by. If `orders` is unspecified, all values
7979      * are sorted in ascending order. Otherwise, specify an order of "desc" for
7980      * descending or "asc" for ascending sort order of corresponding values.
7981      *
7982      * @static
7983      * @memberOf _
7984      * @category Collection
7985      * @param {Array|Object} collection The collection to iterate over.
7986      * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
7987      * @param {string[]} [orders] The sort orders of `iteratees`.
7988      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7989      * @returns {Array} Returns the new sorted array.
7990      * @example
7991      *
7992      * var users = [
7993      *   { 'user': 'fred',   'age': 48 },
7994      *   { 'user': 'barney', 'age': 34 },
7995      *   { 'user': 'fred',   'age': 42 },
7996      *   { 'user': 'barney', 'age': 36 }
7997      * ];
7998      *
7999      * // Sort by `user` in ascending order and by `age` in descending order.
8000      * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
8001      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8002      */
8003     function orderBy(collection, iteratees, orders, guard) {
8004       if (collection == null) {
8005         return [];
8006       }
8007       if (!isArray(iteratees)) {
8008         iteratees = iteratees == null ? [] : [iteratees];
8009       }
8010       orders = guard ? undefined : orders;
8011       if (!isArray(orders)) {
8012         orders = orders == null ? [] : [orders];
8013       }
8014       return baseOrderBy(collection, iteratees, orders);
8015     }
8016
8017     /**
8018      * Creates an array of elements split into two groups, the first of which
8019      * contains elements `predicate` returns truthy for, the second of which
8020      * contains elements `predicate` returns falsey for. The predicate is
8021      * invoked with one argument: (value).
8022      *
8023      * @static
8024      * @memberOf _
8025      * @category Collection
8026      * @param {Array|Object} collection The collection to iterate over.
8027      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8028      * @returns {Array} Returns the array of grouped elements.
8029      * @example
8030      *
8031      * var users = [
8032      *   { 'user': 'barney',  'age': 36, 'active': false },
8033      *   { 'user': 'fred',    'age': 40, 'active': true },
8034      *   { 'user': 'pebbles', 'age': 1,  'active': false }
8035      * ];
8036      *
8037      * _.partition(users, function(o) { return o.active; });
8038      * // => objects for [['fred'], ['barney', 'pebbles']]
8039      *
8040      * // The `_.matches` iteratee shorthand.
8041      * _.partition(users, { 'age': 1, 'active': false });
8042      * // => objects for [['pebbles'], ['barney', 'fred']]
8043      *
8044      * // The `_.matchesProperty` iteratee shorthand.
8045      * _.partition(users, ['active', false]);
8046      * // => objects for [['barney', 'pebbles'], ['fred']]
8047      *
8048      * // The `_.property` iteratee shorthand.
8049      * _.partition(users, 'active');
8050      * // => objects for [['fred'], ['barney', 'pebbles']]
8051      */
8052     var partition = createAggregator(function(result, value, key) {
8053       result[key ? 0 : 1].push(value);
8054     }, function() { return [[], []]; });
8055
8056     /**
8057      * Reduces `collection` to a value which is the accumulated result of running
8058      * each element in `collection` through `iteratee`, where each successive
8059      * invocation is supplied the return value of the previous. If `accumulator`
8060      * is not given the first element of `collection` is used as the initial
8061      * value. The iteratee is invoked with four arguments:
8062      * (accumulator, value, index|key, collection).
8063      *
8064      * Many lodash methods are guarded to work as iteratees for methods like
8065      * `_.reduce`, `_.reduceRight`, and `_.transform`.
8066      *
8067      * The guarded methods are:
8068      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
8069      * and `sortBy`
8070      *
8071      * @static
8072      * @memberOf _
8073      * @category Collection
8074      * @param {Array|Object} collection The collection to iterate over.
8075      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8076      * @param {*} [accumulator] The initial value.
8077      * @returns {*} Returns the accumulated value.
8078      * @example
8079      *
8080      * _.reduce([1, 2], function(sum, n) {
8081      *   return sum + n;
8082      * }, 0);
8083      * // => 3
8084      *
8085      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
8086      *   (result[value] || (result[value] = [])).push(key);
8087      *   return result;
8088      * }, {});
8089      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
8090      */
8091     function reduce(collection, iteratee, accumulator) {
8092       var func = isArray(collection) ? arrayReduce : baseReduce,
8093           initAccum = arguments.length < 3;
8094
8095       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
8096     }
8097
8098     /**
8099      * This method is like `_.reduce` except that it iterates over elements of
8100      * `collection` from right to left.
8101      *
8102      * @static
8103      * @memberOf _
8104      * @category Collection
8105      * @param {Array|Object} collection The collection to iterate over.
8106      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8107      * @param {*} [accumulator] The initial value.
8108      * @returns {*} Returns the accumulated value.
8109      * @example
8110      *
8111      * var array = [[0, 1], [2, 3], [4, 5]];
8112      *
8113      * _.reduceRight(array, function(flattened, other) {
8114      *   return flattened.concat(other);
8115      * }, []);
8116      * // => [4, 5, 2, 3, 0, 1]
8117      */
8118     function reduceRight(collection, iteratee, accumulator) {
8119       var func = isArray(collection) ? arrayReduceRight : baseReduce,
8120           initAccum = arguments.length < 3;
8121
8122       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
8123     }
8124
8125     /**
8126      * The opposite of `_.filter`; this method returns the elements of `collection`
8127      * that `predicate` does **not** return truthy for.
8128      *
8129      * @static
8130      * @memberOf _
8131      * @category Collection
8132      * @param {Array|Object} collection The collection to iterate over.
8133      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8134      * @returns {Array} Returns the new filtered array.
8135      * @example
8136      *
8137      * var users = [
8138      *   { 'user': 'barney', 'age': 36, 'active': false },
8139      *   { 'user': 'fred',   'age': 40, 'active': true }
8140      * ];
8141      *
8142      * _.reject(users, function(o) { return !o.active; });
8143      * // => objects for ['fred']
8144      *
8145      * // The `_.matches` iteratee shorthand.
8146      * _.reject(users, { 'age': 40, 'active': true });
8147      * // => objects for ['barney']
8148      *
8149      * // The `_.matchesProperty` iteratee shorthand.
8150      * _.reject(users, ['active', false]);
8151      * // => objects for ['fred']
8152      *
8153      * // The `_.property` iteratee shorthand.
8154      * _.reject(users, 'active');
8155      * // => objects for ['barney']
8156      */
8157     function reject(collection, predicate) {
8158       var func = isArray(collection) ? arrayFilter : baseFilter;
8159       predicate = getIteratee(predicate, 3);
8160       return func(collection, function(value, index, collection) {
8161         return !predicate(value, index, collection);
8162       });
8163     }
8164
8165     /**
8166      * Gets a random element from `collection`.
8167      *
8168      * @static
8169      * @memberOf _
8170      * @category Collection
8171      * @param {Array|Object} collection The collection to sample.
8172      * @returns {*} Returns the random element.
8173      * @example
8174      *
8175      * _.sample([1, 2, 3, 4]);
8176      * // => 2
8177      */
8178     function sample(collection) {
8179       var array = isArrayLike(collection) ? collection : values(collection),
8180           length = array.length;
8181
8182       return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
8183     }
8184
8185     /**
8186      * Gets `n` random elements at unique keys from `collection` up to the
8187      * size of `collection`.
8188      *
8189      * @static
8190      * @memberOf _
8191      * @category Collection
8192      * @param {Array|Object} collection The collection to sample.
8193      * @param {number} [n=0] The number of elements to sample.
8194      * @returns {Array} Returns the random elements.
8195      * @example
8196      *
8197      * _.sampleSize([1, 2, 3], 2);
8198      * // => [3, 1]
8199      *
8200      * _.sampleSize([1, 2, 3], 4);
8201      * // => [2, 3, 1]
8202      */
8203     function sampleSize(collection, n) {
8204       var index = -1,
8205           result = toArray(collection),
8206           length = result.length,
8207           lastIndex = length - 1;
8208
8209       n = baseClamp(toInteger(n), 0, length);
8210       while (++index < n) {
8211         var rand = baseRandom(index, lastIndex),
8212             value = result[rand];
8213
8214         result[rand] = result[index];
8215         result[index] = value;
8216       }
8217       result.length = n;
8218       return result;
8219     }
8220
8221     /**
8222      * Creates an array of shuffled values, using a version of the
8223      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
8224      *
8225      * @static
8226      * @memberOf _
8227      * @category Collection
8228      * @param {Array|Object} collection The collection to shuffle.
8229      * @returns {Array} Returns the new shuffled array.
8230      * @example
8231      *
8232      * _.shuffle([1, 2, 3, 4]);
8233      * // => [4, 1, 3, 2]
8234      */
8235     function shuffle(collection) {
8236       return sampleSize(collection, MAX_ARRAY_LENGTH);
8237     }
8238
8239     /**
8240      * Gets the size of `collection` by returning its length for array-like
8241      * values or the number of own enumerable properties for objects.
8242      *
8243      * @static
8244      * @memberOf _
8245      * @category Collection
8246      * @param {Array|Object} collection The collection to inspect.
8247      * @returns {number} Returns the collection size.
8248      * @example
8249      *
8250      * _.size([1, 2, 3]);
8251      * // => 3
8252      *
8253      * _.size({ 'a': 1, 'b': 2 });
8254      * // => 2
8255      *
8256      * _.size('pebbles');
8257      * // => 7
8258      */
8259     function size(collection) {
8260       if (collection == null) {
8261         return 0;
8262       }
8263       if (isArrayLike(collection)) {
8264         var result = collection.length;
8265         return (result && isString(collection)) ? stringSize(collection) : result;
8266       }
8267       return keys(collection).length;
8268     }
8269
8270     /**
8271      * Checks if `predicate` returns truthy for **any** element of `collection`.
8272      * Iteration is stopped once `predicate` returns truthy. The predicate is
8273      * invoked with three arguments: (value, index|key, collection).
8274      *
8275      * @static
8276      * @memberOf _
8277      * @category Collection
8278      * @param {Array|Object} collection The collection to iterate over.
8279      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8280      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8281      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
8282      * @example
8283      *
8284      * _.some([null, 0, 'yes', false], Boolean);
8285      * // => true
8286      *
8287      * var users = [
8288      *   { 'user': 'barney', 'active': true },
8289      *   { 'user': 'fred',   'active': false }
8290      * ];
8291      *
8292      * // The `_.matches` iteratee shorthand.
8293      * _.some(users, { 'user': 'barney', 'active': false });
8294      * // => false
8295      *
8296      * // The `_.matchesProperty` iteratee shorthand.
8297      * _.some(users, ['active', false]);
8298      * // => true
8299      *
8300      * // The `_.property` iteratee shorthand.
8301      * _.some(users, 'active');
8302      * // => true
8303      */
8304     function some(collection, predicate, guard) {
8305       var func = isArray(collection) ? arraySome : baseSome;
8306       if (guard && isIterateeCall(collection, predicate, guard)) {
8307         predicate = undefined;
8308       }
8309       return func(collection, getIteratee(predicate, 3));
8310     }
8311
8312     /**
8313      * Creates an array of elements, sorted in ascending order by the results of
8314      * running each element in a collection through each iteratee. This method
8315      * performs a stable sort, that is, it preserves the original sort order of
8316      * equal elements. The iteratees are invoked with one argument: (value).
8317      *
8318      * @static
8319      * @memberOf _
8320      * @category Collection
8321      * @param {Array|Object} collection The collection to iterate over.
8322      * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
8323      *  The iteratees to sort by, specified individually or in arrays.
8324      * @returns {Array} Returns the new sorted array.
8325      * @example
8326      *
8327      * var users = [
8328      *   { 'user': 'fred',   'age': 48 },
8329      *   { 'user': 'barney', 'age': 36 },
8330      *   { 'user': 'fred',   'age': 42 },
8331      *   { 'user': 'barney', 'age': 34 }
8332      * ];
8333      *
8334      * _.sortBy(users, function(o) { return o.user; });
8335      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8336      *
8337      * _.sortBy(users, ['user', 'age']);
8338      * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
8339      *
8340      * _.sortBy(users, 'user', function(o) {
8341      *   return Math.floor(o.age / 10);
8342      * });
8343      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8344      */
8345     var sortBy = rest(function(collection, iteratees) {
8346       if (collection == null) {
8347         return [];
8348       }
8349       var length = iteratees.length;
8350       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
8351         iteratees = [];
8352       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
8353         iteratees.length = 1;
8354       }
8355       return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
8356     });
8357
8358     /*------------------------------------------------------------------------*/
8359
8360     /**
8361      * Gets the timestamp of the number of milliseconds that have elapsed since
8362      * the Unix epoch (1 January 1970 00:00:00 UTC).
8363      *
8364      * @static
8365      * @memberOf _
8366      * @type {Function}
8367      * @category Date
8368      * @returns {number} Returns the timestamp.
8369      * @example
8370      *
8371      * _.defer(function(stamp) {
8372      *   console.log(_.now() - stamp);
8373      * }, _.now());
8374      * // => logs the number of milliseconds it took for the deferred function to be invoked
8375      */
8376     var now = Date.now;
8377
8378     /*------------------------------------------------------------------------*/
8379
8380     /**
8381      * The opposite of `_.before`; this method creates a function that invokes
8382      * `func` once it's called `n` or more times.
8383      *
8384      * @static
8385      * @memberOf _
8386      * @category Function
8387      * @param {number} n The number of calls before `func` is invoked.
8388      * @param {Function} func The function to restrict.
8389      * @returns {Function} Returns the new restricted function.
8390      * @example
8391      *
8392      * var saves = ['profile', 'settings'];
8393      *
8394      * var done = _.after(saves.length, function() {
8395      *   console.log('done saving!');
8396      * });
8397      *
8398      * _.forEach(saves, function(type) {
8399      *   asyncSave({ 'type': type, 'complete': done });
8400      * });
8401      * // => logs 'done saving!' after the two async saves have completed
8402      */
8403     function after(n, func) {
8404       if (typeof func != 'function') {
8405         throw new TypeError(FUNC_ERROR_TEXT);
8406       }
8407       n = toInteger(n);
8408       return function() {
8409         if (--n < 1) {
8410           return func.apply(this, arguments);
8411         }
8412       };
8413     }
8414
8415     /**
8416      * Creates a function that accepts up to `n` arguments, ignoring any
8417      * additional arguments.
8418      *
8419      * @static
8420      * @memberOf _
8421      * @category Function
8422      * @param {Function} func The function to cap arguments for.
8423      * @param {number} [n=func.length] The arity cap.
8424      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8425      * @returns {Function} Returns the new function.
8426      * @example
8427      *
8428      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
8429      * // => [6, 8, 10]
8430      */
8431     function ary(func, n, guard) {
8432       n = guard ? undefined : n;
8433       n = (func && n == null) ? func.length : n;
8434       return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
8435     }
8436
8437     /**
8438      * Creates a function that invokes `func`, with the `this` binding and arguments
8439      * of the created function, while it's called less than `n` times. Subsequent
8440      * calls to the created function return the result of the last `func` invocation.
8441      *
8442      * @static
8443      * @memberOf _
8444      * @category Function
8445      * @param {number} n The number of calls at which `func` is no longer invoked.
8446      * @param {Function} func The function to restrict.
8447      * @returns {Function} Returns the new restricted function.
8448      * @example
8449      *
8450      * jQuery(element).on('click', _.before(5, addContactToList));
8451      * // => allows adding up to 4 contacts to the list
8452      */
8453     function before(n, func) {
8454       var result;
8455       if (typeof func != 'function') {
8456         throw new TypeError(FUNC_ERROR_TEXT);
8457       }
8458       n = toInteger(n);
8459       return function() {
8460         if (--n > 0) {
8461           result = func.apply(this, arguments);
8462         }
8463         if (n <= 1) {
8464           func = undefined;
8465         }
8466         return result;
8467       };
8468     }
8469
8470     /**
8471      * Creates a function that invokes `func` with the `this` binding of `thisArg`
8472      * and prepends any additional `_.bind` arguments to those provided to the
8473      * bound function.
8474      *
8475      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
8476      * may be used as a placeholder for partially applied arguments.
8477      *
8478      * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
8479      * property of bound functions.
8480      *
8481      * @static
8482      * @memberOf _
8483      * @category Function
8484      * @param {Function} func The function to bind.
8485      * @param {*} thisArg The `this` binding of `func`.
8486      * @param {...*} [partials] The arguments to be partially applied.
8487      * @returns {Function} Returns the new bound function.
8488      * @example
8489      *
8490      * var greet = function(greeting, punctuation) {
8491      *   return greeting + ' ' + this.user + punctuation;
8492      * };
8493      *
8494      * var object = { 'user': 'fred' };
8495      *
8496      * var bound = _.bind(greet, object, 'hi');
8497      * bound('!');
8498      * // => 'hi fred!'
8499      *
8500      * // Bound with placeholders.
8501      * var bound = _.bind(greet, object, _, '!');
8502      * bound('hi');
8503      * // => 'hi fred!'
8504      */
8505     var bind = rest(function(func, thisArg, partials) {
8506       var bitmask = BIND_FLAG;
8507       if (partials.length) {
8508         var holders = replaceHolders(partials, getPlaceholder(bind));
8509         bitmask |= PARTIAL_FLAG;
8510       }
8511       return createWrapper(func, bitmask, thisArg, partials, holders);
8512     });
8513
8514     /**
8515      * Creates a function that invokes the method at `object[key]` and prepends
8516      * any additional `_.bindKey` arguments to those provided to the bound function.
8517      *
8518      * This method differs from `_.bind` by allowing bound functions to reference
8519      * methods that may be redefined or don't yet exist.
8520      * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
8521      * for more details.
8522      *
8523      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
8524      * builds, may be used as a placeholder for partially applied arguments.
8525      *
8526      * @static
8527      * @memberOf _
8528      * @category Function
8529      * @param {Object} object The object to invoke the method on.
8530      * @param {string} key The key of the method.
8531      * @param {...*} [partials] The arguments to be partially applied.
8532      * @returns {Function} Returns the new bound function.
8533      * @example
8534      *
8535      * var object = {
8536      *   'user': 'fred',
8537      *   'greet': function(greeting, punctuation) {
8538      *     return greeting + ' ' + this.user + punctuation;
8539      *   }
8540      * };
8541      *
8542      * var bound = _.bindKey(object, 'greet', 'hi');
8543      * bound('!');
8544      * // => 'hi fred!'
8545      *
8546      * object.greet = function(greeting, punctuation) {
8547      *   return greeting + 'ya ' + this.user + punctuation;
8548      * };
8549      *
8550      * bound('!');
8551      * // => 'hiya fred!'
8552      *
8553      * // Bound with placeholders.
8554      * var bound = _.bindKey(object, 'greet', _, '!');
8555      * bound('hi');
8556      * // => 'hiya fred!'
8557      */
8558     var bindKey = rest(function(object, key, partials) {
8559       var bitmask = BIND_FLAG | BIND_KEY_FLAG;
8560       if (partials.length) {
8561         var holders = replaceHolders(partials, getPlaceholder(bindKey));
8562         bitmask |= PARTIAL_FLAG;
8563       }
8564       return createWrapper(key, bitmask, object, partials, holders);
8565     });
8566
8567     /**
8568      * Creates a function that accepts arguments of `func` and either invokes
8569      * `func` returning its result, if at least `arity` number of arguments have
8570      * been provided, or returns a function that accepts the remaining `func`
8571      * arguments, and so on. The arity of `func` may be specified if `func.length`
8572      * is not sufficient.
8573      *
8574      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
8575      * may be used as a placeholder for provided arguments.
8576      *
8577      * **Note:** This method doesn't set the "length" property of curried functions.
8578      *
8579      * @static
8580      * @memberOf _
8581      * @category Function
8582      * @param {Function} func The function to curry.
8583      * @param {number} [arity=func.length] The arity of `func`.
8584      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8585      * @returns {Function} Returns the new curried function.
8586      * @example
8587      *
8588      * var abc = function(a, b, c) {
8589      *   return [a, b, c];
8590      * };
8591      *
8592      * var curried = _.curry(abc);
8593      *
8594      * curried(1)(2)(3);
8595      * // => [1, 2, 3]
8596      *
8597      * curried(1, 2)(3);
8598      * // => [1, 2, 3]
8599      *
8600      * curried(1, 2, 3);
8601      * // => [1, 2, 3]
8602      *
8603      * // Curried with placeholders.
8604      * curried(1)(_, 3)(2);
8605      * // => [1, 2, 3]
8606      */
8607     function curry(func, arity, guard) {
8608       arity = guard ? undefined : arity;
8609       var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8610       result.placeholder = curry.placeholder;
8611       return result;
8612     }
8613
8614     /**
8615      * This method is like `_.curry` except that arguments are applied to `func`
8616      * in the manner of `_.partialRight` instead of `_.partial`.
8617      *
8618      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
8619      * builds, may be used as a placeholder for provided arguments.
8620      *
8621      * **Note:** This method doesn't set the "length" property of curried functions.
8622      *
8623      * @static
8624      * @memberOf _
8625      * @category Function
8626      * @param {Function} func The function to curry.
8627      * @param {number} [arity=func.length] The arity of `func`.
8628      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8629      * @returns {Function} Returns the new curried function.
8630      * @example
8631      *
8632      * var abc = function(a, b, c) {
8633      *   return [a, b, c];
8634      * };
8635      *
8636      * var curried = _.curryRight(abc);
8637      *
8638      * curried(3)(2)(1);
8639      * // => [1, 2, 3]
8640      *
8641      * curried(2, 3)(1);
8642      * // => [1, 2, 3]
8643      *
8644      * curried(1, 2, 3);
8645      * // => [1, 2, 3]
8646      *
8647      * // Curried with placeholders.
8648      * curried(3)(1, _)(2);
8649      * // => [1, 2, 3]
8650      */
8651     function curryRight(func, arity, guard) {
8652       arity = guard ? undefined : arity;
8653       var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8654       result.placeholder = curryRight.placeholder;
8655       return result;
8656     }
8657
8658     /**
8659      * Creates a debounced function that delays invoking `func` until after `wait`
8660      * milliseconds have elapsed since the last time the debounced function was
8661      * invoked. The debounced function comes with a `cancel` method to cancel
8662      * delayed `func` invocations and a `flush` method to immediately invoke them.
8663      * Provide an options object to indicate whether `func` should be invoked on
8664      * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
8665      * with the last arguments provided to the debounced function. Subsequent calls
8666      * to the debounced function return the result of the last `func` invocation.
8667      *
8668      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8669      * on the trailing edge of the timeout only if the debounced function is
8670      * invoked more than once during the `wait` timeout.
8671      *
8672      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8673      * for details over the differences between `_.debounce` and `_.throttle`.
8674      *
8675      * @static
8676      * @memberOf _
8677      * @category Function
8678      * @param {Function} func The function to debounce.
8679      * @param {number} [wait=0] The number of milliseconds to delay.
8680      * @param {Object} [options] The options object.
8681      * @param {boolean} [options.leading=false] Specify invoking on the leading
8682      *  edge of the timeout.
8683      * @param {number} [options.maxWait] The maximum time `func` is allowed to be
8684      *  delayed before it's invoked.
8685      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
8686      *  edge of the timeout.
8687      * @returns {Function} Returns the new debounced function.
8688      * @example
8689      *
8690      * // Avoid costly calculations while the window size is in flux.
8691      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
8692      *
8693      * // Invoke `sendMail` when clicked, debouncing subsequent calls.
8694      * jQuery(element).on('click', _.debounce(sendMail, 300, {
8695      *   'leading': true,
8696      *   'trailing': false
8697      * }));
8698      *
8699      * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
8700      * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
8701      * var source = new EventSource('/stream');
8702      * jQuery(source).on('message', debounced);
8703      *
8704      * // Cancel the trailing debounced invocation.
8705      * jQuery(window).on('popstate', debounced.cancel);
8706      */
8707     function debounce(func, wait, options) {
8708       var args,
8709           maxTimeoutId,
8710           result,
8711           stamp,
8712           thisArg,
8713           timeoutId,
8714           trailingCall,
8715           lastCalled = 0,
8716           leading = false,
8717           maxWait = false,
8718           trailing = true;
8719
8720       if (typeof func != 'function') {
8721         throw new TypeError(FUNC_ERROR_TEXT);
8722       }
8723       wait = toNumber(wait) || 0;
8724       if (isObject(options)) {
8725         leading = !!options.leading;
8726         maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
8727         trailing = 'trailing' in options ? !!options.trailing : trailing;
8728       }
8729
8730       function cancel() {
8731         if (timeoutId) {
8732           clearTimeout(timeoutId);
8733         }
8734         if (maxTimeoutId) {
8735           clearTimeout(maxTimeoutId);
8736         }
8737         lastCalled = 0;
8738         args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
8739       }
8740
8741       function complete(isCalled, id) {
8742         if (id) {
8743           clearTimeout(id);
8744         }
8745         maxTimeoutId = timeoutId = trailingCall = undefined;
8746         if (isCalled) {
8747           lastCalled = now();
8748           result = func.apply(thisArg, args);
8749           if (!timeoutId && !maxTimeoutId) {
8750             args = thisArg = undefined;
8751           }
8752         }
8753       }
8754
8755       function delayed() {
8756         var remaining = wait - (now() - stamp);
8757         if (remaining <= 0 || remaining > wait) {
8758           complete(trailingCall, maxTimeoutId);
8759         } else {
8760           timeoutId = setTimeout(delayed, remaining);
8761         }
8762       }
8763
8764       function flush() {
8765         if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
8766           result = func.apply(thisArg, args);
8767         }
8768         cancel();
8769         return result;
8770       }
8771
8772       function maxDelayed() {
8773         complete(trailing, timeoutId);
8774       }
8775
8776       function debounced() {
8777         args = arguments;
8778         stamp = now();
8779         thisArg = this;
8780         trailingCall = trailing && (timeoutId || !leading);
8781
8782         if (maxWait === false) {
8783           var leadingCall = leading && !timeoutId;
8784         } else {
8785           if (!lastCalled && !maxTimeoutId && !leading) {
8786             lastCalled = stamp;
8787           }
8788           var remaining = maxWait - (stamp - lastCalled);
8789
8790           var isCalled = (remaining <= 0 || remaining > maxWait) &&
8791             (leading || maxTimeoutId);
8792
8793           if (isCalled) {
8794             if (maxTimeoutId) {
8795               maxTimeoutId = clearTimeout(maxTimeoutId);
8796             }
8797             lastCalled = stamp;
8798             result = func.apply(thisArg, args);
8799           }
8800           else if (!maxTimeoutId) {
8801             maxTimeoutId = setTimeout(maxDelayed, remaining);
8802           }
8803         }
8804         if (isCalled && timeoutId) {
8805           timeoutId = clearTimeout(timeoutId);
8806         }
8807         else if (!timeoutId && wait !== maxWait) {
8808           timeoutId = setTimeout(delayed, wait);
8809         }
8810         if (leadingCall) {
8811           isCalled = true;
8812           result = func.apply(thisArg, args);
8813         }
8814         if (isCalled && !timeoutId && !maxTimeoutId) {
8815           args = thisArg = undefined;
8816         }
8817         return result;
8818       }
8819       debounced.cancel = cancel;
8820       debounced.flush = flush;
8821       return debounced;
8822     }
8823
8824     /**
8825      * Defers invoking the `func` until the current call stack has cleared. Any
8826      * additional arguments are provided to `func` when it's invoked.
8827      *
8828      * @static
8829      * @memberOf _
8830      * @category Function
8831      * @param {Function} func The function to defer.
8832      * @param {...*} [args] The arguments to invoke `func` with.
8833      * @returns {number} Returns the timer id.
8834      * @example
8835      *
8836      * _.defer(function(text) {
8837      *   console.log(text);
8838      * }, 'deferred');
8839      * // => logs 'deferred' after one or more milliseconds
8840      */
8841     var defer = rest(function(func, args) {
8842       return baseDelay(func, 1, args);
8843     });
8844
8845     /**
8846      * Invokes `func` after `wait` milliseconds. Any additional arguments are
8847      * provided to `func` when it's invoked.
8848      *
8849      * @static
8850      * @memberOf _
8851      * @category Function
8852      * @param {Function} func The function to delay.
8853      * @param {number} wait The number of milliseconds to delay invocation.
8854      * @param {...*} [args] The arguments to invoke `func` with.
8855      * @returns {number} Returns the timer id.
8856      * @example
8857      *
8858      * _.delay(function(text) {
8859      *   console.log(text);
8860      * }, 1000, 'later');
8861      * // => logs 'later' after one second
8862      */
8863     var delay = rest(function(func, wait, args) {
8864       return baseDelay(func, toNumber(wait) || 0, args);
8865     });
8866
8867     /**
8868      * Creates a function that invokes `func` with arguments reversed.
8869      *
8870      * @static
8871      * @memberOf _
8872      * @category Function
8873      * @param {Function} func The function to flip arguments for.
8874      * @returns {Function} Returns the new function.
8875      * @example
8876      *
8877      * var flipped = _.flip(function() {
8878      *   return _.toArray(arguments);
8879      * });
8880      *
8881      * flipped('a', 'b', 'c', 'd');
8882      * // => ['d', 'c', 'b', 'a']
8883      */
8884     function flip(func) {
8885       return createWrapper(func, FLIP_FLAG);
8886     }
8887
8888     /**
8889      * Creates a function that memoizes the result of `func`. If `resolver` is
8890      * provided it determines the cache key for storing the result based on the
8891      * arguments provided to the memoized function. By default, the first argument
8892      * provided to the memoized function is used as the map cache key. The `func`
8893      * is invoked with the `this` binding of the memoized function.
8894      *
8895      * **Note:** The cache is exposed as the `cache` property on the memoized
8896      * function. Its creation may be customized by replacing the `_.memoize.Cache`
8897      * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
8898      * method interface of `delete`, `get`, `has`, and `set`.
8899      *
8900      * @static
8901      * @memberOf _
8902      * @category Function
8903      * @param {Function} func The function to have its output memoized.
8904      * @param {Function} [resolver] The function to resolve the cache key.
8905      * @returns {Function} Returns the new memoizing function.
8906      * @example
8907      *
8908      * var object = { 'a': 1, 'b': 2 };
8909      * var other = { 'c': 3, 'd': 4 };
8910      *
8911      * var values = _.memoize(_.values);
8912      * values(object);
8913      * // => [1, 2]
8914      *
8915      * values(other);
8916      * // => [3, 4]
8917      *
8918      * object.a = 2;
8919      * values(object);
8920      * // => [1, 2]
8921      *
8922      * // Modify the result cache.
8923      * values.cache.set(object, ['a', 'b']);
8924      * values(object);
8925      * // => ['a', 'b']
8926      *
8927      * // Replace `_.memoize.Cache`.
8928      * _.memoize.Cache = WeakMap;
8929      */
8930     function memoize(func, resolver) {
8931       if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
8932         throw new TypeError(FUNC_ERROR_TEXT);
8933       }
8934       var memoized = function() {
8935         var args = arguments,
8936             key = resolver ? resolver.apply(this, args) : args[0],
8937             cache = memoized.cache;
8938
8939         if (cache.has(key)) {
8940           return cache.get(key);
8941         }
8942         var result = func.apply(this, args);
8943         memoized.cache = cache.set(key, result);
8944         return result;
8945       };
8946       memoized.cache = new memoize.Cache;
8947       return memoized;
8948     }
8949
8950     /**
8951      * Creates a function that negates the result of the predicate `func`. The
8952      * `func` predicate is invoked with the `this` binding and arguments of the
8953      * created function.
8954      *
8955      * @static
8956      * @memberOf _
8957      * @category Function
8958      * @param {Function} predicate The predicate to negate.
8959      * @returns {Function} Returns the new function.
8960      * @example
8961      *
8962      * function isEven(n) {
8963      *   return n % 2 == 0;
8964      * }
8965      *
8966      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
8967      * // => [1, 3, 5]
8968      */
8969     function negate(predicate) {
8970       if (typeof predicate != 'function') {
8971         throw new TypeError(FUNC_ERROR_TEXT);
8972       }
8973       return function() {
8974         return !predicate.apply(this, arguments);
8975       };
8976     }
8977
8978     /**
8979      * Creates a function that is restricted to invoking `func` once. Repeat calls
8980      * to the function return the value of the first invocation. The `func` is
8981      * invoked with the `this` binding and arguments of the created function.
8982      *
8983      * @static
8984      * @memberOf _
8985      * @category Function
8986      * @param {Function} func The function to restrict.
8987      * @returns {Function} Returns the new restricted function.
8988      * @example
8989      *
8990      * var initialize = _.once(createApplication);
8991      * initialize();
8992      * initialize();
8993      * // `initialize` invokes `createApplication` once
8994      */
8995     function once(func) {
8996       return before(2, func);
8997     }
8998
8999     /**
9000      * Creates a function that invokes `func` with arguments transformed by
9001      * corresponding `transforms`.
9002      *
9003      * @static
9004      * @memberOf _
9005      * @category Function
9006      * @param {Function} func The function to wrap.
9007      * @param {...(Function|Function[])} [transforms] The functions to transform
9008      * arguments, specified individually or in arrays.
9009      * @returns {Function} Returns the new function.
9010      * @example
9011      *
9012      * function doubled(n) {
9013      *   return n * 2;
9014      * }
9015      *
9016      * function square(n) {
9017      *   return n * n;
9018      * }
9019      *
9020      * var func = _.overArgs(function(x, y) {
9021      *   return [x, y];
9022      * }, square, doubled);
9023      *
9024      * func(9, 3);
9025      * // => [81, 6]
9026      *
9027      * func(10, 5);
9028      * // => [100, 10]
9029      */
9030     var overArgs = rest(function(func, transforms) {
9031       transforms = arrayMap(baseFlatten(transforms, 1), getIteratee());
9032
9033       var funcsLength = transforms.length;
9034       return rest(function(args) {
9035         var index = -1,
9036             length = nativeMin(args.length, funcsLength);
9037
9038         while (++index < length) {
9039           args[index] = transforms[index].call(this, args[index]);
9040         }
9041         return apply(func, this, args);
9042       });
9043     });
9044
9045     /**
9046      * Creates a function that invokes `func` with `partial` arguments prepended
9047      * to those provided to the new function. This method is like `_.bind` except
9048      * it does **not** alter the `this` binding.
9049      *
9050      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
9051      * builds, may be used as a placeholder for partially applied arguments.
9052      *
9053      * **Note:** This method doesn't set the "length" property of partially
9054      * applied functions.
9055      *
9056      * @static
9057      * @memberOf _
9058      * @category Function
9059      * @param {Function} func The function to partially apply arguments to.
9060      * @param {...*} [partials] The arguments to be partially applied.
9061      * @returns {Function} Returns the new partially applied function.
9062      * @example
9063      *
9064      * var greet = function(greeting, name) {
9065      *   return greeting + ' ' + name;
9066      * };
9067      *
9068      * var sayHelloTo = _.partial(greet, 'hello');
9069      * sayHelloTo('fred');
9070      * // => 'hello fred'
9071      *
9072      * // Partially applied with placeholders.
9073      * var greetFred = _.partial(greet, _, 'fred');
9074      * greetFred('hi');
9075      * // => 'hi fred'
9076      */
9077     var partial = rest(function(func, partials) {
9078       var holders = replaceHolders(partials, getPlaceholder(partial));
9079       return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
9080     });
9081
9082     /**
9083      * This method is like `_.partial` except that partially applied arguments
9084      * are appended to those provided to the new function.
9085      *
9086      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
9087      * builds, may be used as a placeholder for partially applied arguments.
9088      *
9089      * **Note:** This method doesn't set the "length" property of partially
9090      * applied functions.
9091      *
9092      * @static
9093      * @memberOf _
9094      * @category Function
9095      * @param {Function} func The function to partially apply arguments to.
9096      * @param {...*} [partials] The arguments to be partially applied.
9097      * @returns {Function} Returns the new partially applied function.
9098      * @example
9099      *
9100      * var greet = function(greeting, name) {
9101      *   return greeting + ' ' + name;
9102      * };
9103      *
9104      * var greetFred = _.partialRight(greet, 'fred');
9105      * greetFred('hi');
9106      * // => 'hi fred'
9107      *
9108      * // Partially applied with placeholders.
9109      * var sayHelloTo = _.partialRight(greet, 'hello', _);
9110      * sayHelloTo('fred');
9111      * // => 'hello fred'
9112      */
9113     var partialRight = rest(function(func, partials) {
9114       var holders = replaceHolders(partials, getPlaceholder(partialRight));
9115       return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
9116     });
9117
9118     /**
9119      * Creates a function that invokes `func` with arguments arranged according
9120      * to the specified indexes where the argument value at the first index is
9121      * provided as the first argument, the argument value at the second index is
9122      * provided as the second argument, and so on.
9123      *
9124      * @static
9125      * @memberOf _
9126      * @category Function
9127      * @param {Function} func The function to rearrange arguments for.
9128      * @param {...(number|number[])} indexes The arranged argument indexes,
9129      *  specified individually or in arrays.
9130      * @returns {Function} Returns the new function.
9131      * @example
9132      *
9133      * var rearged = _.rearg(function(a, b, c) {
9134      *   return [a, b, c];
9135      * }, 2, 0, 1);
9136      *
9137      * rearged('b', 'c', 'a')
9138      * // => ['a', 'b', 'c']
9139      */
9140     var rearg = rest(function(func, indexes) {
9141       return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1));
9142     });
9143
9144     /**
9145      * Creates a function that invokes `func` with the `this` binding of the
9146      * created function and arguments from `start` and beyond provided as an array.
9147      *
9148      * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
9149      *
9150      * @static
9151      * @memberOf _
9152      * @category Function
9153      * @param {Function} func The function to apply a rest parameter to.
9154      * @param {number} [start=func.length-1] The start position of the rest parameter.
9155      * @returns {Function} Returns the new function.
9156      * @example
9157      *
9158      * var say = _.rest(function(what, names) {
9159      *   return what + ' ' + _.initial(names).join(', ') +
9160      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
9161      * });
9162      *
9163      * say('hello', 'fred', 'barney', 'pebbles');
9164      * // => 'hello fred, barney, & pebbles'
9165      */
9166     function rest(func, start) {
9167       if (typeof func != 'function') {
9168         throw new TypeError(FUNC_ERROR_TEXT);
9169       }
9170       start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
9171       return function() {
9172         var args = arguments,
9173             index = -1,
9174             length = nativeMax(args.length - start, 0),
9175             array = Array(length);
9176
9177         while (++index < length) {
9178           array[index] = args[start + index];
9179         }
9180         switch (start) {
9181           case 0: return func.call(this, array);
9182           case 1: return func.call(this, args[0], array);
9183           case 2: return func.call(this, args[0], args[1], array);
9184         }
9185         var otherArgs = Array(start + 1);
9186         index = -1;
9187         while (++index < start) {
9188           otherArgs[index] = args[index];
9189         }
9190         otherArgs[start] = array;
9191         return apply(func, this, otherArgs);
9192       };
9193     }
9194
9195     /**
9196      * Creates a function that invokes `func` with the `this` binding of the created
9197      * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
9198      *
9199      * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
9200      *
9201      * @static
9202      * @memberOf _
9203      * @category Function
9204      * @param {Function} func The function to spread arguments over.
9205      * @param {number} [start=0] The start position of the spread.
9206      * @returns {Function} Returns the new function.
9207      * @example
9208      *
9209      * var say = _.spread(function(who, what) {
9210      *   return who + ' says ' + what;
9211      * });
9212      *
9213      * say(['fred', 'hello']);
9214      * // => 'fred says hello'
9215      *
9216      * var numbers = Promise.all([
9217      *   Promise.resolve(40),
9218      *   Promise.resolve(36)
9219      * ]);
9220      *
9221      * numbers.then(_.spread(function(x, y) {
9222      *   return x + y;
9223      * }));
9224      * // => a Promise of 76
9225      */
9226     function spread(func, start) {
9227       if (typeof func != 'function') {
9228         throw new TypeError(FUNC_ERROR_TEXT);
9229       }
9230       start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
9231       return rest(function(args) {
9232         var array = args[start],
9233             otherArgs = args.slice(0, start);
9234
9235         if (array) {
9236           arrayPush(otherArgs, array);
9237         }
9238         return apply(func, this, otherArgs);
9239       });
9240     }
9241
9242     /**
9243      * Creates a throttled function that only invokes `func` at most once per
9244      * every `wait` milliseconds. The throttled function comes with a `cancel`
9245      * method to cancel delayed `func` invocations and a `flush` method to
9246      * immediately invoke them. Provide an options object to indicate whether
9247      * `func` should be invoked on the leading and/or trailing edge of the `wait`
9248      * timeout. The `func` is invoked with the last arguments provided to the
9249      * throttled function. Subsequent calls to the throttled function return the
9250      * result of the last `func` invocation.
9251      *
9252      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
9253      * on the trailing edge of the timeout only if the throttled function is
9254      * invoked more than once during the `wait` timeout.
9255      *
9256      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
9257      * for details over the differences between `_.throttle` and `_.debounce`.
9258      *
9259      * @static
9260      * @memberOf _
9261      * @category Function
9262      * @param {Function} func The function to throttle.
9263      * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
9264      * @param {Object} [options] The options object.
9265      * @param {boolean} [options.leading=true] Specify invoking on the leading
9266      *  edge of the timeout.
9267      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
9268      *  edge of the timeout.
9269      * @returns {Function} Returns the new throttled function.
9270      * @example
9271      *
9272      * // Avoid excessively updating the position while scrolling.
9273      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
9274      *
9275      * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
9276      * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
9277      * jQuery(element).on('click', throttled);
9278      *
9279      * // Cancel the trailing throttled invocation.
9280      * jQuery(window).on('popstate', throttled.cancel);
9281      */
9282     function throttle(func, wait, options) {
9283       var leading = true,
9284           trailing = true;
9285
9286       if (typeof func != 'function') {
9287         throw new TypeError(FUNC_ERROR_TEXT);
9288       }
9289       if (isObject(options)) {
9290         leading = 'leading' in options ? !!options.leading : leading;
9291         trailing = 'trailing' in options ? !!options.trailing : trailing;
9292       }
9293       return debounce(func, wait, {
9294         'leading': leading,
9295         'maxWait': wait,
9296         'trailing': trailing
9297       });
9298     }
9299
9300     /**
9301      * Creates a function that accepts up to one argument, ignoring any
9302      * additional arguments.
9303      *
9304      * @static
9305      * @memberOf _
9306      * @category Function
9307      * @param {Function} func The function to cap arguments for.
9308      * @returns {Function} Returns the new function.
9309      * @example
9310      *
9311      * _.map(['6', '8', '10'], _.unary(parseInt));
9312      * // => [6, 8, 10]
9313      */
9314     function unary(func) {
9315       return ary(func, 1);
9316     }
9317
9318     /**
9319      * Creates a function that provides `value` to the wrapper function as its
9320      * first argument. Any additional arguments provided to the function are
9321      * appended to those provided to the wrapper function. The wrapper is invoked
9322      * with the `this` binding of the created function.
9323      *
9324      * @static
9325      * @memberOf _
9326      * @category Function
9327      * @param {*} value The value to wrap.
9328      * @param {Function} [wrapper=identity] The wrapper function.
9329      * @returns {Function} Returns the new function.
9330      * @example
9331      *
9332      * var p = _.wrap(_.escape, function(func, text) {
9333      *   return '<p>' + func(text) + '</p>';
9334      * });
9335      *
9336      * p('fred, barney, & pebbles');
9337      * // => '<p>fred, barney, &amp; pebbles</p>'
9338      */
9339     function wrap(value, wrapper) {
9340       wrapper = wrapper == null ? identity : wrapper;
9341       return partial(wrapper, value);
9342     }
9343
9344     /*------------------------------------------------------------------------*/
9345
9346     /**
9347      * Casts `value` as an array if it's not one.
9348      *
9349      * @static
9350      * @memberOf _
9351      * @category Lang
9352      * @param {*} value The value to inspect.
9353      * @returns {Array} Returns the cast array.
9354      * @example
9355      *
9356      * _.castArray(1);
9357      * // => [1]
9358      *
9359      * _.castArray({ 'a': 1 });
9360      * // => [{ 'a': 1 }]
9361      *
9362      * _.castArray('abc');
9363      * // => ['abc']
9364      *
9365      * _.castArray(null);
9366      * // => [null]
9367      *
9368      * _.castArray(undefined);
9369      * // => [undefined]
9370      *
9371      * _.castArray();
9372      * // => []
9373      *
9374      * var array = [1, 2, 3];
9375      * console.log(_.castArray(array) === array);
9376      * // => true
9377      */
9378     function castArray() {
9379       if (!arguments.length) {
9380         return [];
9381       }
9382       var value = arguments[0];
9383       return isArray(value) ? value : [value];
9384     }
9385
9386     /**
9387      * Creates a shallow clone of `value`.
9388      *
9389      * **Note:** This method is loosely based on the
9390      * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
9391      * and supports cloning arrays, array buffers, booleans, date objects, maps,
9392      * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
9393      * arrays. The own enumerable properties of `arguments` objects are cloned
9394      * as plain objects. An empty object is returned for uncloneable values such
9395      * as error objects, functions, DOM nodes, and WeakMaps.
9396      *
9397      * @static
9398      * @memberOf _
9399      * @category Lang
9400      * @param {*} value The value to clone.
9401      * @returns {*} Returns the cloned value.
9402      * @example
9403      *
9404      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9405      *
9406      * var shallow = _.clone(objects);
9407      * console.log(shallow[0] === objects[0]);
9408      * // => true
9409      */
9410     function clone(value) {
9411       return baseClone(value);
9412     }
9413
9414     /**
9415      * This method is like `_.clone` except that it accepts `customizer` which
9416      * is invoked to produce the cloned value. If `customizer` returns `undefined`
9417      * cloning is handled by the method instead. The `customizer` is invoked with
9418      * up to four arguments; (value [, index|key, object, stack]).
9419      *
9420      * @static
9421      * @memberOf _
9422      * @category Lang
9423      * @param {*} value The value to clone.
9424      * @param {Function} [customizer] The function to customize cloning.
9425      * @returns {*} Returns the cloned value.
9426      * @example
9427      *
9428      * function customizer(value) {
9429      *   if (_.isElement(value)) {
9430      *     return value.cloneNode(false);
9431      *   }
9432      * }
9433      *
9434      * var el = _.cloneWith(document.body, customizer);
9435      *
9436      * console.log(el === document.body);
9437      * // => false
9438      * console.log(el.nodeName);
9439      * // => 'BODY'
9440      * console.log(el.childNodes.length);
9441      * // => 0
9442      */
9443     function cloneWith(value, customizer) {
9444       return baseClone(value, false, customizer);
9445     }
9446
9447     /**
9448      * This method is like `_.clone` except that it recursively clones `value`.
9449      *
9450      * @static
9451      * @memberOf _
9452      * @category Lang
9453      * @param {*} value The value to recursively clone.
9454      * @returns {*} Returns the deep cloned value.
9455      * @example
9456      *
9457      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9458      *
9459      * var deep = _.cloneDeep(objects);
9460      * console.log(deep[0] === objects[0]);
9461      * // => false
9462      */
9463     function cloneDeep(value) {
9464       return baseClone(value, true);
9465     }
9466
9467     /**
9468      * This method is like `_.cloneWith` except that it recursively clones `value`.
9469      *
9470      * @static
9471      * @memberOf _
9472      * @category Lang
9473      * @param {*} value The value to recursively clone.
9474      * @param {Function} [customizer] The function to customize cloning.
9475      * @returns {*} Returns the deep cloned value.
9476      * @example
9477      *
9478      * function customizer(value) {
9479      *   if (_.isElement(value)) {
9480      *     return value.cloneNode(true);
9481      *   }
9482      * }
9483      *
9484      * var el = _.cloneDeepWith(document.body, customizer);
9485      *
9486      * console.log(el === document.body);
9487      * // => false
9488      * console.log(el.nodeName);
9489      * // => 'BODY'
9490      * console.log(el.childNodes.length);
9491      * // => 20
9492      */
9493     function cloneDeepWith(value, customizer) {
9494       return baseClone(value, true, customizer);
9495     }
9496
9497     /**
9498      * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
9499      * comparison between two values to determine if they are equivalent.
9500      *
9501      * @static
9502      * @memberOf _
9503      * @category Lang
9504      * @param {*} value The value to compare.
9505      * @param {*} other The other value to compare.
9506      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9507      * @example
9508      *
9509      * var object = { 'user': 'fred' };
9510      * var other = { 'user': 'fred' };
9511      *
9512      * _.eq(object, object);
9513      * // => true
9514      *
9515      * _.eq(object, other);
9516      * // => false
9517      *
9518      * _.eq('a', 'a');
9519      * // => true
9520      *
9521      * _.eq('a', Object('a'));
9522      * // => false
9523      *
9524      * _.eq(NaN, NaN);
9525      * // => true
9526      */
9527     function eq(value, other) {
9528       return value === other || (value !== value && other !== other);
9529     }
9530
9531     /**
9532      * Checks if `value` is greater than `other`.
9533      *
9534      * @static
9535      * @memberOf _
9536      * @category Lang
9537      * @param {*} value The value to compare.
9538      * @param {*} other The other value to compare.
9539      * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
9540      * @example
9541      *
9542      * _.gt(3, 1);
9543      * // => true
9544      *
9545      * _.gt(3, 3);
9546      * // => false
9547      *
9548      * _.gt(1, 3);
9549      * // => false
9550      */
9551     function gt(value, other) {
9552       return value > other;
9553     }
9554
9555     /**
9556      * Checks if `value` is greater than or equal to `other`.
9557      *
9558      * @static
9559      * @memberOf _
9560      * @category Lang
9561      * @param {*} value The value to compare.
9562      * @param {*} other The other value to compare.
9563      * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
9564      * @example
9565      *
9566      * _.gte(3, 1);
9567      * // => true
9568      *
9569      * _.gte(3, 3);
9570      * // => true
9571      *
9572      * _.gte(1, 3);
9573      * // => false
9574      */
9575     function gte(value, other) {
9576       return value >= other;
9577     }
9578
9579     /**
9580      * Checks if `value` is likely an `arguments` object.
9581      *
9582      * @static
9583      * @memberOf _
9584      * @category Lang
9585      * @param {*} value The value to check.
9586      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9587      * @example
9588      *
9589      * _.isArguments(function() { return arguments; }());
9590      * // => true
9591      *
9592      * _.isArguments([1, 2, 3]);
9593      * // => false
9594      */
9595     function isArguments(value) {
9596       // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
9597       return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
9598         (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
9599     }
9600
9601     /**
9602      * Checks if `value` is classified as an `Array` object.
9603      *
9604      * @static
9605      * @memberOf _
9606      * @type {Function}
9607      * @category Lang
9608      * @param {*} value The value to check.
9609      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9610      * @example
9611      *
9612      * _.isArray([1, 2, 3]);
9613      * // => true
9614      *
9615      * _.isArray(document.body.children);
9616      * // => false
9617      *
9618      * _.isArray('abc');
9619      * // => false
9620      *
9621      * _.isArray(_.noop);
9622      * // => false
9623      */
9624     var isArray = Array.isArray;
9625
9626     /**
9627      * Checks if `value` is classified as an `ArrayBuffer` object.
9628      *
9629      * @static
9630      * @memberOf _
9631      * @category Lang
9632      * @param {*} value The value to check.
9633      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9634      * @example
9635      *
9636      * _.isArrayBuffer(new ArrayBuffer(2));
9637      * // => true
9638      *
9639      * _.isArrayBuffer(new Array(2));
9640      * // => false
9641      */
9642     function isArrayBuffer(value) {
9643       return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
9644     }
9645
9646     /**
9647      * Checks if `value` is array-like. A value is considered array-like if it's
9648      * not a function and has a `value.length` that's an integer greater than or
9649      * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
9650      *
9651      * @static
9652      * @memberOf _
9653      * @category Lang
9654      * @param {*} value The value to check.
9655      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
9656      * @example
9657      *
9658      * _.isArrayLike([1, 2, 3]);
9659      * // => true
9660      *
9661      * _.isArrayLike(document.body.children);
9662      * // => true
9663      *
9664      * _.isArrayLike('abc');
9665      * // => true
9666      *
9667      * _.isArrayLike(_.noop);
9668      * // => false
9669      */
9670     function isArrayLike(value) {
9671       return value != null &&
9672         !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
9673     }
9674
9675     /**
9676      * This method is like `_.isArrayLike` except that it also checks if `value`
9677      * is an object.
9678      *
9679      * @static
9680      * @memberOf _
9681      * @category Lang
9682      * @param {*} value The value to check.
9683      * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
9684      * @example
9685      *
9686      * _.isArrayLikeObject([1, 2, 3]);
9687      * // => true
9688      *
9689      * _.isArrayLikeObject(document.body.children);
9690      * // => true
9691      *
9692      * _.isArrayLikeObject('abc');
9693      * // => false
9694      *
9695      * _.isArrayLikeObject(_.noop);
9696      * // => false
9697      */
9698     function isArrayLikeObject(value) {
9699       return isObjectLike(value) && isArrayLike(value);
9700     }
9701
9702     /**
9703      * Checks if `value` is classified as a boolean primitive or object.
9704      *
9705      * @static
9706      * @memberOf _
9707      * @category Lang
9708      * @param {*} value The value to check.
9709      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9710      * @example
9711      *
9712      * _.isBoolean(false);
9713      * // => true
9714      *
9715      * _.isBoolean(null);
9716      * // => false
9717      */
9718     function isBoolean(value) {
9719       return value === true || value === false ||
9720         (isObjectLike(value) && objectToString.call(value) == boolTag);
9721     }
9722
9723     /**
9724      * Checks if `value` is a buffer.
9725      *
9726      * @static
9727      * @memberOf _
9728      * @category Lang
9729      * @param {*} value The value to check.
9730      * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
9731      * @example
9732      *
9733      * _.isBuffer(new Buffer(2));
9734      * // => true
9735      *
9736      * _.isBuffer(new Uint8Array(2));
9737      * // => false
9738      */
9739     var isBuffer = !Buffer ? constant(false) : function(value) {
9740       return value instanceof Buffer;
9741     };
9742
9743     /**
9744      * Checks if `value` is classified as a `Date` object.
9745      *
9746      * @static
9747      * @memberOf _
9748      * @category Lang
9749      * @param {*} value The value to check.
9750      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9751      * @example
9752      *
9753      * _.isDate(new Date);
9754      * // => true
9755      *
9756      * _.isDate('Mon April 23 2012');
9757      * // => false
9758      */
9759     function isDate(value) {
9760       return isObjectLike(value) && objectToString.call(value) == dateTag;
9761     }
9762
9763     /**
9764      * Checks if `value` is likely a DOM element.
9765      *
9766      * @static
9767      * @memberOf _
9768      * @category Lang
9769      * @param {*} value The value to check.
9770      * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
9771      * @example
9772      *
9773      * _.isElement(document.body);
9774      * // => true
9775      *
9776      * _.isElement('<body>');
9777      * // => false
9778      */
9779     function isElement(value) {
9780       return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
9781     }
9782
9783     /**
9784      * Checks if `value` is empty. A value is considered empty unless it's an
9785      * `arguments` object, array, string, or jQuery-like collection with a length
9786      * greater than `0` or an object with own enumerable properties.
9787      *
9788      * @static
9789      * @memberOf _
9790      * @category Lang
9791      * @param {Array|Object|string} value The value to inspect.
9792      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
9793      * @example
9794      *
9795      * _.isEmpty(null);
9796      * // => true
9797      *
9798      * _.isEmpty(true);
9799      * // => true
9800      *
9801      * _.isEmpty(1);
9802      * // => true
9803      *
9804      * _.isEmpty([1, 2, 3]);
9805      * // => false
9806      *
9807      * _.isEmpty({ 'a': 1 });
9808      * // => false
9809      */
9810     function isEmpty(value) {
9811       if (isArrayLike(value) &&
9812           (isArray(value) || isString(value) ||
9813             isFunction(value.splice) || isArguments(value))) {
9814         return !value.length;
9815       }
9816       for (var key in value) {
9817         if (hasOwnProperty.call(value, key)) {
9818           return false;
9819         }
9820       }
9821       return true;
9822     }
9823
9824     /**
9825      * Performs a deep comparison between two values to determine if they are
9826      * equivalent.
9827      *
9828      * **Note:** This method supports comparing arrays, array buffers, booleans,
9829      * date objects, error objects, maps, numbers, `Object` objects, regexes,
9830      * sets, strings, symbols, and typed arrays. `Object` objects are compared
9831      * by their own, not inherited, enumerable properties. Functions and DOM
9832      * nodes are **not** supported.
9833      *
9834      * @static
9835      * @memberOf _
9836      * @category Lang
9837      * @param {*} value The value to compare.
9838      * @param {*} other The other value to compare.
9839      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9840      * @example
9841      *
9842      * var object = { 'user': 'fred' };
9843      * var other = { 'user': 'fred' };
9844      *
9845      * _.isEqual(object, other);
9846      * // => true
9847      *
9848      * object === other;
9849      * // => false
9850      */
9851     function isEqual(value, other) {
9852       return baseIsEqual(value, other);
9853     }
9854
9855     /**
9856      * This method is like `_.isEqual` except that it accepts `customizer` which
9857      * is invoked to compare values. If `customizer` returns `undefined` comparisons
9858      * are handled by the method instead. The `customizer` is invoked with up to
9859      * six arguments: (objValue, othValue [, index|key, object, other, stack]).
9860      *
9861      * @static
9862      * @memberOf _
9863      * @category Lang
9864      * @param {*} value The value to compare.
9865      * @param {*} other The other value to compare.
9866      * @param {Function} [customizer] The function to customize comparisons.
9867      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9868      * @example
9869      *
9870      * function isGreeting(value) {
9871      *   return /^h(?:i|ello)$/.test(value);
9872      * }
9873      *
9874      * function customizer(objValue, othValue) {
9875      *   if (isGreeting(objValue) && isGreeting(othValue)) {
9876      *     return true;
9877      *   }
9878      * }
9879      *
9880      * var array = ['hello', 'goodbye'];
9881      * var other = ['hi', 'goodbye'];
9882      *
9883      * _.isEqualWith(array, other, customizer);
9884      * // => true
9885      */
9886     function isEqualWith(value, other, customizer) {
9887       customizer = typeof customizer == 'function' ? customizer : undefined;
9888       var result = customizer ? customizer(value, other) : undefined;
9889       return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
9890     }
9891
9892     /**
9893      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
9894      * `SyntaxError`, `TypeError`, or `URIError` object.
9895      *
9896      * @static
9897      * @memberOf _
9898      * @category Lang
9899      * @param {*} value The value to check.
9900      * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
9901      * @example
9902      *
9903      * _.isError(new Error);
9904      * // => true
9905      *
9906      * _.isError(Error);
9907      * // => false
9908      */
9909     function isError(value) {
9910       if (!isObjectLike(value)) {
9911         return false;
9912       }
9913       return (objectToString.call(value) == errorTag) ||
9914         (typeof value.message == 'string' && typeof value.name == 'string');
9915     }
9916
9917     /**
9918      * Checks if `value` is a finite primitive number.
9919      *
9920      * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
9921      *
9922      * @static
9923      * @memberOf _
9924      * @category Lang
9925      * @param {*} value The value to check.
9926      * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
9927      * @example
9928      *
9929      * _.isFinite(3);
9930      * // => true
9931      *
9932      * _.isFinite(Number.MAX_VALUE);
9933      * // => true
9934      *
9935      * _.isFinite(3.14);
9936      * // => true
9937      *
9938      * _.isFinite(Infinity);
9939      * // => false
9940      */
9941     function isFinite(value) {
9942       return typeof value == 'number' && nativeIsFinite(value);
9943     }
9944
9945     /**
9946      * Checks if `value` is classified as a `Function` object.
9947      *
9948      * @static
9949      * @memberOf _
9950      * @category Lang
9951      * @param {*} value The value to check.
9952      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9953      * @example
9954      *
9955      * _.isFunction(_);
9956      * // => true
9957      *
9958      * _.isFunction(/abc/);
9959      * // => false
9960      */
9961     function isFunction(value) {
9962       // The use of `Object#toString` avoids issues with the `typeof` operator
9963       // in Safari 8 which returns 'object' for typed array constructors, and
9964       // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
9965       var tag = isObject(value) ? objectToString.call(value) : '';
9966       return tag == funcTag || tag == genTag;
9967     }
9968
9969     /**
9970      * Checks if `value` is an integer.
9971      *
9972      * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
9973      *
9974      * @static
9975      * @memberOf _
9976      * @category Lang
9977      * @param {*} value The value to check.
9978      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
9979      * @example
9980      *
9981      * _.isInteger(3);
9982      * // => true
9983      *
9984      * _.isInteger(Number.MIN_VALUE);
9985      * // => false
9986      *
9987      * _.isInteger(Infinity);
9988      * // => false
9989      *
9990      * _.isInteger('3');
9991      * // => false
9992      */
9993     function isInteger(value) {
9994       return typeof value == 'number' && value == toInteger(value);
9995     }
9996
9997     /**
9998      * Checks if `value` is a valid array-like length.
9999      *
10000      * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10001      *
10002      * @static
10003      * @memberOf _
10004      * @category Lang
10005      * @param {*} value The value to check.
10006      * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
10007      * @example
10008      *
10009      * _.isLength(3);
10010      * // => true
10011      *
10012      * _.isLength(Number.MIN_VALUE);
10013      * // => false
10014      *
10015      * _.isLength(Infinity);
10016      * // => false
10017      *
10018      * _.isLength('3');
10019      * // => false
10020      */
10021     function isLength(value) {
10022       return typeof value == 'number' &&
10023         value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
10024     }
10025
10026     /**
10027      * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
10028      * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
10029      *
10030      * @static
10031      * @memberOf _
10032      * @category Lang
10033      * @param {*} value The value to check.
10034      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
10035      * @example
10036      *
10037      * _.isObject({});
10038      * // => true
10039      *
10040      * _.isObject([1, 2, 3]);
10041      * // => true
10042      *
10043      * _.isObject(_.noop);
10044      * // => true
10045      *
10046      * _.isObject(null);
10047      * // => false
10048      */
10049     function isObject(value) {
10050       var type = typeof value;
10051       return !!value && (type == 'object' || type == 'function');
10052     }
10053
10054     /**
10055      * Checks if `value` is object-like. A value is object-like if it's not `null`
10056      * and has a `typeof` result of "object".
10057      *
10058      * @static
10059      * @memberOf _
10060      * @category Lang
10061      * @param {*} value The value to check.
10062      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
10063      * @example
10064      *
10065      * _.isObjectLike({});
10066      * // => true
10067      *
10068      * _.isObjectLike([1, 2, 3]);
10069      * // => true
10070      *
10071      * _.isObjectLike(_.noop);
10072      * // => false
10073      *
10074      * _.isObjectLike(null);
10075      * // => false
10076      */
10077     function isObjectLike(value) {
10078       return !!value && typeof value == 'object';
10079     }
10080
10081     /**
10082      * Checks if `value` is classified as a `Map` object.
10083      *
10084      * @static
10085      * @memberOf _
10086      * @category Lang
10087      * @param {*} value The value to check.
10088      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10089      * @example
10090      *
10091      * _.isMap(new Map);
10092      * // => true
10093      *
10094      * _.isMap(new WeakMap);
10095      * // => false
10096      */
10097     function isMap(value) {
10098       return isObjectLike(value) && getTag(value) == mapTag;
10099     }
10100
10101     /**
10102      * Performs a partial deep comparison between `object` and `source` to
10103      * determine if `object` contains equivalent property values. This method is
10104      * equivalent to a `_.matches` function when `source` is partially applied.
10105      *
10106      * **Note:** This method supports comparing the same values as `_.isEqual`.
10107      *
10108      * @static
10109      * @memberOf _
10110      * @category Lang
10111      * @param {Object} object The object to inspect.
10112      * @param {Object} source The object of property values to match.
10113      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
10114      * @example
10115      *
10116      * var object = { 'user': 'fred', 'age': 40 };
10117      *
10118      * _.isMatch(object, { 'age': 40 });
10119      * // => true
10120      *
10121      * _.isMatch(object, { 'age': 36 });
10122      * // => false
10123      */
10124     function isMatch(object, source) {
10125       return object === source || baseIsMatch(object, source, getMatchData(source));
10126     }
10127
10128     /**
10129      * This method is like `_.isMatch` except that it accepts `customizer` which
10130      * is invoked to compare values. If `customizer` returns `undefined` comparisons
10131      * are handled by the method instead. The `customizer` is invoked with five
10132      * arguments: (objValue, srcValue, index|key, object, source).
10133      *
10134      * @static
10135      * @memberOf _
10136      * @category Lang
10137      * @param {Object} object The object to inspect.
10138      * @param {Object} source The object of property values to match.
10139      * @param {Function} [customizer] The function to customize comparisons.
10140      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
10141      * @example
10142      *
10143      * function isGreeting(value) {
10144      *   return /^h(?:i|ello)$/.test(value);
10145      * }
10146      *
10147      * function customizer(objValue, srcValue) {
10148      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
10149      *     return true;
10150      *   }
10151      * }
10152      *
10153      * var object = { 'greeting': 'hello' };
10154      * var source = { 'greeting': 'hi' };
10155      *
10156      * _.isMatchWith(object, source, customizer);
10157      * // => true
10158      */
10159     function isMatchWith(object, source, customizer) {
10160       customizer = typeof customizer == 'function' ? customizer : undefined;
10161       return baseIsMatch(object, source, getMatchData(source), customizer);
10162     }
10163
10164     /**
10165      * Checks if `value` is `NaN`.
10166      *
10167      * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
10168      * which returns `true` for `undefined` and other non-numeric values.
10169      *
10170      * @static
10171      * @memberOf _
10172      * @category Lang
10173      * @param {*} value The value to check.
10174      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
10175      * @example
10176      *
10177      * _.isNaN(NaN);
10178      * // => true
10179      *
10180      * _.isNaN(new Number(NaN));
10181      * // => true
10182      *
10183      * isNaN(undefined);
10184      * // => true
10185      *
10186      * _.isNaN(undefined);
10187      * // => false
10188      */
10189     function isNaN(value) {
10190       // An `NaN` primitive is the only value that is not equal to itself.
10191       // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
10192       return isNumber(value) && value != +value;
10193     }
10194
10195     /**
10196      * Checks if `value` is a native function.
10197      *
10198      * @static
10199      * @memberOf _
10200      * @category Lang
10201      * @param {*} value The value to check.
10202      * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
10203      * @example
10204      *
10205      * _.isNative(Array.prototype.push);
10206      * // => true
10207      *
10208      * _.isNative(_);
10209      * // => false
10210      */
10211     function isNative(value) {
10212       if (value == null) {
10213         return false;
10214       }
10215       if (isFunction(value)) {
10216         return reIsNative.test(funcToString.call(value));
10217       }
10218       return isObjectLike(value) &&
10219         (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
10220     }
10221
10222     /**
10223      * Checks if `value` is `null`.
10224      *
10225      * @static
10226      * @memberOf _
10227      * @category Lang
10228      * @param {*} value The value to check.
10229      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
10230      * @example
10231      *
10232      * _.isNull(null);
10233      * // => true
10234      *
10235      * _.isNull(void 0);
10236      * // => false
10237      */
10238     function isNull(value) {
10239       return value === null;
10240     }
10241
10242     /**
10243      * Checks if `value` is `null` or `undefined`.
10244      *
10245      * @static
10246      * @memberOf _
10247      * @category Lang
10248      * @param {*} value The value to check.
10249      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
10250      * @example
10251      *
10252      * _.isNil(null);
10253      * // => true
10254      *
10255      * _.isNil(void 0);
10256      * // => true
10257      *
10258      * _.isNil(NaN);
10259      * // => false
10260      */
10261     function isNil(value) {
10262       return value == null;
10263     }
10264
10265     /**
10266      * Checks if `value` is classified as a `Number` primitive or object.
10267      *
10268      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
10269      * as numbers, use the `_.isFinite` method.
10270      *
10271      * @static
10272      * @memberOf _
10273      * @category Lang
10274      * @param {*} value The value to check.
10275      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10276      * @example
10277      *
10278      * _.isNumber(3);
10279      * // => true
10280      *
10281      * _.isNumber(Number.MIN_VALUE);
10282      * // => true
10283      *
10284      * _.isNumber(Infinity);
10285      * // => true
10286      *
10287      * _.isNumber('3');
10288      * // => false
10289      */
10290     function isNumber(value) {
10291       return typeof value == 'number' ||
10292         (isObjectLike(value) && objectToString.call(value) == numberTag);
10293     }
10294
10295     /**
10296      * Checks if `value` is a plain object, that is, an object created by the
10297      * `Object` constructor or one with a `[[Prototype]]` of `null`.
10298      *
10299      * @static
10300      * @memberOf _
10301      * @category Lang
10302      * @param {*} value The value to check.
10303      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
10304      * @example
10305      *
10306      * function Foo() {
10307      *   this.a = 1;
10308      * }
10309      *
10310      * _.isPlainObject(new Foo);
10311      * // => false
10312      *
10313      * _.isPlainObject([1, 2, 3]);
10314      * // => false
10315      *
10316      * _.isPlainObject({ 'x': 0, 'y': 0 });
10317      * // => true
10318      *
10319      * _.isPlainObject(Object.create(null));
10320      * // => true
10321      */
10322     function isPlainObject(value) {
10323       if (!isObjectLike(value) ||
10324           objectToString.call(value) != objectTag || isHostObject(value)) {
10325         return false;
10326       }
10327       var proto = getPrototypeOf(value);
10328       if (proto === null) {
10329         return true;
10330       }
10331       var Ctor = proto.constructor;
10332       return (typeof Ctor == 'function' &&
10333         Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
10334     }
10335
10336     /**
10337      * Checks if `value` is classified as a `RegExp` object.
10338      *
10339      * @static
10340      * @memberOf _
10341      * @category Lang
10342      * @param {*} value The value to check.
10343      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10344      * @example
10345      *
10346      * _.isRegExp(/abc/);
10347      * // => true
10348      *
10349      * _.isRegExp('/abc/');
10350      * // => false
10351      */
10352     function isRegExp(value) {
10353       return isObject(value) && objectToString.call(value) == regexpTag;
10354     }
10355
10356     /**
10357      * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
10358      * double precision number which isn't the result of a rounded unsafe integer.
10359      *
10360      * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
10361      *
10362      * @static
10363      * @memberOf _
10364      * @category Lang
10365      * @param {*} value The value to check.
10366      * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
10367      * @example
10368      *
10369      * _.isSafeInteger(3);
10370      * // => true
10371      *
10372      * _.isSafeInteger(Number.MIN_VALUE);
10373      * // => false
10374      *
10375      * _.isSafeInteger(Infinity);
10376      * // => false
10377      *
10378      * _.isSafeInteger('3');
10379      * // => false
10380      */
10381     function isSafeInteger(value) {
10382       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
10383     }
10384
10385     /**
10386      * Checks if `value` is classified as a `Set` object.
10387      *
10388      * @static
10389      * @memberOf _
10390      * @category Lang
10391      * @param {*} value The value to check.
10392      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10393      * @example
10394      *
10395      * _.isSet(new Set);
10396      * // => true
10397      *
10398      * _.isSet(new WeakSet);
10399      * // => false
10400      */
10401     function isSet(value) {
10402       return isObjectLike(value) && getTag(value) == setTag;
10403     }
10404
10405     /**
10406      * Checks if `value` is classified as a `String` primitive or object.
10407      *
10408      * @static
10409      * @memberOf _
10410      * @category Lang
10411      * @param {*} value The value to check.
10412      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10413      * @example
10414      *
10415      * _.isString('abc');
10416      * // => true
10417      *
10418      * _.isString(1);
10419      * // => false
10420      */
10421     function isString(value) {
10422       return typeof value == 'string' ||
10423         (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
10424     }
10425
10426     /**
10427      * Checks if `value` is classified as a `Symbol` primitive or object.
10428      *
10429      * @static
10430      * @memberOf _
10431      * @category Lang
10432      * @param {*} value The value to check.
10433      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10434      * @example
10435      *
10436      * _.isSymbol(Symbol.iterator);
10437      * // => true
10438      *
10439      * _.isSymbol('abc');
10440      * // => false
10441      */
10442     function isSymbol(value) {
10443       return typeof value == 'symbol' ||
10444         (isObjectLike(value) && objectToString.call(value) == symbolTag);
10445     }
10446
10447     /**
10448      * Checks if `value` is classified as a typed array.
10449      *
10450      * @static
10451      * @memberOf _
10452      * @category Lang
10453      * @param {*} value The value to check.
10454      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10455      * @example
10456      *
10457      * _.isTypedArray(new Uint8Array);
10458      * // => true
10459      *
10460      * _.isTypedArray([]);
10461      * // => false
10462      */
10463     function isTypedArray(value) {
10464       return isObjectLike(value) &&
10465         isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
10466     }
10467
10468     /**
10469      * Checks if `value` is `undefined`.
10470      *
10471      * @static
10472      * @memberOf _
10473      * @category Lang
10474      * @param {*} value The value to check.
10475      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
10476      * @example
10477      *
10478      * _.isUndefined(void 0);
10479      * // => true
10480      *
10481      * _.isUndefined(null);
10482      * // => false
10483      */
10484     function isUndefined(value) {
10485       return value === undefined;
10486     }
10487
10488     /**
10489      * Checks if `value` is classified as a `WeakMap` object.
10490      *
10491      * @static
10492      * @memberOf _
10493      * @category Lang
10494      * @param {*} value The value to check.
10495      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10496      * @example
10497      *
10498      * _.isWeakMap(new WeakMap);
10499      * // => true
10500      *
10501      * _.isWeakMap(new Map);
10502      * // => false
10503      */
10504     function isWeakMap(value) {
10505       return isObjectLike(value) && getTag(value) == weakMapTag;
10506     }
10507
10508     /**
10509      * Checks if `value` is classified as a `WeakSet` object.
10510      *
10511      * @static
10512      * @memberOf _
10513      * @category Lang
10514      * @param {*} value The value to check.
10515      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10516      * @example
10517      *
10518      * _.isWeakSet(new WeakSet);
10519      * // => true
10520      *
10521      * _.isWeakSet(new Set);
10522      * // => false
10523      */
10524     function isWeakSet(value) {
10525       return isObjectLike(value) && objectToString.call(value) == weakSetTag;
10526     }
10527
10528     /**
10529      * Checks if `value` is less than `other`.
10530      *
10531      * @static
10532      * @memberOf _
10533      * @category Lang
10534      * @param {*} value The value to compare.
10535      * @param {*} other The other value to compare.
10536      * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
10537      * @example
10538      *
10539      * _.lt(1, 3);
10540      * // => true
10541      *
10542      * _.lt(3, 3);
10543      * // => false
10544      *
10545      * _.lt(3, 1);
10546      * // => false
10547      */
10548     function lt(value, other) {
10549       return value < other;
10550     }
10551
10552     /**
10553      * Checks if `value` is less than or equal to `other`.
10554      *
10555      * @static
10556      * @memberOf _
10557      * @category Lang
10558      * @param {*} value The value to compare.
10559      * @param {*} other The other value to compare.
10560      * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
10561      * @example
10562      *
10563      * _.lte(1, 3);
10564      * // => true
10565      *
10566      * _.lte(3, 3);
10567      * // => true
10568      *
10569      * _.lte(3, 1);
10570      * // => false
10571      */
10572     function lte(value, other) {
10573       return value <= other;
10574     }
10575
10576     /**
10577      * Converts `value` to an array.
10578      *
10579      * @static
10580      * @memberOf _
10581      * @category Lang
10582      * @param {*} value The value to convert.
10583      * @returns {Array} Returns the converted array.
10584      * @example
10585      *
10586      * _.toArray({ 'a': 1, 'b': 2 });
10587      * // => [1, 2]
10588      *
10589      * _.toArray('abc');
10590      * // => ['a', 'b', 'c']
10591      *
10592      * _.toArray(1);
10593      * // => []
10594      *
10595      * _.toArray(null);
10596      * // => []
10597      */
10598     function toArray(value) {
10599       if (!value) {
10600         return [];
10601       }
10602       if (isArrayLike(value)) {
10603         return isString(value) ? stringToArray(value) : copyArray(value);
10604       }
10605       if (iteratorSymbol && value[iteratorSymbol]) {
10606         return iteratorToArray(value[iteratorSymbol]());
10607       }
10608       var tag = getTag(value),
10609           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
10610
10611       return func(value);
10612     }
10613
10614     /**
10615      * Converts `value` to an integer.
10616      *
10617      * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
10618      *
10619      * @static
10620      * @memberOf _
10621      * @category Lang
10622      * @param {*} value The value to convert.
10623      * @returns {number} Returns the converted integer.
10624      * @example
10625      *
10626      * _.toInteger(3);
10627      * // => 3
10628      *
10629      * _.toInteger(Number.MIN_VALUE);
10630      * // => 0
10631      *
10632      * _.toInteger(Infinity);
10633      * // => 1.7976931348623157e+308
10634      *
10635      * _.toInteger('3');
10636      * // => 3
10637      */
10638     function toInteger(value) {
10639       if (!value) {
10640         return value === 0 ? value : 0;
10641       }
10642       value = toNumber(value);
10643       if (value === INFINITY || value === -INFINITY) {
10644         var sign = (value < 0 ? -1 : 1);
10645         return sign * MAX_INTEGER;
10646       }
10647       var remainder = value % 1;
10648       return value === value ? (remainder ? value - remainder : value) : 0;
10649     }
10650
10651     /**
10652      * Converts `value` to an integer suitable for use as the length of an
10653      * array-like object.
10654      *
10655      * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10656      *
10657      * @static
10658      * @memberOf _
10659      * @category Lang
10660      * @param {*} value The value to convert.
10661      * @returns {number} Returns the converted integer.
10662      * @example
10663      *
10664      * _.toLength(3);
10665      * // => 3
10666      *
10667      * _.toLength(Number.MIN_VALUE);
10668      * // => 0
10669      *
10670      * _.toLength(Infinity);
10671      * // => 4294967295
10672      *
10673      * _.toLength('3');
10674      * // => 3
10675      */
10676     function toLength(value) {
10677       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
10678     }
10679
10680     /**
10681      * Converts `value` to a number.
10682      *
10683      * @static
10684      * @memberOf _
10685      * @category Lang
10686      * @param {*} value The value to process.
10687      * @returns {number} Returns the number.
10688      * @example
10689      *
10690      * _.toNumber(3);
10691      * // => 3
10692      *
10693      * _.toNumber(Number.MIN_VALUE);
10694      * // => 5e-324
10695      *
10696      * _.toNumber(Infinity);
10697      * // => Infinity
10698      *
10699      * _.toNumber('3');
10700      * // => 3
10701      */
10702     function toNumber(value) {
10703       if (isObject(value)) {
10704         var other = isFunction(value.valueOf) ? value.valueOf() : value;
10705         value = isObject(other) ? (other + '') : other;
10706       }
10707       if (typeof value != 'string') {
10708         return value === 0 ? value : +value;
10709       }
10710       value = value.replace(reTrim, '');
10711       var isBinary = reIsBinary.test(value);
10712       return (isBinary || reIsOctal.test(value))
10713         ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
10714         : (reIsBadHex.test(value) ? NAN : +value);
10715     }
10716
10717     /**
10718      * Converts `value` to a plain object flattening inherited enumerable
10719      * properties of `value` to own properties of the plain object.
10720      *
10721      * @static
10722      * @memberOf _
10723      * @category Lang
10724      * @param {*} value The value to convert.
10725      * @returns {Object} Returns the converted plain object.
10726      * @example
10727      *
10728      * function Foo() {
10729      *   this.b = 2;
10730      * }
10731      *
10732      * Foo.prototype.c = 3;
10733      *
10734      * _.assign({ 'a': 1 }, new Foo);
10735      * // => { 'a': 1, 'b': 2 }
10736      *
10737      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
10738      * // => { 'a': 1, 'b': 2, 'c': 3 }
10739      */
10740     function toPlainObject(value) {
10741       return copyObject(value, keysIn(value));
10742     }
10743
10744     /**
10745      * Converts `value` to a safe integer. A safe integer can be compared and
10746      * represented correctly.
10747      *
10748      * @static
10749      * @memberOf _
10750      * @category Lang
10751      * @param {*} value The value to convert.
10752      * @returns {number} Returns the converted integer.
10753      * @example
10754      *
10755      * _.toSafeInteger(3);
10756      * // => 3
10757      *
10758      * _.toSafeInteger(Number.MIN_VALUE);
10759      * // => 0
10760      *
10761      * _.toSafeInteger(Infinity);
10762      * // => 9007199254740991
10763      *
10764      * _.toSafeInteger('3');
10765      * // => 3
10766      */
10767     function toSafeInteger(value) {
10768       return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
10769     }
10770
10771     /**
10772      * Converts `value` to a string if it's not one. An empty string is returned
10773      * for `null` and `undefined` values. The sign of `-0` is preserved.
10774      *
10775      * @static
10776      * @memberOf _
10777      * @category Lang
10778      * @param {*} value The value to process.
10779      * @returns {string} Returns the string.
10780      * @example
10781      *
10782      * _.toString(null);
10783      * // => ''
10784      *
10785      * _.toString(-0);
10786      * // => '-0'
10787      *
10788      * _.toString([1, 2, 3]);
10789      * // => '1,2,3'
10790      */
10791     function toString(value) {
10792       // Exit early for strings to avoid a performance hit in some environments.
10793       if (typeof value == 'string') {
10794         return value;
10795       }
10796       if (value == null) {
10797         return '';
10798       }
10799       if (isSymbol(value)) {
10800         return Symbol ? symbolToString.call(value) : '';
10801       }
10802       var result = (value + '');
10803       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
10804     }
10805
10806     /*------------------------------------------------------------------------*/
10807
10808     /**
10809      * Assigns own enumerable properties of source objects to the destination
10810      * object. Source objects are applied from left to right. Subsequent sources
10811      * overwrite property assignments of previous sources.
10812      *
10813      * **Note:** This method mutates `object` and is loosely based on
10814      * [`Object.assign`](https://mdn.io/Object/assign).
10815      *
10816      * @static
10817      * @memberOf _
10818      * @category Object
10819      * @param {Object} object The destination object.
10820      * @param {...Object} [sources] The source objects.
10821      * @returns {Object} Returns `object`.
10822      * @example
10823      *
10824      * function Foo() {
10825      *   this.c = 3;
10826      * }
10827      *
10828      * function Bar() {
10829      *   this.e = 5;
10830      * }
10831      *
10832      * Foo.prototype.d = 4;
10833      * Bar.prototype.f = 6;
10834      *
10835      * _.assign({ 'a': 1 }, new Foo, new Bar);
10836      * // => { 'a': 1, 'c': 3, 'e': 5 }
10837      */
10838     var assign = createAssigner(function(object, source) {
10839       copyObject(source, keys(source), object);
10840     });
10841
10842     /**
10843      * This method is like `_.assign` except that it iterates over own and
10844      * inherited source properties.
10845      *
10846      * **Note:** This method mutates `object`.
10847      *
10848      * @static
10849      * @memberOf _
10850      * @alias extend
10851      * @category Object
10852      * @param {Object} object The destination object.
10853      * @param {...Object} [sources] The source objects.
10854      * @returns {Object} Returns `object`.
10855      * @example
10856      *
10857      * function Foo() {
10858      *   this.b = 2;
10859      * }
10860      *
10861      * function Bar() {
10862      *   this.d = 4;
10863      * }
10864      *
10865      * Foo.prototype.c = 3;
10866      * Bar.prototype.e = 5;
10867      *
10868      * _.assignIn({ 'a': 1 }, new Foo, new Bar);
10869      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
10870      */
10871     var assignIn = createAssigner(function(object, source) {
10872       copyObject(source, keysIn(source), object);
10873     });
10874
10875     /**
10876      * This method is like `_.assignIn` except that it accepts `customizer` which
10877      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10878      * assignment is handled by the method instead. The `customizer` is invoked
10879      * with five arguments: (objValue, srcValue, key, object, source).
10880      *
10881      * **Note:** This method mutates `object`.
10882      *
10883      * @static
10884      * @memberOf _
10885      * @alias extendWith
10886      * @category Object
10887      * @param {Object} object The destination object.
10888      * @param {...Object} sources The source objects.
10889      * @param {Function} [customizer] The function to customize assigned values.
10890      * @returns {Object} Returns `object`.
10891      * @example
10892      *
10893      * function customizer(objValue, srcValue) {
10894      *   return _.isUndefined(objValue) ? srcValue : objValue;
10895      * }
10896      *
10897      * var defaults = _.partialRight(_.assignInWith, customizer);
10898      *
10899      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10900      * // => { 'a': 1, 'b': 2 }
10901      */
10902     var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
10903       copyObjectWith(source, keysIn(source), object, customizer);
10904     });
10905
10906     /**
10907      * This method is like `_.assign` except that it accepts `customizer` which
10908      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10909      * assignment is handled by the method instead. The `customizer` is invoked
10910      * with five arguments: (objValue, srcValue, key, object, source).
10911      *
10912      * **Note:** This method mutates `object`.
10913      *
10914      * @static
10915      * @memberOf _
10916      * @category Object
10917      * @param {Object} object The destination object.
10918      * @param {...Object} sources The source objects.
10919      * @param {Function} [customizer] The function to customize assigned values.
10920      * @returns {Object} Returns `object`.
10921      * @example
10922      *
10923      * function customizer(objValue, srcValue) {
10924      *   return _.isUndefined(objValue) ? srcValue : objValue;
10925      * }
10926      *
10927      * var defaults = _.partialRight(_.assignWith, customizer);
10928      *
10929      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10930      * // => { 'a': 1, 'b': 2 }
10931      */
10932     var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
10933       copyObjectWith(source, keys(source), object, customizer);
10934     });
10935
10936     /**
10937      * Creates an array of values corresponding to `paths` of `object`.
10938      *
10939      * @static
10940      * @memberOf _
10941      * @category Object
10942      * @param {Object} object The object to iterate over.
10943      * @param {...(string|string[])} [paths] The property paths of elements to pick,
10944      *  specified individually or in arrays.
10945      * @returns {Array} Returns the new array of picked elements.
10946      * @example
10947      *
10948      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
10949      *
10950      * _.at(object, ['a[0].b.c', 'a[1]']);
10951      * // => [3, 4]
10952      *
10953      * _.at(['a', 'b', 'c'], 0, 2);
10954      * // => ['a', 'c']
10955      */
10956     var at = rest(function(object, paths) {
10957       return baseAt(object, baseFlatten(paths, 1));
10958     });
10959
10960     /**
10961      * Creates an object that inherits from the `prototype` object. If a `properties`
10962      * object is given its own enumerable properties are assigned to the created object.
10963      *
10964      * @static
10965      * @memberOf _
10966      * @category Object
10967      * @param {Object} prototype The object to inherit from.
10968      * @param {Object} [properties] The properties to assign to the object.
10969      * @returns {Object} Returns the new object.
10970      * @example
10971      *
10972      * function Shape() {
10973      *   this.x = 0;
10974      *   this.y = 0;
10975      * }
10976      *
10977      * function Circle() {
10978      *   Shape.call(this);
10979      * }
10980      *
10981      * Circle.prototype = _.create(Shape.prototype, {
10982      *   'constructor': Circle
10983      * });
10984      *
10985      * var circle = new Circle;
10986      * circle instanceof Circle;
10987      * // => true
10988      *
10989      * circle instanceof Shape;
10990      * // => true
10991      */
10992     function create(prototype, properties) {
10993       var result = baseCreate(prototype);
10994       return properties ? baseAssign(result, properties) : result;
10995     }
10996
10997     /**
10998      * Assigns own and inherited enumerable properties of source objects to the
10999      * destination object for all destination properties that resolve to `undefined`.
11000      * Source objects are applied from left to right. Once a property is set,
11001      * additional values of the same property are ignored.
11002      *
11003      * **Note:** This method mutates `object`.
11004      *
11005      * @static
11006      * @memberOf _
11007      * @category Object
11008      * @param {Object} object The destination object.
11009      * @param {...Object} [sources] The source objects.
11010      * @returns {Object} Returns `object`.
11011      * @example
11012      *
11013      * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
11014      * // => { 'user': 'barney', 'age': 36 }
11015      */
11016     var defaults = rest(function(args) {
11017       args.push(undefined, assignInDefaults);
11018       return apply(assignInWith, undefined, args);
11019     });
11020
11021     /**
11022      * This method is like `_.defaults` except that it recursively assigns
11023      * default properties.
11024      *
11025      * **Note:** This method mutates `object`.
11026      *
11027      * @static
11028      * @memberOf _
11029      * @category Object
11030      * @param {Object} object The destination object.
11031      * @param {...Object} [sources] The source objects.
11032      * @returns {Object} Returns `object`.
11033      * @example
11034      *
11035      * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
11036      * // => { 'user': { 'name': 'barney', 'age': 36 } }
11037      *
11038      */
11039     var defaultsDeep = rest(function(args) {
11040       args.push(undefined, mergeDefaults);
11041       return apply(mergeWith, undefined, args);
11042     });
11043
11044     /**
11045      * This method is like `_.find` except that it returns the key of the first
11046      * element `predicate` returns truthy for instead of the element itself.
11047      *
11048      * @static
11049      * @memberOf _
11050      * @category Object
11051      * @param {Object} object The object to search.
11052      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
11053      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
11054      * @example
11055      *
11056      * var users = {
11057      *   'barney':  { 'age': 36, 'active': true },
11058      *   'fred':    { 'age': 40, 'active': false },
11059      *   'pebbles': { 'age': 1,  'active': true }
11060      * };
11061      *
11062      * _.findKey(users, function(o) { return o.age < 40; });
11063      * // => 'barney' (iteration order is not guaranteed)
11064      *
11065      * // The `_.matches` iteratee shorthand.
11066      * _.findKey(users, { 'age': 1, 'active': true });
11067      * // => 'pebbles'
11068      *
11069      * // The `_.matchesProperty` iteratee shorthand.
11070      * _.findKey(users, ['active', false]);
11071      * // => 'fred'
11072      *
11073      * // The `_.property` iteratee shorthand.
11074      * _.findKey(users, 'active');
11075      * // => 'barney'
11076      */
11077     function findKey(object, predicate) {
11078       return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
11079     }
11080
11081     /**
11082      * This method is like `_.findKey` except that it iterates over elements of
11083      * a collection in the opposite order.
11084      *
11085      * @static
11086      * @memberOf _
11087      * @category Object
11088      * @param {Object} object The object to search.
11089      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
11090      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
11091      * @example
11092      *
11093      * var users = {
11094      *   'barney':  { 'age': 36, 'active': true },
11095      *   'fred':    { 'age': 40, 'active': false },
11096      *   'pebbles': { 'age': 1,  'active': true }
11097      * };
11098      *
11099      * _.findLastKey(users, function(o) { return o.age < 40; });
11100      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
11101      *
11102      * // The `_.matches` iteratee shorthand.
11103      * _.findLastKey(users, { 'age': 36, 'active': true });
11104      * // => 'barney'
11105      *
11106      * // The `_.matchesProperty` iteratee shorthand.
11107      * _.findLastKey(users, ['active', false]);
11108      * // => 'fred'
11109      *
11110      * // The `_.property` iteratee shorthand.
11111      * _.findLastKey(users, 'active');
11112      * // => 'pebbles'
11113      */
11114     function findLastKey(object, predicate) {
11115       return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
11116     }
11117
11118     /**
11119      * Iterates over own and inherited enumerable properties of an object invoking
11120      * `iteratee` for each property. The iteratee is invoked with three arguments:
11121      * (value, key, object). Iteratee functions may exit iteration early by explicitly
11122      * returning `false`.
11123      *
11124      * @static
11125      * @memberOf _
11126      * @category Object
11127      * @param {Object} object The object to iterate over.
11128      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11129      * @returns {Object} Returns `object`.
11130      * @example
11131      *
11132      * function Foo() {
11133      *   this.a = 1;
11134      *   this.b = 2;
11135      * }
11136      *
11137      * Foo.prototype.c = 3;
11138      *
11139      * _.forIn(new Foo, function(value, key) {
11140      *   console.log(key);
11141      * });
11142      * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
11143      */
11144     function forIn(object, iteratee) {
11145       return object == null
11146         ? object
11147         : baseFor(object, baseCastFunction(iteratee), keysIn);
11148     }
11149
11150     /**
11151      * This method is like `_.forIn` except that it iterates over properties of
11152      * `object` in the opposite order.
11153      *
11154      * @static
11155      * @memberOf _
11156      * @category Object
11157      * @param {Object} object The object to iterate over.
11158      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11159      * @returns {Object} Returns `object`.
11160      * @example
11161      *
11162      * function Foo() {
11163      *   this.a = 1;
11164      *   this.b = 2;
11165      * }
11166      *
11167      * Foo.prototype.c = 3;
11168      *
11169      * _.forInRight(new Foo, function(value, key) {
11170      *   console.log(key);
11171      * });
11172      * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
11173      */
11174     function forInRight(object, iteratee) {
11175       return object == null
11176         ? object
11177         : baseForRight(object, baseCastFunction(iteratee), keysIn);
11178     }
11179
11180     /**
11181      * Iterates over own enumerable properties of an object invoking `iteratee`
11182      * for each property. The iteratee is invoked with three arguments:
11183      * (value, key, object). Iteratee functions may exit iteration early by
11184      * explicitly returning `false`.
11185      *
11186      * @static
11187      * @memberOf _
11188      * @category Object
11189      * @param {Object} object The object to iterate over.
11190      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11191      * @returns {Object} Returns `object`.
11192      * @example
11193      *
11194      * function Foo() {
11195      *   this.a = 1;
11196      *   this.b = 2;
11197      * }
11198      *
11199      * Foo.prototype.c = 3;
11200      *
11201      * _.forOwn(new Foo, function(value, key) {
11202      *   console.log(key);
11203      * });
11204      * // => logs 'a' then 'b' (iteration order is not guaranteed)
11205      */
11206     function forOwn(object, iteratee) {
11207       return object && baseForOwn(object, baseCastFunction(iteratee));
11208     }
11209
11210     /**
11211      * This method is like `_.forOwn` except that it iterates over properties of
11212      * `object` in the opposite order.
11213      *
11214      * @static
11215      * @memberOf _
11216      * @category Object
11217      * @param {Object} object The object to iterate over.
11218      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11219      * @returns {Object} Returns `object`.
11220      * @example
11221      *
11222      * function Foo() {
11223      *   this.a = 1;
11224      *   this.b = 2;
11225      * }
11226      *
11227      * Foo.prototype.c = 3;
11228      *
11229      * _.forOwnRight(new Foo, function(value, key) {
11230      *   console.log(key);
11231      * });
11232      * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
11233      */
11234     function forOwnRight(object, iteratee) {
11235       return object && baseForOwnRight(object, baseCastFunction(iteratee));
11236     }
11237
11238     /**
11239      * Creates an array of function property names from own enumerable properties
11240      * of `object`.
11241      *
11242      * @static
11243      * @memberOf _
11244      * @category Object
11245      * @param {Object} object The object to inspect.
11246      * @returns {Array} Returns the new array of property names.
11247      * @example
11248      *
11249      * function Foo() {
11250      *   this.a = _.constant('a');
11251      *   this.b = _.constant('b');
11252      * }
11253      *
11254      * Foo.prototype.c = _.constant('c');
11255      *
11256      * _.functions(new Foo);
11257      * // => ['a', 'b']
11258      */
11259     function functions(object) {
11260       return object == null ? [] : baseFunctions(object, keys(object));
11261     }
11262
11263     /**
11264      * Creates an array of function property names from own and inherited
11265      * enumerable properties of `object`.
11266      *
11267      * @static
11268      * @memberOf _
11269      * @category Object
11270      * @param {Object} object The object to inspect.
11271      * @returns {Array} Returns the new array of property names.
11272      * @example
11273      *
11274      * function Foo() {
11275      *   this.a = _.constant('a');
11276      *   this.b = _.constant('b');
11277      * }
11278      *
11279      * Foo.prototype.c = _.constant('c');
11280      *
11281      * _.functionsIn(new Foo);
11282      * // => ['a', 'b', 'c']
11283      */
11284     function functionsIn(object) {
11285       return object == null ? [] : baseFunctions(object, keysIn(object));
11286     }
11287
11288     /**
11289      * Gets the value at `path` of `object`. If the resolved value is
11290      * `undefined` the `defaultValue` is used in its place.
11291      *
11292      * @static
11293      * @memberOf _
11294      * @category Object
11295      * @param {Object} object The object to query.
11296      * @param {Array|string} path The path of the property to get.
11297      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11298      * @returns {*} Returns the resolved value.
11299      * @example
11300      *
11301      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11302      *
11303      * _.get(object, 'a[0].b.c');
11304      * // => 3
11305      *
11306      * _.get(object, ['a', '0', 'b', 'c']);
11307      * // => 3
11308      *
11309      * _.get(object, 'a.b.c', 'default');
11310      * // => 'default'
11311      */
11312     function get(object, path, defaultValue) {
11313       var result = object == null ? undefined : baseGet(object, path);
11314       return result === undefined ? defaultValue : result;
11315     }
11316
11317     /**
11318      * Checks if `path` is a direct property of `object`.
11319      *
11320      * @static
11321      * @memberOf _
11322      * @category Object
11323      * @param {Object} object The object to query.
11324      * @param {Array|string} path The path to check.
11325      * @returns {boolean} Returns `true` if `path` exists, else `false`.
11326      * @example
11327      *
11328      * var object = { 'a': { 'b': { 'c': 3 } } };
11329      * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
11330      *
11331      * _.has(object, 'a');
11332      * // => true
11333      *
11334      * _.has(object, 'a.b.c');
11335      * // => true
11336      *
11337      * _.has(object, ['a', 'b', 'c']);
11338      * // => true
11339      *
11340      * _.has(other, 'a');
11341      * // => false
11342      */
11343     function has(object, path) {
11344       return hasPath(object, path, baseHas);
11345     }
11346
11347     /**
11348      * Checks if `path` is a direct or inherited property of `object`.
11349      *
11350      * @static
11351      * @memberOf _
11352      * @category Object
11353      * @param {Object} object The object to query.
11354      * @param {Array|string} path The path to check.
11355      * @returns {boolean} Returns `true` if `path` exists, else `false`.
11356      * @example
11357      *
11358      * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
11359      *
11360      * _.hasIn(object, 'a');
11361      * // => true
11362      *
11363      * _.hasIn(object, 'a.b.c');
11364      * // => true
11365      *
11366      * _.hasIn(object, ['a', 'b', 'c']);
11367      * // => true
11368      *
11369      * _.hasIn(object, 'b');
11370      * // => false
11371      */
11372     function hasIn(object, path) {
11373       return hasPath(object, path, baseHasIn);
11374     }
11375
11376     /**
11377      * Creates an object composed of the inverted keys and values of `object`.
11378      * If `object` contains duplicate values, subsequent values overwrite property
11379      * assignments of previous values.
11380      *
11381      * @static
11382      * @memberOf _
11383      * @category Object
11384      * @param {Object} object The object to invert.
11385      * @returns {Object} Returns the new inverted object.
11386      * @example
11387      *
11388      * var object = { 'a': 1, 'b': 2, 'c': 1 };
11389      *
11390      * _.invert(object);
11391      * // => { '1': 'c', '2': 'b' }
11392      */
11393     var invert = createInverter(function(result, value, key) {
11394       result[value] = key;
11395     }, constant(identity));
11396
11397     /**
11398      * This method is like `_.invert` except that the inverted object is generated
11399      * from the results of running each element of `object` through `iteratee`.
11400      * The corresponding inverted value of each inverted key is an array of keys
11401      * responsible for generating the inverted value. The iteratee is invoked
11402      * with one argument: (value).
11403      *
11404      * @static
11405      * @memberOf _
11406      * @category Object
11407      * @param {Object} object The object to invert.
11408      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
11409      * @returns {Object} Returns the new inverted object.
11410      * @example
11411      *
11412      * var object = { 'a': 1, 'b': 2, 'c': 1 };
11413      *
11414      * _.invertBy(object);
11415      * // => { '1': ['a', 'c'], '2': ['b'] }
11416      *
11417      * _.invertBy(object, function(value) {
11418      *   return 'group' + value;
11419      * });
11420      * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
11421      */
11422     var invertBy = createInverter(function(result, value, key) {
11423       if (hasOwnProperty.call(result, value)) {
11424         result[value].push(key);
11425       } else {
11426         result[value] = [key];
11427       }
11428     }, getIteratee);
11429
11430     /**
11431      * Invokes the method at `path` of `object`.
11432      *
11433      * @static
11434      * @memberOf _
11435      * @category Object
11436      * @param {Object} object The object to query.
11437      * @param {Array|string} path The path of the method to invoke.
11438      * @param {...*} [args] The arguments to invoke the method with.
11439      * @returns {*} Returns the result of the invoked method.
11440      * @example
11441      *
11442      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
11443      *
11444      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
11445      * // => [2, 3]
11446      */
11447     var invoke = rest(baseInvoke);
11448
11449     /**
11450      * Creates an array of the own enumerable property names of `object`.
11451      *
11452      * **Note:** Non-object values are coerced to objects. See the
11453      * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
11454      * for more details.
11455      *
11456      * @static
11457      * @memberOf _
11458      * @category Object
11459      * @param {Object} object The object to query.
11460      * @returns {Array} Returns the array of property names.
11461      * @example
11462      *
11463      * function Foo() {
11464      *   this.a = 1;
11465      *   this.b = 2;
11466      * }
11467      *
11468      * Foo.prototype.c = 3;
11469      *
11470      * _.keys(new Foo);
11471      * // => ['a', 'b'] (iteration order is not guaranteed)
11472      *
11473      * _.keys('hi');
11474      * // => ['0', '1']
11475      */
11476     function keys(object) {
11477       var isProto = isPrototype(object);
11478       if (!(isProto || isArrayLike(object))) {
11479         return baseKeys(object);
11480       }
11481       var indexes = indexKeys(object),
11482           skipIndexes = !!indexes,
11483           result = indexes || [],
11484           length = result.length;
11485
11486       for (var key in object) {
11487         if (baseHas(object, key) &&
11488             !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11489             !(isProto && key == 'constructor')) {
11490           result.push(key);
11491         }
11492       }
11493       return result;
11494     }
11495
11496     /**
11497      * Creates an array of the own and inherited enumerable property names of `object`.
11498      *
11499      * **Note:** Non-object values are coerced to objects.
11500      *
11501      * @static
11502      * @memberOf _
11503      * @category Object
11504      * @param {Object} object The object to query.
11505      * @returns {Array} Returns the array of property names.
11506      * @example
11507      *
11508      * function Foo() {
11509      *   this.a = 1;
11510      *   this.b = 2;
11511      * }
11512      *
11513      * Foo.prototype.c = 3;
11514      *
11515      * _.keysIn(new Foo);
11516      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
11517      */
11518     function keysIn(object) {
11519       var index = -1,
11520           isProto = isPrototype(object),
11521           props = baseKeysIn(object),
11522           propsLength = props.length,
11523           indexes = indexKeys(object),
11524           skipIndexes = !!indexes,
11525           result = indexes || [],
11526           length = result.length;
11527
11528       while (++index < propsLength) {
11529         var key = props[index];
11530         if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11531             !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
11532           result.push(key);
11533         }
11534       }
11535       return result;
11536     }
11537
11538     /**
11539      * The opposite of `_.mapValues`; this method creates an object with the
11540      * same values as `object` and keys generated by running each own enumerable
11541      * property of `object` through `iteratee`. The iteratee is invoked with
11542      * three arguments: (value, key, object).
11543      *
11544      * @static
11545      * @memberOf _
11546      * @category Object
11547      * @param {Object} object The object to iterate over.
11548      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11549      * @returns {Object} Returns the new mapped object.
11550      * @example
11551      *
11552      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
11553      *   return key + value;
11554      * });
11555      * // => { 'a1': 1, 'b2': 2 }
11556      */
11557     function mapKeys(object, iteratee) {
11558       var result = {};
11559       iteratee = getIteratee(iteratee, 3);
11560
11561       baseForOwn(object, function(value, key, object) {
11562         result[iteratee(value, key, object)] = value;
11563       });
11564       return result;
11565     }
11566
11567     /**
11568      * Creates an object with the same keys as `object` and values generated by
11569      * running each own enumerable property of `object` through `iteratee`. The
11570      * iteratee is invoked with three arguments: (value, key, object).
11571      *
11572      * @static
11573      * @memberOf _
11574      * @category Object
11575      * @param {Object} object The object to iterate over.
11576      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11577      * @returns {Object} Returns the new mapped object.
11578      * @example
11579      *
11580      * var users = {
11581      *   'fred':    { 'user': 'fred',    'age': 40 },
11582      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
11583      * };
11584      *
11585      * _.mapValues(users, function(o) { return o.age; });
11586      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11587      *
11588      * // The `_.property` iteratee shorthand.
11589      * _.mapValues(users, 'age');
11590      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11591      */
11592     function mapValues(object, iteratee) {
11593       var result = {};
11594       iteratee = getIteratee(iteratee, 3);
11595
11596       baseForOwn(object, function(value, key, object) {
11597         result[key] = iteratee(value, key, object);
11598       });
11599       return result;
11600     }
11601
11602     /**
11603      * Recursively merges own and inherited enumerable properties of source objects
11604      * into the destination object. Source properties that resolve to `undefined`
11605      * are skipped if a destination value exists. Array and plain object properties
11606      * are merged recursively. Other objects and value types are overridden by
11607      * assignment. Source objects are applied from left to right. Subsequent
11608      * sources overwrite property assignments of previous sources.
11609      *
11610      * **Note:** This method mutates `object`.
11611      *
11612      * @static
11613      * @memberOf _
11614      * @category Object
11615      * @param {Object} object The destination object.
11616      * @param {...Object} [sources] The source objects.
11617      * @returns {Object} Returns `object`.
11618      * @example
11619      *
11620      * var users = {
11621      *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
11622      * };
11623      *
11624      * var ages = {
11625      *   'data': [{ 'age': 36 }, { 'age': 40 }]
11626      * };
11627      *
11628      * _.merge(users, ages);
11629      * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
11630      */
11631     var merge = createAssigner(function(object, source, srcIndex) {
11632       baseMerge(object, source, srcIndex);
11633     });
11634
11635     /**
11636      * This method is like `_.merge` except that it accepts `customizer` which
11637      * is invoked to produce the merged values of the destination and source
11638      * properties. If `customizer` returns `undefined` merging is handled by the
11639      * method instead. The `customizer` is invoked with seven arguments:
11640      * (objValue, srcValue, key, object, source, stack).
11641      *
11642      * **Note:** This method mutates `object`.
11643      *
11644      * @static
11645      * @memberOf _
11646      * @category Object
11647      * @param {Object} object The destination object.
11648      * @param {...Object} sources The source objects.
11649      * @param {Function} customizer The function to customize assigned values.
11650      * @returns {Object} Returns `object`.
11651      * @example
11652      *
11653      * function customizer(objValue, srcValue) {
11654      *   if (_.isArray(objValue)) {
11655      *     return objValue.concat(srcValue);
11656      *   }
11657      * }
11658      *
11659      * var object = {
11660      *   'fruits': ['apple'],
11661      *   'vegetables': ['beet']
11662      * };
11663      *
11664      * var other = {
11665      *   'fruits': ['banana'],
11666      *   'vegetables': ['carrot']
11667      * };
11668      *
11669      * _.mergeWith(object, other, customizer);
11670      * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
11671      */
11672     var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
11673       baseMerge(object, source, srcIndex, customizer);
11674     });
11675
11676     /**
11677      * The opposite of `_.pick`; this method creates an object composed of the
11678      * own and inherited enumerable properties of `object` that are not omitted.
11679      *
11680      * @static
11681      * @memberOf _
11682      * @category Object
11683      * @param {Object} object The source object.
11684      * @param {...(string|string[])} [props] The property names to omit, specified
11685      *  individually or in arrays.
11686      * @returns {Object} Returns the new object.
11687      * @example
11688      *
11689      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11690      *
11691      * _.omit(object, ['a', 'c']);
11692      * // => { 'b': '2' }
11693      */
11694     var omit = rest(function(object, props) {
11695       if (object == null) {
11696         return {};
11697       }
11698       props = arrayMap(baseFlatten(props, 1), String);
11699       return basePick(object, baseDifference(keysIn(object), props));
11700     });
11701
11702     /**
11703      * The opposite of `_.pickBy`; this method creates an object composed of
11704      * the own and inherited enumerable properties of `object` that `predicate`
11705      * doesn't return truthy for. The predicate is invoked with two arguments:
11706      * (value, key).
11707      *
11708      * @static
11709      * @memberOf _
11710      * @category Object
11711      * @param {Object} object The source object.
11712      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11713      * @returns {Object} Returns the new object.
11714      * @example
11715      *
11716      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11717      *
11718      * _.omitBy(object, _.isNumber);
11719      * // => { 'b': '2' }
11720      */
11721     function omitBy(object, predicate) {
11722       predicate = getIteratee(predicate);
11723       return basePickBy(object, function(value, key) {
11724         return !predicate(value, key);
11725       });
11726     }
11727
11728     /**
11729      * Creates an object composed of the picked `object` properties.
11730      *
11731      * @static
11732      * @memberOf _
11733      * @category Object
11734      * @param {Object} object The source object.
11735      * @param {...(string|string[])} [props] The property names to pick, specified
11736      *  individually or in arrays.
11737      * @returns {Object} Returns the new object.
11738      * @example
11739      *
11740      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11741      *
11742      * _.pick(object, ['a', 'c']);
11743      * // => { 'a': 1, 'c': 3 }
11744      */
11745     var pick = rest(function(object, props) {
11746       return object == null ? {} : basePick(object, baseFlatten(props, 1));
11747     });
11748
11749     /**
11750      * Creates an object composed of the `object` properties `predicate` returns
11751      * truthy for. The predicate is invoked with two arguments: (value, key).
11752      *
11753      * @static
11754      * @memberOf _
11755      * @category Object
11756      * @param {Object} object The source object.
11757      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11758      * @returns {Object} Returns the new object.
11759      * @example
11760      *
11761      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11762      *
11763      * _.pickBy(object, _.isNumber);
11764      * // => { 'a': 1, 'c': 3 }
11765      */
11766     function pickBy(object, predicate) {
11767       return object == null ? {} : basePickBy(object, getIteratee(predicate));
11768     }
11769
11770     /**
11771      * This method is like `_.get` except that if the resolved value is a function
11772      * it's invoked with the `this` binding of its parent object and its result
11773      * is returned.
11774      *
11775      * @static
11776      * @memberOf _
11777      * @category Object
11778      * @param {Object} object The object to query.
11779      * @param {Array|string} path The path of the property to resolve.
11780      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11781      * @returns {*} Returns the resolved value.
11782      * @example
11783      *
11784      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
11785      *
11786      * _.result(object, 'a[0].b.c1');
11787      * // => 3
11788      *
11789      * _.result(object, 'a[0].b.c2');
11790      * // => 4
11791      *
11792      * _.result(object, 'a[0].b.c3', 'default');
11793      * // => 'default'
11794      *
11795      * _.result(object, 'a[0].b.c3', _.constant('default'));
11796      * // => 'default'
11797      */
11798     function result(object, path, defaultValue) {
11799       if (!isKey(path, object)) {
11800         path = baseCastPath(path);
11801         var result = get(object, path);
11802         object = parent(object, path);
11803       } else {
11804         result = object == null ? undefined : object[path];
11805       }
11806       if (result === undefined) {
11807         result = defaultValue;
11808       }
11809       return isFunction(result) ? result.call(object) : result;
11810     }
11811
11812     /**
11813      * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
11814      * it's created. Arrays are created for missing index properties while objects
11815      * are created for all other missing properties. Use `_.setWith` to customize
11816      * `path` creation.
11817      *
11818      * **Note:** This method mutates `object`.
11819      *
11820      * @static
11821      * @memberOf _
11822      * @category Object
11823      * @param {Object} object The object to modify.
11824      * @param {Array|string} path The path of the property to set.
11825      * @param {*} value The value to set.
11826      * @returns {Object} Returns `object`.
11827      * @example
11828      *
11829      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11830      *
11831      * _.set(object, 'a[0].b.c', 4);
11832      * console.log(object.a[0].b.c);
11833      * // => 4
11834      *
11835      * _.set(object, 'x[0].y.z', 5);
11836      * console.log(object.x[0].y.z);
11837      * // => 5
11838      */
11839     function set(object, path, value) {
11840       return object == null ? object : baseSet(object, path, value);
11841     }
11842
11843     /**
11844      * This method is like `_.set` except that it accepts `customizer` which is
11845      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
11846      * path creation is handled by the method instead. The `customizer` is invoked
11847      * with three arguments: (nsValue, key, nsObject).
11848      *
11849      * **Note:** This method mutates `object`.
11850      *
11851      * @static
11852      * @memberOf _
11853      * @category Object
11854      * @param {Object} object The object to modify.
11855      * @param {Array|string} path The path of the property to set.
11856      * @param {*} value The value to set.
11857      * @param {Function} [customizer] The function to customize assigned values.
11858      * @returns {Object} Returns `object`.
11859      * @example
11860      *
11861      * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
11862      * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
11863      */
11864     function setWith(object, path, value, customizer) {
11865       customizer = typeof customizer == 'function' ? customizer : undefined;
11866       return object == null ? object : baseSet(object, path, value, customizer);
11867     }
11868
11869     /**
11870      * Creates an array of own enumerable key-value pairs for `object` which
11871      * can be consumed by `_.fromPairs`.
11872      *
11873      * @static
11874      * @memberOf _
11875      * @category Object
11876      * @param {Object} object The object to query.
11877      * @returns {Array} Returns the new array of key-value pairs.
11878      * @example
11879      *
11880      * function Foo() {
11881      *   this.a = 1;
11882      *   this.b = 2;
11883      * }
11884      *
11885      * Foo.prototype.c = 3;
11886      *
11887      * _.toPairs(new Foo);
11888      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
11889      */
11890     function toPairs(object) {
11891       return baseToPairs(object, keys(object));
11892     }
11893
11894     /**
11895      * Creates an array of own and inherited enumerable key-value pairs for
11896      * `object` which can be consumed by `_.fromPairs`.
11897      *
11898      * @static
11899      * @memberOf _
11900      * @category Object
11901      * @param {Object} object The object to query.
11902      * @returns {Array} Returns the new array of key-value pairs.
11903      * @example
11904      *
11905      * function Foo() {
11906      *   this.a = 1;
11907      *   this.b = 2;
11908      * }
11909      *
11910      * Foo.prototype.c = 3;
11911      *
11912      * _.toPairsIn(new Foo);
11913      * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
11914      */
11915     function toPairsIn(object) {
11916       return baseToPairs(object, keysIn(object));
11917     }
11918
11919     /**
11920      * An alternative to `_.reduce`; this method transforms `object` to a new
11921      * `accumulator` object which is the result of running each of its own enumerable
11922      * properties through `iteratee`, with each invocation potentially mutating
11923      * the `accumulator` object. The iteratee is invoked with four arguments:
11924      * (accumulator, value, key, object). Iteratee functions may exit iteration
11925      * early by explicitly returning `false`.
11926      *
11927      * @static
11928      * @memberOf _
11929      * @category Object
11930      * @param {Array|Object} object The object to iterate over.
11931      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11932      * @param {*} [accumulator] The custom accumulator value.
11933      * @returns {*} Returns the accumulated value.
11934      * @example
11935      *
11936      * _.transform([2, 3, 4], function(result, n) {
11937      *   result.push(n *= n);
11938      *   return n % 2 == 0;
11939      * }, []);
11940      * // => [4, 9]
11941      *
11942      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
11943      *   (result[value] || (result[value] = [])).push(key);
11944      * }, {});
11945      * // => { '1': ['a', 'c'], '2': ['b'] }
11946      */
11947     function transform(object, iteratee, accumulator) {
11948       var isArr = isArray(object) || isTypedArray(object);
11949       iteratee = getIteratee(iteratee, 4);
11950
11951       if (accumulator == null) {
11952         if (isArr || isObject(object)) {
11953           var Ctor = object.constructor;
11954           if (isArr) {
11955             accumulator = isArray(object) ? new Ctor : [];
11956           } else {
11957             accumulator = isFunction(Ctor) ? baseCreate(getPrototypeOf(object)) : {};
11958           }
11959         } else {
11960           accumulator = {};
11961         }
11962       }
11963       (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
11964         return iteratee(accumulator, value, index, object);
11965       });
11966       return accumulator;
11967     }
11968
11969     /**
11970      * Removes the property at `path` of `object`.
11971      *
11972      * **Note:** This method mutates `object`.
11973      *
11974      * @static
11975      * @memberOf _
11976      * @category Object
11977      * @param {Object} object The object to modify.
11978      * @param {Array|string} path The path of the property to unset.
11979      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
11980      * @example
11981      *
11982      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
11983      * _.unset(object, 'a[0].b.c');
11984      * // => true
11985      *
11986      * console.log(object);
11987      * // => { 'a': [{ 'b': {} }] };
11988      *
11989      * _.unset(object, 'a[0].b.c');
11990      * // => true
11991      *
11992      * console.log(object);
11993      * // => { 'a': [{ 'b': {} }] };
11994      */
11995     function unset(object, path) {
11996       return object == null ? true : baseUnset(object, path);
11997     }
11998
11999     /**
12000      * Creates an array of the own enumerable property values of `object`.
12001      *
12002      * **Note:** Non-object values are coerced to objects.
12003      *
12004      * @static
12005      * @memberOf _
12006      * @category Object
12007      * @param {Object} object The object to query.
12008      * @returns {Array} Returns the array of property values.
12009      * @example
12010      *
12011      * function Foo() {
12012      *   this.a = 1;
12013      *   this.b = 2;
12014      * }
12015      *
12016      * Foo.prototype.c = 3;
12017      *
12018      * _.values(new Foo);
12019      * // => [1, 2] (iteration order is not guaranteed)
12020      *
12021      * _.values('hi');
12022      * // => ['h', 'i']
12023      */
12024     function values(object) {
12025       return object ? baseValues(object, keys(object)) : [];
12026     }
12027
12028     /**
12029      * Creates an array of the own and inherited enumerable property values of `object`.
12030      *
12031      * **Note:** Non-object values are coerced to objects.
12032      *
12033      * @static
12034      * @memberOf _
12035      * @category Object
12036      * @param {Object} object The object to query.
12037      * @returns {Array} Returns the array of property values.
12038      * @example
12039      *
12040      * function Foo() {
12041      *   this.a = 1;
12042      *   this.b = 2;
12043      * }
12044      *
12045      * Foo.prototype.c = 3;
12046      *
12047      * _.valuesIn(new Foo);
12048      * // => [1, 2, 3] (iteration order is not guaranteed)
12049      */
12050     function valuesIn(object) {
12051       return object == null ? [] : baseValues(object, keysIn(object));
12052     }
12053
12054     /*------------------------------------------------------------------------*/
12055
12056     /**
12057      * Clamps `number` within the inclusive `lower` and `upper` bounds.
12058      *
12059      * @static
12060      * @memberOf _
12061      * @category Number
12062      * @param {number} number The number to clamp.
12063      * @param {number} [lower] The lower bound.
12064      * @param {number} upper The upper bound.
12065      * @returns {number} Returns the clamped number.
12066      * @example
12067      *
12068      * _.clamp(-10, -5, 5);
12069      * // => -5
12070      *
12071      * _.clamp(10, -5, 5);
12072      * // => 5
12073      */
12074     function clamp(number, lower, upper) {
12075       if (upper === undefined) {
12076         upper = lower;
12077         lower = undefined;
12078       }
12079       if (upper !== undefined) {
12080         upper = toNumber(upper);
12081         upper = upper === upper ? upper : 0;
12082       }
12083       if (lower !== undefined) {
12084         lower = toNumber(lower);
12085         lower = lower === lower ? lower : 0;
12086       }
12087       return baseClamp(toNumber(number), lower, upper);
12088     }
12089
12090     /**
12091      * Checks if `n` is between `start` and up to but not including, `end`. If
12092      * `end` is not specified it's set to `start` with `start` then set to `0`.
12093      * If `start` is greater than `end` the params are swapped to support
12094      * negative ranges.
12095      *
12096      * @static
12097      * @memberOf _
12098      * @category Number
12099      * @param {number} number The number to check.
12100      * @param {number} [start=0] The start of the range.
12101      * @param {number} end The end of the range.
12102      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
12103      * @example
12104      *
12105      * _.inRange(3, 2, 4);
12106      * // => true
12107      *
12108      * _.inRange(4, 8);
12109      * // => true
12110      *
12111      * _.inRange(4, 2);
12112      * // => false
12113      *
12114      * _.inRange(2, 2);
12115      * // => false
12116      *
12117      * _.inRange(1.2, 2);
12118      * // => true
12119      *
12120      * _.inRange(5.2, 4);
12121      * // => false
12122      *
12123      * _.inRange(-3, -2, -6);
12124      * // => true
12125      */
12126     function inRange(number, start, end) {
12127       start = toNumber(start) || 0;
12128       if (end === undefined) {
12129         end = start;
12130         start = 0;
12131       } else {
12132         end = toNumber(end) || 0;
12133       }
12134       number = toNumber(number);
12135       return baseInRange(number, start, end);
12136     }
12137
12138     /**
12139      * Produces a random number between the inclusive `lower` and `upper` bounds.
12140      * If only one argument is provided a number between `0` and the given number
12141      * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
12142      * a floating-point number is returned instead of an integer.
12143      *
12144      * **Note:** JavaScript follows the IEEE-754 standard for resolving
12145      * floating-point values which can produce unexpected results.
12146      *
12147      * @static
12148      * @memberOf _
12149      * @category Number
12150      * @param {number} [lower=0] The lower bound.
12151      * @param {number} [upper=1] The upper bound.
12152      * @param {boolean} [floating] Specify returning a floating-point number.
12153      * @returns {number} Returns the random number.
12154      * @example
12155      *
12156      * _.random(0, 5);
12157      * // => an integer between 0 and 5
12158      *
12159      * _.random(5);
12160      * // => also an integer between 0 and 5
12161      *
12162      * _.random(5, true);
12163      * // => a floating-point number between 0 and 5
12164      *
12165      * _.random(1.2, 5.2);
12166      * // => a floating-point number between 1.2 and 5.2
12167      */
12168     function random(lower, upper, floating) {
12169       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
12170         upper = floating = undefined;
12171       }
12172       if (floating === undefined) {
12173         if (typeof upper == 'boolean') {
12174           floating = upper;
12175           upper = undefined;
12176         }
12177         else if (typeof lower == 'boolean') {
12178           floating = lower;
12179           lower = undefined;
12180         }
12181       }
12182       if (lower === undefined && upper === undefined) {
12183         lower = 0;
12184         upper = 1;
12185       }
12186       else {
12187         lower = toNumber(lower) || 0;
12188         if (upper === undefined) {
12189           upper = lower;
12190           lower = 0;
12191         } else {
12192           upper = toNumber(upper) || 0;
12193         }
12194       }
12195       if (lower > upper) {
12196         var temp = lower;
12197         lower = upper;
12198         upper = temp;
12199       }
12200       if (floating || lower % 1 || upper % 1) {
12201         var rand = nativeRandom();
12202         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
12203       }
12204       return baseRandom(lower, upper);
12205     }
12206
12207     /*------------------------------------------------------------------------*/
12208
12209     /**
12210      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
12211      *
12212      * @static
12213      * @memberOf _
12214      * @category String
12215      * @param {string} [string=''] The string to convert.
12216      * @returns {string} Returns the camel cased string.
12217      * @example
12218      *
12219      * _.camelCase('Foo Bar');
12220      * // => 'fooBar'
12221      *
12222      * _.camelCase('--foo-bar');
12223      * // => 'fooBar'
12224      *
12225      * _.camelCase('__foo_bar__');
12226      * // => 'fooBar'
12227      */
12228     var camelCase = createCompounder(function(result, word, index) {
12229       word = word.toLowerCase();
12230       return result + (index ? capitalize(word) : word);
12231     });
12232
12233     /**
12234      * Converts the first character of `string` to upper case and the remaining
12235      * to lower case.
12236      *
12237      * @static
12238      * @memberOf _
12239      * @category String
12240      * @param {string} [string=''] The string to capitalize.
12241      * @returns {string} Returns the capitalized string.
12242      * @example
12243      *
12244      * _.capitalize('FRED');
12245      * // => 'Fred'
12246      */
12247     function capitalize(string) {
12248       return upperFirst(toString(string).toLowerCase());
12249     }
12250
12251     /**
12252      * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
12253      * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
12254      *
12255      * @static
12256      * @memberOf _
12257      * @category String
12258      * @param {string} [string=''] The string to deburr.
12259      * @returns {string} Returns the deburred string.
12260      * @example
12261      *
12262      * _.deburr('déjà vu');
12263      * // => 'deja vu'
12264      */
12265     function deburr(string) {
12266       string = toString(string);
12267       return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
12268     }
12269
12270     /**
12271      * Checks if `string` ends with the given target string.
12272      *
12273      * @static
12274      * @memberOf _
12275      * @category String
12276      * @param {string} [string=''] The string to search.
12277      * @param {string} [target] The string to search for.
12278      * @param {number} [position=string.length] The position to search from.
12279      * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
12280      * @example
12281      *
12282      * _.endsWith('abc', 'c');
12283      * // => true
12284      *
12285      * _.endsWith('abc', 'b');
12286      * // => false
12287      *
12288      * _.endsWith('abc', 'b', 2);
12289      * // => true
12290      */
12291     function endsWith(string, target, position) {
12292       string = toString(string);
12293       target = typeof target == 'string' ? target : (target + '');
12294
12295       var length = string.length;
12296       position = position === undefined
12297         ? length
12298         : baseClamp(toInteger(position), 0, length);
12299
12300       position -= target.length;
12301       return position >= 0 && string.indexOf(target, position) == position;
12302     }
12303
12304     /**
12305      * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
12306      * their corresponding HTML entities.
12307      *
12308      * **Note:** No other characters are escaped. To escape additional
12309      * characters use a third-party library like [_he_](https://mths.be/he).
12310      *
12311      * Though the ">" character is escaped for symmetry, characters like
12312      * ">" and "/" don't need escaping in HTML and have no special meaning
12313      * unless they're part of a tag or unquoted attribute value.
12314      * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
12315      * (under "semi-related fun fact") for more details.
12316      *
12317      * Backticks are escaped because in IE < 9, they can break out of
12318      * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
12319      * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
12320      * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
12321      * for more details.
12322      *
12323      * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
12324      * to reduce XSS vectors.
12325      *
12326      * @static
12327      * @memberOf _
12328      * @category String
12329      * @param {string} [string=''] The string to escape.
12330      * @returns {string} Returns the escaped string.
12331      * @example
12332      *
12333      * _.escape('fred, barney, & pebbles');
12334      * // => 'fred, barney, &amp; pebbles'
12335      */
12336     function escape(string) {
12337       string = toString(string);
12338       return (string && reHasUnescapedHtml.test(string))
12339         ? string.replace(reUnescapedHtml, escapeHtmlChar)
12340         : string;
12341     }
12342
12343     /**
12344      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
12345      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
12346      *
12347      * @static
12348      * @memberOf _
12349      * @category String
12350      * @param {string} [string=''] The string to escape.
12351      * @returns {string} Returns the escaped string.
12352      * @example
12353      *
12354      * _.escapeRegExp('[lodash](https://lodash.com/)');
12355      * // => '\[lodash\]\(https://lodash\.com/\)'
12356      */
12357     function escapeRegExp(string) {
12358       string = toString(string);
12359       return (string && reHasRegExpChar.test(string))
12360         ? string.replace(reRegExpChar, '\\$&')
12361         : string;
12362     }
12363
12364     /**
12365      * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
12366      *
12367      * @static
12368      * @memberOf _
12369      * @category String
12370      * @param {string} [string=''] The string to convert.
12371      * @returns {string} Returns the kebab cased string.
12372      * @example
12373      *
12374      * _.kebabCase('Foo Bar');
12375      * // => 'foo-bar'
12376      *
12377      * _.kebabCase('fooBar');
12378      * // => 'foo-bar'
12379      *
12380      * _.kebabCase('__foo_bar__');
12381      * // => 'foo-bar'
12382      */
12383     var kebabCase = createCompounder(function(result, word, index) {
12384       return result + (index ? '-' : '') + word.toLowerCase();
12385     });
12386
12387     /**
12388      * Converts `string`, as space separated words, to lower case.
12389      *
12390      * @static
12391      * @memberOf _
12392      * @category String
12393      * @param {string} [string=''] The string to convert.
12394      * @returns {string} Returns the lower cased string.
12395      * @example
12396      *
12397      * _.lowerCase('--Foo-Bar');
12398      * // => 'foo bar'
12399      *
12400      * _.lowerCase('fooBar');
12401      * // => 'foo bar'
12402      *
12403      * _.lowerCase('__FOO_BAR__');
12404      * // => 'foo bar'
12405      */
12406     var lowerCase = createCompounder(function(result, word, index) {
12407       return result + (index ? ' ' : '') + word.toLowerCase();
12408     });
12409
12410     /**
12411      * Converts the first character of `string` to lower case.
12412      *
12413      * @static
12414      * @memberOf _
12415      * @category String
12416      * @param {string} [string=''] The string to convert.
12417      * @returns {string} Returns the converted string.
12418      * @example
12419      *
12420      * _.lowerFirst('Fred');
12421      * // => 'fred'
12422      *
12423      * _.lowerFirst('FRED');
12424      * // => 'fRED'
12425      */
12426     var lowerFirst = createCaseFirst('toLowerCase');
12427
12428     /**
12429      * Converts the first character of `string` to upper case.
12430      *
12431      * @static
12432      * @memberOf _
12433      * @category String
12434      * @param {string} [string=''] The string to convert.
12435      * @returns {string} Returns the converted string.
12436      * @example
12437      *
12438      * _.upperFirst('fred');
12439      * // => 'Fred'
12440      *
12441      * _.upperFirst('FRED');
12442      * // => 'FRED'
12443      */
12444     var upperFirst = createCaseFirst('toUpperCase');
12445
12446     /**
12447      * Pads `string` on the left and right sides if it's shorter than `length`.
12448      * Padding characters are truncated if they can't be evenly divided by `length`.
12449      *
12450      * @static
12451      * @memberOf _
12452      * @category String
12453      * @param {string} [string=''] The string to pad.
12454      * @param {number} [length=0] The padding length.
12455      * @param {string} [chars=' '] The string used as padding.
12456      * @returns {string} Returns the padded string.
12457      * @example
12458      *
12459      * _.pad('abc', 8);
12460      * // => '  abc   '
12461      *
12462      * _.pad('abc', 8, '_-');
12463      * // => '_-abc_-_'
12464      *
12465      * _.pad('abc', 3);
12466      * // => 'abc'
12467      */
12468     function pad(string, length, chars) {
12469       string = toString(string);
12470       length = toInteger(length);
12471
12472       var strLength = stringSize(string);
12473       if (!length || strLength >= length) {
12474         return string;
12475       }
12476       var mid = (length - strLength) / 2,
12477           leftLength = nativeFloor(mid),
12478           rightLength = nativeCeil(mid);
12479
12480       return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
12481     }
12482
12483     /**
12484      * Pads `string` on the right side if it's shorter than `length`. Padding
12485      * characters are truncated if they exceed `length`.
12486      *
12487      * @static
12488      * @memberOf _
12489      * @category String
12490      * @param {string} [string=''] The string to pad.
12491      * @param {number} [length=0] The padding length.
12492      * @param {string} [chars=' '] The string used as padding.
12493      * @returns {string} Returns the padded string.
12494      * @example
12495      *
12496      * _.padEnd('abc', 6);
12497      * // => 'abc   '
12498      *
12499      * _.padEnd('abc', 6, '_-');
12500      * // => 'abc_-_'
12501      *
12502      * _.padEnd('abc', 3);
12503      * // => 'abc'
12504      */
12505     function padEnd(string, length, chars) {
12506       string = toString(string);
12507       return string + createPadding(string, length, chars);
12508     }
12509
12510     /**
12511      * Pads `string` on the left side if it's shorter than `length`. Padding
12512      * characters are truncated if they exceed `length`.
12513      *
12514      * @static
12515      * @memberOf _
12516      * @category String
12517      * @param {string} [string=''] The string to pad.
12518      * @param {number} [length=0] The padding length.
12519      * @param {string} [chars=' '] The string used as padding.
12520      * @returns {string} Returns the padded string.
12521      * @example
12522      *
12523      * _.padStart('abc', 6);
12524      * // => '   abc'
12525      *
12526      * _.padStart('abc', 6, '_-');
12527      * // => '_-_abc'
12528      *
12529      * _.padStart('abc', 3);
12530      * // => 'abc'
12531      */
12532     function padStart(string, length, chars) {
12533       string = toString(string);
12534       return createPadding(string, length, chars) + string;
12535     }
12536
12537     /**
12538      * Converts `string` to an integer of the specified radix. If `radix` is
12539      * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
12540      * in which case a `radix` of `16` is used.
12541      *
12542      * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2)
12543      * of `parseInt`.
12544      *
12545      * @static
12546      * @memberOf _
12547      * @category String
12548      * @param {string} string The string to convert.
12549      * @param {number} [radix=10] The radix to interpret `value` by.
12550      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12551      * @returns {number} Returns the converted integer.
12552      * @example
12553      *
12554      * _.parseInt('08');
12555      * // => 8
12556      *
12557      * _.map(['6', '08', '10'], _.parseInt);
12558      * // => [6, 8, 10]
12559      */
12560     function parseInt(string, radix, guard) {
12561       // Chrome fails to trim leading <BOM> whitespace characters.
12562       // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
12563       if (guard || radix == null) {
12564         radix = 0;
12565       } else if (radix) {
12566         radix = +radix;
12567       }
12568       string = toString(string).replace(reTrim, '');
12569       return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
12570     }
12571
12572     /**
12573      * Repeats the given string `n` times.
12574      *
12575      * @static
12576      * @memberOf _
12577      * @category String
12578      * @param {string} [string=''] The string to repeat.
12579      * @param {number} [n=0] The number of times to repeat the string.
12580      * @returns {string} Returns the repeated string.
12581      * @example
12582      *
12583      * _.repeat('*', 3);
12584      * // => '***'
12585      *
12586      * _.repeat('abc', 2);
12587      * // => 'abcabc'
12588      *
12589      * _.repeat('abc', 0);
12590      * // => ''
12591      */
12592     function repeat(string, n) {
12593       string = toString(string);
12594       n = toInteger(n);
12595
12596       var result = '';
12597       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
12598         return result;
12599       }
12600       // Leverage the exponentiation by squaring algorithm for a faster repeat.
12601       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
12602       do {
12603         if (n % 2) {
12604           result += string;
12605         }
12606         n = nativeFloor(n / 2);
12607         string += string;
12608       } while (n);
12609
12610       return result;
12611     }
12612
12613     /**
12614      * Replaces matches for `pattern` in `string` with `replacement`.
12615      *
12616      * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
12617      *
12618      * @static
12619      * @memberOf _
12620      * @category String
12621      * @param {string} [string=''] The string to modify.
12622      * @param {RegExp|string} pattern The pattern to replace.
12623      * @param {Function|string} replacement The match replacement.
12624      * @returns {string} Returns the modified string.
12625      * @example
12626      *
12627      * _.replace('Hi Fred', 'Fred', 'Barney');
12628      * // => 'Hi Barney'
12629      */
12630     function replace() {
12631       var args = arguments,
12632           string = toString(args[0]);
12633
12634       return args.length < 3 ? string : string.replace(args[1], args[2]);
12635     }
12636
12637     /**
12638      * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
12639      *
12640      * @static
12641      * @memberOf _
12642      * @category String
12643      * @param {string} [string=''] The string to convert.
12644      * @returns {string} Returns the snake cased string.
12645      * @example
12646      *
12647      * _.snakeCase('Foo Bar');
12648      * // => 'foo_bar'
12649      *
12650      * _.snakeCase('fooBar');
12651      * // => 'foo_bar'
12652      *
12653      * _.snakeCase('--foo-bar');
12654      * // => 'foo_bar'
12655      */
12656     var snakeCase = createCompounder(function(result, word, index) {
12657       return result + (index ? '_' : '') + word.toLowerCase();
12658     });
12659
12660     /**
12661      * Splits `string` by `separator`.
12662      *
12663      * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
12664      *
12665      * @static
12666      * @memberOf _
12667      * @category String
12668      * @param {string} [string=''] The string to split.
12669      * @param {RegExp|string} separator The separator pattern to split by.
12670      * @param {number} [limit] The length to truncate results to.
12671      * @returns {Array} Returns the new array of string segments.
12672      * @example
12673      *
12674      * _.split('a-b-c', '-', 2);
12675      * // => ['a', 'b']
12676      */
12677     function split(string, separator, limit) {
12678       return toString(string).split(separator, limit);
12679     }
12680
12681     /**
12682      * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
12683      *
12684      * @static
12685      * @memberOf _
12686      * @category String
12687      * @param {string} [string=''] The string to convert.
12688      * @returns {string} Returns the start cased string.
12689      * @example
12690      *
12691      * _.startCase('--foo-bar');
12692      * // => 'Foo Bar'
12693      *
12694      * _.startCase('fooBar');
12695      * // => 'Foo Bar'
12696      *
12697      * _.startCase('__foo_bar__');
12698      * // => 'Foo Bar'
12699      */
12700     var startCase = createCompounder(function(result, word, index) {
12701       return result + (index ? ' ' : '') + capitalize(word);
12702     });
12703
12704     /**
12705      * Checks if `string` starts with the given target string.
12706      *
12707      * @static
12708      * @memberOf _
12709      * @category String
12710      * @param {string} [string=''] The string to search.
12711      * @param {string} [target] The string to search for.
12712      * @param {number} [position=0] The position to search from.
12713      * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
12714      * @example
12715      *
12716      * _.startsWith('abc', 'a');
12717      * // => true
12718      *
12719      * _.startsWith('abc', 'b');
12720      * // => false
12721      *
12722      * _.startsWith('abc', 'b', 1);
12723      * // => true
12724      */
12725     function startsWith(string, target, position) {
12726       string = toString(string);
12727       position = baseClamp(toInteger(position), 0, string.length);
12728       return string.lastIndexOf(target, position) == position;
12729     }
12730
12731     /**
12732      * Creates a compiled template function that can interpolate data properties
12733      * in "interpolate" delimiters, HTML-escape interpolated data properties in
12734      * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
12735      * properties may be accessed as free variables in the template. If a setting
12736      * object is given it takes precedence over `_.templateSettings` values.
12737      *
12738      * **Note:** In the development build `_.template` utilizes
12739      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
12740      * for easier debugging.
12741      *
12742      * For more information on precompiling templates see
12743      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
12744      *
12745      * For more information on Chrome extension sandboxes see
12746      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
12747      *
12748      * @static
12749      * @memberOf _
12750      * @category String
12751      * @param {string} [string=''] The template string.
12752      * @param {Object} [options] The options object.
12753      * @param {RegExp} [options.escape] The HTML "escape" delimiter.
12754      * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
12755      * @param {Object} [options.imports] An object to import into the template as free variables.
12756      * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
12757      * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
12758      * @param {string} [options.variable] The data object variable name.
12759      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12760      * @returns {Function} Returns the compiled template function.
12761      * @example
12762      *
12763      * // Use the "interpolate" delimiter to create a compiled template.
12764      * var compiled = _.template('hello <%= user %>!');
12765      * compiled({ 'user': 'fred' });
12766      * // => 'hello fred!'
12767      *
12768      * // Use the HTML "escape" delimiter to escape data property values.
12769      * var compiled = _.template('<b><%- value %></b>');
12770      * compiled({ 'value': '<script>' });
12771      * // => '<b>&lt;script&gt;</b>'
12772      *
12773      * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
12774      * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
12775      * compiled({ 'users': ['fred', 'barney'] });
12776      * // => '<li>fred</li><li>barney</li>'
12777      *
12778      * // Use the internal `print` function in "evaluate" delimiters.
12779      * var compiled = _.template('<% print("hello " + user); %>!');
12780      * compiled({ 'user': 'barney' });
12781      * // => 'hello barney!'
12782      *
12783      * // Use the ES delimiter as an alternative to the default "interpolate" delimiter.
12784      * var compiled = _.template('hello ${ user }!');
12785      * compiled({ 'user': 'pebbles' });
12786      * // => 'hello pebbles!'
12787      *
12788      * // Use custom template delimiters.
12789      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
12790      * var compiled = _.template('hello {{ user }}!');
12791      * compiled({ 'user': 'mustache' });
12792      * // => 'hello mustache!'
12793      *
12794      * // Use backslashes to treat delimiters as plain text.
12795      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
12796      * compiled({ 'value': 'ignored' });
12797      * // => '<%- value %>'
12798      *
12799      * // Use the `imports` option to import `jQuery` as `jq`.
12800      * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
12801      * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
12802      * compiled({ 'users': ['fred', 'barney'] });
12803      * // => '<li>fred</li><li>barney</li>'
12804      *
12805      * // Use the `sourceURL` option to specify a custom sourceURL for the template.
12806      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
12807      * compiled(data);
12808      * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
12809      *
12810      * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
12811      * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
12812      * compiled.source;
12813      * // => function(data) {
12814      * //   var __t, __p = '';
12815      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
12816      * //   return __p;
12817      * // }
12818      *
12819      * // Use the `source` property to inline compiled templates for meaningful
12820      * // line numbers in error messages and stack traces.
12821      * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
12822      *   var JST = {\
12823      *     "main": ' + _.template(mainText).source + '\
12824      *   };\
12825      * ');
12826      */
12827     function template(string, options, guard) {
12828       // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
12829       // and Laura Doktorova's doT.js (https://github.com/olado/doT).
12830       var settings = lodash.templateSettings;
12831
12832       if (guard && isIterateeCall(string, options, guard)) {
12833         options = undefined;
12834       }
12835       string = toString(string);
12836       options = assignInWith({}, options, settings, assignInDefaults);
12837
12838       var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
12839           importsKeys = keys(imports),
12840           importsValues = baseValues(imports, importsKeys);
12841
12842       var isEscaping,
12843           isEvaluating,
12844           index = 0,
12845           interpolate = options.interpolate || reNoMatch,
12846           source = "__p += '";
12847
12848       // Compile the regexp to match each delimiter.
12849       var reDelimiters = RegExp(
12850         (options.escape || reNoMatch).source + '|' +
12851         interpolate.source + '|' +
12852         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
12853         (options.evaluate || reNoMatch).source + '|$'
12854       , 'g');
12855
12856       // Use a sourceURL for easier debugging.
12857       var sourceURL = '//# sourceURL=' +
12858         ('sourceURL' in options
12859           ? options.sourceURL
12860           : ('lodash.templateSources[' + (++templateCounter) + ']')
12861         ) + '\n';
12862
12863       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
12864         interpolateValue || (interpolateValue = esTemplateValue);
12865
12866         // Escape characters that can't be included in string literals.
12867         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
12868
12869         // Replace delimiters with snippets.
12870         if (escapeValue) {
12871           isEscaping = true;
12872           source += "' +\n__e(" + escapeValue + ") +\n'";
12873         }
12874         if (evaluateValue) {
12875           isEvaluating = true;
12876           source += "';\n" + evaluateValue + ";\n__p += '";
12877         }
12878         if (interpolateValue) {
12879           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
12880         }
12881         index = offset + match.length;
12882
12883         // The JS engine embedded in Adobe products needs `match` returned in
12884         // order to produce the correct `offset` value.
12885         return match;
12886       });
12887
12888       source += "';\n";
12889
12890       // If `variable` is not specified wrap a with-statement around the generated
12891       // code to add the data object to the top of the scope chain.
12892       var variable = options.variable;
12893       if (!variable) {
12894         source = 'with (obj) {\n' + source + '\n}\n';
12895       }
12896       // Cleanup code by stripping empty strings.
12897       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
12898         .replace(reEmptyStringMiddle, '$1')
12899         .replace(reEmptyStringTrailing, '$1;');
12900
12901       // Frame code as the function body.
12902       source = 'function(' + (variable || 'obj') + ') {\n' +
12903         (variable
12904           ? ''
12905           : 'obj || (obj = {});\n'
12906         ) +
12907         "var __t, __p = ''" +
12908         (isEscaping
12909            ? ', __e = _.escape'
12910            : ''
12911         ) +
12912         (isEvaluating
12913           ? ', __j = Array.prototype.join;\n' +
12914             "function print() { __p += __j.call(arguments, '') }\n"
12915           : ';\n'
12916         ) +
12917         source +
12918         'return __p\n}';
12919
12920       var result = attempt(function() {
12921         return Function(importsKeys, sourceURL + 'return ' + source)
12922           .apply(undefined, importsValues);
12923       });
12924
12925       // Provide the compiled function's source by its `toString` method or
12926       // the `source` property as a convenience for inlining compiled templates.
12927       result.source = source;
12928       if (isError(result)) {
12929         throw result;
12930       }
12931       return result;
12932     }
12933
12934     /**
12935      * Converts `string`, as a whole, to lower case.
12936      *
12937      * @static
12938      * @memberOf _
12939      * @category String
12940      * @param {string} [string=''] The string to convert.
12941      * @returns {string} Returns the lower cased string.
12942      * @example
12943      *
12944      * _.toLower('--Foo-Bar');
12945      * // => '--foo-bar'
12946      *
12947      * _.toLower('fooBar');
12948      * // => 'foobar'
12949      *
12950      * _.toLower('__FOO_BAR__');
12951      * // => '__foo_bar__'
12952      */
12953     function toLower(value) {
12954       return toString(value).toLowerCase();
12955     }
12956
12957     /**
12958      * Converts `string`, as a whole, to upper case.
12959      *
12960      * @static
12961      * @memberOf _
12962      * @category String
12963      * @param {string} [string=''] The string to convert.
12964      * @returns {string} Returns the upper cased string.
12965      * @example
12966      *
12967      * _.toUpper('--foo-bar');
12968      * // => '--FOO-BAR'
12969      *
12970      * _.toUpper('fooBar');
12971      * // => 'FOOBAR'
12972      *
12973      * _.toUpper('__foo_bar__');
12974      * // => '__FOO_BAR__'
12975      */
12976     function toUpper(value) {
12977       return toString(value).toUpperCase();
12978     }
12979
12980     /**
12981      * Removes leading and trailing whitespace or specified characters from `string`.
12982      *
12983      * @static
12984      * @memberOf _
12985      * @category String
12986      * @param {string} [string=''] The string to trim.
12987      * @param {string} [chars=whitespace] The characters to trim.
12988      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12989      * @returns {string} Returns the trimmed string.
12990      * @example
12991      *
12992      * _.trim('  abc  ');
12993      * // => 'abc'
12994      *
12995      * _.trim('-_-abc-_-', '_-');
12996      * // => 'abc'
12997      *
12998      * _.map(['  foo  ', '  bar  '], _.trim);
12999      * // => ['foo', 'bar']
13000      */
13001     function trim(string, chars, guard) {
13002       string = toString(string);
13003       if (!string) {
13004         return string;
13005       }
13006       if (guard || chars === undefined) {
13007         return string.replace(reTrim, '');
13008       }
13009       chars = (chars + '');
13010       if (!chars) {
13011         return string;
13012       }
13013       var strSymbols = stringToArray(string),
13014           chrSymbols = stringToArray(chars);
13015
13016       return strSymbols
13017         .slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1)
13018         .join('');
13019     }
13020
13021     /**
13022      * Removes trailing whitespace or specified characters from `string`.
13023      *
13024      * @static
13025      * @memberOf _
13026      * @category String
13027      * @param {string} [string=''] The string to trim.
13028      * @param {string} [chars=whitespace] The characters to trim.
13029      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
13030      * @returns {string} Returns the trimmed string.
13031      * @example
13032      *
13033      * _.trimEnd('  abc  ');
13034      * // => '  abc'
13035      *
13036      * _.trimEnd('-_-abc-_-', '_-');
13037      * // => '-_-abc'
13038      */
13039     function trimEnd(string, chars, guard) {
13040       string = toString(string);
13041       if (!string) {
13042         return string;
13043       }
13044       if (guard || chars === undefined) {
13045         return string.replace(reTrimEnd, '');
13046       }
13047       chars = (chars + '');
13048       if (!chars) {
13049         return string;
13050       }
13051       var strSymbols = stringToArray(string);
13052       return strSymbols
13053         .slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1)
13054         .join('');
13055     }
13056
13057     /**
13058      * Removes leading whitespace or specified characters from `string`.
13059      *
13060      * @static
13061      * @memberOf _
13062      * @category String
13063      * @param {string} [string=''] The string to trim.
13064      * @param {string} [chars=whitespace] The characters to trim.
13065      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
13066      * @returns {string} Returns the trimmed string.
13067      * @example
13068      *
13069      * _.trimStart('  abc  ');
13070      * // => 'abc  '
13071      *
13072      * _.trimStart('-_-abc-_-', '_-');
13073      * // => 'abc-_-'
13074      */
13075     function trimStart(string, chars, guard) {
13076       string = toString(string);
13077       if (!string) {
13078         return string;
13079       }
13080       if (guard || chars === undefined) {
13081         return string.replace(reTrimStart, '');
13082       }
13083       chars = (chars + '');
13084       if (!chars) {
13085         return string;
13086       }
13087       var strSymbols = stringToArray(string);
13088       return strSymbols
13089         .slice(charsStartIndex(strSymbols, stringToArray(chars)))
13090         .join('');
13091     }
13092
13093     /**
13094      * Truncates `string` if it's longer than the given maximum string length.
13095      * The last characters of the truncated string are replaced with the omission
13096      * string which defaults to "...".
13097      *
13098      * @static
13099      * @memberOf _
13100      * @category String
13101      * @param {string} [string=''] The string to truncate.
13102      * @param {Object} [options=({})] The options object.
13103      * @param {number} [options.length=30] The maximum string length.
13104      * @param {string} [options.omission='...'] The string to indicate text is omitted.
13105      * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
13106      * @returns {string} Returns the truncated string.
13107      * @example
13108      *
13109      * _.truncate('hi-diddly-ho there, neighborino');
13110      * // => 'hi-diddly-ho there, neighbo...'
13111      *
13112      * _.truncate('hi-diddly-ho there, neighborino', {
13113      *   'length': 24,
13114      *   'separator': ' '
13115      * });
13116      * // => 'hi-diddly-ho there,...'
13117      *
13118      * _.truncate('hi-diddly-ho there, neighborino', {
13119      *   'length': 24,
13120      *   'separator': /,? +/
13121      * });
13122      * // => 'hi-diddly-ho there...'
13123      *
13124      * _.truncate('hi-diddly-ho there, neighborino', {
13125      *   'omission': ' [...]'
13126      * });
13127      * // => 'hi-diddly-ho there, neig [...]'
13128      */
13129     function truncate(string, options) {
13130       var length = DEFAULT_TRUNC_LENGTH,
13131           omission = DEFAULT_TRUNC_OMISSION;
13132
13133       if (isObject(options)) {
13134         var separator = 'separator' in options ? options.separator : separator;
13135         length = 'length' in options ? toInteger(options.length) : length;
13136         omission = 'omission' in options ? toString(options.omission) : omission;
13137       }
13138       string = toString(string);
13139
13140       var strLength = string.length;
13141       if (reHasComplexSymbol.test(string)) {
13142         var strSymbols = stringToArray(string);
13143         strLength = strSymbols.length;
13144       }
13145       if (length >= strLength) {
13146         return string;
13147       }
13148       var end = length - stringSize(omission);
13149       if (end < 1) {
13150         return omission;
13151       }
13152       var result = strSymbols
13153         ? strSymbols.slice(0, end).join('')
13154         : string.slice(0, end);
13155
13156       if (separator === undefined) {
13157         return result + omission;
13158       }
13159       if (strSymbols) {
13160         end += (result.length - end);
13161       }
13162       if (isRegExp(separator)) {
13163         if (string.slice(end).search(separator)) {
13164           var match,
13165               substring = result;
13166
13167           if (!separator.global) {
13168             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
13169           }
13170           separator.lastIndex = 0;
13171           while ((match = separator.exec(substring))) {
13172             var newEnd = match.index;
13173           }
13174           result = result.slice(0, newEnd === undefined ? end : newEnd);
13175         }
13176       } else if (string.indexOf(separator, end) != end) {
13177         var index = result.lastIndexOf(separator);
13178         if (index > -1) {
13179           result = result.slice(0, index);
13180         }
13181       }
13182       return result + omission;
13183     }
13184
13185     /**
13186      * The inverse of `_.escape`; this method converts the HTML entities
13187      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their
13188      * corresponding characters.
13189      *
13190      * **Note:** No other HTML entities are unescaped. To unescape additional HTML
13191      * entities use a third-party library like [_he_](https://mths.be/he).
13192      *
13193      * @static
13194      * @memberOf _
13195      * @category String
13196      * @param {string} [string=''] The string to unescape.
13197      * @returns {string} Returns the unescaped string.
13198      * @example
13199      *
13200      * _.unescape('fred, barney, &amp; pebbles');
13201      * // => 'fred, barney, & pebbles'
13202      */
13203     function unescape(string) {
13204       string = toString(string);
13205       return (string && reHasEscapedHtml.test(string))
13206         ? string.replace(reEscapedHtml, unescapeHtmlChar)
13207         : string;
13208     }
13209
13210     /**
13211      * Converts `string`, as space separated words, to upper case.
13212      *
13213      * @static
13214      * @memberOf _
13215      * @category String
13216      * @param {string} [string=''] The string to convert.
13217      * @returns {string} Returns the upper cased string.
13218      * @example
13219      *
13220      * _.upperCase('--foo-bar');
13221      * // => 'FOO BAR'
13222      *
13223      * _.upperCase('fooBar');
13224      * // => 'FOO BAR'
13225      *
13226      * _.upperCase('__foo_bar__');
13227      * // => 'FOO BAR'
13228      */
13229     var upperCase = createCompounder(function(result, word, index) {
13230       return result + (index ? ' ' : '') + word.toUpperCase();
13231     });
13232
13233     /**
13234      * Splits `string` into an array of its words.
13235      *
13236      * @static
13237      * @memberOf _
13238      * @category String
13239      * @param {string} [string=''] The string to inspect.
13240      * @param {RegExp|string} [pattern] The pattern to match words.
13241      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
13242      * @returns {Array} Returns the words of `string`.
13243      * @example
13244      *
13245      * _.words('fred, barney, & pebbles');
13246      * // => ['fred', 'barney', 'pebbles']
13247      *
13248      * _.words('fred, barney, & pebbles', /[^, ]+/g);
13249      * // => ['fred', 'barney', '&', 'pebbles']
13250      */
13251     function words(string, pattern, guard) {
13252       string = toString(string);
13253       pattern = guard ? undefined : pattern;
13254
13255       if (pattern === undefined) {
13256         pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
13257       }
13258       return string.match(pattern) || [];
13259     }
13260
13261     /*------------------------------------------------------------------------*/
13262
13263     /**
13264      * Attempts to invoke `func`, returning either the result or the caught error
13265      * object. Any additional arguments are provided to `func` when it's invoked.
13266      *
13267      * @static
13268      * @memberOf _
13269      * @category Util
13270      * @param {Function} func The function to attempt.
13271      * @returns {*} Returns the `func` result or error object.
13272      * @example
13273      *
13274      * // Avoid throwing errors for invalid selectors.
13275      * var elements = _.attempt(function(selector) {
13276      *   return document.querySelectorAll(selector);
13277      * }, '>_>');
13278      *
13279      * if (_.isError(elements)) {
13280      *   elements = [];
13281      * }
13282      */
13283     var attempt = rest(function(func, args) {
13284       try {
13285         return apply(func, undefined, args);
13286       } catch (e) {
13287         return isError(e) ? e : new Error(e);
13288       }
13289     });
13290
13291     /**
13292      * Binds methods of an object to the object itself, overwriting the existing
13293      * method.
13294      *
13295      * **Note:** This method doesn't set the "length" property of bound functions.
13296      *
13297      * @static
13298      * @memberOf _
13299      * @category Util
13300      * @param {Object} object The object to bind and assign the bound methods to.
13301      * @param {...(string|string[])} methodNames The object method names to bind,
13302      *  specified individually or in arrays.
13303      * @returns {Object} Returns `object`.
13304      * @example
13305      *
13306      * var view = {
13307      *   'label': 'docs',
13308      *   'onClick': function() {
13309      *     console.log('clicked ' + this.label);
13310      *   }
13311      * };
13312      *
13313      * _.bindAll(view, 'onClick');
13314      * jQuery(element).on('click', view.onClick);
13315      * // => logs 'clicked docs' when clicked
13316      */
13317     var bindAll = rest(function(object, methodNames) {
13318       arrayEach(baseFlatten(methodNames, 1), function(key) {
13319         object[key] = bind(object[key], object);
13320       });
13321       return object;
13322     });
13323
13324     /**
13325      * Creates a function that iterates over `pairs` invoking the corresponding
13326      * function of the first predicate to return truthy. The predicate-function
13327      * pairs are invoked with the `this` binding and arguments of the created
13328      * function.
13329      *
13330      * @static
13331      * @memberOf _
13332      * @category Util
13333      * @param {Array} pairs The predicate-function pairs.
13334      * @returns {Function} Returns the new function.
13335      * @example
13336      *
13337      * var func = _.cond([
13338      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
13339      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
13340      *   [_.constant(true),                _.constant('no match')]
13341      * ]);
13342      *
13343      * func({ 'a': 1, 'b': 2 });
13344      * // => 'matches A'
13345      *
13346      * func({ 'a': 0, 'b': 1 });
13347      * // => 'matches B'
13348      *
13349      * func({ 'a': '1', 'b': '2' });
13350      * // => 'no match'
13351      */
13352     function cond(pairs) {
13353       var length = pairs ? pairs.length : 0,
13354           toIteratee = getIteratee();
13355
13356       pairs = !length ? [] : arrayMap(pairs, function(pair) {
13357         if (typeof pair[1] != 'function') {
13358           throw new TypeError(FUNC_ERROR_TEXT);
13359         }
13360         return [toIteratee(pair[0]), pair[1]];
13361       });
13362
13363       return rest(function(args) {
13364         var index = -1;
13365         while (++index < length) {
13366           var pair = pairs[index];
13367           if (apply(pair[0], this, args)) {
13368             return apply(pair[1], this, args);
13369           }
13370         }
13371       });
13372     }
13373
13374     /**
13375      * Creates a function that invokes the predicate properties of `source` with
13376      * the corresponding property values of a given object, returning `true` if
13377      * all predicates return truthy, else `false`.
13378      *
13379      * @static
13380      * @memberOf _
13381      * @category Util
13382      * @param {Object} source The object of property predicates to conform to.
13383      * @returns {Function} Returns the new function.
13384      * @example
13385      *
13386      * var users = [
13387      *   { 'user': 'barney', 'age': 36 },
13388      *   { 'user': 'fred',   'age': 40 }
13389      * ];
13390      *
13391      * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
13392      * // => [{ 'user': 'fred', 'age': 40 }]
13393      */
13394     function conforms(source) {
13395       return baseConforms(baseClone(source, true));
13396     }
13397
13398     /**
13399      * Creates a function that returns `value`.
13400      *
13401      * @static
13402      * @memberOf _
13403      * @category Util
13404      * @param {*} value The value to return from the new function.
13405      * @returns {Function} Returns the new function.
13406      * @example
13407      *
13408      * var object = { 'user': 'fred' };
13409      * var getter = _.constant(object);
13410      *
13411      * getter() === object;
13412      * // => true
13413      */
13414     function constant(value) {
13415       return function() {
13416         return value;
13417       };
13418     }
13419
13420     /**
13421      * Creates a function that returns the result of invoking the given functions
13422      * with the `this` binding of the created function, where each successive
13423      * invocation is supplied the return value of the previous.
13424      *
13425      * @static
13426      * @memberOf _
13427      * @category Util
13428      * @param {...(Function|Function[])} [funcs] Functions to invoke.
13429      * @returns {Function} Returns the new function.
13430      * @example
13431      *
13432      * function square(n) {
13433      *   return n * n;
13434      * }
13435      *
13436      * var addSquare = _.flow(_.add, square);
13437      * addSquare(1, 2);
13438      * // => 9
13439      */
13440     var flow = createFlow();
13441
13442     /**
13443      * This method is like `_.flow` except that it creates a function that
13444      * invokes the given functions from right to left.
13445      *
13446      * @static
13447      * @memberOf _
13448      * @category Util
13449      * @param {...(Function|Function[])} [funcs] Functions to invoke.
13450      * @returns {Function} Returns the new function.
13451      * @example
13452      *
13453      * function square(n) {
13454      *   return n * n;
13455      * }
13456      *
13457      * var addSquare = _.flowRight(square, _.add);
13458      * addSquare(1, 2);
13459      * // => 9
13460      */
13461     var flowRight = createFlow(true);
13462
13463     /**
13464      * This method returns the first argument given to it.
13465      *
13466      * @static
13467      * @memberOf _
13468      * @category Util
13469      * @param {*} value Any value.
13470      * @returns {*} Returns `value`.
13471      * @example
13472      *
13473      * var object = { 'user': 'fred' };
13474      *
13475      * _.identity(object) === object;
13476      * // => true
13477      */
13478     function identity(value) {
13479       return value;
13480     }
13481
13482     /**
13483      * Creates a function that invokes `func` with the arguments of the created
13484      * function. If `func` is a property name the created callback returns the
13485      * property value for a given element. If `func` is an object the created
13486      * callback returns `true` for elements that contain the equivalent object
13487      * properties, otherwise it returns `false`.
13488      *
13489      * @static
13490      * @memberOf _
13491      * @category Util
13492      * @param {*} [func=_.identity] The value to convert to a callback.
13493      * @returns {Function} Returns the callback.
13494      * @example
13495      *
13496      * var users = [
13497      *   { 'user': 'barney', 'age': 36 },
13498      *   { 'user': 'fred',   'age': 40 }
13499      * ];
13500      *
13501      * // Create custom iteratee shorthands.
13502      * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
13503      *   var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
13504      *   return !p ? callback(func) : function(object) {
13505      *     return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
13506      *   };
13507      * });
13508      *
13509      * _.filter(users, 'age > 36');
13510      * // => [{ 'user': 'fred', 'age': 40 }]
13511      */
13512     function iteratee(func) {
13513       return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));
13514     }
13515
13516     /**
13517      * Creates a function that performs a partial deep comparison between a given
13518      * object and `source`, returning `true` if the given object has equivalent
13519      * property values, else `false`. The created function is equivalent to
13520      * `_.isMatch` with a `source` partially applied.
13521      *
13522      * **Note:** This method supports comparing the same values as `_.isEqual`.
13523      *
13524      * @static
13525      * @memberOf _
13526      * @category Util
13527      * @param {Object} source The object of property values to match.
13528      * @returns {Function} Returns the new function.
13529      * @example
13530      *
13531      * var users = [
13532      *   { 'user': 'barney', 'age': 36, 'active': true },
13533      *   { 'user': 'fred',   'age': 40, 'active': false }
13534      * ];
13535      *
13536      * _.filter(users, _.matches({ 'age': 40, 'active': false }));
13537      * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
13538      */
13539     function matches(source) {
13540       return baseMatches(baseClone(source, true));
13541     }
13542
13543     /**
13544      * Creates a function that performs a partial deep comparison between the
13545      * value at `path` of a given object to `srcValue`, returning `true` if the
13546      * object value is equivalent, else `false`.
13547      *
13548      * **Note:** This method supports comparing the same values as `_.isEqual`.
13549      *
13550      * @static
13551      * @memberOf _
13552      * @category Util
13553      * @param {Array|string} path The path of the property to get.
13554      * @param {*} srcValue The value to match.
13555      * @returns {Function} Returns the new function.
13556      * @example
13557      *
13558      * var users = [
13559      *   { 'user': 'barney' },
13560      *   { 'user': 'fred' }
13561      * ];
13562      *
13563      * _.find(users, _.matchesProperty('user', 'fred'));
13564      * // => { 'user': 'fred' }
13565      */
13566     function matchesProperty(path, srcValue) {
13567       return baseMatchesProperty(path, baseClone(srcValue, true));
13568     }
13569
13570     /**
13571      * Creates a function that invokes the method at `path` of a given object.
13572      * Any additional arguments are provided to the invoked method.
13573      *
13574      * @static
13575      * @memberOf _
13576      * @category Util
13577      * @param {Array|string} path The path of the method to invoke.
13578      * @param {...*} [args] The arguments to invoke the method with.
13579      * @returns {Function} Returns the new function.
13580      * @example
13581      *
13582      * var objects = [
13583      *   { 'a': { 'b': { 'c': _.constant(2) } } },
13584      *   { 'a': { 'b': { 'c': _.constant(1) } } }
13585      * ];
13586      *
13587      * _.map(objects, _.method('a.b.c'));
13588      * // => [2, 1]
13589      *
13590      * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
13591      * // => [1, 2]
13592      */
13593     var method = rest(function(path, args) {
13594       return function(object) {
13595         return baseInvoke(object, path, args);
13596       };
13597     });
13598
13599     /**
13600      * The opposite of `_.method`; this method creates a function that invokes
13601      * the method at a given path of `object`. Any additional arguments are
13602      * provided to the invoked method.
13603      *
13604      * @static
13605      * @memberOf _
13606      * @category Util
13607      * @param {Object} object The object to query.
13608      * @param {...*} [args] The arguments to invoke the method with.
13609      * @returns {Function} Returns the new function.
13610      * @example
13611      *
13612      * var array = _.times(3, _.constant),
13613      *     object = { 'a': array, 'b': array, 'c': array };
13614      *
13615      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
13616      * // => [2, 0]
13617      *
13618      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
13619      * // => [2, 0]
13620      */
13621     var methodOf = rest(function(object, args) {
13622       return function(path) {
13623         return baseInvoke(object, path, args);
13624       };
13625     });
13626
13627     /**
13628      * Adds all own enumerable function properties of a source object to the
13629      * destination object. If `object` is a function then methods are added to
13630      * its prototype as well.
13631      *
13632      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
13633      * avoid conflicts caused by modifying the original.
13634      *
13635      * @static
13636      * @memberOf _
13637      * @category Util
13638      * @param {Function|Object} [object=lodash] The destination object.
13639      * @param {Object} source The object of functions to add.
13640      * @param {Object} [options] The options object.
13641      * @param {boolean} [options.chain=true] Specify whether the functions added
13642      *  are chainable.
13643      * @returns {Function|Object} Returns `object`.
13644      * @example
13645      *
13646      * function vowels(string) {
13647      *   return _.filter(string, function(v) {
13648      *     return /[aeiou]/i.test(v);
13649      *   });
13650      * }
13651      *
13652      * _.mixin({ 'vowels': vowels });
13653      * _.vowels('fred');
13654      * // => ['e']
13655      *
13656      * _('fred').vowels().value();
13657      * // => ['e']
13658      *
13659      * _.mixin({ 'vowels': vowels }, { 'chain': false });
13660      * _('fred').vowels();
13661      * // => ['e']
13662      */
13663     function mixin(object, source, options) {
13664       var props = keys(source),
13665           methodNames = baseFunctions(source, props);
13666
13667       if (options == null &&
13668           !(isObject(source) && (methodNames.length || !props.length))) {
13669         options = source;
13670         source = object;
13671         object = this;
13672         methodNames = baseFunctions(source, keys(source));
13673       }
13674       var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
13675           isFunc = isFunction(object);
13676
13677       arrayEach(methodNames, function(methodName) {
13678         var func = source[methodName];
13679         object[methodName] = func;
13680         if (isFunc) {
13681           object.prototype[methodName] = function() {
13682             var chainAll = this.__chain__;
13683             if (chain || chainAll) {
13684               var result = object(this.__wrapped__),
13685                   actions = result.__actions__ = copyArray(this.__actions__);
13686
13687               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
13688               result.__chain__ = chainAll;
13689               return result;
13690             }
13691             return func.apply(object, arrayPush([this.value()], arguments));
13692           };
13693         }
13694       });
13695
13696       return object;
13697     }
13698
13699     /**
13700      * Reverts the `_` variable to its previous value and returns a reference to
13701      * the `lodash` function.
13702      *
13703      * @static
13704      * @memberOf _
13705      * @category Util
13706      * @returns {Function} Returns the `lodash` function.
13707      * @example
13708      *
13709      * var lodash = _.noConflict();
13710      */
13711     function noConflict() {
13712       if (root._ === this) {
13713         root._ = oldDash;
13714       }
13715       return this;
13716     }
13717
13718     /**
13719      * A no-operation function that returns `undefined` regardless of the
13720      * arguments it receives.
13721      *
13722      * @static
13723      * @memberOf _
13724      * @category Util
13725      * @example
13726      *
13727      * var object = { 'user': 'fred' };
13728      *
13729      * _.noop(object) === undefined;
13730      * // => true
13731      */
13732     function noop() {
13733       // No operation performed.
13734     }
13735
13736     /**
13737      * Creates a function that returns its nth argument.
13738      *
13739      * @static
13740      * @memberOf _
13741      * @category Util
13742      * @param {number} [n=0] The index of the argument to return.
13743      * @returns {Function} Returns the new function.
13744      * @example
13745      *
13746      * var func = _.nthArg(1);
13747      *
13748      * func('a', 'b', 'c');
13749      * // => 'b'
13750      */
13751     function nthArg(n) {
13752       n = toInteger(n);
13753       return function() {
13754         return arguments[n];
13755       };
13756     }
13757
13758     /**
13759      * Creates a function that invokes `iteratees` with the arguments provided
13760      * to the created function and returns their results.
13761      *
13762      * @static
13763      * @memberOf _
13764      * @category Util
13765      * @param {...(Function|Function[])} iteratees The iteratees to invoke.
13766      * @returns {Function} Returns the new function.
13767      * @example
13768      *
13769      * var func = _.over(Math.max, Math.min);
13770      *
13771      * func(1, 2, 3, 4);
13772      * // => [4, 1]
13773      */
13774     var over = createOver(arrayMap);
13775
13776     /**
13777      * Creates a function that checks if **all** of the `predicates` return
13778      * truthy when invoked with the arguments provided to the created function.
13779      *
13780      * @static
13781      * @memberOf _
13782      * @category Util
13783      * @param {...(Function|Function[])} predicates The predicates to check.
13784      * @returns {Function} Returns the new function.
13785      * @example
13786      *
13787      * var func = _.overEvery(Boolean, isFinite);
13788      *
13789      * func('1');
13790      * // => true
13791      *
13792      * func(null);
13793      * // => false
13794      *
13795      * func(NaN);
13796      * // => false
13797      */
13798     var overEvery = createOver(arrayEvery);
13799
13800     /**
13801      * Creates a function that checks if **any** of the `predicates` return
13802      * truthy when invoked with the arguments provided to the created function.
13803      *
13804      * @static
13805      * @memberOf _
13806      * @category Util
13807      * @param {...(Function|Function[])} predicates The predicates to check.
13808      * @returns {Function} Returns the new function.
13809      * @example
13810      *
13811      * var func = _.overSome(Boolean, isFinite);
13812      *
13813      * func('1');
13814      * // => true
13815      *
13816      * func(null);
13817      * // => true
13818      *
13819      * func(NaN);
13820      * // => false
13821      */
13822     var overSome = createOver(arraySome);
13823
13824     /**
13825      * Creates a function that returns the value at `path` of a given object.
13826      *
13827      * @static
13828      * @memberOf _
13829      * @category Util
13830      * @param {Array|string} path The path of the property to get.
13831      * @returns {Function} Returns the new function.
13832      * @example
13833      *
13834      * var objects = [
13835      *   { 'a': { 'b': { 'c': 2 } } },
13836      *   { 'a': { 'b': { 'c': 1 } } }
13837      * ];
13838      *
13839      * _.map(objects, _.property('a.b.c'));
13840      * // => [2, 1]
13841      *
13842      * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
13843      * // => [1, 2]
13844      */
13845     function property(path) {
13846       return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
13847     }
13848
13849     /**
13850      * The opposite of `_.property`; this method creates a function that returns
13851      * the value at a given path of `object`.
13852      *
13853      * @static
13854      * @memberOf _
13855      * @category Util
13856      * @param {Object} object The object to query.
13857      * @returns {Function} Returns the new function.
13858      * @example
13859      *
13860      * var array = [0, 1, 2],
13861      *     object = { 'a': array, 'b': array, 'c': array };
13862      *
13863      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
13864      * // => [2, 0]
13865      *
13866      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
13867      * // => [2, 0]
13868      */
13869     function propertyOf(object) {
13870       return function(path) {
13871         return object == null ? undefined : baseGet(object, path);
13872       };
13873     }
13874
13875     /**
13876      * Creates an array of numbers (positive and/or negative) progressing from
13877      * `start` up to, but not including, `end`. A step of `-1` is used if a negative
13878      * `start` is specified without an `end` or `step`. If `end` is not specified
13879      * it's set to `start` with `start` then set to `0`.
13880      *
13881      * **Note:** JavaScript follows the IEEE-754 standard for resolving
13882      * floating-point values which can produce unexpected results.
13883      *
13884      * @static
13885      * @memberOf _
13886      * @category Util
13887      * @param {number} [start=0] The start of the range.
13888      * @param {number} end The end of the range.
13889      * @param {number} [step=1] The value to increment or decrement by.
13890      * @returns {Array} Returns the new array of numbers.
13891      * @example
13892      *
13893      * _.range(4);
13894      * // => [0, 1, 2, 3]
13895      *
13896      * _.range(-4);
13897      * // => [0, -1, -2, -3]
13898      *
13899      * _.range(1, 5);
13900      * // => [1, 2, 3, 4]
13901      *
13902      * _.range(0, 20, 5);
13903      * // => [0, 5, 10, 15]
13904      *
13905      * _.range(0, -4, -1);
13906      * // => [0, -1, -2, -3]
13907      *
13908      * _.range(1, 4, 0);
13909      * // => [1, 1, 1]
13910      *
13911      * _.range(0);
13912      * // => []
13913      */
13914     var range = createRange();
13915
13916     /**
13917      * This method is like `_.range` except that it populates values in
13918      * descending order.
13919      *
13920      * @static
13921      * @memberOf _
13922      * @category Util
13923      * @param {number} [start=0] The start of the range.
13924      * @param {number} end The end of the range.
13925      * @param {number} [step=1] The value to increment or decrement by.
13926      * @returns {Array} Returns the new array of numbers.
13927      * @example
13928      *
13929      * _.rangeRight(4);
13930      * // => [3, 2, 1, 0]
13931      *
13932      * _.rangeRight(-4);
13933      * // => [-3, -2, -1, 0]
13934      *
13935      * _.rangeRight(1, 5);
13936      * // => [4, 3, 2, 1]
13937      *
13938      * _.rangeRight(0, 20, 5);
13939      * // => [15, 10, 5, 0]
13940      *
13941      * _.rangeRight(0, -4, -1);
13942      * // => [-3, -2, -1, 0]
13943      *
13944      * _.rangeRight(1, 4, 0);
13945      * // => [1, 1, 1]
13946      *
13947      * _.rangeRight(0);
13948      * // => []
13949      */
13950     var rangeRight = createRange(true);
13951
13952     /**
13953      * Invokes the iteratee `n` times, returning an array of the results of
13954      * each invocation. The iteratee is invoked with one argument; (index).
13955      *
13956      * @static
13957      * @memberOf _
13958      * @category Util
13959      * @param {number} n The number of times to invoke `iteratee`.
13960      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13961      * @returns {Array} Returns the array of results.
13962      * @example
13963      *
13964      * _.times(3, String);
13965      * // => ['0', '1', '2']
13966      *
13967      *  _.times(4, _.constant(true));
13968      * // => [true, true, true, true]
13969      */
13970     function times(n, iteratee) {
13971       n = toInteger(n);
13972       if (n < 1 || n > MAX_SAFE_INTEGER) {
13973         return [];
13974       }
13975       var index = MAX_ARRAY_LENGTH,
13976           length = nativeMin(n, MAX_ARRAY_LENGTH);
13977
13978       iteratee = baseCastFunction(iteratee);
13979       n -= MAX_ARRAY_LENGTH;
13980
13981       var result = baseTimes(length, iteratee);
13982       while (++index < n) {
13983         iteratee(index);
13984       }
13985       return result;
13986     }
13987
13988     /**
13989      * Converts `value` to a property path array.
13990      *
13991      * @static
13992      * @memberOf _
13993      * @category Util
13994      * @param {*} value The value to convert.
13995      * @returns {Array} Returns the new property path array.
13996      * @example
13997      *
13998      * _.toPath('a.b.c');
13999      * // => ['a', 'b', 'c']
14000      *
14001      * _.toPath('a[0].b.c');
14002      * // => ['a', '0', 'b', 'c']
14003      *
14004      * var path = ['a', 'b', 'c'],
14005      *     newPath = _.toPath(path);
14006      *
14007      * console.log(newPath);
14008      * // => ['a', 'b', 'c']
14009      *
14010      * console.log(path === newPath);
14011      * // => false
14012      */
14013     function toPath(value) {
14014       return isArray(value) ? arrayMap(value, String) : stringToPath(value);
14015     }
14016
14017     /**
14018      * Generates a unique ID. If `prefix` is given the ID is appended to it.
14019      *
14020      * @static
14021      * @memberOf _
14022      * @category Util
14023      * @param {string} [prefix=''] The value to prefix the ID with.
14024      * @returns {string} Returns the unique ID.
14025      * @example
14026      *
14027      * _.uniqueId('contact_');
14028      * // => 'contact_104'
14029      *
14030      * _.uniqueId();
14031      * // => '105'
14032      */
14033     function uniqueId(prefix) {
14034       var id = ++idCounter;
14035       return toString(prefix) + id;
14036     }
14037
14038     /*------------------------------------------------------------------------*/
14039
14040     /**
14041      * Adds two numbers.
14042      *
14043      * @static
14044      * @memberOf _
14045      * @category Math
14046      * @param {number} augend The first number in an addition.
14047      * @param {number} addend The second number in an addition.
14048      * @returns {number} Returns the total.
14049      * @example
14050      *
14051      * _.add(6, 4);
14052      * // => 10
14053      */
14054     function add(augend, addend) {
14055       var result;
14056       if (augend === undefined && addend === undefined) {
14057         return 0;
14058       }
14059       if (augend !== undefined) {
14060         result = augend;
14061       }
14062       if (addend !== undefined) {
14063         result = result === undefined ? addend : (result + addend);
14064       }
14065       return result;
14066     }
14067
14068     /**
14069      * Computes `number` rounded up to `precision`.
14070      *
14071      * @static
14072      * @memberOf _
14073      * @category Math
14074      * @param {number} number The number to round up.
14075      * @param {number} [precision=0] The precision to round up to.
14076      * @returns {number} Returns the rounded up number.
14077      * @example
14078      *
14079      * _.ceil(4.006);
14080      * // => 5
14081      *
14082      * _.ceil(6.004, 2);
14083      * // => 6.01
14084      *
14085      * _.ceil(6040, -2);
14086      * // => 6100
14087      */
14088     var ceil = createRound('ceil');
14089
14090     /**
14091      * Computes `number` rounded down to `precision`.
14092      *
14093      * @static
14094      * @memberOf _
14095      * @category Math
14096      * @param {number} number The number to round down.
14097      * @param {number} [precision=0] The precision to round down to.
14098      * @returns {number} Returns the rounded down number.
14099      * @example
14100      *
14101      * _.floor(4.006);
14102      * // => 4
14103      *
14104      * _.floor(0.046, 2);
14105      * // => 0.04
14106      *
14107      * _.floor(4060, -2);
14108      * // => 4000
14109      */
14110     var floor = createRound('floor');
14111
14112     /**
14113      * Computes the maximum value of `array`. If `array` is empty or falsey
14114      * `undefined` is returned.
14115      *
14116      * @static
14117      * @memberOf _
14118      * @category Math
14119      * @param {Array} array The array to iterate over.
14120      * @returns {*} Returns the maximum value.
14121      * @example
14122      *
14123      * _.max([4, 2, 8, 6]);
14124      * // => 8
14125      *
14126      * _.max([]);
14127      * // => undefined
14128      */
14129     function max(array) {
14130       return (array && array.length)
14131         ? baseExtremum(array, identity, gt)
14132         : undefined;
14133     }
14134
14135     /**
14136      * This method is like `_.max` except that it accepts `iteratee` which is
14137      * invoked for each element in `array` to generate the criterion by which
14138      * the value is ranked. The iteratee is invoked with one argument: (value).
14139      *
14140      * @static
14141      * @memberOf _
14142      * @category Math
14143      * @param {Array} array The array to iterate over.
14144      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14145      * @returns {*} Returns the maximum value.
14146      * @example
14147      *
14148      * var objects = [{ 'n': 1 }, { 'n': 2 }];
14149      *
14150      * _.maxBy(objects, function(o) { return o.n; });
14151      * // => { 'n': 2 }
14152      *
14153      * // The `_.property` iteratee shorthand.
14154      * _.maxBy(objects, 'n');
14155      * // => { 'n': 2 }
14156      */
14157     function maxBy(array, iteratee) {
14158       return (array && array.length)
14159         ? baseExtremum(array, getIteratee(iteratee), gt)
14160         : undefined;
14161     }
14162
14163     /**
14164      * Computes the mean of the values in `array`.
14165      *
14166      * @static
14167      * @memberOf _
14168      * @category Math
14169      * @param {Array} array The array to iterate over.
14170      * @returns {number} Returns the mean.
14171      * @example
14172      *
14173      * _.mean([4, 2, 8, 6]);
14174      * // => 5
14175      */
14176     function mean(array) {
14177       return sum(array) / (array ? array.length : 0);
14178     }
14179
14180     /**
14181      * Computes the minimum value of `array`. If `array` is empty or falsey
14182      * `undefined` is returned.
14183      *
14184      * @static
14185      * @memberOf _
14186      * @category Math
14187      * @param {Array} array The array to iterate over.
14188      * @returns {*} Returns the minimum value.
14189      * @example
14190      *
14191      * _.min([4, 2, 8, 6]);
14192      * // => 2
14193      *
14194      * _.min([]);
14195      * // => undefined
14196      */
14197     function min(array) {
14198       return (array && array.length)
14199         ? baseExtremum(array, identity, lt)
14200         : undefined;
14201     }
14202
14203     /**
14204      * This method is like `_.min` except that it accepts `iteratee` which is
14205      * invoked for each element in `array` to generate the criterion by which
14206      * the value is ranked. The iteratee is invoked with one argument: (value).
14207      *
14208      * @static
14209      * @memberOf _
14210      * @category Math
14211      * @param {Array} array The array to iterate over.
14212      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14213      * @returns {*} Returns the minimum value.
14214      * @example
14215      *
14216      * var objects = [{ 'n': 1 }, { 'n': 2 }];
14217      *
14218      * _.minBy(objects, function(o) { return o.n; });
14219      * // => { 'n': 1 }
14220      *
14221      * // The `_.property` iteratee shorthand.
14222      * _.minBy(objects, 'n');
14223      * // => { 'n': 1 }
14224      */
14225     function minBy(array, iteratee) {
14226       return (array && array.length)
14227         ? baseExtremum(array, getIteratee(iteratee), lt)
14228         : undefined;
14229     }
14230
14231     /**
14232      * Computes `number` rounded to `precision`.
14233      *
14234      * @static
14235      * @memberOf _
14236      * @category Math
14237      * @param {number} number The number to round.
14238      * @param {number} [precision=0] The precision to round to.
14239      * @returns {number} Returns the rounded number.
14240      * @example
14241      *
14242      * _.round(4.006);
14243      * // => 4
14244      *
14245      * _.round(4.006, 2);
14246      * // => 4.01
14247      *
14248      * _.round(4060, -2);
14249      * // => 4100
14250      */
14251     var round = createRound('round');
14252
14253     /**
14254      * Subtract two numbers.
14255      *
14256      * @static
14257      * @memberOf _
14258      * @category Math
14259      * @param {number} minuend The first number in a subtraction.
14260      * @param {number} subtrahend The second number in a subtraction.
14261      * @returns {number} Returns the difference.
14262      * @example
14263      *
14264      * _.subtract(6, 4);
14265      * // => 2
14266      */
14267     function subtract(minuend, subtrahend) {
14268       var result;
14269       if (minuend === undefined && subtrahend === undefined) {
14270         return 0;
14271       }
14272       if (minuend !== undefined) {
14273         result = minuend;
14274       }
14275       if (subtrahend !== undefined) {
14276         result = result === undefined ? subtrahend : (result - subtrahend);
14277       }
14278       return result;
14279     }
14280
14281     /**
14282      * Computes the sum of the values in `array`.
14283      *
14284      * @static
14285      * @memberOf _
14286      * @category Math
14287      * @param {Array} array The array to iterate over.
14288      * @returns {number} Returns the sum.
14289      * @example
14290      *
14291      * _.sum([4, 2, 8, 6]);
14292      * // => 20
14293      */
14294     function sum(array) {
14295       return (array && array.length)
14296         ? baseSum(array, identity)
14297         : 0;
14298     }
14299
14300     /**
14301      * This method is like `_.sum` except that it accepts `iteratee` which is
14302      * invoked for each element in `array` to generate the value to be summed.
14303      * The iteratee is invoked with one argument: (value).
14304      *
14305      * @static
14306      * @memberOf _
14307      * @category Math
14308      * @param {Array} array The array to iterate over.
14309      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14310      * @returns {number} Returns the sum.
14311      * @example
14312      *
14313      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
14314      *
14315      * _.sumBy(objects, function(o) { return o.n; });
14316      * // => 20
14317      *
14318      * // The `_.property` iteratee shorthand.
14319      * _.sumBy(objects, 'n');
14320      * // => 20
14321      */
14322     function sumBy(array, iteratee) {
14323       return (array && array.length)
14324         ? baseSum(array, getIteratee(iteratee))
14325         : 0;
14326     }
14327
14328     /*------------------------------------------------------------------------*/
14329
14330     // Ensure wrappers are instances of `baseLodash`.
14331     lodash.prototype = baseLodash.prototype;
14332
14333     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
14334     LodashWrapper.prototype.constructor = LodashWrapper;
14335
14336     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
14337     LazyWrapper.prototype.constructor = LazyWrapper;
14338
14339     // Avoid inheriting from `Object.prototype` when possible.
14340     Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
14341
14342     // Add functions to the `MapCache`.
14343     MapCache.prototype.clear = mapClear;
14344     MapCache.prototype['delete'] = mapDelete;
14345     MapCache.prototype.get = mapGet;
14346     MapCache.prototype.has = mapHas;
14347     MapCache.prototype.set = mapSet;
14348
14349     // Add functions to the `SetCache`.
14350     SetCache.prototype.push = cachePush;
14351
14352     // Add functions to the `Stack` cache.
14353     Stack.prototype.clear = stackClear;
14354     Stack.prototype['delete'] = stackDelete;
14355     Stack.prototype.get = stackGet;
14356     Stack.prototype.has = stackHas;
14357     Stack.prototype.set = stackSet;
14358
14359     // Assign cache to `_.memoize`.
14360     memoize.Cache = MapCache;
14361
14362     // Add functions that return wrapped values when chaining.
14363     lodash.after = after;
14364     lodash.ary = ary;
14365     lodash.assign = assign;
14366     lodash.assignIn = assignIn;
14367     lodash.assignInWith = assignInWith;
14368     lodash.assignWith = assignWith;
14369     lodash.at = at;
14370     lodash.before = before;
14371     lodash.bind = bind;
14372     lodash.bindAll = bindAll;
14373     lodash.bindKey = bindKey;
14374     lodash.castArray = castArray;
14375     lodash.chain = chain;
14376     lodash.chunk = chunk;
14377     lodash.compact = compact;
14378     lodash.concat = concat;
14379     lodash.cond = cond;
14380     lodash.conforms = conforms;
14381     lodash.constant = constant;
14382     lodash.countBy = countBy;
14383     lodash.create = create;
14384     lodash.curry = curry;
14385     lodash.curryRight = curryRight;
14386     lodash.debounce = debounce;
14387     lodash.defaults = defaults;
14388     lodash.defaultsDeep = defaultsDeep;
14389     lodash.defer = defer;
14390     lodash.delay = delay;
14391     lodash.difference = difference;
14392     lodash.differenceBy = differenceBy;
14393     lodash.differenceWith = differenceWith;
14394     lodash.drop = drop;
14395     lodash.dropRight = dropRight;
14396     lodash.dropRightWhile = dropRightWhile;
14397     lodash.dropWhile = dropWhile;
14398     lodash.fill = fill;
14399     lodash.filter = filter;
14400     lodash.flatMap = flatMap;
14401     lodash.flatten = flatten;
14402     lodash.flattenDeep = flattenDeep;
14403     lodash.flattenDepth = flattenDepth;
14404     lodash.flip = flip;
14405     lodash.flow = flow;
14406     lodash.flowRight = flowRight;
14407     lodash.fromPairs = fromPairs;
14408     lodash.functions = functions;
14409     lodash.functionsIn = functionsIn;
14410     lodash.groupBy = groupBy;
14411     lodash.initial = initial;
14412     lodash.intersection = intersection;
14413     lodash.intersectionBy = intersectionBy;
14414     lodash.intersectionWith = intersectionWith;
14415     lodash.invert = invert;
14416     lodash.invertBy = invertBy;
14417     lodash.invokeMap = invokeMap;
14418     lodash.iteratee = iteratee;
14419     lodash.keyBy = keyBy;
14420     lodash.keys = keys;
14421     lodash.keysIn = keysIn;
14422     lodash.map = map;
14423     lodash.mapKeys = mapKeys;
14424     lodash.mapValues = mapValues;
14425     lodash.matches = matches;
14426     lodash.matchesProperty = matchesProperty;
14427     lodash.memoize = memoize;
14428     lodash.merge = merge;
14429     lodash.mergeWith = mergeWith;
14430     lodash.method = method;
14431     lodash.methodOf = methodOf;
14432     lodash.mixin = mixin;
14433     lodash.negate = negate;
14434     lodash.nthArg = nthArg;
14435     lodash.omit = omit;
14436     lodash.omitBy = omitBy;
14437     lodash.once = once;
14438     lodash.orderBy = orderBy;
14439     lodash.over = over;
14440     lodash.overArgs = overArgs;
14441     lodash.overEvery = overEvery;
14442     lodash.overSome = overSome;
14443     lodash.partial = partial;
14444     lodash.partialRight = partialRight;
14445     lodash.partition = partition;
14446     lodash.pick = pick;
14447     lodash.pickBy = pickBy;
14448     lodash.property = property;
14449     lodash.propertyOf = propertyOf;
14450     lodash.pull = pull;
14451     lodash.pullAll = pullAll;
14452     lodash.pullAllBy = pullAllBy;
14453     lodash.pullAt = pullAt;
14454     lodash.range = range;
14455     lodash.rangeRight = rangeRight;
14456     lodash.rearg = rearg;
14457     lodash.reject = reject;
14458     lodash.remove = remove;
14459     lodash.rest = rest;
14460     lodash.reverse = reverse;
14461     lodash.sampleSize = sampleSize;
14462     lodash.set = set;
14463     lodash.setWith = setWith;
14464     lodash.shuffle = shuffle;
14465     lodash.slice = slice;
14466     lodash.sortBy = sortBy;
14467     lodash.sortedUniq = sortedUniq;
14468     lodash.sortedUniqBy = sortedUniqBy;
14469     lodash.split = split;
14470     lodash.spread = spread;
14471     lodash.tail = tail;
14472     lodash.take = take;
14473     lodash.takeRight = takeRight;
14474     lodash.takeRightWhile = takeRightWhile;
14475     lodash.takeWhile = takeWhile;
14476     lodash.tap = tap;
14477     lodash.throttle = throttle;
14478     lodash.thru = thru;
14479     lodash.toArray = toArray;
14480     lodash.toPairs = toPairs;
14481     lodash.toPairsIn = toPairsIn;
14482     lodash.toPath = toPath;
14483     lodash.toPlainObject = toPlainObject;
14484     lodash.transform = transform;
14485     lodash.unary = unary;
14486     lodash.union = union;
14487     lodash.unionBy = unionBy;
14488     lodash.unionWith = unionWith;
14489     lodash.uniq = uniq;
14490     lodash.uniqBy = uniqBy;
14491     lodash.uniqWith = uniqWith;
14492     lodash.unset = unset;
14493     lodash.unzip = unzip;
14494     lodash.unzipWith = unzipWith;
14495     lodash.values = values;
14496     lodash.valuesIn = valuesIn;
14497     lodash.without = without;
14498     lodash.words = words;
14499     lodash.wrap = wrap;
14500     lodash.xor = xor;
14501     lodash.xorBy = xorBy;
14502     lodash.xorWith = xorWith;
14503     lodash.zip = zip;
14504     lodash.zipObject = zipObject;
14505     lodash.zipObjectDeep = zipObjectDeep;
14506     lodash.zipWith = zipWith;
14507
14508     // Add aliases.
14509     lodash.extend = assignIn;
14510     lodash.extendWith = assignInWith;
14511
14512     // Add functions to `lodash.prototype`.
14513     mixin(lodash, lodash);
14514
14515     /*------------------------------------------------------------------------*/
14516
14517     // Add functions that return unwrapped values when chaining.
14518     lodash.add = add;
14519     lodash.attempt = attempt;
14520     lodash.camelCase = camelCase;
14521     lodash.capitalize = capitalize;
14522     lodash.ceil = ceil;
14523     lodash.clamp = clamp;
14524     lodash.clone = clone;
14525     lodash.cloneDeep = cloneDeep;
14526     lodash.cloneDeepWith = cloneDeepWith;
14527     lodash.cloneWith = cloneWith;
14528     lodash.deburr = deburr;
14529     lodash.endsWith = endsWith;
14530     lodash.eq = eq;
14531     lodash.escape = escape;
14532     lodash.escapeRegExp = escapeRegExp;
14533     lodash.every = every;
14534     lodash.find = find;
14535     lodash.findIndex = findIndex;
14536     lodash.findKey = findKey;
14537     lodash.findLast = findLast;
14538     lodash.findLastIndex = findLastIndex;
14539     lodash.findLastKey = findLastKey;
14540     lodash.floor = floor;
14541     lodash.forEach = forEach;
14542     lodash.forEachRight = forEachRight;
14543     lodash.forIn = forIn;
14544     lodash.forInRight = forInRight;
14545     lodash.forOwn = forOwn;
14546     lodash.forOwnRight = forOwnRight;
14547     lodash.get = get;
14548     lodash.gt = gt;
14549     lodash.gte = gte;
14550     lodash.has = has;
14551     lodash.hasIn = hasIn;
14552     lodash.head = head;
14553     lodash.identity = identity;
14554     lodash.includes = includes;
14555     lodash.indexOf = indexOf;
14556     lodash.inRange = inRange;
14557     lodash.invoke = invoke;
14558     lodash.isArguments = isArguments;
14559     lodash.isArray = isArray;
14560     lodash.isArrayBuffer = isArrayBuffer;
14561     lodash.isArrayLike = isArrayLike;
14562     lodash.isArrayLikeObject = isArrayLikeObject;
14563     lodash.isBoolean = isBoolean;
14564     lodash.isBuffer = isBuffer;
14565     lodash.isDate = isDate;
14566     lodash.isElement = isElement;
14567     lodash.isEmpty = isEmpty;
14568     lodash.isEqual = isEqual;
14569     lodash.isEqualWith = isEqualWith;
14570     lodash.isError = isError;
14571     lodash.isFinite = isFinite;
14572     lodash.isFunction = isFunction;
14573     lodash.isInteger = isInteger;
14574     lodash.isLength = isLength;
14575     lodash.isMap = isMap;
14576     lodash.isMatch = isMatch;
14577     lodash.isMatchWith = isMatchWith;
14578     lodash.isNaN = isNaN;
14579     lodash.isNative = isNative;
14580     lodash.isNil = isNil;
14581     lodash.isNull = isNull;
14582     lodash.isNumber = isNumber;
14583     lodash.isObject = isObject;
14584     lodash.isObjectLike = isObjectLike;
14585     lodash.isPlainObject = isPlainObject;
14586     lodash.isRegExp = isRegExp;
14587     lodash.isSafeInteger = isSafeInteger;
14588     lodash.isSet = isSet;
14589     lodash.isString = isString;
14590     lodash.isSymbol = isSymbol;
14591     lodash.isTypedArray = isTypedArray;
14592     lodash.isUndefined = isUndefined;
14593     lodash.isWeakMap = isWeakMap;
14594     lodash.isWeakSet = isWeakSet;
14595     lodash.join = join;
14596     lodash.kebabCase = kebabCase;
14597     lodash.last = last;
14598     lodash.lastIndexOf = lastIndexOf;
14599     lodash.lowerCase = lowerCase;
14600     lodash.lowerFirst = lowerFirst;
14601     lodash.lt = lt;
14602     lodash.lte = lte;
14603     lodash.max = max;
14604     lodash.maxBy = maxBy;
14605     lodash.mean = mean;
14606     lodash.min = min;
14607     lodash.minBy = minBy;
14608     lodash.noConflict = noConflict;
14609     lodash.noop = noop;
14610     lodash.now = now;
14611     lodash.pad = pad;
14612     lodash.padEnd = padEnd;
14613     lodash.padStart = padStart;
14614     lodash.parseInt = parseInt;
14615     lodash.random = random;
14616     lodash.reduce = reduce;
14617     lodash.reduceRight = reduceRight;
14618     lodash.repeat = repeat;
14619     lodash.replace = replace;
14620     lodash.result = result;
14621     lodash.round = round;
14622     lodash.runInContext = runInContext;
14623     lodash.sample = sample;
14624     lodash.size = size;
14625     lodash.snakeCase = snakeCase;
14626     lodash.some = some;
14627     lodash.sortedIndex = sortedIndex;
14628     lodash.sortedIndexBy = sortedIndexBy;
14629     lodash.sortedIndexOf = sortedIndexOf;
14630     lodash.sortedLastIndex = sortedLastIndex;
14631     lodash.sortedLastIndexBy = sortedLastIndexBy;
14632     lodash.sortedLastIndexOf = sortedLastIndexOf;
14633     lodash.startCase = startCase;
14634     lodash.startsWith = startsWith;
14635     lodash.subtract = subtract;
14636     lodash.sum = sum;
14637     lodash.sumBy = sumBy;
14638     lodash.template = template;
14639     lodash.times = times;
14640     lodash.toInteger = toInteger;
14641     lodash.toLength = toLength;
14642     lodash.toLower = toLower;
14643     lodash.toNumber = toNumber;
14644     lodash.toSafeInteger = toSafeInteger;
14645     lodash.toString = toString;
14646     lodash.toUpper = toUpper;
14647     lodash.trim = trim;
14648     lodash.trimEnd = trimEnd;
14649     lodash.trimStart = trimStart;
14650     lodash.truncate = truncate;
14651     lodash.unescape = unescape;
14652     lodash.uniqueId = uniqueId;
14653     lodash.upperCase = upperCase;
14654     lodash.upperFirst = upperFirst;
14655
14656     // Add aliases.
14657     lodash.each = forEach;
14658     lodash.eachRight = forEachRight;
14659     lodash.first = head;
14660
14661     mixin(lodash, (function() {
14662       var source = {};
14663       baseForOwn(lodash, function(func, methodName) {
14664         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
14665           source[methodName] = func;
14666         }
14667       });
14668       return source;
14669     }()), { 'chain': false });
14670
14671     /*------------------------------------------------------------------------*/
14672
14673     /**
14674      * The semantic version number.
14675      *
14676      * @static
14677      * @memberOf _
14678      * @type {string}
14679      */
14680     lodash.VERSION = VERSION;
14681
14682     // Assign default placeholders.
14683     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
14684       lodash[methodName].placeholder = lodash;
14685     });
14686
14687     // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
14688     arrayEach(['drop', 'take'], function(methodName, index) {
14689       LazyWrapper.prototype[methodName] = function(n) {
14690         var filtered = this.__filtered__;
14691         if (filtered && !index) {
14692           return new LazyWrapper(this);
14693         }
14694         n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
14695
14696         var result = this.clone();
14697         if (filtered) {
14698           result.__takeCount__ = nativeMin(n, result.__takeCount__);
14699         } else {
14700           result.__views__.push({
14701             'size': nativeMin(n, MAX_ARRAY_LENGTH),
14702             'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
14703           });
14704         }
14705         return result;
14706       };
14707
14708       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
14709         return this.reverse()[methodName](n).reverse();
14710       };
14711     });
14712
14713     // Add `LazyWrapper` methods that accept an `iteratee` value.
14714     arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
14715       var type = index + 1,
14716           isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
14717
14718       LazyWrapper.prototype[methodName] = function(iteratee) {
14719         var result = this.clone();
14720         result.__iteratees__.push({
14721           'iteratee': getIteratee(iteratee, 3),
14722           'type': type
14723         });
14724         result.__filtered__ = result.__filtered__ || isFilter;
14725         return result;
14726       };
14727     });
14728
14729     // Add `LazyWrapper` methods for `_.head` and `_.last`.
14730     arrayEach(['head', 'last'], function(methodName, index) {
14731       var takeName = 'take' + (index ? 'Right' : '');
14732
14733       LazyWrapper.prototype[methodName] = function() {
14734         return this[takeName](1).value()[0];
14735       };
14736     });
14737
14738     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
14739     arrayEach(['initial', 'tail'], function(methodName, index) {
14740       var dropName = 'drop' + (index ? '' : 'Right');
14741
14742       LazyWrapper.prototype[methodName] = function() {
14743         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
14744       };
14745     });
14746
14747     LazyWrapper.prototype.compact = function() {
14748       return this.filter(identity);
14749     };
14750
14751     LazyWrapper.prototype.find = function(predicate) {
14752       return this.filter(predicate).head();
14753     };
14754
14755     LazyWrapper.prototype.findLast = function(predicate) {
14756       return this.reverse().find(predicate);
14757     };
14758
14759     LazyWrapper.prototype.invokeMap = rest(function(path, args) {
14760       if (typeof path == 'function') {
14761         return new LazyWrapper(this);
14762       }
14763       return this.map(function(value) {
14764         return baseInvoke(value, path, args);
14765       });
14766     });
14767
14768     LazyWrapper.prototype.reject = function(predicate) {
14769       predicate = getIteratee(predicate, 3);
14770       return this.filter(function(value) {
14771         return !predicate(value);
14772       });
14773     };
14774
14775     LazyWrapper.prototype.slice = function(start, end) {
14776       start = toInteger(start);
14777
14778       var result = this;
14779       if (result.__filtered__ && (start > 0 || end < 0)) {
14780         return new LazyWrapper(result);
14781       }
14782       if (start < 0) {
14783         result = result.takeRight(-start);
14784       } else if (start) {
14785         result = result.drop(start);
14786       }
14787       if (end !== undefined) {
14788         end = toInteger(end);
14789         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
14790       }
14791       return result;
14792     };
14793
14794     LazyWrapper.prototype.takeRightWhile = function(predicate) {
14795       return this.reverse().takeWhile(predicate).reverse();
14796     };
14797
14798     LazyWrapper.prototype.toArray = function() {
14799       return this.take(MAX_ARRAY_LENGTH);
14800     };
14801
14802     // Add `LazyWrapper` methods to `lodash.prototype`.
14803     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14804       var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
14805           isTaker = /^(?:head|last)$/.test(methodName),
14806           lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
14807           retUnwrapped = isTaker || /^find/.test(methodName);
14808
14809       if (!lodashFunc) {
14810         return;
14811       }
14812       lodash.prototype[methodName] = function() {
14813         var value = this.__wrapped__,
14814             args = isTaker ? [1] : arguments,
14815             isLazy = value instanceof LazyWrapper,
14816             iteratee = args[0],
14817             useLazy = isLazy || isArray(value);
14818
14819         var interceptor = function(value) {
14820           var result = lodashFunc.apply(lodash, arrayPush([value], args));
14821           return (isTaker && chainAll) ? result[0] : result;
14822         };
14823
14824         if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
14825           // Avoid lazy use if the iteratee has a "length" value other than `1`.
14826           isLazy = useLazy = false;
14827         }
14828         var chainAll = this.__chain__,
14829             isHybrid = !!this.__actions__.length,
14830             isUnwrapped = retUnwrapped && !chainAll,
14831             onlyLazy = isLazy && !isHybrid;
14832
14833         if (!retUnwrapped && useLazy) {
14834           value = onlyLazy ? value : new LazyWrapper(this);
14835           var result = func.apply(value, args);
14836           result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
14837           return new LodashWrapper(result, chainAll);
14838         }
14839         if (isUnwrapped && onlyLazy) {
14840           return func.apply(this, args);
14841         }
14842         result = this.thru(interceptor);
14843         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
14844       };
14845     });
14846
14847     // Add `Array` and `String` methods to `lodash.prototype`.
14848     arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
14849       var func = arrayProto[methodName],
14850           chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
14851           retUnwrapped = /^(?:pop|shift)$/.test(methodName);
14852
14853       lodash.prototype[methodName] = function() {
14854         var args = arguments;
14855         if (retUnwrapped && !this.__chain__) {
14856           return func.apply(this.value(), args);
14857         }
14858         return this[chainName](function(value) {
14859           return func.apply(value, args);
14860         });
14861       };
14862     });
14863
14864     // Map minified function names to their real names.
14865     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14866       var lodashFunc = lodash[methodName];
14867       if (lodashFunc) {
14868         var key = (lodashFunc.name + ''),
14869             names = realNames[key] || (realNames[key] = []);
14870
14871         names.push({ 'name': methodName, 'func': lodashFunc });
14872       }
14873     });
14874
14875     realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{
14876       'name': 'wrapper',
14877       'func': undefined
14878     }];
14879
14880     // Add functions to the lazy wrapper.
14881     LazyWrapper.prototype.clone = lazyClone;
14882     LazyWrapper.prototype.reverse = lazyReverse;
14883     LazyWrapper.prototype.value = lazyValue;
14884
14885     // Add chaining functions to the `lodash` wrapper.
14886     lodash.prototype.at = wrapperAt;
14887     lodash.prototype.chain = wrapperChain;
14888     lodash.prototype.commit = wrapperCommit;
14889     lodash.prototype.flatMap = wrapperFlatMap;
14890     lodash.prototype.next = wrapperNext;
14891     lodash.prototype.plant = wrapperPlant;
14892     lodash.prototype.reverse = wrapperReverse;
14893     lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
14894
14895     if (iteratorSymbol) {
14896       lodash.prototype[iteratorSymbol] = wrapperToIterator;
14897     }
14898     return lodash;
14899   }
14900
14901   /*--------------------------------------------------------------------------*/
14902
14903   // Export lodash.
14904   var _ = runInContext();
14905
14906   // Expose lodash on the free variable `window` or `self` when available. This
14907   // prevents errors in cases where lodash is loaded by a script tag in the presence
14908   // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
14909   (freeWindow || freeSelf || {})._ = _;
14910
14911   // Some AMD build optimizers like r.js check for condition patterns like the following:
14912   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
14913     // Define as an anonymous module so, through path mapping, it can be
14914     // referenced as the "underscore" module.
14915     define(function() {
14916       return _;
14917     });
14918   }
14919   // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
14920   else if (freeExports && freeModule) {
14921     // Export for Node.js.
14922     if (moduleExports) {
14923       (freeModule.exports = _)._ = _;
14924     }
14925     // Export for CommonJS support.
14926     freeExports._ = _;
14927   }
14928   else {
14929     // Export to the global object.
14930     root._ = _;
14931   }
14932 }.call(this));