Security update for permissions_by_term
[yaffs-website] / node_modules / uncss / node_modules / lodash / lodash.js
1 /**
2  * @license
3  * lodash 4.0.1 (Custom Build) <https://lodash.com/>
4  * Build: `lodash -d -o ./lodash.js`
5  * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
6  * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7  * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8  * Available under MIT license <https://lodash.com/license>
9  */
10 ;(function() {
11
12   /** Used as a safe reference for `undefined` in pre-ES5 environments. */
13   var undefined;
14
15   /** Used as the semantic version number. */
16   var VERSION = '4.0.1';
17
18   /** Used to compose bitmasks for wrapper metadata. */
19   var BIND_FLAG = 1,
20       BIND_KEY_FLAG = 2,
21       CURRY_BOUND_FLAG = 4,
22       CURRY_FLAG = 8,
23       CURRY_RIGHT_FLAG = 16,
24       PARTIAL_FLAG = 32,
25       PARTIAL_RIGHT_FLAG = 64,
26       ARY_FLAG = 128,
27       REARG_FLAG = 256,
28       FLIP_FLAG = 512;
29
30   /** Used to compose bitmasks for comparison styles. */
31   var UNORDERED_COMPARE_FLAG = 1,
32       PARTIAL_COMPARE_FLAG = 2;
33
34   /** Used as default options for `_.truncate`. */
35   var DEFAULT_TRUNC_LENGTH = 30,
36       DEFAULT_TRUNC_OMISSION = '...';
37
38   /** Used to detect hot functions by number of calls within a span of milliseconds. */
39   var HOT_COUNT = 150,
40       HOT_SPAN = 16;
41
42   /** Used as the size to enable large array optimizations. */
43   var LARGE_ARRAY_SIZE = 200;
44
45   /** Used to indicate the type of lazy iteratees. */
46   var LAZY_FILTER_FLAG = 1,
47       LAZY_MAP_FLAG = 2,
48       LAZY_WHILE_FLAG = 3;
49
50   /** Used as the `TypeError` message for "Functions" methods. */
51   var FUNC_ERROR_TEXT = 'Expected a function';
52
53   /** Used to stand-in for `undefined` hash values. */
54   var HASH_UNDEFINED = '__lodash_hash_undefined__';
55
56   /** Used as references for various `Number` constants. */
57   var INFINITY = 1 / 0,
58       MAX_SAFE_INTEGER = 9007199254740991,
59       MAX_INTEGER = 1.7976931348623157e+308,
60       NAN = 0 / 0;
61
62   /** Used as references for the maximum length and index of an array. */
63   var MAX_ARRAY_LENGTH = 4294967295,
64       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
65       HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
66
67   /** Used as the internal argument placeholder. */
68   var PLACEHOLDER = '__lodash_placeholder__';
69
70   /** `Object#toString` result references. */
71   var argsTag = '[object Arguments]',
72       arrayTag = '[object Array]',
73       boolTag = '[object Boolean]',
74       dateTag = '[object Date]',
75       errorTag = '[object Error]',
76       funcTag = '[object Function]',
77       genTag = '[object GeneratorFunction]',
78       mapTag = '[object Map]',
79       numberTag = '[object Number]',
80       objectTag = '[object Object]',
81       regexpTag = '[object RegExp]',
82       setTag = '[object Set]',
83       stringTag = '[object String]',
84       symbolTag = '[object Symbol]',
85       weakMapTag = '[object WeakMap]';
86
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', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function',
235     '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) ? exports : null;
338
339   /** Detect free variable `module`. */
340   var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
341
342   /** Detect free variable `global` from Node.js. */
343   var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
344
345   /** Detect free variable `self`. */
346   var freeSelf = checkGlobal(objectTypes[typeof self] && self);
347
348   /** Detect free variable `window`. */
349   var freeWindow = checkGlobal(objectTypes[typeof window] && window);
350
351   /** Detect the popular CommonJS extension `module.exports`. */
352   var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
353
354   /** Detect `this` as the global object. */
355   var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
356
357   /**
358    * Used as a reference to the global object.
359    *
360    * The `this` value is used if it's the global object to avoid Greasemonkey's
361    * restricted `window` object, otherwise the `window` object is used.
362    */
363   var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
364
365   /*--------------------------------------------------------------------------*/
366
367   /**
368    * Adds the key-value `pair` to `map`.
369    *
370    * @private
371    * @param {Object} map The map to modify.
372    * @param {Array} pair The key-value pair to add.
373    * @returns {Object} Returns `map`.
374    */
375   function addMapEntry(map, pair) {
376     map.set(pair[0], pair[1]);
377     return map;
378   }
379
380   /**
381    * Adds `value` to `set`.
382    *
383    * @private
384    * @param {Object} set The set to modify.
385    * @param {*} value The value to add.
386    * @returns {Object} Returns `set`.
387    */
388   function addSetEntry(set, value) {
389     set.add(value);
390     return set;
391   }
392
393   /**
394    * A faster alternative to `Function#apply`, this function invokes `func`
395    * with the `this` binding of `thisArg` and the arguments of `args`.
396    *
397    * @private
398    * @param {Function} func The function to invoke.
399    * @param {*} thisArg The `this` binding of `func`.
400    * @param {...*} [args] The arguments to invoke `func` with.
401    * @returns {*} Returns the result of `func`.
402    */
403   function apply(func, thisArg, args) {
404     var length = args ? args.length : 0;
405     switch (length) {
406       case 0: return func.call(thisArg);
407       case 1: return func.call(thisArg, args[0]);
408       case 2: return func.call(thisArg, args[0], args[1]);
409       case 3: return func.call(thisArg, args[0], args[1], args[2]);
410     }
411     return func.apply(thisArg, args);
412   }
413
414   /**
415    * Creates a new array concatenating `array` with `other`.
416    *
417    * @private
418    * @param {Array} array The first array to concatenate.
419    * @param {Array} other The second array to concatenate.
420    * @returns {Array} Returns the new concatenated array.
421    */
422   function arrayConcat(array, other) {
423     var index = -1,
424         length = array.length,
425         othIndex = -1,
426         othLength = other.length,
427         result = Array(length + othLength);
428
429     while (++index < length) {
430       result[index] = array[index];
431     }
432     while (++othIndex < othLength) {
433       result[index++] = other[othIndex];
434     }
435     return result;
436   }
437
438   /**
439    * A specialized version of `_.forEach` for arrays without support for
440    * iteratee shorthands.
441    *
442    * @private
443    * @param {Array} array The array to iterate over.
444    * @param {Function} iteratee The function invoked per iteration.
445    * @returns {Array} Returns `array`.
446    */
447   function arrayEach(array, iteratee) {
448     var index = -1,
449         length = array.length;
450
451     while (++index < length) {
452       if (iteratee(array[index], index, array) === false) {
453         break;
454       }
455     }
456     return array;
457   }
458
459   /**
460    * A specialized version of `_.forEachRight` for arrays without support for
461    * iteratee shorthands.
462    *
463    * @private
464    * @param {Array} array The array to iterate over.
465    * @param {Function} iteratee The function invoked per iteration.
466    * @returns {Array} Returns `array`.
467    */
468   function arrayEachRight(array, iteratee) {
469     var length = array.length;
470
471     while (length--) {
472       if (iteratee(array[length], length, array) === false) {
473         break;
474       }
475     }
476     return array;
477   }
478
479   /**
480    * A specialized version of `_.every` for arrays without support for
481    * iteratee shorthands.
482    *
483    * @private
484    * @param {Array} array The array to iterate over.
485    * @param {Function} predicate The function invoked per iteration.
486    * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
487    */
488   function arrayEvery(array, predicate) {
489     var index = -1,
490         length = array.length;
491
492     while (++index < length) {
493       if (!predicate(array[index], index, array)) {
494         return false;
495       }
496     }
497     return true;
498   }
499
500   /**
501    * A specialized version of `_.filter` for arrays without support for
502    * iteratee shorthands.
503    *
504    * @private
505    * @param {Array} array The array to iterate over.
506    * @param {Function} predicate The function invoked per iteration.
507    * @returns {Array} Returns the new filtered array.
508    */
509   function arrayFilter(array, predicate) {
510     var index = -1,
511         length = array.length,
512         resIndex = -1,
513         result = [];
514
515     while (++index < length) {
516       var value = array[index];
517       if (predicate(value, index, array)) {
518         result[++resIndex] = value;
519       }
520     }
521     return result;
522   }
523
524   /**
525    * A specialized version of `_.includes` for arrays without support for
526    * specifying an index to search from.
527    *
528    * @private
529    * @param {Array} array The array to search.
530    * @param {*} target The value to search for.
531    * @returns {boolean} Returns `true` if `target` is found, else `false`.
532    */
533   function arrayIncludes(array, value) {
534     return !!array.length && baseIndexOf(array, value, 0) > -1;
535   }
536
537   /**
538    * A specialized version of `_.includesWith` for arrays without support for
539    * specifying an index to search from.
540    *
541    * @private
542    * @param {Array} array The array to search.
543    * @param {*} target The value to search for.
544    * @param {Function} comparator The comparator invoked per element.
545    * @returns {boolean} Returns `true` if `target` is found, else `false`.
546    */
547   function arrayIncludesWith(array, value, comparator) {
548     var index = -1,
549         length = array.length;
550
551     while (++index < length) {
552       if (comparator(value, array[index])) {
553         return true;
554       }
555     }
556     return false;
557   }
558
559   /**
560    * A specialized version of `_.map` for arrays without support for iteratee
561    * shorthands.
562    *
563    * @private
564    * @param {Array} array The array to iterate over.
565    * @param {Function} iteratee The function invoked per iteration.
566    * @returns {Array} Returns the new mapped array.
567    */
568   function arrayMap(array, iteratee) {
569     var index = -1,
570         length = array.length,
571         result = Array(length);
572
573     while (++index < length) {
574       result[index] = iteratee(array[index], index, array);
575     }
576     return result;
577   }
578
579   /**
580    * Appends the elements of `values` to `array`.
581    *
582    * @private
583    * @param {Array} array The array to modify.
584    * @param {Array} values The values to append.
585    * @returns {Array} Returns `array`.
586    */
587   function arrayPush(array, values) {
588     var index = -1,
589         length = values.length,
590         offset = array.length;
591
592     while (++index < length) {
593       array[offset + index] = values[index];
594     }
595     return array;
596   }
597
598   /**
599    * A specialized version of `_.reduce` for arrays without support for
600    * iteratee shorthands.
601    *
602    * @private
603    * @param {Array} array The array to iterate over.
604    * @param {Function} iteratee The function invoked per iteration.
605    * @param {*} [accumulator] The initial value.
606    * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
607    * @returns {*} Returns the accumulated value.
608    */
609   function arrayReduce(array, iteratee, accumulator, initAccum) {
610     var index = -1,
611         length = array.length;
612
613     if (initAccum && length) {
614       accumulator = array[++index];
615     }
616     while (++index < length) {
617       accumulator = iteratee(accumulator, array[index], index, array);
618     }
619     return accumulator;
620   }
621
622   /**
623    * A specialized version of `_.reduceRight` for arrays without support for
624    * iteratee shorthands.
625    *
626    * @private
627    * @param {Array} array The array to iterate over.
628    * @param {Function} iteratee The function invoked per iteration.
629    * @param {*} [accumulator] The initial value.
630    * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value.
631    * @returns {*} Returns the accumulated value.
632    */
633   function arrayReduceRight(array, iteratee, accumulator, initAccum) {
634     var length = array.length;
635     if (initAccum && length) {
636       accumulator = array[--length];
637     }
638     while (length--) {
639       accumulator = iteratee(accumulator, array[length], length, array);
640     }
641     return accumulator;
642   }
643
644   /**
645    * A specialized version of `_.some` for arrays without support for iteratee
646    * shorthands.
647    *
648    * @private
649    * @param {Array} array The array to iterate over.
650    * @param {Function} predicate The function invoked per iteration.
651    * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
652    */
653   function arraySome(array, predicate) {
654     var index = -1,
655         length = array.length;
656
657     while (++index < length) {
658       if (predicate(array[index], index, array)) {
659         return true;
660       }
661     }
662     return false;
663   }
664
665   /**
666    * The base implementation of methods like `_.max` and `_.min` which accepts a
667    * `comparator` to determine the extremum value.
668    *
669    * @private
670    * @param {Array} array The array to iterate over.
671    * @param {Function} iteratee The iteratee invoked per iteration.
672    * @param {Function} comparator The comparator used to compare values.
673    * @returns {*} Returns the extremum value.
674    */
675   function baseExtremum(array, iteratee, comparator) {
676     var index = -1,
677         length = array.length;
678
679     while (++index < length) {
680       var value = array[index],
681           current = iteratee(value);
682
683       if (current != null && (computed === undefined
684             ? current === current
685             : comparator(current, computed)
686           )) {
687         var computed = current,
688             result = value;
689       }
690     }
691     return result;
692   }
693
694   /**
695    * The base implementation of methods like `_.find` and `_.findKey`, without
696    * support for iteratee shorthands, which iterates over `collection` using
697    * `eachFunc`.
698    *
699    * @private
700    * @param {Array|Object} collection The collection to search.
701    * @param {Function} predicate The function invoked per iteration.
702    * @param {Function} eachFunc The function to iterate over `collection`.
703    * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
704    * @returns {*} Returns the found element or its key, else `undefined`.
705    */
706   function baseFind(collection, predicate, eachFunc, retKey) {
707     var result;
708     eachFunc(collection, function(value, key, collection) {
709       if (predicate(value, key, collection)) {
710         result = retKey ? key : value;
711         return false;
712       }
713     });
714     return result;
715   }
716
717   /**
718    * The base implementation of `_.findIndex` and `_.findLastIndex` without
719    * support for iteratee shorthands.
720    *
721    * @private
722    * @param {Array} array The array to search.
723    * @param {Function} predicate The function invoked per iteration.
724    * @param {boolean} [fromRight] Specify iterating from right to left.
725    * @returns {number} Returns the index of the matched value, else `-1`.
726    */
727   function baseFindIndex(array, predicate, fromRight) {
728     var length = array.length,
729         index = fromRight ? length : -1;
730
731     while ((fromRight ? index-- : ++index < length)) {
732       if (predicate(array[index], index, array)) {
733         return index;
734       }
735     }
736     return -1;
737   }
738
739   /**
740    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
741    *
742    * @private
743    * @param {Array} array The array to search.
744    * @param {*} value The value to search for.
745    * @param {number} fromIndex The index to search from.
746    * @returns {number} Returns the index of the matched value, else `-1`.
747    */
748   function baseIndexOf(array, value, fromIndex) {
749     if (value !== value) {
750       return indexOfNaN(array, fromIndex);
751     }
752     var index = fromIndex - 1,
753         length = array.length;
754
755     while (++index < length) {
756       if (array[index] === value) {
757         return index;
758       }
759     }
760     return -1;
761   }
762
763   /**
764    * The base implementation of `_.reduce` and `_.reduceRight`, without support
765    * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
766    *
767    * @private
768    * @param {Array|Object} collection The collection to iterate over.
769    * @param {Function} iteratee The function invoked per iteration.
770    * @param {*} accumulator The initial value.
771    * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
772    * @param {Function} eachFunc The function to iterate over `collection`.
773    * @returns {*} Returns the accumulated value.
774    */
775   function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
776     eachFunc(collection, function(value, index, collection) {
777       accumulator = initAccum
778         ? (initAccum = false, value)
779         : iteratee(accumulator, value, index, collection);
780     });
781     return accumulator;
782   }
783
784   /**
785    * The base implementation of `_.sortBy` which uses `comparer` to define
786    * the sort order of `array` and replaces criteria objects with their
787    * corresponding values.
788    *
789    * @private
790    * @param {Array} array The array to sort.
791    * @param {Function} comparer The function to define sort order.
792    * @returns {Array} Returns `array`.
793    */
794   function baseSortBy(array, comparer) {
795     var length = array.length;
796
797     array.sort(comparer);
798     while (length--) {
799       array[length] = array[length].value;
800     }
801     return array;
802   }
803
804   /**
805    * The base implementation of `_.sum` without support for iteratee shorthands.
806    *
807    * @private
808    * @param {Array} array The array to iterate over.
809    * @param {Function} iteratee The function invoked per iteration.
810    * @returns {number} Returns the sum.
811    */
812   function baseSum(array, iteratee) {
813     var result,
814         index = -1,
815         length = array.length;
816
817     while (++index < length) {
818       var current = iteratee(array[index]);
819       if (current !== undefined) {
820         result = result === undefined ? current : (result + current);
821       }
822     }
823     return result;
824   }
825
826   /**
827    * The base implementation of `_.times` without support for iteratee shorthands
828    * or max array length checks.
829    *
830    * @private
831    * @param {number} n The number of times to invoke `iteratee`.
832    * @param {Function} iteratee The function invoked per iteration.
833    * @returns {Array} Returns the array of results.
834    */
835   function baseTimes(n, iteratee) {
836     var index = -1,
837         result = Array(n);
838
839     while (++index < n) {
840       result[index] = iteratee(index);
841     }
842     return result;
843   }
844
845   /**
846    * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
847    * of key-value pairs for `object` corresponding to the property names of `props`.
848    *
849    * @private
850    * @param {Object} object The object to query.
851    * @param {Array} props The property names to get values for.
852    * @returns {Object} Returns the new array of key-value pairs.
853    */
854   function baseToPairs(object, props) {
855     return arrayMap(props, function(key) {
856       return [key, object[key]];
857     });
858   }
859
860   /**
861    * The base implementation of `_.unary` without support for storing wrapper metadata.
862    *
863    * @private
864    * @param {Function} func The function to cap arguments for.
865    * @returns {Function} Returns the new function.
866    */
867   function baseUnary(func) {
868     return function(value) {
869       return func(value);
870     };
871   }
872
873   /**
874    * The base implementation of `_.values` and `_.valuesIn` which creates an
875    * array of `object` property values corresponding to the property names
876    * 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 array of property values.
882    */
883   function baseValues(object, props) {
884     return arrayMap(props, function(key) {
885       return object[key];
886     });
887   }
888
889   /**
890    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
891    * that is not found in the character symbols.
892    *
893    * @private
894    * @param {Array} strSymbols The string symbols to inspect.
895    * @param {Array} chrSymbols The character symbols to find.
896    * @returns {number} Returns the index of the first unmatched string symbol.
897    */
898   function charsStartIndex(strSymbols, chrSymbols) {
899     var index = -1,
900         length = strSymbols.length;
901
902     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
903     return index;
904   }
905
906   /**
907    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
908    * that is not found in the character symbols.
909    *
910    * @private
911    * @param {Array} strSymbols The string symbols to inspect.
912    * @param {Array} chrSymbols The character symbols to find.
913    * @returns {number} Returns the index of the last unmatched string symbol.
914    */
915   function charsEndIndex(strSymbols, chrSymbols) {
916     var index = strSymbols.length;
917
918     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
919     return index;
920   }
921
922   /**
923    * Checks if `value` is a global object.
924    *
925    * @private
926    * @param {*} value The value to check.
927    * @returns {null|Object} Returns `value` if it's a global object, else `null`.
928    */
929   function checkGlobal(value) {
930     return (value && value.Object === Object) ? value : null;
931   }
932
933   /**
934    * Compares values to sort them in ascending order.
935    *
936    * @private
937    * @param {*} value The value to compare.
938    * @param {*} other The other value to compare.
939    * @returns {number} Returns the sort order indicator for `value`.
940    */
941   function compareAscending(value, other) {
942     if (value !== other) {
943       var valIsNull = value === null,
944           valIsUndef = value === undefined,
945           valIsReflexive = value === value;
946
947       var othIsNull = other === null,
948           othIsUndef = other === undefined,
949           othIsReflexive = other === other;
950
951       if ((value > other && !othIsNull) || !valIsReflexive ||
952           (valIsNull && !othIsUndef && othIsReflexive) ||
953           (valIsUndef && othIsReflexive)) {
954         return 1;
955       }
956       if ((value < other && !valIsNull) || !othIsReflexive ||
957           (othIsNull && !valIsUndef && valIsReflexive) ||
958           (othIsUndef && valIsReflexive)) {
959         return -1;
960       }
961     }
962     return 0;
963   }
964
965   /**
966    * Used by `_.orderBy` to compare multiple properties of a value to another
967    * and stable sort them.
968    *
969    * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
970    * specify an order of "desc" for descending or "asc" for ascending sort order
971    * of corresponding values.
972    *
973    * @private
974    * @param {Object} object The object to compare.
975    * @param {Object} other The other object to compare.
976    * @param {boolean[]|string[]} orders The order to sort by for each property.
977    * @returns {number} Returns the sort order indicator for `object`.
978    */
979   function compareMultiple(object, other, orders) {
980     var index = -1,
981         objCriteria = object.criteria,
982         othCriteria = other.criteria,
983         length = objCriteria.length,
984         ordersLength = orders.length;
985
986     while (++index < length) {
987       var result = compareAscending(objCriteria[index], othCriteria[index]);
988       if (result) {
989         if (index >= ordersLength) {
990           return result;
991         }
992         var order = orders[index];
993         return result * (order == 'desc' ? -1 : 1);
994       }
995     }
996     // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
997     // that causes it, under certain circumstances, to provide the same value for
998     // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
999     // for more details.
1000     //
1001     // This also ensures a stable sort in V8 and other engines.
1002     // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
1003     return object.index - other.index;
1004   }
1005
1006   /**
1007    * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
1008    *
1009    * @private
1010    * @param {string} letter The matched letter to deburr.
1011    * @returns {string} Returns the deburred letter.
1012    */
1013   function deburrLetter(letter) {
1014     return deburredLetters[letter];
1015   }
1016
1017   /**
1018    * Used by `_.escape` to convert characters to HTML entities.
1019    *
1020    * @private
1021    * @param {string} chr The matched character to escape.
1022    * @returns {string} Returns the escaped character.
1023    */
1024   function escapeHtmlChar(chr) {
1025     return htmlEscapes[chr];
1026   }
1027
1028   /**
1029    * Used by `_.template` to escape characters for inclusion in compiled string literals.
1030    *
1031    * @private
1032    * @param {string} chr The matched character to escape.
1033    * @returns {string} Returns the escaped character.
1034    */
1035   function escapeStringChar(chr) {
1036     return '\\' + stringEscapes[chr];
1037   }
1038
1039   /**
1040    * Gets the index at which the first occurrence of `NaN` is found in `array`.
1041    *
1042    * @private
1043    * @param {Array} array The array to search.
1044    * @param {number} fromIndex The index to search from.
1045    * @param {boolean} [fromRight] Specify iterating from right to left.
1046    * @returns {number} Returns the index of the matched `NaN`, else `-1`.
1047    */
1048   function indexOfNaN(array, fromIndex, fromRight) {
1049     var length = array.length,
1050         index = fromIndex + (fromRight ? 0 : -1);
1051
1052     while ((fromRight ? index-- : ++index < length)) {
1053       var other = array[index];
1054       if (other !== other) {
1055         return index;
1056       }
1057     }
1058     return -1;
1059   }
1060
1061   /**
1062    * Checks if `value` is a host object in IE < 9.
1063    *
1064    * @private
1065    * @param {*} value The value to check.
1066    * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
1067    */
1068   function isHostObject(value) {
1069     // Many host objects are `Object` objects that can coerce to strings
1070     // despite having improperly defined `toString` methods.
1071     var result = false;
1072     if (value != null && typeof value.toString != 'function') {
1073       try {
1074         result = !!(value + '');
1075       } catch (e) {}
1076     }
1077     return result;
1078   }
1079
1080   /**
1081    * Checks if `value` is a valid array-like index.
1082    *
1083    * @private
1084    * @param {*} value The value to check.
1085    * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
1086    * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
1087    */
1088   function isIndex(value, length) {
1089     value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
1090     length = length == null ? MAX_SAFE_INTEGER : length;
1091     return value > -1 && value % 1 == 0 && value < length;
1092   }
1093
1094   /**
1095    * Converts `iterator` to an array.
1096    *
1097    * @private
1098    * @param {Object} iterator The iterator to convert.
1099    * @returns {Array} Returns the converted array.
1100    */
1101   function iteratorToArray(iterator) {
1102     var data,
1103         result = [];
1104
1105     while (!(data = iterator.next()).done) {
1106       result.push(data.value);
1107     }
1108     return result;
1109   }
1110
1111   /**
1112    * Converts `map` to an array.
1113    *
1114    * @private
1115    * @param {Object} map The map to convert.
1116    * @returns {Array} Returns the converted array.
1117    */
1118   function mapToArray(map) {
1119     var index = -1,
1120         result = Array(map.size);
1121
1122     map.forEach(function(value, key) {
1123       result[++index] = [key, value];
1124     });
1125     return result;
1126   }
1127
1128   /**
1129    * Replaces all `placeholder` elements in `array` with an internal placeholder
1130    * and returns an array of their indexes.
1131    *
1132    * @private
1133    * @param {Array} array The array to modify.
1134    * @param {*} placeholder The placeholder to replace.
1135    * @returns {Array} Returns the new array of placeholder indexes.
1136    */
1137   function replaceHolders(array, placeholder) {
1138     var index = -1,
1139         length = array.length,
1140         resIndex = -1,
1141         result = [];
1142
1143     while (++index < length) {
1144       if (array[index] === placeholder) {
1145         array[index] = PLACEHOLDER;
1146         result[++resIndex] = index;
1147       }
1148     }
1149     return result;
1150   }
1151
1152   /**
1153    * Converts `set` to an array.
1154    *
1155    * @private
1156    * @param {Object} set The set to convert.
1157    * @returns {Array} Returns the converted array.
1158    */
1159   function setToArray(set) {
1160     var index = -1,
1161         result = Array(set.size);
1162
1163     set.forEach(function(value) {
1164       result[++index] = value;
1165     });
1166     return result;
1167   }
1168
1169   /**
1170    * Gets the number of symbols in `string`.
1171    *
1172    * @private
1173    * @param {string} string The string to inspect.
1174    * @returns {number} Returns the string size.
1175    */
1176   function stringSize(string) {
1177     if (!(string && reHasComplexSymbol.test(string))) {
1178       return string.length;
1179     }
1180     var result = reComplexSymbol.lastIndex = 0;
1181     while (reComplexSymbol.test(string)) {
1182       result++;
1183     }
1184     return result;
1185   }
1186
1187   /**
1188    * Converts `string` to an array.
1189    *
1190    * @private
1191    * @param {string} string The string to convert.
1192    * @returns {Array} Returns the converted array.
1193    */
1194   function stringToArray(string) {
1195     return string.match(reComplexSymbol);
1196   }
1197
1198   /**
1199    * Used by `_.unescape` to convert HTML entities to characters.
1200    *
1201    * @private
1202    * @param {string} chr The matched character to unescape.
1203    * @returns {string} Returns the unescaped character.
1204    */
1205   function unescapeHtmlChar(chr) {
1206     return htmlUnescapes[chr];
1207   }
1208
1209   /*--------------------------------------------------------------------------*/
1210
1211   /**
1212    * Create a new pristine `lodash` function using the `context` object.
1213    *
1214    * @static
1215    * @memberOf _
1216    * @category Util
1217    * @param {Object} [context=root] The context object.
1218    * @returns {Function} Returns a new `lodash` function.
1219    * @example
1220    *
1221    * _.mixin({ 'foo': _.constant('foo') });
1222    *
1223    * var lodash = _.runInContext();
1224    * lodash.mixin({ 'bar': lodash.constant('bar') });
1225    *
1226    * _.isFunction(_.foo);
1227    * // => true
1228    * _.isFunction(_.bar);
1229    * // => false
1230    *
1231    * lodash.isFunction(lodash.foo);
1232    * // => false
1233    * lodash.isFunction(lodash.bar);
1234    * // => true
1235    *
1236    * // using `context` to mock `Date#getTime` use in `_.now`
1237    * var mock = _.runInContext({
1238    *   'Date': function() {
1239    *     return { 'getTime': getTimeMock };
1240    *   }
1241    * });
1242    *
1243    * // or creating a suped-up `defer` in Node.js
1244    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1245    */
1246   function runInContext(context) {
1247     context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
1248
1249     /** Built-in constructor references. */
1250     var Date = context.Date,
1251         Error = context.Error,
1252         Math = context.Math,
1253         RegExp = context.RegExp,
1254         TypeError = context.TypeError;
1255
1256     /** Used for built-in method references. */
1257     var arrayProto = context.Array.prototype,
1258         objectProto = context.Object.prototype;
1259
1260     /** Used to resolve the decompiled source of functions. */
1261     var funcToString = context.Function.prototype.toString;
1262
1263     /** Used to check objects for own properties. */
1264     var hasOwnProperty = objectProto.hasOwnProperty;
1265
1266     /** Used to generate unique IDs. */
1267     var idCounter = 0;
1268
1269     /** Used to infer the `Object` constructor. */
1270     var objectCtorString = funcToString.call(Object);
1271
1272     /**
1273      * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1274      * of values.
1275      */
1276     var objectToString = objectProto.toString;
1277
1278     /** Used to restore the original `_` reference in `_.noConflict`. */
1279     var oldDash = root._;
1280
1281     /** Used to detect if a method is native. */
1282     var reIsNative = RegExp('^' +
1283       funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1284       .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1285     );
1286
1287     /** Built-in value references. */
1288     var Reflect = context.Reflect,
1289         Symbol = context.Symbol,
1290         Uint8Array = context.Uint8Array,
1291         clearTimeout = context.clearTimeout,
1292         enumerate = Reflect ? Reflect.enumerate : undefined,
1293         getPrototypeOf = Object.getPrototypeOf,
1294         getOwnPropertySymbols = Object.getOwnPropertySymbols,
1295         iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
1296         propertyIsEnumerable = objectProto.propertyIsEnumerable,
1297         setTimeout = context.setTimeout,
1298         splice = arrayProto.splice;
1299
1300     /* Built-in method references for those with the same name as other `lodash` methods. */
1301     var nativeCeil = Math.ceil,
1302         nativeFloor = Math.floor,
1303         nativeIsFinite = context.isFinite,
1304         nativeJoin = arrayProto.join,
1305         nativeKeys = Object.keys,
1306         nativeMax = Math.max,
1307         nativeMin = Math.min,
1308         nativeParseInt = context.parseInt,
1309         nativeRandom = Math.random,
1310         nativeReverse = arrayProto.reverse;
1311
1312     /* Built-in method references that are verified to be native. */
1313     var Map = getNative(context, 'Map'),
1314         Set = getNative(context, 'Set'),
1315         WeakMap = getNative(context, 'WeakMap'),
1316         nativeCreate = getNative(Object, 'create');
1317
1318     /** Used to store function metadata. */
1319     var metaMap = WeakMap && new WeakMap;
1320
1321     /** Used to detect maps and sets. */
1322     var mapCtorString = Map ? funcToString.call(Map) : '',
1323         setCtorString = Set ? funcToString.call(Set) : '';
1324
1325     /** Used to convert symbols to primitives and strings. */
1326     var symbolProto = Symbol ? Symbol.prototype : undefined,
1327         symbolValueOf = Symbol ? symbolProto.valueOf : undefined,
1328         symbolToString = Symbol ? symbolProto.toString : undefined;
1329
1330     /** Used to lookup unminified function names. */
1331     var realNames = {};
1332
1333     /*------------------------------------------------------------------------*/
1334
1335     /**
1336      * Creates a `lodash` object which wraps `value` to enable implicit method
1337      * chaining. Methods that operate on and return arrays, collections, and
1338      * functions can be chained together. Methods that retrieve a single value or
1339      * may return a primitive value will automatically end the chain sequence and
1340      * return the unwrapped value. Otherwise, the value must be unwrapped with
1341      * `_#value`.
1342      *
1343      * Explicit chaining, which must be unwrapped with `_#value` in all cases,
1344      * may be enabled using `_.chain`.
1345      *
1346      * The execution of chained methods is lazy, that is, it's deferred until
1347      * `_#value` is implicitly or explicitly called.
1348      *
1349      * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
1350      * fusion is an optimization to merge iteratee calls; this avoids the creation
1351      * of intermediate arrays and can greatly reduce the number of iteratee executions.
1352      * Sections of a chain sequence qualify for shortcut fusion if the section is
1353      * applied to an array of at least two hundred elements and any iteratees
1354      * accept only one argument. The heuristic for whether a section qualifies
1355      * for shortcut fusion is subject to change.
1356      *
1357      * Chaining is supported in custom builds as long as the `_#value` method is
1358      * directly or indirectly included in the build.
1359      *
1360      * In addition to lodash methods, wrappers have `Array` and `String` methods.
1361      *
1362      * The wrapper `Array` methods are:
1363      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1364      *
1365      * The wrapper `String` methods are:
1366      * `replace` and `split`
1367      *
1368      * The wrapper methods that support shortcut fusion are:
1369      * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1370      * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1371      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1372      *
1373      * The chainable wrapper methods are:
1374      * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
1375      * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
1376      * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
1377      * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
1378      * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
1379      * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
1380      * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
1381      * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invokeMap`,
1382      * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`,
1383      * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`,
1384      * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`,
1385      * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`,
1386      * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`,
1387      * `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`,
1388      * `reject`, `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`,
1389      * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`,
1390      * `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`,
1391      * `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`,
1392      * `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`,
1393      * `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `without`,
1394      * `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, and `zipWith`
1395      *
1396      * The wrapper methods that are **not** chainable by default are:
1397      * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1398      * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
1399      * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
1400      * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`,
1401      * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1402      * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1403      * `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
1404      * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
1405      * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`, `isMatchWith`,
1406      * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`,
1407      * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isString`, `isUndefined`,
1408      * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`,
1409      * `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`,
1410      * `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`,
1411      * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
1412      * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
1413      * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
1414      * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toLower`,
1415      * `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`,
1416      * `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
1417      * `upperCase`, `upperFirst`, `value`, and `words`
1418      *
1419      * @name _
1420      * @constructor
1421      * @category Seq
1422      * @param {*} value The value to wrap in a `lodash` instance.
1423      * @returns {Object} Returns the new `lodash` wrapper instance.
1424      * @example
1425      *
1426      * function square(n) {
1427      *   return n * n;
1428      * }
1429      *
1430      * var wrapped = _([1, 2, 3]);
1431      *
1432      * // returns an unwrapped value
1433      * wrapped.reduce(_.add);
1434      * // => 6
1435      *
1436      * // returns a wrapped value
1437      * var squares = wrapped.map(square);
1438      *
1439      * _.isArray(squares);
1440      * // => false
1441      *
1442      * _.isArray(squares.value());
1443      * // => true
1444      */
1445     function lodash(value) {
1446       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1447         if (value instanceof LodashWrapper) {
1448           return value;
1449         }
1450         if (hasOwnProperty.call(value, '__wrapped__')) {
1451           return wrapperClone(value);
1452         }
1453       }
1454       return new LodashWrapper(value);
1455     }
1456
1457     /**
1458      * The function whose prototype all chaining wrappers inherit from.
1459      *
1460      * @private
1461      */
1462     function baseLodash() {
1463       // No operation performed.
1464     }
1465
1466     /**
1467      * The base constructor for creating `lodash` wrapper objects.
1468      *
1469      * @private
1470      * @param {*} value The value to wrap.
1471      * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
1472      */
1473     function LodashWrapper(value, chainAll) {
1474       this.__wrapped__ = value;
1475       this.__actions__ = [];
1476       this.__chain__ = !!chainAll;
1477       this.__index__ = 0;
1478       this.__values__ = undefined;
1479     }
1480
1481     /**
1482      * By default, the template delimiters used by lodash are like those in
1483      * embedded Ruby (ERB). Change the following template settings to use
1484      * alternative delimiters.
1485      *
1486      * @static
1487      * @memberOf _
1488      * @type Object
1489      */
1490     lodash.templateSettings = {
1491
1492       /**
1493        * Used to detect `data` property values to be HTML-escaped.
1494        *
1495        * @memberOf _.templateSettings
1496        * @type RegExp
1497        */
1498       'escape': reEscape,
1499
1500       /**
1501        * Used to detect code to be evaluated.
1502        *
1503        * @memberOf _.templateSettings
1504        * @type RegExp
1505        */
1506       'evaluate': reEvaluate,
1507
1508       /**
1509        * Used to detect `data` property values to inject.
1510        *
1511        * @memberOf _.templateSettings
1512        * @type RegExp
1513        */
1514       'interpolate': reInterpolate,
1515
1516       /**
1517        * Used to reference the data object in the template text.
1518        *
1519        * @memberOf _.templateSettings
1520        * @type string
1521        */
1522       'variable': '',
1523
1524       /**
1525        * Used to import variables into the compiled template.
1526        *
1527        * @memberOf _.templateSettings
1528        * @type Object
1529        */
1530       'imports': {
1531
1532         /**
1533          * A reference to the `lodash` function.
1534          *
1535          * @memberOf _.templateSettings.imports
1536          * @type Function
1537          */
1538         '_': lodash
1539       }
1540     };
1541
1542     /*------------------------------------------------------------------------*/
1543
1544     /**
1545      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1546      *
1547      * @private
1548      * @param {*} value The value to wrap.
1549      */
1550     function LazyWrapper(value) {
1551       this.__wrapped__ = value;
1552       this.__actions__ = [];
1553       this.__dir__ = 1;
1554       this.__filtered__ = false;
1555       this.__iteratees__ = [];
1556       this.__takeCount__ = MAX_ARRAY_LENGTH;
1557       this.__views__ = [];
1558     }
1559
1560     /**
1561      * Creates a clone of the lazy wrapper object.
1562      *
1563      * @private
1564      * @name clone
1565      * @memberOf LazyWrapper
1566      * @returns {Object} Returns the cloned `LazyWrapper` object.
1567      */
1568     function lazyClone() {
1569       var result = new LazyWrapper(this.__wrapped__);
1570       result.__actions__ = copyArray(this.__actions__);
1571       result.__dir__ = this.__dir__;
1572       result.__filtered__ = this.__filtered__;
1573       result.__iteratees__ = copyArray(this.__iteratees__);
1574       result.__takeCount__ = this.__takeCount__;
1575       result.__views__ = copyArray(this.__views__);
1576       return result;
1577     }
1578
1579     /**
1580      * Reverses the direction of lazy iteration.
1581      *
1582      * @private
1583      * @name reverse
1584      * @memberOf LazyWrapper
1585      * @returns {Object} Returns the new reversed `LazyWrapper` object.
1586      */
1587     function lazyReverse() {
1588       if (this.__filtered__) {
1589         var result = new LazyWrapper(this);
1590         result.__dir__ = -1;
1591         result.__filtered__ = true;
1592       } else {
1593         result = this.clone();
1594         result.__dir__ *= -1;
1595       }
1596       return result;
1597     }
1598
1599     /**
1600      * Extracts the unwrapped value from its lazy wrapper.
1601      *
1602      * @private
1603      * @name value
1604      * @memberOf LazyWrapper
1605      * @returns {*} Returns the unwrapped value.
1606      */
1607     function lazyValue() {
1608       var array = this.__wrapped__.value(),
1609           dir = this.__dir__,
1610           isArr = isArray(array),
1611           isRight = dir < 0,
1612           arrLength = isArr ? array.length : 0,
1613           view = getView(0, arrLength, this.__views__),
1614           start = view.start,
1615           end = view.end,
1616           length = end - start,
1617           index = isRight ? end : (start - 1),
1618           iteratees = this.__iteratees__,
1619           iterLength = iteratees.length,
1620           resIndex = 0,
1621           takeCount = nativeMin(length, this.__takeCount__);
1622
1623       if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
1624         return baseWrapperValue(array, this.__actions__);
1625       }
1626       var result = [];
1627
1628       outer:
1629       while (length-- && resIndex < takeCount) {
1630         index += dir;
1631
1632         var iterIndex = -1,
1633             value = array[index];
1634
1635         while (++iterIndex < iterLength) {
1636           var data = iteratees[iterIndex],
1637               iteratee = data.iteratee,
1638               type = data.type,
1639               computed = iteratee(value);
1640
1641           if (type == LAZY_MAP_FLAG) {
1642             value = computed;
1643           } else if (!computed) {
1644             if (type == LAZY_FILTER_FLAG) {
1645               continue outer;
1646             } else {
1647               break outer;
1648             }
1649           }
1650         }
1651         result[resIndex++] = value;
1652       }
1653       return result;
1654     }
1655
1656     /*------------------------------------------------------------------------*/
1657
1658     /**
1659      * Creates an hash object.
1660      *
1661      * @private
1662      * @returns {Object} Returns the new hash object.
1663      */
1664     function Hash() {}
1665
1666     /**
1667      * Removes `key` and its value from the hash.
1668      *
1669      * @private
1670      * @param {Object} hash The hash to modify.
1671      * @param {string} key The key of the value to remove.
1672      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1673      */
1674     function hashDelete(hash, key) {
1675       return hashHas(hash, key) && delete hash[key];
1676     }
1677
1678     /**
1679      * Gets the hash value for `key`.
1680      *
1681      * @private
1682      * @param {Object} hash The hash to query.
1683      * @param {string} key The key of the value to get.
1684      * @returns {*} Returns the entry value.
1685      */
1686     function hashGet(hash, key) {
1687       if (nativeCreate) {
1688         var result = hash[key];
1689         return result === HASH_UNDEFINED ? undefined : result;
1690       }
1691       return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
1692     }
1693
1694     /**
1695      * Checks if a hash value for `key` exists.
1696      *
1697      * @private
1698      * @param {Object} hash The hash to query.
1699      * @param {string} key The key of the entry to check.
1700      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1701      */
1702     function hashHas(hash, key) {
1703       return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
1704     }
1705
1706     /**
1707      * Sets the hash `key` to `value`.
1708      *
1709      * @private
1710      * @param {Object} hash The hash to modify.
1711      * @param {string} key The key of the value to set.
1712      * @param {*} value The value to set.
1713      */
1714     function hashSet(hash, key, value) {
1715       hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1716     }
1717
1718     /*------------------------------------------------------------------------*/
1719
1720     /**
1721      * Creates a map cache object to store key-value pairs.
1722      *
1723      * @private
1724      * @param {Array} [values] The values to cache.
1725      */
1726     function MapCache(values) {
1727       var index = -1,
1728           length = values ? values.length : 0;
1729
1730       this.clear();
1731       while (++index < length) {
1732         var entry = values[index];
1733         this.set(entry[0], entry[1]);
1734       }
1735     }
1736
1737     /**
1738      * Removes all key-value entries from the map.
1739      *
1740      * @private
1741      * @name clear
1742      * @memberOf MapCache
1743      */
1744     function mapClear() {
1745       this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], 'string': new Hash };
1746     }
1747
1748     /**
1749      * Removes `key` and its value from the map.
1750      *
1751      * @private
1752      * @name delete
1753      * @memberOf MapCache
1754      * @param {string} key The key of the value to remove.
1755      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1756      */
1757     function mapDelete(key) {
1758       var data = this.__data__;
1759       if (isKeyable(key)) {
1760         return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
1761       }
1762       return Map ? data.map['delete'](key) : assocDelete(data.map, key);
1763     }
1764
1765     /**
1766      * Gets the map value for `key`.
1767      *
1768      * @private
1769      * @name get
1770      * @memberOf MapCache
1771      * @param {string} key The key of the value to get.
1772      * @returns {*} Returns the entry value.
1773      */
1774     function mapGet(key) {
1775       var data = this.__data__;
1776       if (isKeyable(key)) {
1777         return hashGet(typeof key == 'string' ? data.string : data.hash, key);
1778       }
1779       return Map ? data.map.get(key) : assocGet(data.map, key);
1780     }
1781
1782     /**
1783      * Checks if a map value for `key` exists.
1784      *
1785      * @private
1786      * @name has
1787      * @memberOf MapCache
1788      * @param {string} key The key of the entry to check.
1789      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1790      */
1791     function mapHas(key) {
1792       var data = this.__data__;
1793       if (isKeyable(key)) {
1794         return hashHas(typeof key == 'string' ? data.string : data.hash, key);
1795       }
1796       return Map ? data.map.has(key) : assocHas(data.map, key);
1797     }
1798
1799     /**
1800      * Sets the map `key` to `value`.
1801      *
1802      * @private
1803      * @name set
1804      * @memberOf MapCache
1805      * @param {string} key The key of the value to set.
1806      * @param {*} value The value to set.
1807      * @returns {Object} Returns the map cache object.
1808      */
1809     function mapSet(key, value) {
1810       var data = this.__data__;
1811       if (isKeyable(key)) {
1812         hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
1813       } else if (Map) {
1814         data.map.set(key, value);
1815       } else {
1816         assocSet(data.map, key, value);
1817       }
1818       return this;
1819     }
1820
1821     /*------------------------------------------------------------------------*/
1822
1823     /**
1824      *
1825      * Creates a set cache object to store unique values.
1826      *
1827      * @private
1828      * @param {Array} [values] The values to cache.
1829      */
1830     function SetCache(values) {
1831       var index = -1,
1832           length = values ? values.length : 0;
1833
1834       this.__data__ = new MapCache;
1835       while (++index < length) {
1836         this.push(values[index]);
1837       }
1838     }
1839
1840     /**
1841      * Checks if `value` is in `cache`.
1842      *
1843      * @private
1844      * @param {Object} cache The set cache to search.
1845      * @param {*} value The value to search for.
1846      * @returns {number} Returns `true` if `value` is found, else `false`.
1847      */
1848     function cacheHas(cache, value) {
1849       var map = cache.__data__;
1850       if (isKeyable(value)) {
1851         var data = map.__data__,
1852             hash = typeof value == 'string' ? data.string : data.hash;
1853
1854         return hash[value] === HASH_UNDEFINED;
1855       }
1856       return map.has(value);
1857     }
1858
1859     /**
1860      * Adds `value` to the set cache.
1861      *
1862      * @private
1863      * @name push
1864      * @memberOf SetCache
1865      * @param {*} value The value to cache.
1866      */
1867     function cachePush(value) {
1868       var map = this.__data__;
1869       if (isKeyable(value)) {
1870         var data = map.__data__,
1871             hash = typeof value == 'string' ? data.string : data.hash;
1872
1873         hash[value] = HASH_UNDEFINED;
1874       }
1875       else {
1876         map.set(value, HASH_UNDEFINED);
1877       }
1878     }
1879
1880     /*------------------------------------------------------------------------*/
1881
1882     /**
1883      * Creates a stack cache object to store key-value pairs.
1884      *
1885      * @private
1886      * @param {Array} [values] The values to cache.
1887      */
1888     function Stack(values) {
1889       var index = -1,
1890           length = values ? values.length : 0;
1891
1892       this.clear();
1893       while (++index < length) {
1894         var entry = values[index];
1895         this.set(entry[0], entry[1]);
1896       }
1897     }
1898
1899     /**
1900      * Removes all key-value entries from the stack.
1901      *
1902      * @private
1903      * @name clear
1904      * @memberOf Stack
1905      */
1906     function stackClear() {
1907       this.__data__ = { 'array': [], 'map': null };
1908     }
1909
1910     /**
1911      * Removes `key` and its value from the stack.
1912      *
1913      * @private
1914      * @name delete
1915      * @memberOf Stack
1916      * @param {string} key The key of the value to remove.
1917      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1918      */
1919     function stackDelete(key) {
1920       var data = this.__data__,
1921           array = data.array;
1922
1923       return array ? assocDelete(array, key) : data.map['delete'](key);
1924     }
1925
1926     /**
1927      * Gets the stack value for `key`.
1928      *
1929      * @private
1930      * @name get
1931      * @memberOf Stack
1932      * @param {string} key The key of the value to get.
1933      * @returns {*} Returns the entry value.
1934      */
1935     function stackGet(key) {
1936       var data = this.__data__,
1937           array = data.array;
1938
1939       return array ? assocGet(array, key) : data.map.get(key);
1940     }
1941
1942     /**
1943      * Checks if a stack value for `key` exists.
1944      *
1945      * @private
1946      * @name has
1947      * @memberOf Stack
1948      * @param {string} key The key of the entry to check.
1949      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1950      */
1951     function stackHas(key) {
1952       var data = this.__data__,
1953           array = data.array;
1954
1955       return array ? assocHas(array, key) : data.map.has(key);
1956     }
1957
1958     /**
1959      * Sets the stack `key` to `value`.
1960      *
1961      * @private
1962      * @name set
1963      * @memberOf Stack
1964      * @param {string} key The key of the value to set.
1965      * @param {*} value The value to set.
1966      * @returns {Object} Returns the stack cache object.
1967      */
1968     function stackSet(key, value) {
1969       var data = this.__data__,
1970           array = data.array;
1971
1972       if (array) {
1973         if (array.length < (LARGE_ARRAY_SIZE - 1)) {
1974           assocSet(array, key, value);
1975         } else {
1976           data.array = null;
1977           data.map = new MapCache(array);
1978         }
1979       }
1980       var map = data.map;
1981       if (map) {
1982         map.set(key, value);
1983       }
1984       return this;
1985     }
1986
1987     /*------------------------------------------------------------------------*/
1988
1989     /**
1990      * Removes `key` and its value from the associative array.
1991      *
1992      * @private
1993      * @param {Array} array The array to query.
1994      * @param {string} key The key of the value to remove.
1995      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1996      */
1997     function assocDelete(array, key) {
1998       var index = assocIndexOf(array, key);
1999       if (index < 0) {
2000         return false;
2001       }
2002       var lastIndex = array.length - 1;
2003       if (index == lastIndex) {
2004         array.pop();
2005       } else {
2006         splice.call(array, index, 1);
2007       }
2008       return true;
2009     }
2010
2011     /**
2012      * Gets the associative array value for `key`.
2013      *
2014      * @private
2015      * @param {Array} array The array to query.
2016      * @param {string} key The key of the value to get.
2017      * @returns {*} Returns the entry value.
2018      */
2019     function assocGet(array, key) {
2020       var index = assocIndexOf(array, key);
2021       return index < 0 ? undefined : array[index][1];
2022     }
2023
2024     /**
2025      * Checks if an associative array value for `key` exists.
2026      *
2027      * @private
2028      * @param {Array} array The array to query.
2029      * @param {string} key The key of the entry to check.
2030      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2031      */
2032     function assocHas(array, key) {
2033       return assocIndexOf(array, key) > -1;
2034     }
2035
2036     /**
2037      * Gets the index at which the first occurrence of `key` is found in `array`
2038      * of key-value pairs.
2039      *
2040      * @private
2041      * @param {Array} array The array to search.
2042      * @param {*} key The key to search for.
2043      * @returns {number} Returns the index of the matched value, else `-1`.
2044      */
2045     function assocIndexOf(array, key) {
2046       var length = array.length;
2047       while (length--) {
2048         if (eq(array[length][0], key)) {
2049           return length;
2050         }
2051       }
2052       return -1;
2053     }
2054
2055     /**
2056      * Sets the associative array `key` to `value`.
2057      *
2058      * @private
2059      * @param {Array} array The array to modify.
2060      * @param {string} key The key of the value to set.
2061      * @param {*} value The value to set.
2062      */
2063     function assocSet(array, key, value) {
2064       var index = assocIndexOf(array, key);
2065       if (index < 0) {
2066         array.push([key, value]);
2067       } else {
2068         array[index][1] = value;
2069       }
2070     }
2071
2072     /*------------------------------------------------------------------------*/
2073
2074     /**
2075      * Used by `_.defaults` to customize its `_.assignIn` use.
2076      *
2077      * @private
2078      * @param {*} objValue The destination value.
2079      * @param {*} srcValue The source value.
2080      * @param {string} key The key of the property to assign.
2081      * @param {Object} object The parent object of `objValue`.
2082      * @returns {*} Returns the value to assign.
2083      */
2084     function assignInDefaults(objValue, srcValue, key, object) {
2085       if (objValue === undefined ||
2086           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2087         return srcValue;
2088       }
2089       return objValue;
2090     }
2091
2092     /**
2093      * This function is like `assignValue` except that it doesn't assign `undefined` values.
2094      *
2095      * @private
2096      * @param {Object} object The object to modify.
2097      * @param {string} key The key of the property to assign.
2098      * @param {*} value The value to assign.
2099      */
2100     function assignMergeValue(object, key, value) {
2101       if ((value !== undefined && !eq(object[key], value)) ||
2102           (typeof key == 'number' && value === undefined && !(key in object))) {
2103         object[key] = value;
2104       }
2105     }
2106
2107     /**
2108      * Assigns `value` to `key` of `object` if the existing value is not equivalent
2109      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
2110      * for equality comparisons.
2111      *
2112      * @private
2113      * @param {Object} object The object to modify.
2114      * @param {string} key The key of the property to assign.
2115      * @param {*} value The value to assign.
2116      */
2117     function assignValue(object, key, value) {
2118       var objValue = object[key];
2119       if ((!eq(objValue, value) ||
2120             (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
2121           (value === undefined && !(key in object))) {
2122         object[key] = value;
2123       }
2124     }
2125
2126     /**
2127      * The base implementation of `_.assign` without support for multiple sources
2128      * or `customizer` functions.
2129      *
2130      * @private
2131      * @param {Object} object The destination object.
2132      * @param {Object} source The source object.
2133      * @returns {Object} Returns `object`.
2134      */
2135     function baseAssign(object, source) {
2136       return object && copyObject(source, keys(source), object);
2137     }
2138
2139     /**
2140      * The base implementation of `_.at` without support for individual paths.
2141      *
2142      * @private
2143      * @param {Object} object The object to iterate over.
2144      * @param {string[]} paths The property paths of elements to pick.
2145      * @returns {Array} Returns the new array of picked elements.
2146      */
2147     function baseAt(object, paths) {
2148       var index = -1,
2149           isNil = object == null,
2150           length = paths.length,
2151           result = Array(length);
2152
2153       while (++index < length) {
2154         result[index] = isNil ? undefined : get(object, paths[index]);
2155       }
2156       return result;
2157     }
2158
2159     /**
2160      * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
2161      *
2162      * @private
2163      * @param {number} number The number to clamp.
2164      * @param {number} [lower] The lower bound.
2165      * @param {number} upper The upper bound.
2166      * @returns {number} Returns the clamped number.
2167      */
2168     function baseClamp(number, lower, upper) {
2169       if (number === number) {
2170         if (upper !== undefined) {
2171           number = number <= upper ? number : upper;
2172         }
2173         if (lower !== undefined) {
2174           number = number >= lower ? number : lower;
2175         }
2176       }
2177       return number;
2178     }
2179
2180     /**
2181      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2182      * traversed objects.
2183      *
2184      * @private
2185      * @param {*} value The value to clone.
2186      * @param {boolean} [isDeep] Specify a deep clone.
2187      * @param {Function} [customizer] The function to customize cloning.
2188      * @param {string} [key] The key of `value`.
2189      * @param {Object} [object] The parent object of `value`.
2190      * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2191      * @returns {*} Returns the cloned value.
2192      */
2193     function baseClone(value, isDeep, customizer, key, object, stack) {
2194       var result;
2195       if (customizer) {
2196         result = object ? customizer(value, key, object, stack) : customizer(value);
2197       }
2198       if (result !== undefined) {
2199         return result;
2200       }
2201       if (!isObject(value)) {
2202         return value;
2203       }
2204       var isArr = isArray(value);
2205       if (isArr) {
2206         result = initCloneArray(value);
2207         if (!isDeep) {
2208           return copyArray(value, result);
2209         }
2210       } else {
2211         var tag = getTag(value),
2212             isFunc = tag == funcTag || tag == genTag;
2213
2214         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2215           if (isHostObject(value)) {
2216             return object ? value : {};
2217           }
2218           result = initCloneObject(isFunc ? {} : value);
2219           if (!isDeep) {
2220             return copySymbols(value, baseAssign(result, value));
2221           }
2222         } else {
2223           return cloneableTags[tag]
2224             ? initCloneByTag(value, tag, isDeep)
2225             : (object ? value : {});
2226         }
2227       }
2228       // Check for circular references and return its corresponding clone.
2229       stack || (stack = new Stack);
2230       var stacked = stack.get(value);
2231       if (stacked) {
2232         return stacked;
2233       }
2234       stack.set(value, result);
2235
2236       // Recursively populate clone (susceptible to call stack limits).
2237       (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
2238         assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
2239       });
2240       return isArr ? result : copySymbols(value, result);
2241     }
2242
2243     /**
2244      * The base implementation of `_.conforms` which doesn't clone `source`.
2245      *
2246      * @private
2247      * @param {Object} source The object of property predicates to conform to.
2248      * @returns {Function} Returns the new function.
2249      */
2250     function baseConforms(source) {
2251       var props = keys(source),
2252           length = props.length;
2253
2254       return function(object) {
2255         if (object == null) {
2256           return !length;
2257         }
2258         var index = length;
2259         while (index--) {
2260           var key = props[index],
2261               predicate = source[key],
2262               value = object[key];
2263
2264           if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
2265             return false;
2266           }
2267         }
2268         return true;
2269       };
2270     }
2271
2272     /**
2273      * The base implementation of `_.create` without support for assigning
2274      * properties to the created object.
2275      *
2276      * @private
2277      * @param {Object} prototype The object to inherit from.
2278      * @returns {Object} Returns the new object.
2279      */
2280     var baseCreate = (function() {
2281       function object() {}
2282       return function(prototype) {
2283         if (isObject(prototype)) {
2284           object.prototype = prototype;
2285           var result = new object;
2286           object.prototype = undefined;
2287         }
2288         return result || {};
2289       };
2290     }());
2291
2292     /**
2293      * The base implementation of `_.delay` and `_.defer` which accepts an array
2294      * of `func` arguments.
2295      *
2296      * @private
2297      * @param {Function} func The function to delay.
2298      * @param {number} wait The number of milliseconds to delay invocation.
2299      * @param {Object} args The arguments provide to `func`.
2300      * @returns {number} Returns the timer id.
2301      */
2302     function baseDelay(func, wait, args) {
2303       if (typeof func != 'function') {
2304         throw new TypeError(FUNC_ERROR_TEXT);
2305       }
2306       return setTimeout(function() { func.apply(undefined, args); }, wait);
2307     }
2308
2309     /**
2310      * The base implementation of methods like `_.difference` without support for
2311      * excluding multiple arrays or iteratee shorthands.
2312      *
2313      * @private
2314      * @param {Array} array The array to inspect.
2315      * @param {Array} values The values to exclude.
2316      * @param {Function} [iteratee] The iteratee invoked per element.
2317      * @param {Function} [comparator] The comparator invoked per element.
2318      * @returns {Array} Returns the new array of filtered values.
2319      */
2320     function baseDifference(array, values, iteratee, comparator) {
2321       var index = -1,
2322           includes = arrayIncludes,
2323           isCommon = true,
2324           length = array.length,
2325           result = [],
2326           valuesLength = values.length;
2327
2328       if (!length) {
2329         return result;
2330       }
2331       if (iteratee) {
2332         values = arrayMap(values, baseUnary(iteratee));
2333       }
2334       if (comparator) {
2335         includes = arrayIncludesWith;
2336         isCommon = false;
2337       }
2338       else if (values.length >= LARGE_ARRAY_SIZE) {
2339         includes = cacheHas;
2340         isCommon = false;
2341         values = new SetCache(values);
2342       }
2343       outer:
2344       while (++index < length) {
2345         var value = array[index],
2346             computed = iteratee ? iteratee(value) : value;
2347
2348         if (isCommon && computed === computed) {
2349           var valuesIndex = valuesLength;
2350           while (valuesIndex--) {
2351             if (values[valuesIndex] === computed) {
2352               continue outer;
2353             }
2354           }
2355           result.push(value);
2356         }
2357         else if (!includes(values, computed, comparator)) {
2358           result.push(value);
2359         }
2360       }
2361       return result;
2362     }
2363
2364     /**
2365      * The base implementation of `_.forEach` without support for iteratee shorthands.
2366      *
2367      * @private
2368      * @param {Array|Object} collection The collection to iterate over.
2369      * @param {Function} iteratee The function invoked per iteration.
2370      * @returns {Array|Object} Returns `collection`.
2371      */
2372     var baseEach = createBaseEach(baseForOwn);
2373
2374     /**
2375      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2376      *
2377      * @private
2378      * @param {Array|Object} collection The collection to iterate over.
2379      * @param {Function} iteratee The function invoked per iteration.
2380      * @returns {Array|Object} Returns `collection`.
2381      */
2382     var baseEachRight = createBaseEach(baseForOwnRight, true);
2383
2384     /**
2385      * The base implementation of `_.every` without support for iteratee shorthands.
2386      *
2387      * @private
2388      * @param {Array|Object} collection The collection to iterate over.
2389      * @param {Function} predicate The function invoked per iteration.
2390      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
2391      */
2392     function baseEvery(collection, predicate) {
2393       var result = true;
2394       baseEach(collection, function(value, index, collection) {
2395         result = !!predicate(value, index, collection);
2396         return result;
2397       });
2398       return result;
2399     }
2400
2401     /**
2402      * The base implementation of `_.fill` without an iteratee call guard.
2403      *
2404      * @private
2405      * @param {Array} array The array to fill.
2406      * @param {*} value The value to fill `array` with.
2407      * @param {number} [start=0] The start position.
2408      * @param {number} [end=array.length] The end position.
2409      * @returns {Array} Returns `array`.
2410      */
2411     function baseFill(array, value, start, end) {
2412       var length = array.length;
2413
2414       start = toInteger(start);
2415       if (start < 0) {
2416         start = -start > length ? 0 : (length + start);
2417       }
2418       end = (end === undefined || end > length) ? length : toInteger(end);
2419       if (end < 0) {
2420         end += length;
2421       }
2422       end = start > end ? 0 : toLength(end);
2423       while (start < end) {
2424         array[start++] = value;
2425       }
2426       return array;
2427     }
2428
2429     /**
2430      * The base implementation of `_.filter` without support for iteratee shorthands.
2431      *
2432      * @private
2433      * @param {Array|Object} collection The collection to iterate over.
2434      * @param {Function} predicate The function invoked per iteration.
2435      * @returns {Array} Returns the new filtered array.
2436      */
2437     function baseFilter(collection, predicate) {
2438       var result = [];
2439       baseEach(collection, function(value, index, collection) {
2440         if (predicate(value, index, collection)) {
2441           result.push(value);
2442         }
2443       });
2444       return result;
2445     }
2446
2447     /**
2448      * The base implementation of `_.flatten` with support for restricting flattening.
2449      *
2450      * @private
2451      * @param {Array} array The array to flatten.
2452      * @param {boolean} [isDeep] Specify a deep flatten.
2453      * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
2454      * @param {Array} [result=[]] The initial result value.
2455      * @returns {Array} Returns the new flattened array.
2456      */
2457     function baseFlatten(array, isDeep, isStrict, result) {
2458       result || (result = []);
2459
2460       var index = -1,
2461           length = array.length;
2462
2463       while (++index < length) {
2464         var value = array[index];
2465         if (isArrayLikeObject(value) &&
2466             (isStrict || isArray(value) || isArguments(value))) {
2467           if (isDeep) {
2468             // Recursively flatten arrays (susceptible to call stack limits).
2469             baseFlatten(value, isDeep, isStrict, result);
2470           } else {
2471             arrayPush(result, value);
2472           }
2473         } else if (!isStrict) {
2474           result[result.length] = value;
2475         }
2476       }
2477       return result;
2478     }
2479
2480     /**
2481      * The base implementation of `baseForIn` and `baseForOwn` which iterates
2482      * over `object` properties returned by `keysFunc` invoking `iteratee` for
2483      * each property. Iteratee functions may exit iteration early by explicitly
2484      * returning `false`.
2485      *
2486      * @private
2487      * @param {Object} object The object to iterate over.
2488      * @param {Function} iteratee The function invoked per iteration.
2489      * @param {Function} keysFunc The function to get the keys of `object`.
2490      * @returns {Object} Returns `object`.
2491      */
2492     var baseFor = createBaseFor();
2493
2494     /**
2495      * This function is like `baseFor` except that it iterates over properties
2496      * in the opposite order.
2497      *
2498      * @private
2499      * @param {Object} object The object to iterate over.
2500      * @param {Function} iteratee The function invoked per iteration.
2501      * @param {Function} keysFunc The function to get the keys of `object`.
2502      * @returns {Object} Returns `object`.
2503      */
2504     var baseForRight = createBaseFor(true);
2505
2506     /**
2507      * The base implementation of `_.forIn` without support for iteratee shorthands.
2508      *
2509      * @private
2510      * @param {Object} object The object to iterate over.
2511      * @param {Function} iteratee The function invoked per iteration.
2512      * @returns {Object} Returns `object`.
2513      */
2514     function baseForIn(object, iteratee) {
2515       return object == null ? object : baseFor(object, iteratee, keysIn);
2516     }
2517
2518     /**
2519      * The base implementation of `_.forOwn` without support for iteratee shorthands.
2520      *
2521      * @private
2522      * @param {Object} object The object to iterate over.
2523      * @param {Function} iteratee The function invoked per iteration.
2524      * @returns {Object} Returns `object`.
2525      */
2526     function baseForOwn(object, iteratee) {
2527       return object && baseFor(object, iteratee, keys);
2528     }
2529
2530     /**
2531      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2532      *
2533      * @private
2534      * @param {Object} object The object to iterate over.
2535      * @param {Function} iteratee The function invoked per iteration.
2536      * @returns {Object} Returns `object`.
2537      */
2538     function baseForOwnRight(object, iteratee) {
2539       return object && baseForRight(object, iteratee, keys);
2540     }
2541
2542     /**
2543      * The base implementation of `_.functions` which creates an array of
2544      * `object` function property names filtered from those provided.
2545      *
2546      * @private
2547      * @param {Object} object The object to inspect.
2548      * @param {Array} props The property names to filter.
2549      * @returns {Array} Returns the new array of filtered property names.
2550      */
2551     function baseFunctions(object, props) {
2552       return arrayFilter(props, function(key) {
2553         return isFunction(object[key]);
2554       });
2555     }
2556
2557     /**
2558      * The base implementation of `_.get` without support for default values.
2559      *
2560      * @private
2561      * @param {Object} object The object to query.
2562      * @param {Array|string} path The path of the property to get.
2563      * @returns {*} Returns the resolved value.
2564      */
2565     function baseGet(object, path) {
2566       path = isKey(path, object) ? [path + ''] : baseToPath(path);
2567
2568       var index = 0,
2569           length = path.length;
2570
2571       while (object != null && index < length) {
2572         object = object[path[index++]];
2573       }
2574       return (index && index == length) ? object : undefined;
2575     }
2576
2577     /**
2578      * The base implementation of `_.has` without support for deep paths.
2579      *
2580      * @private
2581      * @param {Object} object The object to query.
2582      * @param {Array|string} key The key to check.
2583      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2584      */
2585     function baseHas(object, key) {
2586       // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
2587       // that are composed entirely of index properties, return `false` for
2588       // `hasOwnProperty` checks of them.
2589       return hasOwnProperty.call(object, key) ||
2590         (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
2591     }
2592
2593     /**
2594      * The base implementation of `_.hasIn` without support for deep paths.
2595      *
2596      * @private
2597      * @param {Object} object The object to query.
2598      * @param {Array|string} key The key to check.
2599      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2600      */
2601     function baseHasIn(object, key) {
2602       return key in Object(object);
2603     }
2604
2605     /**
2606      * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
2607      *
2608      * @private
2609      * @param {number} number The number to check.
2610      * @param {number} start The start of the range.
2611      * @param {number} end The end of the range.
2612      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
2613      */
2614     function baseInRange(number, start, end) {
2615       return number >= nativeMin(start, end) && number < nativeMax(start, end);
2616     }
2617
2618     /**
2619      * The base implementation of methods like `_.intersection`, without support
2620      * for iteratee shorthands, that accepts an array of arrays to inspect.
2621      *
2622      * @private
2623      * @param {Array} arrays The arrays to inspect.
2624      * @param {Function} [iteratee] The iteratee invoked per element.
2625      * @param {Function} [comparator] The comparator invoked per element.
2626      * @returns {Array} Returns the new array of shared values.
2627      */
2628     function baseIntersection(arrays, iteratee, comparator) {
2629       var includes = comparator ? arrayIncludesWith : arrayIncludes,
2630           othLength = arrays.length,
2631           othIndex = othLength,
2632           caches = Array(othLength),
2633           result = [];
2634
2635       while (othIndex--) {
2636         var array = arrays[othIndex];
2637         if (othIndex && iteratee) {
2638           array = arrayMap(array, baseUnary(iteratee));
2639         }
2640         caches[othIndex] = !comparator && (iteratee || array.length >= 120)
2641           ? new SetCache(othIndex && array)
2642           : undefined;
2643       }
2644       array = arrays[0];
2645
2646       var index = -1,
2647           length = array.length,
2648           seen = caches[0];
2649
2650       outer:
2651       while (++index < length) {
2652         var value = array[index],
2653             computed = iteratee ? iteratee(value) : value;
2654
2655         if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) {
2656           var othIndex = othLength;
2657           while (--othIndex) {
2658             var cache = caches[othIndex];
2659             if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) {
2660               continue outer;
2661             }
2662           }
2663           if (seen) {
2664             seen.push(computed);
2665           }
2666           result.push(value);
2667         }
2668       }
2669       return result;
2670     }
2671
2672     /**
2673      * The base implementation of `_.invoke` without support for individual
2674      * method arguments.
2675      *
2676      * @private
2677      * @param {Object} object The object to query.
2678      * @param {Array|string} path The path of the method to invoke.
2679      * @param {Array} args The arguments to invoke the method with.
2680      * @returns {*} Returns the result of the invoked method.
2681      */
2682     function baseInvoke(object, path, args) {
2683       if (!isKey(path, object)) {
2684         path = baseToPath(path);
2685         object = parent(object, path);
2686         path = last(path);
2687       }
2688       var func = object == null ? object : object[path];
2689       return func == null ? undefined : apply(func, object, args);
2690     }
2691
2692     /**
2693      * The base implementation of `_.isEqual` which supports partial comparisons
2694      * and tracks traversed objects.
2695      *
2696      * @private
2697      * @param {*} value The value to compare.
2698      * @param {*} other The other value to compare.
2699      * @param {Function} [customizer] The function to customize comparisons.
2700      * @param {boolean} [bitmask] The bitmask of comparison flags.
2701      *  The bitmask may be composed of the following flags:
2702      *     1 - Unordered comparison
2703      *     2 - Partial comparison
2704      * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2705      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2706      */
2707     function baseIsEqual(value, other, customizer, bitmask, stack) {
2708       if (value === other) {
2709         return true;
2710       }
2711       if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
2712         return value !== value && other !== other;
2713       }
2714       return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
2715     }
2716
2717     /**
2718      * A specialized version of `baseIsEqual` for arrays and objects which performs
2719      * deep comparisons and tracks traversed objects enabling objects with circular
2720      * references to be compared.
2721      *
2722      * @private
2723      * @param {Object} object The object to compare.
2724      * @param {Object} other The other object to compare.
2725      * @param {Function} equalFunc The function to determine equivalents of values.
2726      * @param {Function} [customizer] The function to customize comparisons.
2727      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
2728      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2729      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2730      */
2731     function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
2732       var objIsArr = isArray(object),
2733           othIsArr = isArray(other),
2734           objTag = arrayTag,
2735           othTag = arrayTag;
2736
2737       if (!objIsArr) {
2738         objTag = getTag(object);
2739         if (objTag == argsTag) {
2740           objTag = objectTag;
2741         } else if (objTag != objectTag) {
2742           objIsArr = isTypedArray(object);
2743         }
2744       }
2745       if (!othIsArr) {
2746         othTag = getTag(other);
2747         if (othTag == argsTag) {
2748           othTag = objectTag;
2749         } else if (othTag != objectTag) {
2750           othIsArr = isTypedArray(other);
2751         }
2752       }
2753       var objIsObj = objTag == objectTag && !isHostObject(object),
2754           othIsObj = othTag == objectTag && !isHostObject(other),
2755           isSameTag = objTag == othTag;
2756
2757       if (isSameTag && !(objIsArr || objIsObj)) {
2758         return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
2759       }
2760       var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
2761       if (!isPartial) {
2762         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2763             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2764
2765         if (objIsWrapped || othIsWrapped) {
2766           return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
2767         }
2768       }
2769       if (!isSameTag) {
2770         return false;
2771       }
2772       stack || (stack = new Stack);
2773       return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
2774     }
2775
2776     /**
2777      * The base implementation of `_.isMatch` without support for iteratee shorthands.
2778      *
2779      * @private
2780      * @param {Object} object The object to inspect.
2781      * @param {Object} source The object of property values to match.
2782      * @param {Array} matchData The property names, values, and compare flags to match.
2783      * @param {Function} [customizer] The function to customize comparisons.
2784      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
2785      */
2786     function baseIsMatch(object, source, matchData, customizer) {
2787       var index = matchData.length,
2788           length = index,
2789           noCustomizer = !customizer;
2790
2791       if (object == null) {
2792         return !length;
2793       }
2794       object = Object(object);
2795       while (index--) {
2796         var data = matchData[index];
2797         if ((noCustomizer && data[2])
2798               ? data[1] !== object[data[0]]
2799               : !(data[0] in object)
2800             ) {
2801           return false;
2802         }
2803       }
2804       while (++index < length) {
2805         data = matchData[index];
2806         var key = data[0],
2807             objValue = object[key],
2808             srcValue = data[1];
2809
2810         if (noCustomizer && data[2]) {
2811           if (objValue === undefined && !(key in object)) {
2812             return false;
2813           }
2814         } else {
2815           var stack = new Stack,
2816               result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
2817
2818           if (!(result === undefined
2819                 ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
2820                 : result
2821               )) {
2822             return false;
2823           }
2824         }
2825       }
2826       return true;
2827     }
2828
2829     /**
2830      * The base implementation of `_.iteratee`.
2831      *
2832      * @private
2833      * @param {*} [value=_.identity] The value to convert to an iteratee.
2834      * @returns {Function} Returns the iteratee.
2835      */
2836     function baseIteratee(value) {
2837       var type = typeof value;
2838       if (type == 'function') {
2839         return value;
2840       }
2841       if (value == null) {
2842         return identity;
2843       }
2844       if (type == 'object') {
2845         return isArray(value)
2846           ? baseMatchesProperty(value[0], value[1])
2847           : baseMatches(value);
2848       }
2849       return property(value);
2850     }
2851
2852     /**
2853      * The base implementation of `_.keys` which doesn't skip the constructor
2854      * property of prototypes or treat sparse arrays as dense.
2855      *
2856      * @private
2857      * @type Function
2858      * @param {Object} object The object to query.
2859      * @returns {Array} Returns the array of property names.
2860      */
2861     function baseKeys(object) {
2862       return nativeKeys(Object(object));
2863     }
2864
2865     /**
2866      * The base implementation of `_.keysIn` which doesn't skip the constructor
2867      * property of prototypes or treat sparse arrays as dense.
2868      *
2869      * @private
2870      * @param {Object} object The object to query.
2871      * @returns {Array} Returns the array of property names.
2872      */
2873     function baseKeysIn(object) {
2874       object = object == null ? object : Object(object);
2875
2876       var result = [];
2877       for (var key in object) {
2878         result.push(key);
2879       }
2880       return result;
2881     }
2882
2883     // Fallback for IE < 9 with es6-shim.
2884     if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
2885       baseKeysIn = function(object) {
2886         return iteratorToArray(enumerate(object));
2887       };
2888     }
2889
2890     /**
2891      * The base implementation of `_.map` without support for iteratee shorthands.
2892      *
2893      * @private
2894      * @param {Array|Object} collection The collection to iterate over.
2895      * @param {Function} iteratee The function invoked per iteration.
2896      * @returns {Array} Returns the new mapped array.
2897      */
2898     function baseMap(collection, iteratee) {
2899       var index = -1,
2900           result = isArrayLike(collection) ? Array(collection.length) : [];
2901
2902       baseEach(collection, function(value, key, collection) {
2903         result[++index] = iteratee(value, key, collection);
2904       });
2905       return result;
2906     }
2907
2908     /**
2909      * The base implementation of `_.matches` which doesn't clone `source`.
2910      *
2911      * @private
2912      * @param {Object} source The object of property values to match.
2913      * @returns {Function} Returns the new function.
2914      */
2915     function baseMatches(source) {
2916       var matchData = getMatchData(source);
2917       if (matchData.length == 1 && matchData[0][2]) {
2918         var key = matchData[0][0],
2919             value = matchData[0][1];
2920
2921         return function(object) {
2922           if (object == null) {
2923             return false;
2924           }
2925           return object[key] === value &&
2926             (value !== undefined || (key in Object(object)));
2927         };
2928       }
2929       return function(object) {
2930         return object === source || baseIsMatch(object, source, matchData);
2931       };
2932     }
2933
2934     /**
2935      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
2936      *
2937      * @private
2938      * @param {string} path The path of the property to get.
2939      * @param {*} srcValue The value to match.
2940      * @returns {Function} Returns the new function.
2941      */
2942     function baseMatchesProperty(path, srcValue) {
2943       return function(object) {
2944         var objValue = get(object, path);
2945         return (objValue === undefined && objValue === srcValue)
2946           ? hasIn(object, path)
2947           : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
2948       };
2949     }
2950
2951     /**
2952      * The base implementation of `_.merge` without support for multiple sources.
2953      *
2954      * @private
2955      * @param {Object} object The destination object.
2956      * @param {Object} source The source object.
2957      * @param {number} srcIndex The index of `source`.
2958      * @param {Function} [customizer] The function to customize merged values.
2959      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
2960      */
2961     function baseMerge(object, source, srcIndex, customizer, stack) {
2962       if (object === source) {
2963         return;
2964       }
2965       var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source);
2966       arrayEach(props || source, function(srcValue, key) {
2967         if (props) {
2968           key = srcValue;
2969           srcValue = source[key];
2970         }
2971         if (isObject(srcValue)) {
2972           stack || (stack = new Stack);
2973           baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
2974         }
2975         else {
2976           var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined;
2977           if (newValue === undefined) {
2978             newValue = srcValue;
2979           }
2980           assignMergeValue(object, key, newValue);
2981         }
2982       });
2983     }
2984
2985     /**
2986      * A specialized version of `baseMerge` for arrays and objects which performs
2987      * deep merges and tracks traversed objects enabling objects with circular
2988      * references to be merged.
2989      *
2990      * @private
2991      * @param {Object} object The destination object.
2992      * @param {Object} source The source object.
2993      * @param {string} key The key of the value to merge.
2994      * @param {number} srcIndex The index of `source`.
2995      * @param {Function} mergeFunc The function to merge values.
2996      * @param {Function} [customizer] The function to customize assigned values.
2997      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
2998      */
2999     function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3000       var objValue = object[key],
3001           srcValue = source[key],
3002           stacked = stack.get(srcValue) || stack.get(objValue);
3003
3004       if (stacked) {
3005         assignMergeValue(object, key, stacked);
3006         return;
3007       }
3008       var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined,
3009           isCommon = newValue === undefined;
3010
3011       if (isCommon) {
3012         newValue = srcValue;
3013         if (isArray(srcValue) || isTypedArray(srcValue)) {
3014           if (isArray(objValue)) {
3015             newValue = srcIndex ? copyArray(objValue) : objValue;
3016           }
3017           else if (isArrayLikeObject(objValue)) {
3018             newValue = copyArray(objValue);
3019           }
3020           else {
3021             newValue = baseClone(srcValue);
3022           }
3023         }
3024         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3025           if (isArguments(objValue)) {
3026             newValue = toPlainObject(objValue);
3027           }
3028           else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3029             newValue = baseClone(srcValue);
3030           }
3031           else {
3032             newValue = srcIndex ? baseClone(objValue) : objValue;
3033           }
3034         }
3035         else {
3036           isCommon = false;
3037         }
3038       }
3039       stack.set(srcValue, newValue);
3040
3041       if (isCommon) {
3042         // Recursively merge objects and arrays (susceptible to call stack limits).
3043         mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3044       }
3045       assignMergeValue(object, key, newValue);
3046     }
3047
3048     /**
3049      * The base implementation of `_.orderBy` without param guards.
3050      *
3051      * @private
3052      * @param {Array|Object} collection The collection to iterate over.
3053      * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3054      * @param {string[]} orders The sort orders of `iteratees`.
3055      * @returns {Array} Returns the new sorted array.
3056      */
3057     function baseOrderBy(collection, iteratees, orders) {
3058       var index = -1,
3059           toIteratee = getIteratee();
3060
3061       iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
3062         return toIteratee(iteratee);
3063       });
3064
3065       var result = baseMap(collection, function(value, key, collection) {
3066         var criteria = arrayMap(iteratees, function(iteratee) {
3067           return iteratee(value);
3068         });
3069         return { 'criteria': criteria, 'index': ++index, 'value': value };
3070       });
3071
3072       return baseSortBy(result, function(object, other) {
3073         return compareMultiple(object, other, orders);
3074       });
3075     }
3076
3077     /**
3078      * The base implementation of `_.pick` without support for individual
3079      * property names.
3080      *
3081      * @private
3082      * @param {Object} object The source object.
3083      * @param {string[]} props The property names to pick.
3084      * @returns {Object} Returns the new object.
3085      */
3086     function basePick(object, props) {
3087       object = Object(object);
3088       return arrayReduce(props, function(result, key) {
3089         if (key in object) {
3090           result[key] = object[key];
3091         }
3092         return result;
3093       }, {});
3094     }
3095
3096     /**
3097      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3098      *
3099      * @private
3100      * @param {Object} object The source object.
3101      * @param {Function} predicate The function invoked per property.
3102      * @returns {Object} Returns the new object.
3103      */
3104     function basePickBy(object, predicate) {
3105       var result = {};
3106       baseForIn(object, function(value, key) {
3107         if (predicate(value, key)) {
3108           result[key] = value;
3109         }
3110       });
3111       return result;
3112     }
3113
3114     /**
3115      * The base implementation of `_.property` without support for deep paths.
3116      *
3117      * @private
3118      * @param {string} key The key of the property to get.
3119      * @returns {Function} Returns the new function.
3120      */
3121     function baseProperty(key) {
3122       return function(object) {
3123         return object == null ? undefined : object[key];
3124       };
3125     }
3126
3127     /**
3128      * A specialized version of `baseProperty` which supports deep paths.
3129      *
3130      * @private
3131      * @param {Array|string} path The path of the property to get.
3132      * @returns {Function} Returns the new function.
3133      */
3134     function basePropertyDeep(path) {
3135       return function(object) {
3136         return baseGet(object, path);
3137       };
3138     }
3139
3140     /**
3141      * The base implementation of `_.pullAll`.
3142      *
3143      * @private
3144      * @param {Array} array The array to modify.
3145      * @param {Array} values The values to remove.
3146      * @returns {Array} Returns `array`.
3147      */
3148     function basePullAll(array, values) {
3149       return basePullAllBy(array, values);
3150     }
3151
3152     /**
3153      * The base implementation of `_.pullAllBy` without support for iteratee
3154      * shorthands.
3155      *
3156      * @private
3157      * @param {Array} array The array to modify.
3158      * @param {Array} values The values to remove.
3159      * @param {Function} [iteratee] The iteratee invoked per element.
3160      * @returns {Array} Returns `array`.
3161      */
3162     function basePullAllBy(array, values, iteratee) {
3163       var index = -1,
3164           length = values.length,
3165           seen = array;
3166
3167       if (iteratee) {
3168         seen = arrayMap(array, function(value) { return iteratee(value); });
3169       }
3170       while (++index < length) {
3171         var fromIndex = 0,
3172             value = values[index],
3173             computed = iteratee ? iteratee(value) : value;
3174
3175         while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
3176           if (seen !== array) {
3177             splice.call(seen, fromIndex, 1);
3178           }
3179           splice.call(array, fromIndex, 1);
3180         }
3181       }
3182       return array;
3183     }
3184
3185     /**
3186      * The base implementation of `_.pullAt` without support for individual
3187      * indexes or capturing the removed elements.
3188      *
3189      * @private
3190      * @param {Array} array The array to modify.
3191      * @param {number[]} indexes The indexes of elements to remove.
3192      * @returns {Array} Returns `array`.
3193      */
3194     function basePullAt(array, indexes) {
3195       var length = array ? indexes.length : 0,
3196           lastIndex = length - 1;
3197
3198       while (length--) {
3199         var index = indexes[length];
3200         if (lastIndex == length || index != previous) {
3201           var previous = index;
3202           if (isIndex(index)) {
3203             splice.call(array, index, 1);
3204           }
3205           else if (!isKey(index, array)) {
3206             var path = baseToPath(index),
3207                 object = parent(array, path);
3208
3209             if (object != null) {
3210               delete object[last(path)];
3211             }
3212           }
3213           else {
3214             delete array[index];
3215           }
3216         }
3217       }
3218       return array;
3219     }
3220
3221     /**
3222      * The base implementation of `_.random` without support for returning
3223      * floating-point numbers.
3224      *
3225      * @private
3226      * @param {number} lower The lower bound.
3227      * @param {number} upper The upper bound.
3228      * @returns {number} Returns the random number.
3229      */
3230     function baseRandom(lower, upper) {
3231       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3232     }
3233
3234     /**
3235      * The base implementation of `_.range` and `_.rangeRight` which doesn't
3236      * coerce arguments to numbers.
3237      *
3238      * @private
3239      * @param {number} start The start of the range.
3240      * @param {number} end The end of the range.
3241      * @param {number} step The value to increment or decrement by.
3242      * @param {boolean} [fromRight] Specify iterating from right to left.
3243      * @returns {Array} Returns the new array of numbers.
3244      */
3245     function baseRange(start, end, step, fromRight) {
3246       var index = -1,
3247           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3248           result = Array(length);
3249
3250       while (length--) {
3251         result[fromRight ? length : ++index] = start;
3252         start += step;
3253       }
3254       return result;
3255     }
3256
3257     /**
3258      * The base implementation of `_.set`.
3259      *
3260      * @private
3261      * @param {Object} object The object to query.
3262      * @param {Array|string} path The path of the property to set.
3263      * @param {*} value The value to set.
3264      * @param {Function} [customizer] The function to customize path creation.
3265      * @returns {Object} Returns `object`.
3266      */
3267     function baseSet(object, path, value, customizer) {
3268       path = isKey(path, object) ? [path + ''] : baseToPath(path);
3269
3270       var index = -1,
3271           length = path.length,
3272           lastIndex = length - 1,
3273           nested = object;
3274
3275       while (nested != null && ++index < length) {
3276         var key = path[index];
3277         if (isObject(nested)) {
3278           var newValue = value;
3279           if (index != lastIndex) {
3280             var objValue = nested[key];
3281             newValue = customizer ? customizer(objValue, key, nested) : undefined;
3282             if (newValue === undefined) {
3283               newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue;
3284             }
3285           }
3286           assignValue(nested, key, newValue);
3287         }
3288         nested = nested[key];
3289       }
3290       return object;
3291     }
3292
3293     /**
3294      * The base implementation of `setData` without support for hot loop detection.
3295      *
3296      * @private
3297      * @param {Function} func The function to associate metadata with.
3298      * @param {*} data The metadata.
3299      * @returns {Function} Returns `func`.
3300      */
3301     var baseSetData = !metaMap ? identity : function(func, data) {
3302       metaMap.set(func, data);
3303       return func;
3304     };
3305
3306     /**
3307      * The base implementation of `_.slice` without an iteratee call guard.
3308      *
3309      * @private
3310      * @param {Array} array The array to slice.
3311      * @param {number} [start=0] The start position.
3312      * @param {number} [end=array.length] The end position.
3313      * @returns {Array} Returns the slice of `array`.
3314      */
3315     function baseSlice(array, start, end) {
3316       var index = -1,
3317           length = array.length;
3318
3319       if (start < 0) {
3320         start = -start > length ? 0 : (length + start);
3321       }
3322       end = end > length ? length : end;
3323       if (end < 0) {
3324         end += length;
3325       }
3326       length = start > end ? 0 : ((end - start) >>> 0);
3327       start >>>= 0;
3328
3329       var result = Array(length);
3330       while (++index < length) {
3331         result[index] = array[index + start];
3332       }
3333       return result;
3334     }
3335
3336     /**
3337      * The base implementation of `_.some` without support for iteratee shorthands.
3338      *
3339      * @private
3340      * @param {Array|Object} collection The collection to iterate over.
3341      * @param {Function} predicate The function invoked per iteration.
3342      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
3343      */
3344     function baseSome(collection, predicate) {
3345       var result;
3346
3347       baseEach(collection, function(value, index, collection) {
3348         result = predicate(value, index, collection);
3349         return !result;
3350       });
3351       return !!result;
3352     }
3353
3354     /**
3355      * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
3356      * performs a binary search of `array` to determine the index at which `value`
3357      * should be inserted into `array` in order to maintain its sort order.
3358      *
3359      * @private
3360      * @param {Array} array The sorted array to inspect.
3361      * @param {*} value The value to evaluate.
3362      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3363      * @returns {number} Returns the index at which `value` should be inserted
3364      *  into `array`.
3365      */
3366     function baseSortedIndex(array, value, retHighest) {
3367       var low = 0,
3368           high = array ? array.length : low;
3369
3370       if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
3371         while (low < high) {
3372           var mid = (low + high) >>> 1,
3373               computed = array[mid];
3374
3375           if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
3376             low = mid + 1;
3377           } else {
3378             high = mid;
3379           }
3380         }
3381         return high;
3382       }
3383       return baseSortedIndexBy(array, value, identity, retHighest);
3384     }
3385
3386     /**
3387      * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
3388      * which invokes `iteratee` for `value` and each element of `array` to compute
3389      * their sort ranking. The iteratee is invoked with one argument; (value).
3390      *
3391      * @private
3392      * @param {Array} array The sorted array to inspect.
3393      * @param {*} value The value to evaluate.
3394      * @param {Function} iteratee The iteratee invoked per element.
3395      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3396      * @returns {number} Returns the index at which `value` should be inserted into `array`.
3397      */
3398     function baseSortedIndexBy(array, value, iteratee, retHighest) {
3399       value = iteratee(value);
3400
3401       var low = 0,
3402           high = array ? array.length : 0,
3403           valIsNaN = value !== value,
3404           valIsNull = value === null,
3405           valIsUndef = value === undefined;
3406
3407       while (low < high) {
3408         var mid = nativeFloor((low + high) / 2),
3409             computed = iteratee(array[mid]),
3410             isDef = computed !== undefined,
3411             isReflexive = computed === computed;
3412
3413         if (valIsNaN) {
3414           var setLow = isReflexive || retHighest;
3415         } else if (valIsNull) {
3416           setLow = isReflexive && isDef && (retHighest || computed != null);
3417         } else if (valIsUndef) {
3418           setLow = isReflexive && (retHighest || isDef);
3419         } else if (computed == null) {
3420           setLow = false;
3421         } else {
3422           setLow = retHighest ? (computed <= value) : (computed < value);
3423         }
3424         if (setLow) {
3425           low = mid + 1;
3426         } else {
3427           high = mid;
3428         }
3429       }
3430       return nativeMin(high, MAX_ARRAY_INDEX);
3431     }
3432
3433     /**
3434      * The base implementation of `_.sortedUniq`.
3435      *
3436      * @private
3437      * @param {Array} array The array to inspect.
3438      * @returns {Array} Returns the new duplicate free array.
3439      */
3440     function baseSortedUniq(array) {
3441       return baseSortedUniqBy(array);
3442     }
3443
3444     /**
3445      * The base implementation of `_.sortedUniqBy` without support for iteratee
3446      * shorthands.
3447      *
3448      * @private
3449      * @param {Array} array The array to inspect.
3450      * @param {Function} [iteratee] The iteratee invoked per element.
3451      * @returns {Array} Returns the new duplicate free array.
3452      */
3453     function baseSortedUniqBy(array, iteratee) {
3454       var index = 0,
3455           length = array.length,
3456           value = array[0],
3457           computed = iteratee ? iteratee(value) : value,
3458           seen = computed,
3459           resIndex = 0,
3460           result = [value];
3461
3462       while (++index < length) {
3463         value = array[index],
3464         computed = iteratee ? iteratee(value) : value;
3465
3466         if (!eq(computed, seen)) {
3467           seen = computed;
3468           result[++resIndex] = value;
3469         }
3470       }
3471       return result;
3472     }
3473
3474     /**
3475      * The base implementation of `_.toPath` which only converts `value` to a
3476      * path if it's not one.
3477      *
3478      * @private
3479      * @param {*} value The value to process.
3480      * @returns {Array} Returns the property path array.
3481      */
3482     function baseToPath(value) {
3483       return isArray(value) ? value : stringToPath(value);
3484     }
3485
3486     /**
3487      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
3488      *
3489      * @private
3490      * @param {Array} array The array to inspect.
3491      * @param {Function} [iteratee] The iteratee invoked per element.
3492      * @param {Function} [comparator] The comparator invoked per element.
3493      * @returns {Array} Returns the new duplicate free array.
3494      */
3495     function baseUniq(array, iteratee, comparator) {
3496       var index = -1,
3497           includes = arrayIncludes,
3498           length = array.length,
3499           isCommon = true,
3500           result = [],
3501           seen = result;
3502
3503       if (comparator) {
3504         isCommon = false;
3505         includes = arrayIncludesWith;
3506       }
3507       else if (length >= LARGE_ARRAY_SIZE) {
3508         var set = iteratee ? null : createSet(array);
3509         if (set) {
3510           return setToArray(set);
3511         }
3512         isCommon = false;
3513         includes = cacheHas;
3514         seen = new SetCache;
3515       }
3516       else {
3517         seen = iteratee ? [] : result;
3518       }
3519       outer:
3520       while (++index < length) {
3521         var value = array[index],
3522             computed = iteratee ? iteratee(value) : value;
3523
3524         if (isCommon && computed === computed) {
3525           var seenIndex = seen.length;
3526           while (seenIndex--) {
3527             if (seen[seenIndex] === computed) {
3528               continue outer;
3529             }
3530           }
3531           if (iteratee) {
3532             seen.push(computed);
3533           }
3534           result.push(value);
3535         }
3536         else if (!includes(seen, computed, comparator)) {
3537           if (seen !== result) {
3538             seen.push(computed);
3539           }
3540           result.push(value);
3541         }
3542       }
3543       return result;
3544     }
3545
3546     /**
3547      * The base implementation of `_.unset`.
3548      *
3549      * @private
3550      * @param {Object} object The object to modify.
3551      * @param {Array|string} path The path of the property to unset.
3552      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
3553      */
3554     function baseUnset(object, path) {
3555       path = isKey(path, object) ? [path + ''] : baseToPath(path);
3556       object = parent(object, path);
3557       var key = last(path);
3558       return (object != null && has(object, key)) ? delete object[key] : true;
3559     }
3560
3561     /**
3562      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
3563      * without support for iteratee shorthands.
3564      *
3565      * @private
3566      * @param {Array} array The array to query.
3567      * @param {Function} predicate The function invoked per iteration.
3568      * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
3569      * @param {boolean} [fromRight] Specify iterating from right to left.
3570      * @returns {Array} Returns the slice of `array`.
3571      */
3572     function baseWhile(array, predicate, isDrop, fromRight) {
3573       var length = array.length,
3574           index = fromRight ? length : -1;
3575
3576       while ((fromRight ? index-- : ++index < length) &&
3577         predicate(array[index], index, array)) {}
3578
3579       return isDrop
3580         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
3581         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
3582     }
3583
3584     /**
3585      * The base implementation of `wrapperValue` which returns the result of
3586      * performing a sequence of actions on the unwrapped `value`, where each
3587      * successive action is supplied the return value of the previous.
3588      *
3589      * @private
3590      * @param {*} value The unwrapped value.
3591      * @param {Array} actions Actions to perform to resolve the unwrapped value.
3592      * @returns {*} Returns the resolved value.
3593      */
3594     function baseWrapperValue(value, actions) {
3595       var result = value;
3596       if (result instanceof LazyWrapper) {
3597         result = result.value();
3598       }
3599       return arrayReduce(actions, function(result, action) {
3600         return action.func.apply(action.thisArg, arrayPush([result], action.args));
3601       }, result);
3602     }
3603
3604     /**
3605      * The base implementation of methods like `_.xor`, without support for
3606      * iteratee shorthands, that accepts an array of arrays to inspect.
3607      *
3608      * @private
3609      * @param {Array} arrays The arrays to inspect.
3610      * @param {Function} [iteratee] The iteratee invoked per element.
3611      * @param {Function} [comparator] The comparator invoked per element.
3612      * @returns {Array} Returns the new array of values.
3613      */
3614     function baseXor(arrays, iteratee, comparator) {
3615       var index = -1,
3616           length = arrays.length;
3617
3618       while (++index < length) {
3619         var result = result
3620           ? arrayPush(
3621               baseDifference(result, arrays[index], iteratee, comparator),
3622               baseDifference(arrays[index], result, iteratee, comparator)
3623             )
3624           : arrays[index];
3625       }
3626       return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
3627     }
3628
3629     /**
3630      * Creates a clone of `buffer`.
3631      *
3632      * @private
3633      * @param {ArrayBuffer} buffer The array buffer to clone.
3634      * @returns {ArrayBuffer} Returns the cloned array buffer.
3635      */
3636     function cloneBuffer(buffer) {
3637       var Ctor = buffer.constructor,
3638           result = new Ctor(buffer.byteLength),
3639           view = new Uint8Array(result);
3640
3641       view.set(new Uint8Array(buffer));
3642       return result;
3643     }
3644
3645     /**
3646      * Creates a clone of `map`.
3647      *
3648      * @private
3649      * @param {Object} map The map to clone.
3650      * @returns {Object} Returns the cloned map.
3651      */
3652     function cloneMap(map) {
3653       var Ctor = map.constructor;
3654       return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
3655     }
3656
3657     /**
3658      * Creates a clone of `regexp`.
3659      *
3660      * @private
3661      * @param {Object} regexp The regexp to clone.
3662      * @returns {Object} Returns the cloned regexp.
3663      */
3664     function cloneRegExp(regexp) {
3665       var Ctor = regexp.constructor,
3666           result = new Ctor(regexp.source, reFlags.exec(regexp));
3667
3668       result.lastIndex = regexp.lastIndex;
3669       return result;
3670     }
3671
3672     /**
3673      * Creates a clone of `set`.
3674      *
3675      * @private
3676      * @param {Object} set The set to clone.
3677      * @returns {Object} Returns the cloned set.
3678      */
3679     function cloneSet(set) {
3680       var Ctor = set.constructor;
3681       return arrayReduce(setToArray(set), addSetEntry, new Ctor);
3682     }
3683
3684     /**
3685      * Creates a clone of the `symbol` object.
3686      *
3687      * @private
3688      * @param {Object} symbol The symbol object to clone.
3689      * @returns {Object} Returns the cloned symbol object.
3690      */
3691     function cloneSymbol(symbol) {
3692       return Symbol ? Object(symbolValueOf.call(symbol)) : {};
3693     }
3694
3695     /**
3696      * Creates a clone of `typedArray`.
3697      *
3698      * @private
3699      * @param {Object} typedArray The typed array to clone.
3700      * @param {boolean} [isDeep] Specify a deep clone.
3701      * @returns {Object} Returns the cloned typed array.
3702      */
3703     function cloneTypedArray(typedArray, isDeep) {
3704       var buffer = typedArray.buffer,
3705           Ctor = typedArray.constructor;
3706
3707       return new Ctor(isDeep ? cloneBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
3708     }
3709
3710     /**
3711      * Creates an array that is the composition of partially applied arguments,
3712      * placeholders, and provided arguments into a single array of arguments.
3713      *
3714      * @private
3715      * @param {Array|Object} args The provided arguments.
3716      * @param {Array} partials The arguments to prepend to those provided.
3717      * @param {Array} holders The `partials` placeholder indexes.
3718      * @returns {Array} Returns the new array of composed arguments.
3719      */
3720     function composeArgs(args, partials, holders) {
3721       var holdersLength = holders.length,
3722           argsIndex = -1,
3723           argsLength = nativeMax(args.length - holdersLength, 0),
3724           leftIndex = -1,
3725           leftLength = partials.length,
3726           result = Array(leftLength + argsLength);
3727
3728       while (++leftIndex < leftLength) {
3729         result[leftIndex] = partials[leftIndex];
3730       }
3731       while (++argsIndex < holdersLength) {
3732         result[holders[argsIndex]] = args[argsIndex];
3733       }
3734       while (argsLength--) {
3735         result[leftIndex++] = args[argsIndex++];
3736       }
3737       return result;
3738     }
3739
3740     /**
3741      * This function is like `composeArgs` except that the arguments composition
3742      * is tailored for `_.partialRight`.
3743      *
3744      * @private
3745      * @param {Array|Object} args The provided arguments.
3746      * @param {Array} partials The arguments to append to those provided.
3747      * @param {Array} holders The `partials` placeholder indexes.
3748      * @returns {Array} Returns the new array of composed arguments.
3749      */
3750     function composeArgsRight(args, partials, holders) {
3751       var holdersIndex = -1,
3752           holdersLength = holders.length,
3753           argsIndex = -1,
3754           argsLength = nativeMax(args.length - holdersLength, 0),
3755           rightIndex = -1,
3756           rightLength = partials.length,
3757           result = Array(argsLength + rightLength);
3758
3759       while (++argsIndex < argsLength) {
3760         result[argsIndex] = args[argsIndex];
3761       }
3762       var offset = argsIndex;
3763       while (++rightIndex < rightLength) {
3764         result[offset + rightIndex] = partials[rightIndex];
3765       }
3766       while (++holdersIndex < holdersLength) {
3767         result[offset + holders[holdersIndex]] = args[argsIndex++];
3768       }
3769       return result;
3770     }
3771
3772     /**
3773      * Copies the values of `source` to `array`.
3774      *
3775      * @private
3776      * @param {Array} source The array to copy values from.
3777      * @param {Array} [array=[]] The array to copy values to.
3778      * @returns {Array} Returns `array`.
3779      */
3780     function copyArray(source, array) {
3781       var index = -1,
3782           length = source.length;
3783
3784       array || (array = Array(length));
3785       while (++index < length) {
3786         array[index] = source[index];
3787       }
3788       return array;
3789     }
3790
3791     /**
3792      * Copies properties of `source` to `object`.
3793      *
3794      * @private
3795      * @param {Object} source The object to copy properties from.
3796      * @param {Array} props The property names to copy.
3797      * @param {Object} [object={}] The object to copy properties to.
3798      * @returns {Object} Returns `object`.
3799      */
3800     function copyObject(source, props, object) {
3801       return copyObjectWith(source, props, object);
3802     }
3803
3804     /**
3805      * This function is like `copyObject` except that it accepts a function to
3806      * customize copied values.
3807      *
3808      * @private
3809      * @param {Object} source The object to copy properties from.
3810      * @param {Array} props The property names to copy.
3811      * @param {Object} [object={}] The object to copy properties to.
3812      * @param {Function} [customizer] The function to customize copied values.
3813      * @returns {Object} Returns `object`.
3814      */
3815     function copyObjectWith(source, props, object, customizer) {
3816       object || (object = {});
3817
3818       var index = -1,
3819           length = props.length;
3820
3821       while (++index < length) {
3822         var key = props[index],
3823             newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
3824
3825         assignValue(object, key, newValue);
3826       }
3827       return object;
3828     }
3829
3830     /**
3831      * Copies own symbol properties of `source` to `object`.
3832      *
3833      * @private
3834      * @param {Object} source The object to copy symbols from.
3835      * @param {Object} [object={}] The object to copy symbols to.
3836      * @returns {Object} Returns `object`.
3837      */
3838     function copySymbols(source, object) {
3839       return copyObject(source, getSymbols(source), object);
3840     }
3841
3842     /**
3843      * Creates a function like `_.groupBy`.
3844      *
3845      * @private
3846      * @param {Function} setter The function to set keys and values of the accumulator object.
3847      * @param {Function} [initializer] The function to initialize the accumulator object.
3848      * @returns {Function} Returns the new aggregator function.
3849      */
3850     function createAggregator(setter, initializer) {
3851       return function(collection, iteratee) {
3852         var result = initializer ? initializer() : {};
3853         iteratee = getIteratee(iteratee);
3854
3855         if (isArray(collection)) {
3856           var index = -1,
3857               length = collection.length;
3858
3859           while (++index < length) {
3860             var value = collection[index];
3861             setter(result, value, iteratee(value), collection);
3862           }
3863         } else {
3864           baseEach(collection, function(value, key, collection) {
3865             setter(result, value, iteratee(value), collection);
3866           });
3867         }
3868         return result;
3869       };
3870     }
3871
3872     /**
3873      * Creates a function like `_.assign`.
3874      *
3875      * @private
3876      * @param {Function} assigner The function to assign values.
3877      * @returns {Function} Returns the new assigner function.
3878      */
3879     function createAssigner(assigner) {
3880       return rest(function(object, sources) {
3881         var index = -1,
3882             length = sources.length,
3883             customizer = length > 1 ? sources[length - 1] : undefined,
3884             guard = length > 2 ? sources[2] : undefined;
3885
3886         customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
3887         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
3888           customizer = length < 3 ? undefined : customizer;
3889           length = 1;
3890         }
3891         object = Object(object);
3892         while (++index < length) {
3893           var source = sources[index];
3894           if (source) {
3895             assigner(object, source, index, customizer);
3896           }
3897         }
3898         return object;
3899       });
3900     }
3901
3902     /**
3903      * Creates a `baseEach` or `baseEachRight` function.
3904      *
3905      * @private
3906      * @param {Function} eachFunc The function to iterate over a collection.
3907      * @param {boolean} [fromRight] Specify iterating from right to left.
3908      * @returns {Function} Returns the new base function.
3909      */
3910     function createBaseEach(eachFunc, fromRight) {
3911       return function(collection, iteratee) {
3912         if (collection == null) {
3913           return collection;
3914         }
3915         if (!isArrayLike(collection)) {
3916           return eachFunc(collection, iteratee);
3917         }
3918         var length = collection.length,
3919             index = fromRight ? length : -1,
3920             iterable = Object(collection);
3921
3922         while ((fromRight ? index-- : ++index < length)) {
3923           if (iteratee(iterable[index], index, iterable) === false) {
3924             break;
3925           }
3926         }
3927         return collection;
3928       };
3929     }
3930
3931     /**
3932      * Creates a base function for methods like `_.forIn`.
3933      *
3934      * @private
3935      * @param {boolean} [fromRight] Specify iterating from right to left.
3936      * @returns {Function} Returns the new base function.
3937      */
3938     function createBaseFor(fromRight) {
3939       return function(object, iteratee, keysFunc) {
3940         var index = -1,
3941             iterable = Object(object),
3942             props = keysFunc(object),
3943             length = props.length;
3944
3945         while (length--) {
3946           var key = props[fromRight ? length : ++index];
3947           if (iteratee(iterable[key], key, iterable) === false) {
3948             break;
3949           }
3950         }
3951         return object;
3952       };
3953     }
3954
3955     /**
3956      * Creates a function that wraps `func` to invoke it with the optional `this`
3957      * binding of `thisArg`.
3958      *
3959      * @private
3960      * @param {Function} func The function to wrap.
3961      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
3962      * @param {*} [thisArg] The `this` binding of `func`.
3963      * @returns {Function} Returns the new wrapped function.
3964      */
3965     function createBaseWrapper(func, bitmask, thisArg) {
3966       var isBind = bitmask & BIND_FLAG,
3967           Ctor = createCtorWrapper(func);
3968
3969       function wrapper() {
3970         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
3971         return fn.apply(isBind ? thisArg : this, arguments);
3972       }
3973       return wrapper;
3974     }
3975
3976     /**
3977      * Creates a function like `_.lowerFirst`.
3978      *
3979      * @private
3980      * @param {string} methodName The name of the `String` case method to use.
3981      * @returns {Function} Returns the new function.
3982      */
3983     function createCaseFirst(methodName) {
3984       return function(string) {
3985         string = toString(string);
3986
3987         var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined,
3988             chr = strSymbols ? strSymbols[0] : string.charAt(0),
3989             trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
3990
3991         return chr[methodName]() + trailing;
3992       };
3993     }
3994
3995     /**
3996      * Creates a function like `_.camelCase`.
3997      *
3998      * @private
3999      * @param {Function} callback The function to combine each word.
4000      * @returns {Function} Returns the new compounder function.
4001      */
4002     function createCompounder(callback) {
4003       return function(string) {
4004         return arrayReduce(words(deburr(string)), callback, '');
4005       };
4006     }
4007
4008     /**
4009      * Creates a function that produces an instance of `Ctor` regardless of
4010      * whether it was invoked as part of a `new` expression or by `call` or `apply`.
4011      *
4012      * @private
4013      * @param {Function} Ctor The constructor to wrap.
4014      * @returns {Function} Returns the new wrapped function.
4015      */
4016     function createCtorWrapper(Ctor) {
4017       return function() {
4018         // Use a `switch` statement to work with class constructors.
4019         // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
4020         // for more details.
4021         var args = arguments;
4022         switch (args.length) {
4023           case 0: return new Ctor;
4024           case 1: return new Ctor(args[0]);
4025           case 2: return new Ctor(args[0], args[1]);
4026           case 3: return new Ctor(args[0], args[1], args[2]);
4027           case 4: return new Ctor(args[0], args[1], args[2], args[3]);
4028           case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
4029           case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
4030           case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
4031         }
4032         var thisBinding = baseCreate(Ctor.prototype),
4033             result = Ctor.apply(thisBinding, args);
4034
4035         // Mimic the constructor's `return` behavior.
4036         // See https://es5.github.io/#x13.2.2 for more details.
4037         return isObject(result) ? result : thisBinding;
4038       };
4039     }
4040
4041     /**
4042      * Creates a function that wraps `func` to enable currying.
4043      *
4044      * @private
4045      * @param {Function} func The function to wrap.
4046      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4047      * @param {number} arity The arity of `func`.
4048      * @returns {Function} Returns the new wrapped function.
4049      */
4050     function createCurryWrapper(func, bitmask, arity) {
4051       var Ctor = createCtorWrapper(func);
4052
4053       function wrapper() {
4054         var length = arguments.length,
4055             index = length,
4056             args = Array(length),
4057             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func,
4058             placeholder = wrapper.placeholder;
4059
4060         while (index--) {
4061           args[index] = arguments[index];
4062         }
4063         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
4064           ? []
4065           : replaceHolders(args, placeholder);
4066
4067         length -= holders.length;
4068         return length < arity
4069           ? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length)
4070           : apply(fn, this, args);
4071       }
4072       return wrapper;
4073     }
4074
4075     /**
4076      * Creates a `_.flow` or `_.flowRight` function.
4077      *
4078      * @private
4079      * @param {boolean} [fromRight] Specify iterating from right to left.
4080      * @returns {Function} Returns the new flow function.
4081      */
4082     function createFlow(fromRight) {
4083       return rest(function(funcs) {
4084         funcs = baseFlatten(funcs);
4085
4086         var length = funcs.length,
4087             index = length,
4088             prereq = LodashWrapper.prototype.thru;
4089
4090         if (fromRight) {
4091           funcs.reverse();
4092         }
4093         while (index--) {
4094           var func = funcs[index];
4095           if (typeof func != 'function') {
4096             throw new TypeError(FUNC_ERROR_TEXT);
4097           }
4098           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
4099             var wrapper = new LodashWrapper([], true);
4100           }
4101         }
4102         index = wrapper ? index : length;
4103         while (++index < length) {
4104           func = funcs[index];
4105
4106           var funcName = getFuncName(func),
4107               data = funcName == 'wrapper' ? getData(func) : undefined;
4108
4109           if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
4110             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
4111           } else {
4112             wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
4113           }
4114         }
4115         return function() {
4116           var args = arguments,
4117               value = args[0];
4118
4119           if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
4120             return wrapper.plant(value).value();
4121           }
4122           var index = 0,
4123               result = length ? funcs[index].apply(this, args) : value;
4124
4125           while (++index < length) {
4126             result = funcs[index].call(this, result);
4127           }
4128           return result;
4129         };
4130       });
4131     }
4132
4133     /**
4134      * Creates a function that wraps `func` to invoke it with optional `this`
4135      * binding of `thisArg`, partial application, and currying.
4136      *
4137      * @private
4138      * @param {Function|string} func The function or method name to wrap.
4139      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4140      * @param {*} [thisArg] The `this` binding of `func`.
4141      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4142      * @param {Array} [holders] The `partials` placeholder indexes.
4143      * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
4144      * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
4145      * @param {Array} [argPos] The argument positions of the new function.
4146      * @param {number} [ary] The arity cap of `func`.
4147      * @param {number} [arity] The arity of `func`.
4148      * @returns {Function} Returns the new wrapped function.
4149      */
4150     function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
4151       var isAry = bitmask & ARY_FLAG,
4152           isBind = bitmask & BIND_FLAG,
4153           isBindKey = bitmask & BIND_KEY_FLAG,
4154           isCurry = bitmask & CURRY_FLAG,
4155           isCurryRight = bitmask & CURRY_RIGHT_FLAG,
4156           isFlip = bitmask & FLIP_FLAG,
4157           Ctor = isBindKey ? undefined : createCtorWrapper(func);
4158
4159       function wrapper() {
4160         var length = arguments.length,
4161             index = length,
4162             args = Array(length);
4163
4164         while (index--) {
4165           args[index] = arguments[index];
4166         }
4167         if (partials) {
4168           args = composeArgs(args, partials, holders);
4169         }
4170         if (partialsRight) {
4171           args = composeArgsRight(args, partialsRight, holdersRight);
4172         }
4173         if (isCurry || isCurryRight) {
4174           var placeholder = wrapper.placeholder,
4175               argsHolders = replaceHolders(args, placeholder);
4176
4177           length -= argsHolders.length;
4178           if (length < arity) {
4179             return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length);
4180           }
4181         }
4182         var thisBinding = isBind ? thisArg : this,
4183             fn = isBindKey ? thisBinding[func] : func;
4184
4185         if (argPos) {
4186           args = reorder(args, argPos);
4187         } else if (isFlip && args.length > 1) {
4188           args.reverse();
4189         }
4190         if (isAry && ary < args.length) {
4191           args.length = ary;
4192         }
4193         if (this && this !== root && this instanceof wrapper) {
4194           fn = Ctor || createCtorWrapper(fn);
4195         }
4196         return fn.apply(thisBinding, args);
4197       }
4198       return wrapper;
4199     }
4200
4201     /**
4202      * Creates a function like `_.over`.
4203      *
4204      * @private
4205      * @param {Function} arrayFunc The function to iterate over iteratees.
4206      * @returns {Function} Returns the new invoker function.
4207      */
4208     function createOver(arrayFunc) {
4209       return rest(function(iteratees) {
4210         iteratees = arrayMap(baseFlatten(iteratees), getIteratee());
4211         return rest(function(args) {
4212           var thisArg = this;
4213           return arrayFunc(iteratees, function(iteratee) {
4214             return apply(iteratee, thisArg, args);
4215           });
4216         });
4217       });
4218     }
4219
4220     /**
4221      * Creates the padding for `string` based on `length`. The `chars` string
4222      * is truncated if the number of characters exceeds `length`.
4223      *
4224      * @private
4225      * @param {string} string The string to create padding for.
4226      * @param {number} [length=0] The padding length.
4227      * @param {string} [chars=' '] The string used as padding.
4228      * @returns {string} Returns the padding for `string`.
4229      */
4230     function createPadding(string, length, chars) {
4231       length = toInteger(length);
4232
4233       var strLength = stringSize(string);
4234       if (!length || strLength >= length) {
4235         return '';
4236       }
4237       var padLength = length - strLength;
4238       chars = chars === undefined ? ' ' : (chars + '');
4239
4240       var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
4241       return reHasComplexSymbol.test(chars)
4242         ? stringToArray(result).slice(0, padLength).join('')
4243         : result.slice(0, padLength);
4244     }
4245
4246     /**
4247      * Creates a function that wraps `func` to invoke it with the optional `this`
4248      * binding of `thisArg` and the `partials` prepended to those provided to
4249      * the wrapper.
4250      *
4251      * @private
4252      * @param {Function} func The function to wrap.
4253      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4254      * @param {*} thisArg The `this` binding of `func`.
4255      * @param {Array} partials The arguments to prepend to those provided to the new function.
4256      * @returns {Function} Returns the new wrapped function.
4257      */
4258     function createPartialWrapper(func, bitmask, thisArg, partials) {
4259       var isBind = bitmask & BIND_FLAG,
4260           Ctor = createCtorWrapper(func);
4261
4262       function wrapper() {
4263         var argsIndex = -1,
4264             argsLength = arguments.length,
4265             leftIndex = -1,
4266             leftLength = partials.length,
4267             args = Array(leftLength + argsLength),
4268             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4269
4270         while (++leftIndex < leftLength) {
4271           args[leftIndex] = partials[leftIndex];
4272         }
4273         while (argsLength--) {
4274           args[leftIndex++] = arguments[++argsIndex];
4275         }
4276         return apply(fn, isBind ? thisArg : this, args);
4277       }
4278       return wrapper;
4279     }
4280
4281     /**
4282      * Creates a `_.range` or `_.rangeRight` function.
4283      *
4284      * @private
4285      * @param {boolean} [fromRight] Specify iterating from right to left.
4286      * @returns {Function} Returns the new range function.
4287      */
4288     function createRange(fromRight) {
4289       return function(start, end, step) {
4290         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
4291           end = step = undefined;
4292         }
4293         // Ensure the sign of `-0` is preserved.
4294         start = toNumber(start);
4295         start = start === start ? start : 0;
4296         if (end === undefined) {
4297           end = start;
4298           start = 0;
4299         } else {
4300           end = toNumber(end) || 0;
4301         }
4302         step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
4303         return baseRange(start, end, step, fromRight);
4304       };
4305     }
4306
4307     /**
4308      * Creates a function that wraps `func` to continue currying.
4309      *
4310      * @private
4311      * @param {Function} func The function to wrap.
4312      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4313      * @param {Function} wrapFunc The function to create the `func` wrapper.
4314      * @param {*} placeholder The placeholder to replace.
4315      * @param {*} [thisArg] The `this` binding of `func`.
4316      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4317      * @param {Array} [holders] The `partials` placeholder indexes.
4318      * @param {Array} [argPos] The argument positions of the new function.
4319      * @param {number} [ary] The arity cap of `func`.
4320      * @param {number} [arity] The arity of `func`.
4321      * @returns {Function} Returns the new wrapped function.
4322      */
4323     function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
4324       var isCurry = bitmask & CURRY_FLAG,
4325           newArgPos = argPos ? copyArray(argPos) : undefined,
4326           newsHolders = isCurry ? holders : undefined,
4327           newHoldersRight = isCurry ? undefined : holders,
4328           newPartials = isCurry ? partials : undefined,
4329           newPartialsRight = isCurry ? undefined : partials;
4330
4331       bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
4332       bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
4333
4334       if (!(bitmask & CURRY_BOUND_FLAG)) {
4335         bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
4336       }
4337       var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity],
4338           result = wrapFunc.apply(undefined, newData);
4339
4340       if (isLaziable(func)) {
4341         setData(result, newData);
4342       }
4343       result.placeholder = placeholder;
4344       return result;
4345     }
4346
4347     /**
4348      * Creates a function like `_.round`.
4349      *
4350      * @private
4351      * @param {string} methodName The name of the `Math` method to use when rounding.
4352      * @returns {Function} Returns the new round function.
4353      */
4354     function createRound(methodName) {
4355       var func = Math[methodName];
4356       return function(number, precision) {
4357         number = toNumber(number);
4358         precision = toInteger(precision);
4359         if (precision) {
4360           // Shift with exponential notation to avoid floating-point issues.
4361           // See [MDN](https://mdn.io/round#Examples) for more details.
4362           var pair = (toString(number) + 'e').split('e'),
4363               value = func(pair[0] + 'e' + (+pair[1] + precision));
4364
4365           pair = (toString(value) + 'e').split('e');
4366           return +(pair[0] + 'e' + (+pair[1] - precision));
4367         }
4368         return func(number);
4369       };
4370     }
4371
4372     /**
4373      * Creates a set of `values`.
4374      *
4375      * @private
4376      * @param {Array} values The values to add to the set.
4377      * @returns {Object} Returns the new set.
4378      */
4379     var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
4380       return new Set(values);
4381     };
4382
4383     /**
4384      * Creates a function that either curries or invokes `func` with optional
4385      * `this` binding and partially applied arguments.
4386      *
4387      * @private
4388      * @param {Function|string} func The function or method name to wrap.
4389      * @param {number} bitmask The bitmask of wrapper flags.
4390      *  The bitmask may be composed of the following flags:
4391      *     1 - `_.bind`
4392      *     2 - `_.bindKey`
4393      *     4 - `_.curry` or `_.curryRight` of a bound function
4394      *     8 - `_.curry`
4395      *    16 - `_.curryRight`
4396      *    32 - `_.partial`
4397      *    64 - `_.partialRight`
4398      *   128 - `_.rearg`
4399      *   256 - `_.ary`
4400      * @param {*} [thisArg] The `this` binding of `func`.
4401      * @param {Array} [partials] The arguments to be partially applied.
4402      * @param {Array} [holders] The `partials` placeholder indexes.
4403      * @param {Array} [argPos] The argument positions of the new function.
4404      * @param {number} [ary] The arity cap of `func`.
4405      * @param {number} [arity] The arity of `func`.
4406      * @returns {Function} Returns the new wrapped function.
4407      */
4408     function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
4409       var isBindKey = bitmask & BIND_KEY_FLAG;
4410       if (!isBindKey && typeof func != 'function') {
4411         throw new TypeError(FUNC_ERROR_TEXT);
4412       }
4413       var length = partials ? partials.length : 0;
4414       if (!length) {
4415         bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
4416         partials = holders = undefined;
4417       }
4418       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
4419       arity = arity === undefined ? arity : toInteger(arity);
4420       length -= holders ? holders.length : 0;
4421
4422       if (bitmask & PARTIAL_RIGHT_FLAG) {
4423         var partialsRight = partials,
4424             holdersRight = holders;
4425
4426         partials = holders = undefined;
4427       }
4428       var data = isBindKey ? undefined : getData(func),
4429           newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
4430
4431       if (data) {
4432         mergeData(newData, data);
4433       }
4434       func = newData[0];
4435       bitmask = newData[1];
4436       thisArg = newData[2];
4437       partials = newData[3];
4438       holders = newData[4];
4439       arity = newData[9] = newData[9] == null
4440         ? (isBindKey ? 0 : func.length)
4441         : nativeMax(newData[9] - length, 0);
4442
4443       if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
4444         bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
4445       }
4446       if (!bitmask || bitmask == BIND_FLAG) {
4447         var result = createBaseWrapper(func, bitmask, thisArg);
4448       } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
4449         result = createCurryWrapper(func, bitmask, arity);
4450       } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
4451         result = createPartialWrapper(func, bitmask, thisArg, partials);
4452       } else {
4453         result = createHybridWrapper.apply(undefined, newData);
4454       }
4455       var setter = data ? baseSetData : setData;
4456       return setter(result, newData);
4457     }
4458
4459     /**
4460      * A specialized version of `baseIsEqualDeep` for arrays with support for
4461      * partial deep comparisons.
4462      *
4463      * @private
4464      * @param {Array} array The array to compare.
4465      * @param {Array} other The other array to compare.
4466      * @param {Function} equalFunc The function to determine equivalents of values.
4467      * @param {Function} [customizer] The function to customize comparisons.
4468      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4469      * @param {Object} [stack] Tracks traversed `array` and `other` objects.
4470      * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
4471      */
4472     function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
4473       var index = -1,
4474           isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4475           isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
4476           arrLength = array.length,
4477           othLength = other.length;
4478
4479       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
4480         return false;
4481       }
4482       // Assume cyclic values are equal.
4483       var stacked = stack.get(array);
4484       if (stacked) {
4485         return stacked == other;
4486       }
4487       var result = true;
4488       stack.set(array, other);
4489
4490       // Ignore non-index properties.
4491       while (++index < arrLength) {
4492         var arrValue = array[index],
4493             othValue = other[index];
4494
4495         if (customizer) {
4496           var compared = isPartial
4497             ? customizer(othValue, arrValue, index, other, array, stack)
4498             : customizer(arrValue, othValue, index, array, other, stack);
4499         }
4500         if (compared !== undefined) {
4501           if (compared) {
4502             continue;
4503           }
4504           result = false;
4505           break;
4506         }
4507         // Recursively compare arrays (susceptible to call stack limits).
4508         if (isUnordered) {
4509           if (!arraySome(other, function(othValue) {
4510                 return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
4511               })) {
4512             result = false;
4513             break;
4514           }
4515         } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
4516           result = false;
4517           break;
4518         }
4519       }
4520       stack['delete'](array);
4521       return result;
4522     }
4523
4524     /**
4525      * A specialized version of `baseIsEqualDeep` for comparing objects of
4526      * the same `toStringTag`.
4527      *
4528      * **Note:** This function only supports comparing values with tags of
4529      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4530      *
4531      * @private
4532      * @param {Object} object The object to compare.
4533      * @param {Object} other The other object to compare.
4534      * @param {string} tag The `toStringTag` of the objects to compare.
4535      * @param {Function} equalFunc The function to determine equivalents of values.
4536      * @param {Function} [customizer] The function to customize comparisons.
4537      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4538      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4539      */
4540     function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
4541       switch (tag) {
4542         case arrayBufferTag:
4543           if ((object.byteLength != other.byteLength) ||
4544               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
4545             return false;
4546           }
4547           return true;
4548
4549         case boolTag:
4550         case dateTag:
4551           // Coerce dates and booleans to numbers, dates to milliseconds and booleans
4552           // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
4553           return +object == +other;
4554
4555         case errorTag:
4556           return object.name == other.name && object.message == other.message;
4557
4558         case numberTag:
4559           // Treat `NaN` vs. `NaN` as equal.
4560           return (object != +object) ? other != +other : object == +other;
4561
4562         case regexpTag:
4563         case stringTag:
4564           // Coerce regexes to strings and treat strings primitives and string
4565           // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
4566           return object == (other + '');
4567
4568         case mapTag:
4569           var convert = mapToArray;
4570
4571         case setTag:
4572           var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
4573           convert || (convert = setToArray);
4574
4575           // Recursively compare objects (susceptible to call stack limits).
4576           return (isPartial || object.size == other.size) &&
4577             equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
4578
4579         case symbolTag:
4580           return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
4581       }
4582       return false;
4583     }
4584
4585     /**
4586      * A specialized version of `baseIsEqualDeep` for objects with support for
4587      * partial deep comparisons.
4588      *
4589      * @private
4590      * @param {Object} object The object to compare.
4591      * @param {Object} other The other object to compare.
4592      * @param {Function} equalFunc The function to determine equivalents of values.
4593      * @param {Function} [customizer] The function to customize comparisons.
4594      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4595      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
4596      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4597      */
4598     function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
4599       var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4600           objProps = keys(object),
4601           objLength = objProps.length,
4602           othProps = keys(other),
4603           othLength = othProps.length;
4604
4605       if (objLength != othLength && !isPartial) {
4606         return false;
4607       }
4608       var index = objLength;
4609       while (index--) {
4610         var key = objProps[index];
4611         if (!(isPartial ? key in other : baseHas(other, key))) {
4612           return false;
4613         }
4614       }
4615       // Assume cyclic values are equal.
4616       var stacked = stack.get(object);
4617       if (stacked) {
4618         return stacked == other;
4619       }
4620       var result = true;
4621       stack.set(object, other);
4622
4623       var skipCtor = isPartial;
4624       while (++index < objLength) {
4625         key = objProps[index];
4626         var objValue = object[key],
4627             othValue = other[key];
4628
4629         if (customizer) {
4630           var compared = isPartial
4631             ? customizer(othValue, objValue, key, other, object, stack)
4632             : customizer(objValue, othValue, key, object, other, stack);
4633         }
4634         // Recursively compare objects (susceptible to call stack limits).
4635         if (!(compared === undefined
4636               ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
4637               : compared
4638             )) {
4639           result = false;
4640           break;
4641         }
4642         skipCtor || (skipCtor = key == 'constructor');
4643       }
4644       if (result && !skipCtor) {
4645         var objCtor = object.constructor,
4646             othCtor = other.constructor;
4647
4648         // Non `Object` object instances with different constructors are not equal.
4649         if (objCtor != othCtor &&
4650             ('constructor' in object && 'constructor' in other) &&
4651             !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
4652               typeof othCtor == 'function' && othCtor instanceof othCtor)) {
4653           result = false;
4654         }
4655       }
4656       stack['delete'](object);
4657       return result;
4658     }
4659
4660     /**
4661      * Gets metadata for `func`.
4662      *
4663      * @private
4664      * @param {Function} func The function to query.
4665      * @returns {*} Returns the metadata for `func`.
4666      */
4667     var getData = !metaMap ? noop : function(func) {
4668       return metaMap.get(func);
4669     };
4670
4671     /**
4672      * Gets the name of `func`.
4673      *
4674      * @private
4675      * @param {Function} func The function to query.
4676      * @returns {string} Returns the function name.
4677      */
4678     function getFuncName(func) {
4679       var result = (func.name + ''),
4680           array = realNames[result],
4681           length = hasOwnProperty.call(realNames, result) ? array.length : 0;
4682
4683       while (length--) {
4684         var data = array[length],
4685             otherFunc = data.func;
4686         if (otherFunc == null || otherFunc == func) {
4687           return data.name;
4688         }
4689       }
4690       return result;
4691     }
4692
4693     /**
4694      * Gets the appropriate "iteratee" function. If the `_.iteratee` method is
4695      * customized this function returns the custom method, otherwise it returns
4696      * `baseIteratee`. If arguments are provided the chosen function is invoked
4697      * with them and its result is returned.
4698      *
4699      * @private
4700      * @param {*} [value] The value to convert to an iteratee.
4701      * @param {number} [arity] The arity of the created iteratee.
4702      * @returns {Function} Returns the chosen function or its result.
4703      */
4704     function getIteratee() {
4705       var result = lodash.iteratee || iteratee;
4706       result = result === iteratee ? baseIteratee : result;
4707       return arguments.length ? result(arguments[0], arguments[1]) : result;
4708     }
4709
4710     /**
4711      * Gets the "length" property value of `object`.
4712      *
4713      * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
4714      * that affects Safari on at least iOS 8.1-8.3 ARM64.
4715      *
4716      * @private
4717      * @param {Object} object The object to query.
4718      * @returns {*} Returns the "length" value.
4719      */
4720     var getLength = baseProperty('length');
4721
4722     /**
4723      * Gets the property names, values, and compare flags of `object`.
4724      *
4725      * @private
4726      * @param {Object} object The object to query.
4727      * @returns {Array} Returns the match data of `object`.
4728      */
4729     function getMatchData(object) {
4730       var result = toPairs(object),
4731           length = result.length;
4732
4733       while (length--) {
4734         result[length][2] = isStrictComparable(result[length][1]);
4735       }
4736       return result;
4737     }
4738
4739     /**
4740      * Gets the native function at `key` of `object`.
4741      *
4742      * @private
4743      * @param {Object} object The object to query.
4744      * @param {string} key The key of the method to get.
4745      * @returns {*} Returns the function if it's native, else `undefined`.
4746      */
4747     function getNative(object, key) {
4748       var value = object == null ? undefined : object[key];
4749       return isNative(value) ? value : undefined;
4750     }
4751
4752     /**
4753      * Creates an array of the own symbol properties of `object`.
4754      *
4755      * @private
4756      * @param {Object} object The object to query.
4757      * @returns {Array} Returns the array of symbols.
4758      */
4759     var getSymbols = getOwnPropertySymbols || function() {
4760       return [];
4761     };
4762
4763     /**
4764      * Gets the `toStringTag` of `value`.
4765      *
4766      * @private
4767      * @param {*} value The value to query.
4768      * @returns {string} Returns the `toStringTag`.
4769      */
4770     function getTag(value) {
4771       return objectToString.call(value);
4772     }
4773
4774     // Fallback for IE 11 providing `toStringTag` values for maps and sets.
4775     if ((Map && getTag(new Map) != mapTag) || (Set && getTag(new Set) != setTag)) {
4776       getTag = function(value) {
4777         var result = objectToString.call(value),
4778             Ctor = result == objectTag ? value.constructor : null,
4779             ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
4780
4781         if (ctorString) {
4782           if (ctorString == mapCtorString) {
4783             return mapTag;
4784           }
4785           if (ctorString == setCtorString) {
4786             return setTag;
4787           }
4788         }
4789         return result;
4790       };
4791     }
4792
4793     /**
4794      * Gets the view, applying any `transforms` to the `start` and `end` positions.
4795      *
4796      * @private
4797      * @param {number} start The start of the view.
4798      * @param {number} end The end of the view.
4799      * @param {Array} transforms The transformations to apply to the view.
4800      * @returns {Object} Returns an object containing the `start` and `end`
4801      *  positions of the view.
4802      */
4803     function getView(start, end, transforms) {
4804       var index = -1,
4805           length = transforms.length;
4806
4807       while (++index < length) {
4808         var data = transforms[index],
4809             size = data.size;
4810
4811         switch (data.type) {
4812           case 'drop':      start += size; break;
4813           case 'dropRight': end -= size; break;
4814           case 'take':      end = nativeMin(end, start + size); break;
4815           case 'takeRight': start = nativeMax(start, end - size); break;
4816         }
4817       }
4818       return { 'start': start, 'end': end };
4819     }
4820
4821     /**
4822      * Checks if `path` exists on `object`.
4823      *
4824      * @private
4825      * @param {Object} object The object to query.
4826      * @param {Array|string} path The path to check.
4827      * @param {Function} hasFunc The function to check properties.
4828      * @returns {boolean} Returns `true` if `path` exists, else `false`.
4829      */
4830     function hasPath(object, path, hasFunc) {
4831       if (object == null) {
4832         return false;
4833       }
4834       var result = hasFunc(object, path);
4835       if (!result && !isKey(path)) {
4836         path = baseToPath(path);
4837         object = parent(object, path);
4838         if (object != null) {
4839           path = last(path);
4840           result = hasFunc(object, path);
4841         }
4842       }
4843       return result || (isLength(object && object.length) && isIndex(path, object.length) &&
4844         (isArray(object) || isString(object) || isArguments(object)));
4845     }
4846
4847     /**
4848      * Initializes an array clone.
4849      *
4850      * @private
4851      * @param {Array} array The array to clone.
4852      * @returns {Array} Returns the initialized clone.
4853      */
4854     function initCloneArray(array) {
4855       var length = array.length,
4856           result = array.constructor(length);
4857
4858       // Add properties assigned by `RegExp#exec`.
4859       if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
4860         result.index = array.index;
4861         result.input = array.input;
4862       }
4863       return result;
4864     }
4865
4866     /**
4867      * Initializes an object clone.
4868      *
4869      * @private
4870      * @param {Object} object The object to clone.
4871      * @returns {Object} Returns the initialized clone.
4872      */
4873     function initCloneObject(object) {
4874       var Ctor = object.constructor;
4875       return baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
4876     }
4877
4878     /**
4879      * Initializes an object clone based on its `toStringTag`.
4880      *
4881      * **Note:** This function only supports cloning values with tags of
4882      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4883      *
4884      * @private
4885      * @param {Object} object The object to clone.
4886      * @param {string} tag The `toStringTag` of the object to clone.
4887      * @param {boolean} [isDeep] Specify a deep clone.
4888      * @returns {Object} Returns the initialized clone.
4889      */
4890     function initCloneByTag(object, tag, isDeep) {
4891       var Ctor = object.constructor;
4892       switch (tag) {
4893         case arrayBufferTag:
4894           return cloneBuffer(object);
4895
4896         case boolTag:
4897         case dateTag:
4898           return new Ctor(+object);
4899
4900         case float32Tag: case float64Tag:
4901         case int8Tag: case int16Tag: case int32Tag:
4902         case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
4903           return cloneTypedArray(object, isDeep);
4904
4905         case mapTag:
4906           return cloneMap(object);
4907
4908         case numberTag:
4909         case stringTag:
4910           return new Ctor(object);
4911
4912         case regexpTag:
4913           return cloneRegExp(object);
4914
4915         case setTag:
4916           return cloneSet(object);
4917
4918         case symbolTag:
4919           return cloneSymbol(object);
4920       }
4921     }
4922
4923     /**
4924      * Creates an array of index keys for `object` values of arrays,
4925      * `arguments` objects, and strings, otherwise `null` is returned.
4926      *
4927      * @private
4928      * @param {Object} object The object to query.
4929      * @returns {Array|null} Returns index keys, else `null`.
4930      */
4931     function indexKeys(object) {
4932       var length = object ? object.length : undefined;
4933       return (isLength(length) && (isArray(object) || isString(object) || isArguments(object)))
4934         ? baseTimes(length, String)
4935         : null;
4936     }
4937
4938     /**
4939      * Checks if the provided arguments are from an iteratee call.
4940      *
4941      * @private
4942      * @param {*} value The potential iteratee value argument.
4943      * @param {*} index The potential iteratee index or key argument.
4944      * @param {*} object The potential iteratee object argument.
4945      * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
4946      */
4947     function isIterateeCall(value, index, object) {
4948       if (!isObject(object)) {
4949         return false;
4950       }
4951       var type = typeof index;
4952       if (type == 'number'
4953           ? (isArrayLike(object) && isIndex(index, object.length))
4954           : (type == 'string' && index in object)) {
4955         return eq(object[index], value);
4956       }
4957       return false;
4958     }
4959
4960     /**
4961      * Checks if `value` is a property name and not a property path.
4962      *
4963      * @private
4964      * @param {*} value The value to check.
4965      * @param {Object} [object] The object to query keys on.
4966      * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
4967      */
4968     function isKey(value, object) {
4969       if (typeof value == 'number') {
4970         return true;
4971       }
4972       return !isArray(value) &&
4973         (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
4974           (object != null && value in Object(object)));
4975     }
4976
4977     /**
4978      * Checks if `value` is suitable for use as unique object key.
4979      *
4980      * @private
4981      * @param {*} value The value to check.
4982      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
4983      */
4984     function isKeyable(value) {
4985       var type = typeof value;
4986       return type == 'number' || type == 'boolean' ||
4987         (type == 'string' && value !== '__proto__') || value == null;
4988     }
4989
4990     /**
4991      * Checks if `func` has a lazy counterpart.
4992      *
4993      * @private
4994      * @param {Function} func The function to check.
4995      * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
4996      */
4997     function isLaziable(func) {
4998       var funcName = getFuncName(func),
4999           other = lodash[funcName];
5000
5001       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
5002         return false;
5003       }
5004       if (func === other) {
5005         return true;
5006       }
5007       var data = getData(other);
5008       return !!data && func === data[0];
5009     }
5010
5011     /**
5012      * Checks if `value` is likely a prototype object.
5013      *
5014      * @private
5015      * @param {*} value The value to check.
5016      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
5017      */
5018     function isPrototype(value) {
5019       var Ctor = value && value.constructor,
5020           proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
5021
5022       return value === proto;
5023     }
5024
5025     /**
5026      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
5027      *
5028      * @private
5029      * @param {*} value The value to check.
5030      * @returns {boolean} Returns `true` if `value` if suitable for strict
5031      *  equality comparisons, else `false`.
5032      */
5033     function isStrictComparable(value) {
5034       return value === value && !isObject(value);
5035     }
5036
5037     /**
5038      * Merges the function metadata of `source` into `data`.
5039      *
5040      * Merging metadata reduces the number of wrappers used to invoke a function.
5041      * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
5042      * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
5043      * modify function arguments, making the order in which they are executed important,
5044      * preventing the merging of metadata. However, we make an exception for a safe
5045      * combined case where curried functions have `_.ary` and or `_.rearg` applied.
5046      *
5047      * @private
5048      * @param {Array} data The destination metadata.
5049      * @param {Array} source The source metadata.
5050      * @returns {Array} Returns `data`.
5051      */
5052     function mergeData(data, source) {
5053       var bitmask = data[1],
5054           srcBitmask = source[1],
5055           newBitmask = bitmask | srcBitmask,
5056           isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
5057
5058       var isCombo =
5059         (srcBitmask == ARY_FLAG && (bitmask == CURRY_FLAG)) ||
5060         (srcBitmask == ARY_FLAG && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
5061         (srcBitmask == (ARY_FLAG | REARG_FLAG) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
5062
5063       // Exit early if metadata can't be merged.
5064       if (!(isCommon || isCombo)) {
5065         return data;
5066       }
5067       // Use source `thisArg` if available.
5068       if (srcBitmask & BIND_FLAG) {
5069         data[2] = source[2];
5070         // Set when currying a bound function.
5071         newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
5072       }
5073       // Compose partial arguments.
5074       var value = source[3];
5075       if (value) {
5076         var partials = data[3];
5077         data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
5078         data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
5079       }
5080       // Compose partial right arguments.
5081       value = source[5];
5082       if (value) {
5083         partials = data[5];
5084         data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
5085         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
5086       }
5087       // Use source `argPos` if available.
5088       value = source[7];
5089       if (value) {
5090         data[7] = copyArray(value);
5091       }
5092       // Use source `ary` if it's smaller.
5093       if (srcBitmask & ARY_FLAG) {
5094         data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
5095       }
5096       // Use source `arity` if one is not provided.
5097       if (data[9] == null) {
5098         data[9] = source[9];
5099       }
5100       // Use source `func` and merge bitmasks.
5101       data[0] = source[0];
5102       data[1] = newBitmask;
5103
5104       return data;
5105     }
5106
5107     /**
5108      * Used by `_.defaultsDeep` to customize its `_.merge` use.
5109      *
5110      * @private
5111      * @param {*} objValue The destination value.
5112      * @param {*} srcValue The source value.
5113      * @param {string} key The key of the property to merge.
5114      * @param {Object} object The parent object of `objValue`.
5115      * @param {Object} source The parent object of `srcValue`.
5116      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
5117      * @returns {*} Returns the value to assign.
5118      */
5119     function mergeDefaults(objValue, srcValue, key, object, source, stack) {
5120       if (isObject(objValue) && isObject(srcValue)) {
5121         stack.set(srcValue, objValue);
5122         baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
5123       }
5124       return objValue;
5125     }
5126
5127     /**
5128      * Gets the parent value at `path` of `object`.
5129      *
5130      * @private
5131      * @param {Object} object The object to query.
5132      * @param {Array} path The path to get the parent value of.
5133      * @returns {*} Returns the parent value.
5134      */
5135     function parent(object, path) {
5136       return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
5137     }
5138
5139     /**
5140      * Reorder `array` according to the specified indexes where the element at
5141      * the first index is assigned as the first element, the element at
5142      * the second index is assigned as the second element, and so on.
5143      *
5144      * @private
5145      * @param {Array} array The array to reorder.
5146      * @param {Array} indexes The arranged array indexes.
5147      * @returns {Array} Returns `array`.
5148      */
5149     function reorder(array, indexes) {
5150       var arrLength = array.length,
5151           length = nativeMin(indexes.length, arrLength),
5152           oldArray = copyArray(array);
5153
5154       while (length--) {
5155         var index = indexes[length];
5156         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5157       }
5158       return array;
5159     }
5160
5161     /**
5162      * Sets metadata for `func`.
5163      *
5164      * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
5165      * period of time, it will trip its breaker and transition to an identity function
5166      * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
5167      * for more details.
5168      *
5169      * @private
5170      * @param {Function} func The function to associate metadata with.
5171      * @param {*} data The metadata.
5172      * @returns {Function} Returns `func`.
5173      */
5174     var setData = (function() {
5175       var count = 0,
5176           lastCalled = 0;
5177
5178       return function(key, value) {
5179         var stamp = now(),
5180             remaining = HOT_SPAN - (stamp - lastCalled);
5181
5182         lastCalled = stamp;
5183         if (remaining > 0) {
5184           if (++count >= HOT_COUNT) {
5185             return key;
5186           }
5187         } else {
5188           count = 0;
5189         }
5190         return baseSetData(key, value);
5191       };
5192     }());
5193
5194     /**
5195      * Converts `string` to a property path array.
5196      *
5197      * @private
5198      * @param {string} string The string to convert.
5199      * @returns {Array} Returns the property path array.
5200      */
5201     function stringToPath(string) {
5202       var result = [];
5203       toString(string).replace(rePropName, function(match, number, quote, string) {
5204         result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
5205       });
5206       return result;
5207     }
5208
5209     /**
5210      * Converts `value` to an array-like object if it's not one.
5211      *
5212      * @private
5213      * @param {*} value The value to process.
5214      * @returns {Array} Returns the array-like object.
5215      */
5216     function toArrayLikeObject(value) {
5217       return isArrayLikeObject(value) ? value : [];
5218     }
5219
5220     /**
5221      * Converts `value` to a function if it's not one.
5222      *
5223      * @private
5224      * @param {*} value The value to process.
5225      * @returns {Function} Returns the function.
5226      */
5227     function toFunction(value) {
5228       return typeof value == 'function' ? value : identity;
5229     }
5230
5231     /**
5232      * Creates a clone of `wrapper`.
5233      *
5234      * @private
5235      * @param {Object} wrapper The wrapper to clone.
5236      * @returns {Object} Returns the cloned wrapper.
5237      */
5238     function wrapperClone(wrapper) {
5239       if (wrapper instanceof LazyWrapper) {
5240         return wrapper.clone();
5241       }
5242       var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
5243       result.__actions__ = copyArray(wrapper.__actions__);
5244       result.__index__  = wrapper.__index__;
5245       result.__values__ = wrapper.__values__;
5246       return result;
5247     }
5248
5249     /*------------------------------------------------------------------------*/
5250
5251     /**
5252      * Creates an array of elements split into groups the length of `size`.
5253      * If `array` can't be split evenly, the final chunk will be the remaining
5254      * elements.
5255      *
5256      * @static
5257      * @memberOf _
5258      * @category Array
5259      * @param {Array} array The array to process.
5260      * @param {number} [size=0] The length of each chunk.
5261      * @returns {Array} Returns the new array containing chunks.
5262      * @example
5263      *
5264      * _.chunk(['a', 'b', 'c', 'd'], 2);
5265      * // => [['a', 'b'], ['c', 'd']]
5266      *
5267      * _.chunk(['a', 'b', 'c', 'd'], 3);
5268      * // => [['a', 'b', 'c'], ['d']]
5269      */
5270     function chunk(array, size) {
5271       size = nativeMax(toInteger(size), 0);
5272
5273       var length = array ? array.length : 0;
5274       if (!length || size < 1) {
5275         return [];
5276       }
5277       var index = 0,
5278           resIndex = -1,
5279           result = Array(nativeCeil(length / size));
5280
5281       while (index < length) {
5282         result[++resIndex] = baseSlice(array, index, (index += size));
5283       }
5284       return result;
5285     }
5286
5287     /**
5288      * Creates an array with all falsey values removed. The values `false`, `null`,
5289      * `0`, `""`, `undefined`, and `NaN` are falsey.
5290      *
5291      * @static
5292      * @memberOf _
5293      * @category Array
5294      * @param {Array} array The array to compact.
5295      * @returns {Array} Returns the new array of filtered values.
5296      * @example
5297      *
5298      * _.compact([0, 1, false, 2, '', 3]);
5299      * // => [1, 2, 3]
5300      */
5301     function compact(array) {
5302       var index = -1,
5303           length = array ? array.length : 0,
5304           resIndex = -1,
5305           result = [];
5306
5307       while (++index < length) {
5308         var value = array[index];
5309         if (value) {
5310           result[++resIndex] = value;
5311         }
5312       }
5313       return result;
5314     }
5315
5316     /**
5317      * Creates a new array concatenating `array` with any additional arrays
5318      * and/or values.
5319      *
5320      * @static
5321      * @memberOf _
5322      * @category Array
5323      * @param {Array} array The array to concatenate.
5324      * @param {...*} [values] The values to concatenate.
5325      * @returns {Array} Returns the new concatenated array.
5326      * @example
5327      *
5328      * var array = [1];
5329      * var other = _.concat(array, 2, [3], [[4]]);
5330      *
5331      * console.log(other);
5332      * // => [1, 2, 3, [4]]
5333      *
5334      * console.log(array);
5335      * // => [1]
5336      */
5337     var concat = rest(function(array, values) {
5338       if (!isArray(array)) {
5339         array = array == null ? [] : [Object(array)];
5340       }
5341       values = baseFlatten(values);
5342       return arrayConcat(array, values);
5343     });
5344
5345     /**
5346      * Creates an array of unique `array` values not included in the other
5347      * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5348      * for equality comparisons.
5349      *
5350      * @static
5351      * @memberOf _
5352      * @category Array
5353      * @param {Array} array The array to inspect.
5354      * @param {...Array} [values] The values to exclude.
5355      * @returns {Array} Returns the new array of filtered values.
5356      * @example
5357      *
5358      * _.difference([3, 2, 1], [4, 2]);
5359      * // => [3, 1]
5360      */
5361     var difference = rest(function(array, values) {
5362       return isArrayLikeObject(array)
5363         ? baseDifference(array, baseFlatten(values, false, true))
5364         : [];
5365     });
5366
5367     /**
5368      * This method is like `_.difference` except that it accepts `iteratee` which
5369      * is invoked for each element of `array` and `values` to generate the criterion
5370      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5371      *
5372      * @static
5373      * @memberOf _
5374      * @category Array
5375      * @param {Array} array The array to inspect.
5376      * @param {...Array} [values] The values to exclude.
5377      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5378      * @returns {Array} Returns the new array of filtered values.
5379      * @example
5380      *
5381      * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
5382      * // => [3.1, 1.3]
5383      *
5384      * // using the `_.property` iteratee shorthand
5385      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
5386      * // => [{ 'x': 2 }]
5387      */
5388     var differenceBy = rest(function(array, values) {
5389       var iteratee = last(values);
5390       if (isArrayLikeObject(iteratee)) {
5391         iteratee = undefined;
5392       }
5393       return isArrayLikeObject(array)
5394         ? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee))
5395         : [];
5396     });
5397
5398     /**
5399      * This method is like `_.difference` except that it accepts `comparator`
5400      * which is invoked to compare elements of `array` to `values`. The comparator
5401      * is invoked with two arguments: (arrVal, othVal).
5402      *
5403      * @static
5404      * @memberOf _
5405      * @category Array
5406      * @param {Array} array The array to inspect.
5407      * @param {...Array} [values] The values to exclude.
5408      * @param {Function} [comparator] The comparator invoked per element.
5409      * @returns {Array} Returns the new array of filtered values.
5410      * @example
5411      *
5412      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5413      *
5414      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
5415      * // => [{ 'x': 2, 'y': 1 }]
5416      */
5417     var differenceWith = rest(function(array, values) {
5418       var comparator = last(values);
5419       if (isArrayLikeObject(comparator)) {
5420         comparator = undefined;
5421       }
5422       return isArrayLikeObject(array)
5423         ? baseDifference(array, baseFlatten(values, false, true), undefined, comparator)
5424         : [];
5425     });
5426
5427     /**
5428      * Creates a slice of `array` with `n` elements dropped from the beginning.
5429      *
5430      * @static
5431      * @memberOf _
5432      * @category Array
5433      * @param {Array} array The array to query.
5434      * @param {number} [n=1] The number of elements to drop.
5435      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5436      * @returns {Array} Returns the slice of `array`.
5437      * @example
5438      *
5439      * _.drop([1, 2, 3]);
5440      * // => [2, 3]
5441      *
5442      * _.drop([1, 2, 3], 2);
5443      * // => [3]
5444      *
5445      * _.drop([1, 2, 3], 5);
5446      * // => []
5447      *
5448      * _.drop([1, 2, 3], 0);
5449      * // => [1, 2, 3]
5450      */
5451     function drop(array, n, guard) {
5452       var length = array ? array.length : 0;
5453       if (!length) {
5454         return [];
5455       }
5456       n = (guard || n === undefined) ? 1 : toInteger(n);
5457       return baseSlice(array, n < 0 ? 0 : n, length);
5458     }
5459
5460     /**
5461      * Creates a slice of `array` with `n` elements dropped from the end.
5462      *
5463      * @static
5464      * @memberOf _
5465      * @category Array
5466      * @param {Array} array The array to query.
5467      * @param {number} [n=1] The number of elements to drop.
5468      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5469      * @returns {Array} Returns the slice of `array`.
5470      * @example
5471      *
5472      * _.dropRight([1, 2, 3]);
5473      * // => [1, 2]
5474      *
5475      * _.dropRight([1, 2, 3], 2);
5476      * // => [1]
5477      *
5478      * _.dropRight([1, 2, 3], 5);
5479      * // => []
5480      *
5481      * _.dropRight([1, 2, 3], 0);
5482      * // => [1, 2, 3]
5483      */
5484     function dropRight(array, n, guard) {
5485       var length = array ? array.length : 0;
5486       if (!length) {
5487         return [];
5488       }
5489       n = (guard || n === undefined) ? 1 : toInteger(n);
5490       n = length - n;
5491       return baseSlice(array, 0, n < 0 ? 0 : n);
5492     }
5493
5494     /**
5495      * Creates a slice of `array` excluding elements dropped from the end.
5496      * Elements are dropped until `predicate` returns falsey. The predicate is
5497      * invoked with three arguments: (value, index, array).
5498      *
5499      * @static
5500      * @memberOf _
5501      * @category Array
5502      * @param {Array} array The array to query.
5503      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5504      * @returns {Array} Returns the slice of `array`.
5505      * @example
5506      *
5507      * var users = [
5508      *   { 'user': 'barney',  'active': true },
5509      *   { 'user': 'fred',    'active': false },
5510      *   { 'user': 'pebbles', 'active': false }
5511      * ];
5512      *
5513      * _.dropRightWhile(users, function(o) { return !o.active; });
5514      * // => objects for ['barney']
5515      *
5516      * // using the `_.matches` iteratee shorthand
5517      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
5518      * // => objects for ['barney', 'fred']
5519      *
5520      * // using the `_.matchesProperty` iteratee shorthand
5521      * _.dropRightWhile(users, ['active', false]);
5522      * // => objects for ['barney']
5523      *
5524      * // using the `_.property` iteratee shorthand
5525      * _.dropRightWhile(users, 'active');
5526      * // => objects for ['barney', 'fred', 'pebbles']
5527      */
5528     function dropRightWhile(array, predicate) {
5529       return (array && array.length)
5530         ? baseWhile(array, getIteratee(predicate, 3), true, true)
5531         : [];
5532     }
5533
5534     /**
5535      * Creates a slice of `array` excluding elements dropped from the beginning.
5536      * Elements are dropped until `predicate` returns falsey. The predicate is
5537      * invoked with three arguments: (value, index, array).
5538      *
5539      * @static
5540      * @memberOf _
5541      * @category Array
5542      * @param {Array} array The array to query.
5543      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5544      * @returns {Array} Returns the slice of `array`.
5545      * @example
5546      *
5547      * var users = [
5548      *   { 'user': 'barney',  'active': false },
5549      *   { 'user': 'fred',    'active': false },
5550      *   { 'user': 'pebbles', 'active': true }
5551      * ];
5552      *
5553      * _.dropWhile(users, function(o) { return !o.active; });
5554      * // => objects for ['pebbles']
5555      *
5556      * // using the `_.matches` iteratee shorthand
5557      * _.dropWhile(users, { 'user': 'barney', 'active': false });
5558      * // => objects for ['fred', 'pebbles']
5559      *
5560      * // using the `_.matchesProperty` iteratee shorthand
5561      * _.dropWhile(users, ['active', false]);
5562      * // => objects for ['pebbles']
5563      *
5564      * // using the `_.property` iteratee shorthand
5565      * _.dropWhile(users, 'active');
5566      * // => objects for ['barney', 'fred', 'pebbles']
5567      */
5568     function dropWhile(array, predicate) {
5569       return (array && array.length)
5570         ? baseWhile(array, getIteratee(predicate, 3), true)
5571         : [];
5572     }
5573
5574     /**
5575      * Fills elements of `array` with `value` from `start` up to, but not
5576      * including, `end`.
5577      *
5578      * **Note:** This method mutates `array`.
5579      *
5580      * @static
5581      * @memberOf _
5582      * @category Array
5583      * @param {Array} array The array to fill.
5584      * @param {*} value The value to fill `array` with.
5585      * @param {number} [start=0] The start position.
5586      * @param {number} [end=array.length] The end position.
5587      * @returns {Array} Returns `array`.
5588      * @example
5589      *
5590      * var array = [1, 2, 3];
5591      *
5592      * _.fill(array, 'a');
5593      * console.log(array);
5594      * // => ['a', 'a', 'a']
5595      *
5596      * _.fill(Array(3), 2);
5597      * // => [2, 2, 2]
5598      *
5599      * _.fill([4, 6, 8, 10], '*', 1, 3);
5600      * // => [4, '*', '*', 10]
5601      */
5602     function fill(array, value, start, end) {
5603       var length = array ? array.length : 0;
5604       if (!length) {
5605         return [];
5606       }
5607       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
5608         start = 0;
5609         end = length;
5610       }
5611       return baseFill(array, value, start, end);
5612     }
5613
5614     /**
5615      * This method is like `_.find` except that it returns the index of the first
5616      * element `predicate` returns truthy for instead of the element itself.
5617      *
5618      * @static
5619      * @memberOf _
5620      * @category Array
5621      * @param {Array} array The array to search.
5622      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5623      * @returns {number} Returns the index of the found element, else `-1`.
5624      * @example
5625      *
5626      * var users = [
5627      *   { 'user': 'barney',  'active': false },
5628      *   { 'user': 'fred',    'active': false },
5629      *   { 'user': 'pebbles', 'active': true }
5630      * ];
5631      *
5632      * _.findIndex(users, function(o) { return o.user == 'barney'; });
5633      * // => 0
5634      *
5635      * // using the `_.matches` iteratee shorthand
5636      * _.findIndex(users, { 'user': 'fred', 'active': false });
5637      * // => 1
5638      *
5639      * // using the `_.matchesProperty` iteratee shorthand
5640      * _.findIndex(users, ['active', false]);
5641      * // => 0
5642      *
5643      * // using the `_.property` iteratee shorthand
5644      * _.findIndex(users, 'active');
5645      * // => 2
5646      */
5647     function findIndex(array, predicate) {
5648       return (array && array.length)
5649         ? baseFindIndex(array, getIteratee(predicate, 3))
5650         : -1;
5651     }
5652
5653     /**
5654      * This method is like `_.findIndex` except that it iterates over elements
5655      * of `collection` from right to left.
5656      *
5657      * @static
5658      * @memberOf _
5659      * @category Array
5660      * @param {Array} array The array to search.
5661      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5662      * @returns {number} Returns the index of the found element, else `-1`.
5663      * @example
5664      *
5665      * var users = [
5666      *   { 'user': 'barney',  'active': true },
5667      *   { 'user': 'fred',    'active': false },
5668      *   { 'user': 'pebbles', 'active': false }
5669      * ];
5670      *
5671      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
5672      * // => 2
5673      *
5674      * // using the `_.matches` iteratee shorthand
5675      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
5676      * // => 0
5677      *
5678      * // using the `_.matchesProperty` iteratee shorthand
5679      * _.findLastIndex(users, ['active', false]);
5680      * // => 2
5681      *
5682      * // using the `_.property` iteratee shorthand
5683      * _.findLastIndex(users, 'active');
5684      * // => 0
5685      */
5686     function findLastIndex(array, predicate) {
5687       return (array && array.length)
5688         ? baseFindIndex(array, getIteratee(predicate, 3), true)
5689         : -1;
5690     }
5691
5692     /**
5693      * Creates an array of flattened values by running each element in `array`
5694      * through `iteratee` and concating its result to the other mapped values.
5695      * The iteratee is invoked with three arguments: (value, index|key, array).
5696      *
5697      * @static
5698      * @memberOf _
5699      * @category Array
5700      * @param {Array} array The array to iterate over.
5701      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
5702      * @returns {Array} Returns the new array.
5703      * @example
5704      *
5705      * function duplicate(n) {
5706      *   return [n, n];
5707      * }
5708      *
5709      * _.flatMap([1, 2], duplicate);
5710      * // => [1, 1, 2, 2]
5711      */
5712     function flatMap(array, iteratee) {
5713       var length = array ? array.length : 0;
5714       return length ? baseFlatten(arrayMap(array, getIteratee(iteratee, 3))) : [];
5715     }
5716
5717     /**
5718      * Flattens `array` a single level.
5719      *
5720      * @static
5721      * @memberOf _
5722      * @category Array
5723      * @param {Array} array The array to flatten.
5724      * @returns {Array} Returns the new flattened array.
5725      * @example
5726      *
5727      * _.flatten([1, [2, 3, [4]]]);
5728      * // => [1, 2, 3, [4]]
5729      */
5730     function flatten(array) {
5731       var length = array ? array.length : 0;
5732       return length ? baseFlatten(array) : [];
5733     }
5734
5735     /**
5736      * This method is like `_.flatten` except that it recursively flattens `array`.
5737      *
5738      * @static
5739      * @memberOf _
5740      * @category Array
5741      * @param {Array} array The array to recursively flatten.
5742      * @returns {Array} Returns the new flattened array.
5743      * @example
5744      *
5745      * _.flattenDeep([1, [2, 3, [4]]]);
5746      * // => [1, 2, 3, 4]
5747      */
5748     function flattenDeep(array) {
5749       var length = array ? array.length : 0;
5750       return length ? baseFlatten(array, true) : [];
5751     }
5752
5753     /**
5754      * The inverse of `_.toPairs`; this method returns an object composed
5755      * from key-value `pairs`.
5756      *
5757      * @static
5758      * @memberOf _
5759      * @category Array
5760      * @param {Array} pairs The key-value pairs.
5761      * @returns {Object} Returns the new object.
5762      * @example
5763      *
5764      * _.fromPairs([['fred', 30], ['barney', 40]]);
5765      * // => { 'fred': 30, 'barney': 40 }
5766      */
5767     function fromPairs(pairs) {
5768       var index = -1,
5769           length = pairs ? pairs.length : 0,
5770           result = {};
5771
5772       while (++index < length) {
5773         var pair = pairs[index];
5774         result[pair[0]] = pair[1];
5775       }
5776       return result;
5777     }
5778
5779     /**
5780      * Gets the first element of `array`.
5781      *
5782      * @static
5783      * @memberOf _
5784      * @alias first
5785      * @category Array
5786      * @param {Array} array The array to query.
5787      * @returns {*} Returns the first element of `array`.
5788      * @example
5789      *
5790      * _.head([1, 2, 3]);
5791      * // => 1
5792      *
5793      * _.head([]);
5794      * // => undefined
5795      */
5796     function head(array) {
5797       return array ? array[0] : undefined;
5798     }
5799
5800     /**
5801      * Gets the index at which the first occurrence of `value` is found in `array`
5802      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5803      * for equality comparisons. If `fromIndex` is negative, it's used as the offset
5804      * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
5805      * performs a faster binary search.
5806      *
5807      * @static
5808      * @memberOf _
5809      * @category Array
5810      * @param {Array} array The array to search.
5811      * @param {*} value The value to search for.
5812      * @param {number} [fromIndex=0] The index to search from.
5813      * @returns {number} Returns the index of the matched value, else `-1`.
5814      * @example
5815      *
5816      * _.indexOf([1, 2, 1, 2], 2);
5817      * // => 1
5818      *
5819      * // using `fromIndex`
5820      * _.indexOf([1, 2, 1, 2], 2, 2);
5821      * // => 3
5822      */
5823     function indexOf(array, value, fromIndex) {
5824       var length = array ? array.length : 0;
5825       if (!length) {
5826         return -1;
5827       }
5828       fromIndex = toInteger(fromIndex);
5829       if (fromIndex < 0) {
5830         fromIndex = nativeMax(length + fromIndex, 0);
5831       }
5832       return baseIndexOf(array, value, fromIndex);
5833     }
5834
5835     /**
5836      * Gets all but the last element of `array`.
5837      *
5838      * @static
5839      * @memberOf _
5840      * @category Array
5841      * @param {Array} array The array to query.
5842      * @returns {Array} Returns the slice of `array`.
5843      * @example
5844      *
5845      * _.initial([1, 2, 3]);
5846      * // => [1, 2]
5847      */
5848     function initial(array) {
5849       return dropRight(array, 1);
5850     }
5851
5852     /**
5853      * Creates an array of unique values that are included in all of the provided
5854      * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5855      * for equality comparisons.
5856      *
5857      * @static
5858      * @memberOf _
5859      * @category Array
5860      * @param {...Array} [arrays] The arrays to inspect.
5861      * @returns {Array} Returns the new array of shared values.
5862      * @example
5863      *
5864      * _.intersection([2, 1], [4, 2], [1, 2]);
5865      * // => [2]
5866      */
5867     var intersection = rest(function(arrays) {
5868       var mapped = arrayMap(arrays, toArrayLikeObject);
5869       return (mapped.length && mapped[0] === arrays[0])
5870         ? baseIntersection(mapped)
5871         : [];
5872     });
5873
5874     /**
5875      * This method is like `_.intersection` except that it accepts `iteratee`
5876      * which is invoked for each element of each `arrays` to generate the criterion
5877      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5878      *
5879      * @static
5880      * @memberOf _
5881      * @category Array
5882      * @param {...Array} [arrays] The arrays to inspect.
5883      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5884      * @returns {Array} Returns the new array of shared values.
5885      * @example
5886      *
5887      * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
5888      * // => [2.1]
5889      *
5890      * // using the `_.property` iteratee shorthand
5891      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
5892      * // => [{ 'x': 1 }]
5893      */
5894     var intersectionBy = rest(function(arrays) {
5895       var iteratee = last(arrays),
5896           mapped = arrayMap(arrays, toArrayLikeObject);
5897
5898       if (iteratee === last(mapped)) {
5899         iteratee = undefined;
5900       } else {
5901         mapped.pop();
5902       }
5903       return (mapped.length && mapped[0] === arrays[0])
5904         ? baseIntersection(mapped, getIteratee(iteratee))
5905         : [];
5906     });
5907
5908     /**
5909      * This method is like `_.intersection` except that it accepts `comparator`
5910      * which is invoked to compare elements of `arrays`. The comparator is invoked
5911      * with two arguments: (arrVal, othVal).
5912      *
5913      * @static
5914      * @memberOf _
5915      * @category Array
5916      * @param {...Array} [arrays] The arrays to inspect.
5917      * @param {Function} [comparator] The comparator invoked per element.
5918      * @returns {Array} Returns the new array of shared values.
5919      * @example
5920      *
5921      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5922      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
5923      *
5924      * _.intersectionWith(objects, others, _.isEqual);
5925      * // => [{ 'x': 1, 'y': 2 }]
5926      */
5927     var intersectionWith = rest(function(arrays) {
5928       var comparator = last(arrays),
5929           mapped = arrayMap(arrays, toArrayLikeObject);
5930
5931       if (comparator === last(mapped)) {
5932         comparator = undefined;
5933       } else {
5934         mapped.pop();
5935       }
5936       return (mapped.length && mapped[0] === arrays[0])
5937         ? baseIntersection(mapped, undefined, comparator)
5938         : [];
5939     });
5940
5941     /**
5942      * Converts all elements in `array` into a string separated by `separator`.
5943      *
5944      * @static
5945      * @memberOf _
5946      * @category Array
5947      * @param {Array} array The array to convert.
5948      * @param {string} [separator=','] The element separator.
5949      * @returns {string} Returns the joined string.
5950      * @example
5951      *
5952      * _.join(['a', 'b', 'c'], '~');
5953      * // => 'a~b~c'
5954      */
5955     function join(array, separator) {
5956       return array ? nativeJoin.call(array, separator) : '';
5957     }
5958
5959     /**
5960      * Gets the last element of `array`.
5961      *
5962      * @static
5963      * @memberOf _
5964      * @category Array
5965      * @param {Array} array The array to query.
5966      * @returns {*} Returns the last element of `array`.
5967      * @example
5968      *
5969      * _.last([1, 2, 3]);
5970      * // => 3
5971      */
5972     function last(array) {
5973       var length = array ? array.length : 0;
5974       return length ? array[length - 1] : undefined;
5975     }
5976
5977     /**
5978      * This method is like `_.indexOf` except that it iterates over elements of
5979      * `array` from right to left.
5980      *
5981      * @static
5982      * @memberOf _
5983      * @category Array
5984      * @param {Array} array The array to search.
5985      * @param {*} value The value to search for.
5986      * @param {number} [fromIndex=array.length-1] The index to search from.
5987      * @returns {number} Returns the index of the matched value, else `-1`.
5988      * @example
5989      *
5990      * _.lastIndexOf([1, 2, 1, 2], 2);
5991      * // => 3
5992      *
5993      * // using `fromIndex`
5994      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
5995      * // => 1
5996      */
5997     function lastIndexOf(array, value, fromIndex) {
5998       var length = array ? array.length : 0;
5999       if (!length) {
6000         return -1;
6001       }
6002       var index = length;
6003       if (fromIndex !== undefined) {
6004         index = toInteger(fromIndex);
6005         index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
6006       }
6007       if (value !== value) {
6008         return indexOfNaN(array, index, true);
6009       }
6010       while (index--) {
6011         if (array[index] === value) {
6012           return index;
6013         }
6014       }
6015       return -1;
6016     }
6017
6018     /**
6019      * Removes all provided values from `array` using
6020      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6021      * for equality comparisons.
6022      *
6023      * **Note:** Unlike `_.without`, this method mutates `array`.
6024      *
6025      * @static
6026      * @memberOf _
6027      * @category Array
6028      * @param {Array} array The array to modify.
6029      * @param {...*} [values] The values to remove.
6030      * @returns {Array} Returns `array`.
6031      * @example
6032      *
6033      * var array = [1, 2, 3, 1, 2, 3];
6034      *
6035      * _.pull(array, 2, 3);
6036      * console.log(array);
6037      * // => [1, 1]
6038      */
6039     var pull = rest(pullAll);
6040
6041     /**
6042      * This method is like `_.pull` except that it accepts an array of values to remove.
6043      *
6044      * **Note:** Unlike `_.difference`, this method mutates `array`.
6045      *
6046      * @static
6047      * @memberOf _
6048      * @category Array
6049      * @param {Array} array The array to modify.
6050      * @param {Array} values The values to remove.
6051      * @returns {Array} Returns `array`.
6052      * @example
6053      *
6054      * var array = [1, 2, 3, 1, 2, 3];
6055      *
6056      * _.pullAll(array, [2, 3]);
6057      * console.log(array);
6058      * // => [1, 1]
6059      */
6060     function pullAll(array, values) {
6061       return (array && array.length && values && values.length)
6062         ? basePullAll(array, values)
6063         : array;
6064     }
6065
6066     /**
6067      * This method is like `_.pullAll` except that it accepts `iteratee` which is
6068      * invoked for each element of `array` and `values` to to generate the criterion
6069      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
6070      *
6071      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
6072      *
6073      * @static
6074      * @memberOf _
6075      * @category Array
6076      * @param {Array} array The array to modify.
6077      * @param {Array} values The values to remove.
6078      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6079      * @returns {Array} Returns `array`.
6080      * @example
6081      *
6082      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
6083      *
6084      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
6085      * console.log(array);
6086      * // => [{ 'x': 2 }]
6087      */
6088     function pullAllBy(array, values, iteratee) {
6089       return (array && array.length && values && values.length)
6090         ? basePullAllBy(array, values, getIteratee(iteratee))
6091         : array;
6092     }
6093
6094     /**
6095      * Removes elements from `array` corresponding to `indexes` and returns an
6096      * array of removed elements.
6097      *
6098      * **Note:** Unlike `_.at`, this method mutates `array`.
6099      *
6100      * @static
6101      * @memberOf _
6102      * @category Array
6103      * @param {Array} array The array to modify.
6104      * @param {...(number|number[])} [indexes] The indexes of elements to remove,
6105      *  specified individually or in arrays.
6106      * @returns {Array} Returns the new array of removed elements.
6107      * @example
6108      *
6109      * var array = [5, 10, 15, 20];
6110      * var evens = _.pullAt(array, 1, 3);
6111      *
6112      * console.log(array);
6113      * // => [5, 15]
6114      *
6115      * console.log(evens);
6116      * // => [10, 20]
6117      */
6118     var pullAt = rest(function(array, indexes) {
6119       indexes = arrayMap(baseFlatten(indexes), String);
6120
6121       var result = baseAt(array, indexes);
6122       basePullAt(array, indexes.sort(compareAscending));
6123       return result;
6124     });
6125
6126     /**
6127      * Removes all elements from `array` that `predicate` returns truthy for
6128      * and returns an array of the removed elements. The predicate is invoked with
6129      * three arguments: (value, index, array).
6130      *
6131      * **Note:** Unlike `_.filter`, this method mutates `array`.
6132      *
6133      * @static
6134      * @memberOf _
6135      * @category Array
6136      * @param {Array} array The array to modify.
6137      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6138      * @returns {Array} Returns the new array of removed elements.
6139      * @example
6140      *
6141      * var array = [1, 2, 3, 4];
6142      * var evens = _.remove(array, function(n) {
6143      *   return n % 2 == 0;
6144      * });
6145      *
6146      * console.log(array);
6147      * // => [1, 3]
6148      *
6149      * console.log(evens);
6150      * // => [2, 4]
6151      */
6152     function remove(array, predicate) {
6153       var result = [];
6154       if (!(array && array.length)) {
6155         return result;
6156       }
6157       var index = -1,
6158           indexes = [],
6159           length = array.length;
6160
6161       predicate = getIteratee(predicate, 3);
6162       while (++index < length) {
6163         var value = array[index];
6164         if (predicate(value, index, array)) {
6165           result.push(value);
6166           indexes.push(index);
6167         }
6168       }
6169       basePullAt(array, indexes);
6170       return result;
6171     }
6172
6173     /**
6174      * Reverses `array` so that the first element becomes the last, the second
6175      * element becomes the second to last, and so on.
6176      *
6177      * **Note:** This method mutates `array` and is based on
6178      * [`Array#reverse`](https://mdn.io/Array/reverse).
6179      *
6180      * @static
6181      * @memberOf _
6182      * @category Array
6183      * @returns {Array} Returns `array`.
6184      * @example
6185      *
6186      * var array = [1, 2, 3];
6187      *
6188      * _.reverse(array);
6189      * // => [3, 2, 1]
6190      *
6191      * console.log(array);
6192      * // => [3, 2, 1]
6193      */
6194     function reverse(array) {
6195       return array ? nativeReverse.call(array) : array;
6196     }
6197
6198     /**
6199      * Creates a slice of `array` from `start` up to, but not including, `end`.
6200      *
6201      * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
6202      * to ensure dense arrays are returned.
6203      *
6204      * @static
6205      * @memberOf _
6206      * @category Array
6207      * @param {Array} array The array to slice.
6208      * @param {number} [start=0] The start position.
6209      * @param {number} [end=array.length] The end position.
6210      * @returns {Array} Returns the slice of `array`.
6211      */
6212     function slice(array, start, end) {
6213       var length = array ? array.length : 0;
6214       if (!length) {
6215         return [];
6216       }
6217       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
6218         start = 0;
6219         end = length;
6220       }
6221       else {
6222         start = start == null ? 0 : toInteger(start);
6223         end = end === undefined ? length : toInteger(end);
6224       }
6225       return baseSlice(array, start, end);
6226     }
6227
6228     /**
6229      * Uses a binary search to determine the lowest index at which `value` should
6230      * be inserted into `array` in order to maintain its sort order.
6231      *
6232      * @static
6233      * @memberOf _
6234      * @category Array
6235      * @param {Array} array The sorted array to inspect.
6236      * @param {*} value The value to evaluate.
6237      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6238      * @example
6239      *
6240      * _.sortedIndex([30, 50], 40);
6241      * // => 1
6242      *
6243      * _.sortedIndex([4, 5], 4);
6244      * // => 0
6245      */
6246     function sortedIndex(array, value) {
6247       return baseSortedIndex(array, value);
6248     }
6249
6250     /**
6251      * This method is like `_.sortedIndex` except that it accepts `iteratee`
6252      * which is invoked for `value` and each element of `array` to compute their
6253      * sort ranking. The iteratee is invoked with one argument: (value).
6254      *
6255      * @static
6256      * @memberOf _
6257      * @category Array
6258      * @param {Array} array The sorted array to inspect.
6259      * @param {*} value The value to evaluate.
6260      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6261      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6262      * @example
6263      *
6264      * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
6265      *
6266      * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
6267      * // => 1
6268      *
6269      * // using the `_.property` iteratee shorthand
6270      * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6271      * // => 0
6272      */
6273     function sortedIndexBy(array, value, iteratee) {
6274       return baseSortedIndexBy(array, value, getIteratee(iteratee));
6275     }
6276
6277     /**
6278      * This method is like `_.indexOf` except that it performs a binary
6279      * search on a sorted `array`.
6280      *
6281      * @static
6282      * @memberOf _
6283      * @category Array
6284      * @param {Array} array The array to search.
6285      * @param {*} value The value to search for.
6286      * @returns {number} Returns the index of the matched value, else `-1`.
6287      * @example
6288      *
6289      * _.sortedIndexOf([1, 1, 2, 2], 2);
6290      * // => 2
6291      */
6292     function sortedIndexOf(array, value) {
6293       var length = array ? array.length : 0;
6294       if (length) {
6295         var index = baseSortedIndex(array, value);
6296         if (index < length && eq(array[index], value)) {
6297           return index;
6298         }
6299       }
6300       return -1;
6301     }
6302
6303     /**
6304      * This method is like `_.sortedIndex` except that it returns the highest
6305      * index at which `value` should be inserted into `array` in order to
6306      * maintain its sort order.
6307      *
6308      * @static
6309      * @memberOf _
6310      * @category Array
6311      * @param {Array} array The sorted array to inspect.
6312      * @param {*} value The value to evaluate.
6313      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6314      * @example
6315      *
6316      * _.sortedLastIndex([4, 5], 4);
6317      * // => 1
6318      */
6319     function sortedLastIndex(array, value) {
6320       return baseSortedIndex(array, value, true);
6321     }
6322
6323     /**
6324      * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
6325      * which is invoked for `value` and each element of `array` to compute their
6326      * sort ranking. The iteratee is invoked with one argument: (value).
6327      *
6328      * @static
6329      * @memberOf _
6330      * @category Array
6331      * @param {Array} array The sorted array to inspect.
6332      * @param {*} value The value to evaluate.
6333      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6334      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6335      * @example
6336      *
6337      * // using the `_.property` iteratee shorthand
6338      * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6339      * // => 1
6340      */
6341     function sortedLastIndexBy(array, value, iteratee) {
6342       return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
6343     }
6344
6345     /**
6346      * This method is like `_.lastIndexOf` except that it performs a binary
6347      * search on a sorted `array`.
6348      *
6349      * @static
6350      * @memberOf _
6351      * @category Array
6352      * @param {Array} array The array to search.
6353      * @param {*} value The value to search for.
6354      * @returns {number} Returns the index of the matched value, else `-1`.
6355      * @example
6356      *
6357      * _.sortedLastIndexOf([1, 1, 2, 2], 2);
6358      * // => 3
6359      */
6360     function sortedLastIndexOf(array, value) {
6361       var length = array ? array.length : 0;
6362       if (length) {
6363         var index = baseSortedIndex(array, value, true) - 1;
6364         if (eq(array[index], value)) {
6365           return index;
6366         }
6367       }
6368       return -1;
6369     }
6370
6371     /**
6372      * This method is like `_.uniq` except that it's designed and optimized
6373      * for sorted arrays.
6374      *
6375      * @static
6376      * @memberOf _
6377      * @category Array
6378      * @param {Array} array The array to inspect.
6379      * @returns {Array} Returns the new duplicate free array.
6380      * @example
6381      *
6382      * _.sortedUniq([1, 1, 2]);
6383      * // => [1, 2]
6384      */
6385     function sortedUniq(array) {
6386       return (array && array.length)
6387         ? baseSortedUniq(array)
6388         : [];
6389     }
6390
6391     /**
6392      * This method is like `_.uniqBy` except that it's designed and optimized
6393      * for sorted arrays.
6394      *
6395      * @static
6396      * @memberOf _
6397      * @category Array
6398      * @param {Array} array The array to inspect.
6399      * @param {Function} [iteratee] The iteratee invoked per element.
6400      * @returns {Array} Returns the new duplicate free array.
6401      * @example
6402      *
6403      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
6404      * // => [1.1, 2.2]
6405      */
6406     function sortedUniqBy(array, iteratee) {
6407       return (array && array.length)
6408         ? baseSortedUniqBy(array, getIteratee(iteratee))
6409         : [];
6410     }
6411
6412     /**
6413      * Gets all but the first element of `array`.
6414      *
6415      * @static
6416      * @memberOf _
6417      * @category Array
6418      * @param {Array} array The array to query.
6419      * @returns {Array} Returns the slice of `array`.
6420      * @example
6421      *
6422      * _.tail([1, 2, 3]);
6423      * // => [2, 3]
6424      */
6425     function tail(array) {
6426       return drop(array, 1);
6427     }
6428
6429     /**
6430      * Creates a slice of `array` with `n` elements taken from the beginning.
6431      *
6432      * @static
6433      * @memberOf _
6434      * @category Array
6435      * @param {Array} array The array to query.
6436      * @param {number} [n=1] The number of elements to take.
6437      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6438      * @returns {Array} Returns the slice of `array`.
6439      * @example
6440      *
6441      * _.take([1, 2, 3]);
6442      * // => [1]
6443      *
6444      * _.take([1, 2, 3], 2);
6445      * // => [1, 2]
6446      *
6447      * _.take([1, 2, 3], 5);
6448      * // => [1, 2, 3]
6449      *
6450      * _.take([1, 2, 3], 0);
6451      * // => []
6452      */
6453     function take(array, n, guard) {
6454       if (!(array && array.length)) {
6455         return [];
6456       }
6457       n = (guard || n === undefined) ? 1 : toInteger(n);
6458       return baseSlice(array, 0, n < 0 ? 0 : n);
6459     }
6460
6461     /**
6462      * Creates a slice of `array` with `n` elements taken from the end.
6463      *
6464      * @static
6465      * @memberOf _
6466      * @category Array
6467      * @param {Array} array The array to query.
6468      * @param {number} [n=1] The number of elements to take.
6469      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6470      * @returns {Array} Returns the slice of `array`.
6471      * @example
6472      *
6473      * _.takeRight([1, 2, 3]);
6474      * // => [3]
6475      *
6476      * _.takeRight([1, 2, 3], 2);
6477      * // => [2, 3]
6478      *
6479      * _.takeRight([1, 2, 3], 5);
6480      * // => [1, 2, 3]
6481      *
6482      * _.takeRight([1, 2, 3], 0);
6483      * // => []
6484      */
6485     function takeRight(array, n, guard) {
6486       var length = array ? array.length : 0;
6487       if (!length) {
6488         return [];
6489       }
6490       n = (guard || n === undefined) ? 1 : toInteger(n);
6491       n = length - n;
6492       return baseSlice(array, n < 0 ? 0 : n, length);
6493     }
6494
6495     /**
6496      * Creates a slice of `array` with elements taken from the end. Elements are
6497      * taken until `predicate` returns falsey. The predicate is invoked with three
6498      * arguments: (value, index, array).
6499      *
6500      * @static
6501      * @memberOf _
6502      * @category Array
6503      * @param {Array} array The array to query.
6504      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6505      * @returns {Array} Returns the slice of `array`.
6506      * @example
6507      *
6508      * var users = [
6509      *   { 'user': 'barney',  'active': true },
6510      *   { 'user': 'fred',    'active': false },
6511      *   { 'user': 'pebbles', 'active': false }
6512      * ];
6513      *
6514      * _.takeRightWhile(users, function(o) { return !o.active; });
6515      * // => objects for ['fred', 'pebbles']
6516      *
6517      * // using the `_.matches` iteratee shorthand
6518      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
6519      * // => objects for ['pebbles']
6520      *
6521      * // using the `_.matchesProperty` iteratee shorthand
6522      * _.takeRightWhile(users, ['active', false]);
6523      * // => objects for ['fred', 'pebbles']
6524      *
6525      * // using the `_.property` iteratee shorthand
6526      * _.takeRightWhile(users, 'active');
6527      * // => []
6528      */
6529     function takeRightWhile(array, predicate) {
6530       return (array && array.length)
6531         ? baseWhile(array, getIteratee(predicate, 3), false, true)
6532         : [];
6533     }
6534
6535     /**
6536      * Creates a slice of `array` with elements taken from the beginning. Elements
6537      * are taken until `predicate` returns falsey. The predicate is invoked with
6538      * three arguments: (value, index, array).
6539      *
6540      * @static
6541      * @memberOf _
6542      * @category Array
6543      * @param {Array} array The array to query.
6544      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6545      * @returns {Array} Returns the slice of `array`.
6546      * @example
6547      *
6548      * var users = [
6549      *   { 'user': 'barney',  'active': false },
6550      *   { 'user': 'fred',    'active': false},
6551      *   { 'user': 'pebbles', 'active': true }
6552      * ];
6553      *
6554      * _.takeWhile(users, function(o) { return !o.active; });
6555      * // => objects for ['barney', 'fred']
6556      *
6557      * // using the `_.matches` iteratee shorthand
6558      * _.takeWhile(users, { 'user': 'barney', 'active': false });
6559      * // => objects for ['barney']
6560      *
6561      * // using the `_.matchesProperty` iteratee shorthand
6562      * _.takeWhile(users, ['active', false]);
6563      * // => objects for ['barney', 'fred']
6564      *
6565      * // using the `_.property` iteratee shorthand
6566      * _.takeWhile(users, 'active');
6567      * // => []
6568      */
6569     function takeWhile(array, predicate) {
6570       return (array && array.length)
6571         ? baseWhile(array, getIteratee(predicate, 3))
6572         : [];
6573     }
6574
6575     /**
6576      * Creates an array of unique values, in order, from all of the provided arrays
6577      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6578      * for equality comparisons.
6579      *
6580      * @static
6581      * @memberOf _
6582      * @category Array
6583      * @param {...Array} [arrays] The arrays to inspect.
6584      * @returns {Array} Returns the new array of combined values.
6585      * @example
6586      *
6587      * _.union([2, 1], [4, 2], [1, 2]);
6588      * // => [2, 1, 4]
6589      */
6590     var union = rest(function(arrays) {
6591       return baseUniq(baseFlatten(arrays, false, true));
6592     });
6593
6594     /**
6595      * This method is like `_.union` except that it accepts `iteratee` which is
6596      * invoked for each element of each `arrays` to generate the criterion by which
6597      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6598      *
6599      * @static
6600      * @memberOf _
6601      * @category Array
6602      * @param {...Array} [arrays] The arrays to inspect.
6603      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6604      * @returns {Array} Returns the new array of combined values.
6605      * @example
6606      *
6607      * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6608      * // => [2.1, 1.2, 4.3]
6609      *
6610      * // using the `_.property` iteratee shorthand
6611      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6612      * // => [{ 'x': 1 }, { 'x': 2 }]
6613      */
6614     var unionBy = rest(function(arrays) {
6615       var iteratee = last(arrays);
6616       if (isArrayLikeObject(iteratee)) {
6617         iteratee = undefined;
6618       }
6619       return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee));
6620     });
6621
6622     /**
6623      * This method is like `_.union` except that it accepts `comparator` which
6624      * is invoked to compare elements of `arrays`. The comparator is invoked
6625      * with two arguments: (arrVal, othVal).
6626      *
6627      * @static
6628      * @memberOf _
6629      * @category Array
6630      * @param {...Array} [arrays] The arrays to inspect.
6631      * @param {Function} [comparator] The comparator invoked per element.
6632      * @returns {Array} Returns the new array of combined values.
6633      * @example
6634      *
6635      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6636      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6637      *
6638      * _.unionWith(objects, others, _.isEqual);
6639      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6640      */
6641     var unionWith = rest(function(arrays) {
6642       var comparator = last(arrays);
6643       if (isArrayLikeObject(comparator)) {
6644         comparator = undefined;
6645       }
6646       return baseUniq(baseFlatten(arrays, false, true), undefined, comparator);
6647     });
6648
6649     /**
6650      * Creates a duplicate-free version of an array, using
6651      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6652      * for equality comparisons, in which only the first occurrence of each element
6653      * is kept.
6654      *
6655      * @static
6656      * @memberOf _
6657      * @category Array
6658      * @param {Array} array The array to inspect.
6659      * @returns {Array} Returns the new duplicate free array.
6660      * @example
6661      *
6662      * _.uniq([2, 1, 2]);
6663      * // => [2, 1]
6664      */
6665     function uniq(array) {
6666       return (array && array.length)
6667         ? baseUniq(array)
6668         : [];
6669     }
6670
6671     /**
6672      * This method is like `_.uniq` except that it accepts `iteratee` which is
6673      * invoked for each element in `array` to generate the criterion by which
6674      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6675      *
6676      * @static
6677      * @memberOf _
6678      * @category Array
6679      * @param {Array} array The array to inspect.
6680      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6681      * @returns {Array} Returns the new duplicate free array.
6682      * @example
6683      *
6684      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
6685      * // => [2.1, 1.2]
6686      *
6687      * // using the `_.property` iteratee shorthand
6688      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
6689      * // => [{ 'x': 1 }, { 'x': 2 }]
6690      */
6691     function uniqBy(array, iteratee) {
6692       return (array && array.length)
6693         ? baseUniq(array, getIteratee(iteratee))
6694         : [];
6695     }
6696
6697     /**
6698      * This method is like `_.uniq` except that it accepts `comparator` which
6699      * is invoked to compare elements of `array`. The comparator is invoked with
6700      * two arguments: (arrVal, othVal).
6701      *
6702      * @static
6703      * @memberOf _
6704      * @category Array
6705      * @param {Array} array The array to inspect.
6706      * @param {Function} [comparator] The comparator invoked per element.
6707      * @returns {Array} Returns the new duplicate free array.
6708      * @example
6709      *
6710      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
6711      *
6712      * _.uniqWith(objects, _.isEqual);
6713      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
6714      */
6715     function uniqWith(array, comparator) {
6716       return (array && array.length)
6717         ? baseUniq(array, undefined, comparator)
6718         : [];
6719     }
6720
6721     /**
6722      * This method is like `_.zip` except that it accepts an array of grouped
6723      * elements and creates an array regrouping the elements to their pre-zip
6724      * configuration.
6725      *
6726      * @static
6727      * @memberOf _
6728      * @category Array
6729      * @param {Array} array The array of grouped elements to process.
6730      * @returns {Array} Returns the new array of regrouped elements.
6731      * @example
6732      *
6733      * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
6734      * // => [['fred', 30, true], ['barney', 40, false]]
6735      *
6736      * _.unzip(zipped);
6737      * // => [['fred', 'barney'], [30, 40], [true, false]]
6738      */
6739     function unzip(array) {
6740       if (!(array && array.length)) {
6741         return [];
6742       }
6743       var length = 0;
6744       array = arrayFilter(array, function(group) {
6745         if (isArrayLikeObject(group)) {
6746           length = nativeMax(group.length, length);
6747           return true;
6748         }
6749       });
6750       return baseTimes(length, function(index) {
6751         return arrayMap(array, baseProperty(index));
6752       });
6753     }
6754
6755     /**
6756      * This method is like `_.unzip` except that it accepts `iteratee` to specify
6757      * how regrouped values should be combined. The iteratee is invoked with the
6758      * elements of each group: (...group).
6759      *
6760      * @static
6761      * @memberOf _
6762      * @category Array
6763      * @param {Array} array The array of grouped elements to process.
6764      * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
6765      * @returns {Array} Returns the new array of regrouped elements.
6766      * @example
6767      *
6768      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
6769      * // => [[1, 10, 100], [2, 20, 200]]
6770      *
6771      * _.unzipWith(zipped, _.add);
6772      * // => [3, 30, 300]
6773      */
6774     function unzipWith(array, iteratee) {
6775       if (!(array && array.length)) {
6776         return [];
6777       }
6778       var result = unzip(array);
6779       if (iteratee == null) {
6780         return result;
6781       }
6782       return arrayMap(result, function(group) {
6783         return apply(iteratee, undefined, group);
6784       });
6785     }
6786
6787     /**
6788      * Creates an array excluding all provided values using
6789      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6790      * for equality comparisons.
6791      *
6792      * @static
6793      * @memberOf _
6794      * @category Array
6795      * @param {Array} array The array to filter.
6796      * @param {...*} [values] The values to exclude.
6797      * @returns {Array} Returns the new array of filtered values.
6798      * @example
6799      *
6800      * _.without([1, 2, 1, 3], 1, 2);
6801      * // => [3]
6802      */
6803     var without = rest(function(array, values) {
6804       return isArrayLikeObject(array)
6805         ? baseDifference(array, values)
6806         : [];
6807     });
6808
6809     /**
6810      * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
6811      * of the provided arrays.
6812      *
6813      * @static
6814      * @memberOf _
6815      * @category Array
6816      * @param {...Array} [arrays] The arrays to inspect.
6817      * @returns {Array} Returns the new array of values.
6818      * @example
6819      *
6820      * _.xor([2, 1], [4, 2]);
6821      * // => [1, 4]
6822      */
6823     var xor = rest(function(arrays) {
6824       return baseXor(arrayFilter(arrays, isArrayLikeObject));
6825     });
6826
6827     /**
6828      * This method is like `_.xor` except that it accepts `iteratee` which is
6829      * invoked for each element of each `arrays` to generate the criterion by which
6830      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6831      *
6832      * @static
6833      * @memberOf _
6834      * @category Array
6835      * @param {...Array} [arrays] The arrays to inspect.
6836      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6837      * @returns {Array} Returns the new array of values.
6838      * @example
6839      *
6840      * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6841      * // => [1.2, 4.3]
6842      *
6843      * // using the `_.property` iteratee shorthand
6844      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6845      * // => [{ 'x': 2 }]
6846      */
6847     var xorBy = rest(function(arrays) {
6848       var iteratee = last(arrays);
6849       if (isArrayLikeObject(iteratee)) {
6850         iteratee = undefined;
6851       }
6852       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
6853     });
6854
6855     /**
6856      * This method is like `_.xor` except that it accepts `comparator` which is
6857      * invoked to compare elements of `arrays`. The comparator is invoked with
6858      * two arguments: (arrVal, othVal).
6859      *
6860      * @static
6861      * @memberOf _
6862      * @category Array
6863      * @param {...Array} [arrays] The arrays to inspect.
6864      * @param {Function} [comparator] The comparator invoked per element.
6865      * @returns {Array} Returns the new array of values.
6866      * @example
6867      *
6868      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6869      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6870      *
6871      * _.xorWith(objects, others, _.isEqual);
6872      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6873      */
6874     var xorWith = rest(function(arrays) {
6875       var comparator = last(arrays);
6876       if (isArrayLikeObject(comparator)) {
6877         comparator = undefined;
6878       }
6879       return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
6880     });
6881
6882     /**
6883      * Creates an array of grouped elements, the first of which contains the first
6884      * elements of the given arrays, the second of which contains the second elements
6885      * of the given arrays, and so on.
6886      *
6887      * @static
6888      * @memberOf _
6889      * @category Array
6890      * @param {...Array} [arrays] The arrays to process.
6891      * @returns {Array} Returns the new array of grouped elements.
6892      * @example
6893      *
6894      * _.zip(['fred', 'barney'], [30, 40], [true, false]);
6895      * // => [['fred', 30, true], ['barney', 40, false]]
6896      */
6897     var zip = rest(unzip);
6898
6899     /**
6900      * This method is like `_.fromPairs` except that it accepts two arrays,
6901      * one of property names and one of corresponding values.
6902      *
6903      * @static
6904      * @memberOf _
6905      * @category Array
6906      * @param {Array} [props=[]] The property names.
6907      * @param {Array} [values=[]] The property values.
6908      * @returns {Object} Returns the new object.
6909      * @example
6910      *
6911      * _.zipObject(['fred', 'barney'], [30, 40]);
6912      * // => { 'fred': 30, 'barney': 40 }
6913      */
6914     function zipObject(props, values) {
6915       var index = -1,
6916           length = props ? props.length : 0,
6917           valsLength = values ? values.length : 0,
6918           result = {};
6919
6920       while (++index < length) {
6921         baseSet(result, props[index], index < valsLength ? values[index] : undefined);
6922       }
6923       return result;
6924     }
6925
6926     /**
6927      * This method is like `_.zip` except that it accepts `iteratee` to specify
6928      * how grouped values should be combined. The iteratee is invoked with the
6929      * elements of each group: (...group).
6930      *
6931      * @static
6932      * @memberOf _
6933      * @category Array
6934      * @param {...Array} [arrays] The arrays to process.
6935      * @param {Function} [iteratee=_.identity] The function to combine grouped values.
6936      * @returns {Array} Returns the new array of grouped elements.
6937      * @example
6938      *
6939      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
6940      *   return a + b + c;
6941      * });
6942      * // => [111, 222]
6943      */
6944     var zipWith = rest(function(arrays) {
6945       var length = arrays.length,
6946           iteratee = length > 1 ? arrays[length - 1] : undefined;
6947
6948       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
6949       return unzipWith(arrays, iteratee);
6950     });
6951
6952     /*------------------------------------------------------------------------*/
6953
6954     /**
6955      * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
6956      * The result of such method chaining must be unwrapped with `_#value`.
6957      *
6958      * @static
6959      * @memberOf _
6960      * @category Seq
6961      * @param {*} value The value to wrap.
6962      * @returns {Object} Returns the new `lodash` wrapper instance.
6963      * @example
6964      *
6965      * var users = [
6966      *   { 'user': 'barney',  'age': 36 },
6967      *   { 'user': 'fred',    'age': 40 },
6968      *   { 'user': 'pebbles', 'age': 1 }
6969      * ];
6970      *
6971      * var youngest = _
6972      *   .chain(users)
6973      *   .sortBy('age')
6974      *   .map(function(o) {
6975      *     return o.user + ' is ' + o.age;
6976      *   })
6977      *   .head()
6978      *   .value();
6979      * // => 'pebbles is 1'
6980      */
6981     function chain(value) {
6982       var result = lodash(value);
6983       result.__chain__ = true;
6984       return result;
6985     }
6986
6987     /**
6988      * This method invokes `interceptor` and returns `value`. The interceptor is
6989      * invoked with one argument; (value). The purpose of this method is to "tap into"
6990      * a method chain in order to perform operations on intermediate results within
6991      * the chain.
6992      *
6993      * @static
6994      * @memberOf _
6995      * @category Seq
6996      * @param {*} value The value to provide to `interceptor`.
6997      * @param {Function} interceptor The function to invoke.
6998      * @returns {*} Returns `value`.
6999      * @example
7000      *
7001      * _([1, 2, 3])
7002      *  .tap(function(array) {
7003      *    array.pop();
7004      *  })
7005      *  .reverse()
7006      *  .value();
7007      * // => [2, 1]
7008      */
7009     function tap(value, interceptor) {
7010       interceptor(value);
7011       return value;
7012     }
7013
7014     /**
7015      * This method is like `_.tap` except that it returns the result of `interceptor`.
7016      *
7017      * @static
7018      * @memberOf _
7019      * @category Seq
7020      * @param {*} value The value to provide to `interceptor`.
7021      * @param {Function} interceptor The function to invoke.
7022      * @returns {*} Returns the result of `interceptor`.
7023      * @example
7024      *
7025      * _('  abc  ')
7026      *  .chain()
7027      *  .trim()
7028      *  .thru(function(value) {
7029      *    return [value];
7030      *  })
7031      *  .value();
7032      * // => ['abc']
7033      */
7034     function thru(value, interceptor) {
7035       return interceptor(value);
7036     }
7037
7038     /**
7039      * This method is the wrapper version of `_.at`.
7040      *
7041      * @name at
7042      * @memberOf _
7043      * @category Seq
7044      * @param {...(string|string[])} [paths] The property paths of elements to pick,
7045      *  specified individually or in arrays.
7046      * @returns {Object} Returns the new `lodash` wrapper instance.
7047      * @example
7048      *
7049      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
7050      *
7051      * _(object).at(['a[0].b.c', 'a[1]']).value();
7052      * // => [3, 4]
7053      *
7054      * _(['a', 'b', 'c']).at(0, 2).value();
7055      * // => ['a', 'c']
7056      */
7057     var wrapperAt = rest(function(paths) {
7058       paths = baseFlatten(paths);
7059       var length = paths.length,
7060           start = length ? paths[0] : 0,
7061           value = this.__wrapped__,
7062           interceptor = function(object) { return baseAt(object, paths); };
7063
7064       if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) {
7065         return this.thru(interceptor);
7066       }
7067       value = value.slice(start, +start + (length ? 1 : 0));
7068       value.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
7069       return new LodashWrapper(value, this.__chain__).thru(function(array) {
7070         if (length && !array.length) {
7071           array.push(undefined);
7072         }
7073         return array;
7074       });
7075     });
7076
7077     /**
7078      * Enables explicit method chaining on the wrapper object.
7079      *
7080      * @name chain
7081      * @memberOf _
7082      * @category Seq
7083      * @returns {Object} Returns the new `lodash` wrapper instance.
7084      * @example
7085      *
7086      * var users = [
7087      *   { 'user': 'barney', 'age': 36 },
7088      *   { 'user': 'fred',   'age': 40 }
7089      * ];
7090      *
7091      * // without explicit chaining
7092      * _(users).head();
7093      * // => { 'user': 'barney', 'age': 36 }
7094      *
7095      * // with explicit chaining
7096      * _(users)
7097      *   .chain()
7098      *   .head()
7099      *   .pick('user')
7100      *   .value();
7101      * // => { 'user': 'barney' }
7102      */
7103     function wrapperChain() {
7104       return chain(this);
7105     }
7106
7107     /**
7108      * Executes the chained sequence and returns the wrapped result.
7109      *
7110      * @name commit
7111      * @memberOf _
7112      * @category Seq
7113      * @returns {Object} Returns the new `lodash` wrapper instance.
7114      * @example
7115      *
7116      * var array = [1, 2];
7117      * var wrapped = _(array).push(3);
7118      *
7119      * console.log(array);
7120      * // => [1, 2]
7121      *
7122      * wrapped = wrapped.commit();
7123      * console.log(array);
7124      * // => [1, 2, 3]
7125      *
7126      * wrapped.last();
7127      * // => 3
7128      *
7129      * console.log(array);
7130      * // => [1, 2, 3]
7131      */
7132     function wrapperCommit() {
7133       return new LodashWrapper(this.value(), this.__chain__);
7134     }
7135
7136     /**
7137      * This method is the wrapper version of `_.flatMap`.
7138      *
7139      * @name flatMap
7140      * @memberOf _
7141      * @category Seq
7142      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7143      * @returns {Object} Returns the new `lodash` wrapper instance.
7144      * @example
7145      *
7146      * function duplicate(n) {
7147      *   return [n, n];
7148      * }
7149      *
7150      * _([1, 2]).flatMap(duplicate).value();
7151      * // => [1, 1, 2, 2]
7152      */
7153     function wrapperFlatMap(iteratee) {
7154       return this.map(iteratee).flatten();
7155     }
7156
7157     /**
7158      * Gets the next value on a wrapped object following the
7159      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
7160      *
7161      * @name next
7162      * @memberOf _
7163      * @category Seq
7164      * @returns {Object} Returns the next iterator value.
7165      * @example
7166      *
7167      * var wrapped = _([1, 2]);
7168      *
7169      * wrapped.next();
7170      * // => { 'done': false, 'value': 1 }
7171      *
7172      * wrapped.next();
7173      * // => { 'done': false, 'value': 2 }
7174      *
7175      * wrapped.next();
7176      * // => { 'done': true, 'value': undefined }
7177      */
7178     function wrapperNext() {
7179       if (this.__values__ === undefined) {
7180         this.__values__ = toArray(this.value());
7181       }
7182       var done = this.__index__ >= this.__values__.length,
7183           value = done ? undefined : this.__values__[this.__index__++];
7184
7185       return { 'done': done, 'value': value };
7186     }
7187
7188     /**
7189      * Enables the wrapper to be iterable.
7190      *
7191      * @name Symbol.iterator
7192      * @memberOf _
7193      * @category Seq
7194      * @returns {Object} Returns the wrapper object.
7195      * @example
7196      *
7197      * var wrapped = _([1, 2]);
7198      *
7199      * wrapped[Symbol.iterator]() === wrapped;
7200      * // => true
7201      *
7202      * Array.from(wrapped);
7203      * // => [1, 2]
7204      */
7205     function wrapperToIterator() {
7206       return this;
7207     }
7208
7209     /**
7210      * Creates a clone of the chained sequence planting `value` as the wrapped value.
7211      *
7212      * @name plant
7213      * @memberOf _
7214      * @category Seq
7215      * @param {*} value The value to plant.
7216      * @returns {Object} Returns the new `lodash` wrapper instance.
7217      * @example
7218      *
7219      * function square(n) {
7220      *   return n * n;
7221      * }
7222      *
7223      * var wrapped = _([1, 2]).map(square);
7224      * var other = wrapped.plant([3, 4]);
7225      *
7226      * other.value();
7227      * // => [9, 16]
7228      *
7229      * wrapped.value();
7230      * // => [1, 4]
7231      */
7232     function wrapperPlant(value) {
7233       var result,
7234           parent = this;
7235
7236       while (parent instanceof baseLodash) {
7237         var clone = wrapperClone(parent);
7238         clone.__index__ = 0;
7239         clone.__values__ = undefined;
7240         if (result) {
7241           previous.__wrapped__ = clone;
7242         } else {
7243           result = clone;
7244         }
7245         var previous = clone;
7246         parent = parent.__wrapped__;
7247       }
7248       previous.__wrapped__ = value;
7249       return result;
7250     }
7251
7252     /**
7253      * This method is the wrapper version of `_.reverse`.
7254      *
7255      * **Note:** This method mutates the wrapped array.
7256      *
7257      * @name reverse
7258      * @memberOf _
7259      * @category Seq
7260      * @returns {Object} Returns the new `lodash` wrapper instance.
7261      * @example
7262      *
7263      * var array = [1, 2, 3];
7264      *
7265      * _(array).reverse().value()
7266      * // => [3, 2, 1]
7267      *
7268      * console.log(array);
7269      * // => [3, 2, 1]
7270      */
7271     function wrapperReverse() {
7272       var value = this.__wrapped__;
7273       if (value instanceof LazyWrapper) {
7274         var wrapped = value;
7275         if (this.__actions__.length) {
7276           wrapped = new LazyWrapper(this);
7277         }
7278         wrapped = wrapped.reverse();
7279         wrapped.__actions__.push({ 'func': thru, 'args': [reverse], 'thisArg': undefined });
7280         return new LodashWrapper(wrapped, this.__chain__);
7281       }
7282       return this.thru(reverse);
7283     }
7284
7285     /**
7286      * Executes the chained sequence to extract the unwrapped value.
7287      *
7288      * @name value
7289      * @memberOf _
7290      * @alias toJSON, valueOf
7291      * @category Seq
7292      * @returns {*} Returns the resolved unwrapped value.
7293      * @example
7294      *
7295      * _([1, 2, 3]).value();
7296      * // => [1, 2, 3]
7297      */
7298     function wrapperValue() {
7299       return baseWrapperValue(this.__wrapped__, this.__actions__);
7300     }
7301
7302     /*------------------------------------------------------------------------*/
7303
7304     /**
7305      * Creates an object composed of keys generated from the results of running
7306      * each element of `collection` through `iteratee`. The corresponding value
7307      * of each key is the number of times the key was returned by `iteratee`.
7308      * The iteratee is invoked with one argument: (value).
7309      *
7310      * @static
7311      * @memberOf _
7312      * @category Collection
7313      * @param {Array|Object} collection The collection to iterate over.
7314      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7315      * @returns {Object} Returns the composed aggregate object.
7316      * @example
7317      *
7318      * _.countBy([6.1, 4.2, 6.3], Math.floor);
7319      * // => { '4': 1, '6': 2 }
7320      *
7321      * _.countBy(['one', 'two', 'three'], 'length');
7322      * // => { '3': 2, '5': 1 }
7323      */
7324     var countBy = createAggregator(function(result, value, key) {
7325       hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
7326     });
7327
7328     /**
7329      * Checks if `predicate` returns truthy for **all** elements of `collection`.
7330      * Iteration is stopped once `predicate` returns falsey. The predicate is
7331      * invoked with three arguments: (value, index|key, collection).
7332      *
7333      * @static
7334      * @memberOf _
7335      * @category Collection
7336      * @param {Array|Object} collection The collection to iterate over.
7337      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7338      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
7339      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
7340      * @example
7341      *
7342      * _.every([true, 1, null, 'yes'], Boolean);
7343      * // => false
7344      *
7345      * var users = [
7346      *   { 'user': 'barney', 'active': false },
7347      *   { 'user': 'fred',   'active': false }
7348      * ];
7349      *
7350      * // using the `_.matches` iteratee shorthand
7351      * _.every(users, { 'user': 'barney', 'active': false });
7352      * // => false
7353      *
7354      * // using the `_.matchesProperty` iteratee shorthand
7355      * _.every(users, ['active', false]);
7356      * // => true
7357      *
7358      * // using the `_.property` iteratee shorthand
7359      * _.every(users, 'active');
7360      * // => false
7361      */
7362     function every(collection, predicate, guard) {
7363       var func = isArray(collection) ? arrayEvery : baseEvery;
7364       if (guard && isIterateeCall(collection, predicate, guard)) {
7365         predicate = undefined;
7366       }
7367       return func(collection, getIteratee(predicate, 3));
7368     }
7369
7370     /**
7371      * Iterates over elements of `collection`, returning an array of all elements
7372      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7373      * (value, index|key, collection).
7374      *
7375      * @static
7376      * @memberOf _
7377      * @category Collection
7378      * @param {Array|Object} collection The collection to iterate over.
7379      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7380      * @returns {Array} Returns the new filtered array.
7381      * @example
7382      *
7383      * var users = [
7384      *   { 'user': 'barney', 'age': 36, 'active': true },
7385      *   { 'user': 'fred',   'age': 40, 'active': false }
7386      * ];
7387      *
7388      * _.filter(users, function(o) { return !o.active; });
7389      * // => objects for ['fred']
7390      *
7391      * // using the `_.matches` iteratee shorthand
7392      * _.filter(users, { 'age': 36, 'active': true });
7393      * // => objects for ['barney']
7394      *
7395      * // using the `_.matchesProperty` iteratee shorthand
7396      * _.filter(users, ['active', false]);
7397      * // => objects for ['fred']
7398      *
7399      * // using the `_.property` iteratee shorthand
7400      * _.filter(users, 'active');
7401      * // => objects for ['barney']
7402      */
7403     function filter(collection, predicate) {
7404       var func = isArray(collection) ? arrayFilter : baseFilter;
7405       return func(collection, getIteratee(predicate, 3));
7406     }
7407
7408     /**
7409      * Iterates over elements of `collection`, returning the first element
7410      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7411      * (value, index|key, collection).
7412      *
7413      * @static
7414      * @memberOf _
7415      * @category Collection
7416      * @param {Array|Object} collection The collection to search.
7417      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7418      * @returns {*} Returns the matched element, else `undefined`.
7419      * @example
7420      *
7421      * var users = [
7422      *   { 'user': 'barney',  'age': 36, 'active': true },
7423      *   { 'user': 'fred',    'age': 40, 'active': false },
7424      *   { 'user': 'pebbles', 'age': 1,  'active': true }
7425      * ];
7426      *
7427      * _.find(users, function(o) { return o.age < 40; });
7428      * // => object for 'barney'
7429      *
7430      * // using the `_.matches` iteratee shorthand
7431      * _.find(users, { 'age': 1, 'active': true });
7432      * // => object for 'pebbles'
7433      *
7434      * // using the `_.matchesProperty` iteratee shorthand
7435      * _.find(users, ['active', false]);
7436      * // => object for 'fred'
7437      *
7438      * // using the `_.property` iteratee shorthand
7439      * _.find(users, 'active');
7440      * // => object for 'barney'
7441      */
7442     function find(collection, predicate) {
7443       predicate = getIteratee(predicate, 3);
7444       if (isArray(collection)) {
7445         var index = baseFindIndex(collection, predicate);
7446         return index > -1 ? collection[index] : undefined;
7447       }
7448       return baseFind(collection, predicate, baseEach);
7449     }
7450
7451     /**
7452      * This method is like `_.find` except that it iterates over elements of
7453      * `collection` from right to left.
7454      *
7455      * @static
7456      * @memberOf _
7457      * @category Collection
7458      * @param {Array|Object} collection The collection to search.
7459      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7460      * @returns {*} Returns the matched element, else `undefined`.
7461      * @example
7462      *
7463      * _.findLast([1, 2, 3, 4], function(n) {
7464      *   return n % 2 == 1;
7465      * });
7466      * // => 3
7467      */
7468     function findLast(collection, predicate) {
7469       predicate = getIteratee(predicate, 3);
7470       if (isArray(collection)) {
7471         var index = baseFindIndex(collection, predicate, true);
7472         return index > -1 ? collection[index] : undefined;
7473       }
7474       return baseFind(collection, predicate, baseEachRight);
7475     }
7476
7477     /**
7478      * Iterates over elements of `collection` invoking `iteratee` for each element.
7479      * The iteratee is invoked with three arguments: (value, index|key, collection).
7480      * Iteratee functions may exit iteration early by explicitly returning `false`.
7481      *
7482      * **Note:** As with other "Collections" methods, objects with a "length" property
7483      * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
7484      * for object iteration.
7485      *
7486      * @static
7487      * @memberOf _
7488      * @alias each
7489      * @category Collection
7490      * @param {Array|Object} collection The collection to iterate over.
7491      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7492      * @returns {Array|Object} Returns `collection`.
7493      * @example
7494      *
7495      * _([1, 2]).forEach(function(value) {
7496      *   console.log(value);
7497      * });
7498      * // => logs `1` then `2`
7499      *
7500      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
7501      *   console.log(key);
7502      * });
7503      * // => logs 'a' then 'b' (iteration order is not guaranteed)
7504      */
7505     function forEach(collection, iteratee) {
7506       return (typeof iteratee == 'function' && isArray(collection))
7507         ? arrayEach(collection, iteratee)
7508         : baseEach(collection, toFunction(iteratee));
7509     }
7510
7511     /**
7512      * This method is like `_.forEach` except that it iterates over elements of
7513      * `collection` from right to left.
7514      *
7515      * @static
7516      * @memberOf _
7517      * @alias eachRight
7518      * @category Collection
7519      * @param {Array|Object} collection The collection to iterate over.
7520      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7521      * @returns {Array|Object} Returns `collection`.
7522      * @example
7523      *
7524      * _.forEachRight([1, 2], function(value) {
7525      *   console.log(value);
7526      * });
7527      * // => logs `2` then `1`
7528      */
7529     function forEachRight(collection, iteratee) {
7530       return (typeof iteratee == 'function' && isArray(collection))
7531         ? arrayEachRight(collection, iteratee)
7532         : baseEachRight(collection, toFunction(iteratee));
7533     }
7534
7535     /**
7536      * Creates an object composed of keys generated from the results of running
7537      * each element of `collection` through `iteratee`. The corresponding value
7538      * of each key is an array of elements responsible for generating the key.
7539      * The iteratee is invoked with one argument: (value).
7540      *
7541      * @static
7542      * @memberOf _
7543      * @category Collection
7544      * @param {Array|Object} collection The collection to iterate over.
7545      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7546      * @returns {Object} Returns the composed aggregate object.
7547      * @example
7548      *
7549      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
7550      * // => { '4': [4.2], '6': [6.1, 6.3] }
7551      *
7552      * // using the `_.property` iteratee shorthand
7553      * _.groupBy(['one', 'two', 'three'], 'length');
7554      * // => { '3': ['one', 'two'], '5': ['three'] }
7555      */
7556     var groupBy = createAggregator(function(result, value, key) {
7557       if (hasOwnProperty.call(result, key)) {
7558         result[key].push(value);
7559       } else {
7560         result[key] = [value];
7561       }
7562     });
7563
7564     /**
7565      * Checks if `value` is in `collection`. If `collection` is a string it's checked
7566      * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7567      * is used for equality comparisons. If `fromIndex` is negative, it's used as
7568      * the offset from the end of `collection`.
7569      *
7570      * @static
7571      * @memberOf _
7572      * @category Collection
7573      * @param {Array|Object|string} collection The collection to search.
7574      * @param {*} value The value to search for.
7575      * @param {number} [fromIndex=0] The index to search from.
7576      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7577      * @returns {boolean} Returns `true` if `value` is found, else `false`.
7578      * @example
7579      *
7580      * _.includes([1, 2, 3], 1);
7581      * // => true
7582      *
7583      * _.includes([1, 2, 3], 1, 2);
7584      * // => false
7585      *
7586      * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
7587      * // => true
7588      *
7589      * _.includes('pebbles', 'eb');
7590      * // => true
7591      */
7592     function includes(collection, value, fromIndex, guard) {
7593       collection = isArrayLike(collection) ? collection : values(collection);
7594       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
7595
7596       var length = collection.length;
7597       if (fromIndex < 0) {
7598         fromIndex = nativeMax(length + fromIndex, 0);
7599       }
7600       return isString(collection)
7601         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
7602         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
7603     }
7604
7605     /**
7606      * Invokes the method at `path` of each element in `collection`, returning
7607      * an array of the results of each invoked method. Any additional arguments
7608      * are provided to each invoked method. If `methodName` is a function it's
7609      * invoked for, and `this` bound to, each element in `collection`.
7610      *
7611      * @static
7612      * @memberOf _
7613      * @category Collection
7614      * @param {Array|Object} collection The collection to iterate over.
7615      * @param {Array|Function|string} path The path of the method to invoke or
7616      *  the function invoked per iteration.
7617      * @param {...*} [args] The arguments to invoke each method with.
7618      * @returns {Array} Returns the array of results.
7619      * @example
7620      *
7621      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
7622      * // => [[1, 5, 7], [1, 2, 3]]
7623      *
7624      * _.invokeMap([123, 456], String.prototype.split, '');
7625      * // => [['1', '2', '3'], ['4', '5', '6']]
7626      */
7627     var invokeMap = rest(function(collection, path, args) {
7628       var index = -1,
7629           isFunc = typeof path == 'function',
7630           isProp = isKey(path),
7631           result = isArrayLike(collection) ? Array(collection.length) : [];
7632
7633       baseEach(collection, function(value) {
7634         var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
7635         result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
7636       });
7637       return result;
7638     });
7639
7640     /**
7641      * Creates an object composed of keys generated from the results of running
7642      * each element of `collection` through `iteratee`. The corresponding value
7643      * of each key is the last element responsible for generating the key. The
7644      * iteratee is invoked with one argument: (value).
7645      *
7646      * @static
7647      * @memberOf _
7648      * @category Collection
7649      * @param {Array|Object} collection The collection to iterate over.
7650      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7651      * @returns {Object} Returns the composed aggregate object.
7652      * @example
7653      *
7654      * var keyData = [
7655      *   { 'dir': 'left', 'code': 97 },
7656      *   { 'dir': 'right', 'code': 100 }
7657      * ];
7658      *
7659      * _.keyBy(keyData, function(o) {
7660      *   return String.fromCharCode(o.code);
7661      * });
7662      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
7663      *
7664      * _.keyBy(keyData, 'dir');
7665      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
7666      */
7667     var keyBy = createAggregator(function(result, value, key) {
7668       result[key] = value;
7669     });
7670
7671     /**
7672      * Creates an array of values by running each element in `collection` through
7673      * `iteratee`. The iteratee is invoked with three arguments:
7674      * (value, index|key, collection).
7675      *
7676      * Many lodash methods are guarded to work as iteratees for methods like
7677      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
7678      *
7679      * The guarded methods are:
7680      * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
7681      * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
7682      * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
7683      * and `words`
7684      *
7685      * @static
7686      * @memberOf _
7687      * @category Collection
7688      * @param {Array|Object} collection The collection to iterate over.
7689      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7690      * @returns {Array} Returns the new mapped array.
7691      * @example
7692      *
7693      * function square(n) {
7694      *   return n * n;
7695      * }
7696      *
7697      * _.map([4, 8], square);
7698      * // => [16, 64]
7699      *
7700      * _.map({ 'a': 4, 'b': 8 }, square);
7701      * // => [16, 64] (iteration order is not guaranteed)
7702      *
7703      * var users = [
7704      *   { 'user': 'barney' },
7705      *   { 'user': 'fred' }
7706      * ];
7707      *
7708      * // using the `_.property` iteratee shorthand
7709      * _.map(users, 'user');
7710      * // => ['barney', 'fred']
7711      */
7712     function map(collection, iteratee) {
7713       var func = isArray(collection) ? arrayMap : baseMap;
7714       return func(collection, getIteratee(iteratee, 3));
7715     }
7716
7717     /**
7718      * This method is like `_.sortBy` except that it allows specifying the sort
7719      * orders of the iteratees to sort by. If `orders` is unspecified, all values
7720      * are sorted in ascending order. Otherwise, specify an order of "desc" for
7721      * descending or "asc" for ascending sort order of corresponding values.
7722      *
7723      * @static
7724      * @memberOf _
7725      * @category Collection
7726      * @param {Array|Object} collection The collection to iterate over.
7727      * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
7728      * @param {string[]} [orders] The sort orders of `iteratees`.
7729      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7730      * @returns {Array} Returns the new sorted array.
7731      * @example
7732      *
7733      * var users = [
7734      *   { 'user': 'fred',   'age': 48 },
7735      *   { 'user': 'barney', 'age': 34 },
7736      *   { 'user': 'fred',   'age': 42 },
7737      *   { 'user': 'barney', 'age': 36 }
7738      * ];
7739      *
7740      * // sort by `user` in ascending order and by `age` in descending order
7741      * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
7742      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
7743      */
7744     function orderBy(collection, iteratees, orders, guard) {
7745       if (collection == null) {
7746         return [];
7747       }
7748       if (!isArray(iteratees)) {
7749         iteratees = iteratees == null ? [] : [iteratees];
7750       }
7751       orders = guard ? undefined : orders;
7752       if (!isArray(orders)) {
7753         orders = orders == null ? [] : [orders];
7754       }
7755       return baseOrderBy(collection, iteratees, orders);
7756     }
7757
7758     /**
7759      * Creates an array of elements split into two groups, the first of which
7760      * contains elements `predicate` returns truthy for, the second of which
7761      * contains elements `predicate` returns falsey for. The predicate is
7762      * invoked with one argument: (value).
7763      *
7764      * @static
7765      * @memberOf _
7766      * @category Collection
7767      * @param {Array|Object} collection The collection to iterate over.
7768      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7769      * @returns {Array} Returns the array of grouped elements.
7770      * @example
7771      *
7772      * var users = [
7773      *   { 'user': 'barney',  'age': 36, 'active': false },
7774      *   { 'user': 'fred',    'age': 40, 'active': true },
7775      *   { 'user': 'pebbles', 'age': 1,  'active': false }
7776      * ];
7777      *
7778      * _.partition(users, function(o) { return o.active; });
7779      * // => objects for [['fred'], ['barney', 'pebbles']]
7780      *
7781      * // using the `_.matches` iteratee shorthand
7782      * _.partition(users, { 'age': 1, 'active': false });
7783      * // => objects for [['pebbles'], ['barney', 'fred']]
7784      *
7785      * // using the `_.matchesProperty` iteratee shorthand
7786      * _.partition(users, ['active', false]);
7787      * // => objects for [['barney', 'pebbles'], ['fred']]
7788      *
7789      * // using the `_.property` iteratee shorthand
7790      * _.partition(users, 'active');
7791      * // => objects for [['fred'], ['barney', 'pebbles']]
7792      */
7793     var partition = createAggregator(function(result, value, key) {
7794       result[key ? 0 : 1].push(value);
7795     }, function() { return [[], []]; });
7796
7797     /**
7798      * Reduces `collection` to a value which is the accumulated result of running
7799      * each element in `collection` through `iteratee`, where each successive
7800      * invocation is supplied the return value of the previous. If `accumulator`
7801      * is not provided the first element of `collection` is used as the initial
7802      * value. The iteratee is invoked with four arguments:
7803      * (accumulator, value, index|key, collection).
7804      *
7805      * Many lodash methods are guarded to work as iteratees for methods like
7806      * `_.reduce`, `_.reduceRight`, and `_.transform`.
7807      *
7808      * The guarded methods are:
7809      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
7810      * and `sortBy`
7811      *
7812      * @static
7813      * @memberOf _
7814      * @category Collection
7815      * @param {Array|Object} collection The collection to iterate over.
7816      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7817      * @param {*} [accumulator] The initial value.
7818      * @returns {*} Returns the accumulated value.
7819      * @example
7820      *
7821      * _.reduce([1, 2], function(sum, n) {
7822      *   return sum + n;
7823      * });
7824      * // => 3
7825      *
7826      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
7827      *   (result[value] || (result[value] = [])).push(key);
7828      *   return result;
7829      * }, {});
7830      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
7831      */
7832     function reduce(collection, iteratee, accumulator) {
7833       var func = isArray(collection) ? arrayReduce : baseReduce,
7834           initAccum = arguments.length < 3;
7835
7836       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
7837     }
7838
7839     /**
7840      * This method is like `_.reduce` except that it iterates over elements of
7841      * `collection` from right to left.
7842      *
7843      * @static
7844      * @memberOf _
7845      * @category Collection
7846      * @param {Array|Object} collection The collection to iterate over.
7847      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7848      * @param {*} [accumulator] The initial value.
7849      * @returns {*} Returns the accumulated value.
7850      * @example
7851      *
7852      * var array = [[0, 1], [2, 3], [4, 5]];
7853      *
7854      * _.reduceRight(array, function(flattened, other) {
7855      *   return flattened.concat(other);
7856      * }, []);
7857      * // => [4, 5, 2, 3, 0, 1]
7858      */
7859     function reduceRight(collection, iteratee, accumulator) {
7860       var func = isArray(collection) ? arrayReduceRight : baseReduce,
7861           initAccum = arguments.length < 3;
7862
7863       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
7864     }
7865
7866     /**
7867      * The opposite of `_.filter`; this method returns the elements of `collection`
7868      * that `predicate` does **not** return truthy for.
7869      *
7870      * @static
7871      * @memberOf _
7872      * @category Collection
7873      * @param {Array|Object} collection The collection to iterate over.
7874      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7875      * @returns {Array} Returns the new filtered array.
7876      * @example
7877      *
7878      * var users = [
7879      *   { 'user': 'barney', 'age': 36, 'active': false },
7880      *   { 'user': 'fred',   'age': 40, 'active': true }
7881      * ];
7882      *
7883      * _.reject(users, function(o) { return !o.active; });
7884      * // => objects for ['fred']
7885      *
7886      * // using the `_.matches` iteratee shorthand
7887      * _.reject(users, { 'age': 40, 'active': true });
7888      * // => objects for ['barney']
7889      *
7890      * // using the `_.matchesProperty` iteratee shorthand
7891      * _.reject(users, ['active', false]);
7892      * // => objects for ['fred']
7893      *
7894      * // using the `_.property` iteratee shorthand
7895      * _.reject(users, 'active');
7896      * // => objects for ['barney']
7897      */
7898     function reject(collection, predicate) {
7899       var func = isArray(collection) ? arrayFilter : baseFilter;
7900       predicate = getIteratee(predicate, 3);
7901       return func(collection, function(value, index, collection) {
7902         return !predicate(value, index, collection);
7903       });
7904     }
7905
7906     /**
7907      * Gets a random element from `collection`.
7908      *
7909      * @static
7910      * @memberOf _
7911      * @category Collection
7912      * @param {Array|Object} collection The collection to sample.
7913      * @returns {*} Returns the random element.
7914      * @example
7915      *
7916      * _.sample([1, 2, 3, 4]);
7917      * // => 2
7918      */
7919     function sample(collection) {
7920       var array = isArrayLike(collection) ? collection : values(collection),
7921           length = array.length;
7922
7923       return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
7924     }
7925
7926     /**
7927      * Gets `n` random elements at unique keys from `collection` up to the
7928      * size of `collection`.
7929      *
7930      * @static
7931      * @memberOf _
7932      * @category Collection
7933      * @param {Array|Object} collection The collection to sample.
7934      * @param {number} [n=0] The number of elements to sample.
7935      * @returns {Array} Returns the random elements.
7936      * @example
7937      *
7938      * _.sampleSize([1, 2, 3], 2);
7939      * // => [3, 1]
7940      *
7941      * _.sampleSize([1, 2, 3], 4);
7942      * // => [2, 3, 1]
7943      */
7944     function sampleSize(collection, n) {
7945       var index = -1,
7946           result = toArray(collection),
7947           length = result.length,
7948           lastIndex = length - 1;
7949
7950       n = baseClamp(toInteger(n), 0, length);
7951       while (++index < n) {
7952         var rand = baseRandom(index, lastIndex),
7953             value = result[rand];
7954
7955         result[rand] = result[index];
7956         result[index] = value;
7957       }
7958       result.length = n;
7959       return result;
7960     }
7961
7962     /**
7963      * Creates an array of shuffled values, using a version of the
7964      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
7965      *
7966      * @static
7967      * @memberOf _
7968      * @category Collection
7969      * @param {Array|Object} collection The collection to shuffle.
7970      * @returns {Array} Returns the new shuffled array.
7971      * @example
7972      *
7973      * _.shuffle([1, 2, 3, 4]);
7974      * // => [4, 1, 3, 2]
7975      */
7976     function shuffle(collection) {
7977       return sampleSize(collection, MAX_ARRAY_LENGTH);
7978     }
7979
7980     /**
7981      * Gets the size of `collection` by returning its length for array-like
7982      * values or the number of own enumerable properties for objects.
7983      *
7984      * @static
7985      * @memberOf _
7986      * @category Collection
7987      * @param {Array|Object} collection The collection to inspect.
7988      * @returns {number} Returns the collection size.
7989      * @example
7990      *
7991      * _.size([1, 2, 3]);
7992      * // => 3
7993      *
7994      * _.size({ 'a': 1, 'b': 2 });
7995      * // => 2
7996      *
7997      * _.size('pebbles');
7998      * // => 7
7999      */
8000     function size(collection) {
8001       if (collection == null) {
8002         return 0;
8003       }
8004       if (isArrayLike(collection)) {
8005         var result = collection.length;
8006         return (result && isString(collection)) ? stringSize(collection) : result;
8007       }
8008       return keys(collection).length;
8009     }
8010
8011     /**
8012      * Checks if `predicate` returns truthy for **any** element of `collection`.
8013      * Iteration is stopped once `predicate` returns truthy. The predicate is
8014      * invoked with three arguments: (value, index|key, collection).
8015      *
8016      * @static
8017      * @memberOf _
8018      * @category Collection
8019      * @param {Array|Object} collection The collection to iterate over.
8020      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8021      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8022      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
8023      * @example
8024      *
8025      * _.some([null, 0, 'yes', false], Boolean);
8026      * // => true
8027      *
8028      * var users = [
8029      *   { 'user': 'barney', 'active': true },
8030      *   { 'user': 'fred',   'active': false }
8031      * ];
8032      *
8033      * // using the `_.matches` iteratee shorthand
8034      * _.some(users, { 'user': 'barney', 'active': false });
8035      * // => false
8036      *
8037      * // using the `_.matchesProperty` iteratee shorthand
8038      * _.some(users, ['active', false]);
8039      * // => true
8040      *
8041      * // using the `_.property` iteratee shorthand
8042      * _.some(users, 'active');
8043      * // => true
8044      */
8045     function some(collection, predicate, guard) {
8046       var func = isArray(collection) ? arraySome : baseSome;
8047       if (guard && isIterateeCall(collection, predicate, guard)) {
8048         predicate = undefined;
8049       }
8050       return func(collection, getIteratee(predicate, 3));
8051     }
8052
8053     /**
8054      * Creates an array of elements, sorted in ascending order by the results of
8055      * running each element in a collection through each iteratee. This method
8056      * performs a stable sort, that is, it preserves the original sort order of
8057      * equal elements. The iteratees are invoked with one argument: (value).
8058      *
8059      * @static
8060      * @memberOf _
8061      * @category Collection
8062      * @param {Array|Object} collection The collection to iterate over.
8063      * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
8064      *  The iteratees to sort by, specified individually or in arrays.
8065      * @returns {Array} Returns the new sorted array.
8066      * @example
8067      *
8068      * var users = [
8069      *   { 'user': 'fred',   'age': 48 },
8070      *   { 'user': 'barney', 'age': 36 },
8071      *   { 'user': 'fred',   'age': 42 },
8072      *   { 'user': 'barney', 'age': 34 }
8073      * ];
8074      *
8075      * _.sortBy(users, function(o) { return o.user; });
8076      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8077      *
8078      * _.sortBy(users, ['user', 'age']);
8079      * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
8080      *
8081      * _.sortBy(users, 'user', function(o) {
8082      *   return Math.floor(o.age / 10);
8083      * });
8084      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8085      */
8086     var sortBy = rest(function(collection, iteratees) {
8087       if (collection == null) {
8088         return [];
8089       }
8090       var length = iteratees.length;
8091       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
8092         iteratees = [];
8093       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
8094         iteratees.length = 1;
8095       }
8096       return baseOrderBy(collection, baseFlatten(iteratees), []);
8097     });
8098
8099     /*------------------------------------------------------------------------*/
8100
8101     /**
8102      * Gets the timestamp of the number of milliseconds that have elapsed since
8103      * the Unix epoch (1 January 1970 00:00:00 UTC).
8104      *
8105      * @static
8106      * @memberOf _
8107      * @type Function
8108      * @category Date
8109      * @returns {number} Returns the timestamp.
8110      * @example
8111      *
8112      * _.defer(function(stamp) {
8113      *   console.log(_.now() - stamp);
8114      * }, _.now());
8115      * // => logs the number of milliseconds it took for the deferred function to be invoked
8116      */
8117     var now = Date.now;
8118
8119     /*------------------------------------------------------------------------*/
8120
8121     /**
8122      * The opposite of `_.before`; this method creates a function that invokes
8123      * `func` once it's called `n` or more times.
8124      *
8125      * @static
8126      * @memberOf _
8127      * @category Function
8128      * @param {number} n The number of calls before `func` is invoked.
8129      * @param {Function} func The function to restrict.
8130      * @returns {Function} Returns the new restricted function.
8131      * @example
8132      *
8133      * var saves = ['profile', 'settings'];
8134      *
8135      * var done = _.after(saves.length, function() {
8136      *   console.log('done saving!');
8137      * });
8138      *
8139      * _.forEach(saves, function(type) {
8140      *   asyncSave({ 'type': type, 'complete': done });
8141      * });
8142      * // => logs 'done saving!' after the two async saves have completed
8143      */
8144     function after(n, func) {
8145       if (typeof func != 'function') {
8146         throw new TypeError(FUNC_ERROR_TEXT);
8147       }
8148       n = toInteger(n);
8149       return function() {
8150         if (--n < 1) {
8151           return func.apply(this, arguments);
8152         }
8153       };
8154     }
8155
8156     /**
8157      * Creates a function that accepts up to `n` arguments, ignoring any
8158      * additional arguments.
8159      *
8160      * @static
8161      * @memberOf _
8162      * @category Function
8163      * @param {Function} func The function to cap arguments for.
8164      * @param {number} [n=func.length] The arity cap.
8165      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8166      * @returns {Function} Returns the new function.
8167      * @example
8168      *
8169      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
8170      * // => [6, 8, 10]
8171      */
8172     function ary(func, n, guard) {
8173       n = guard ? undefined : n;
8174       n = (func && n == null) ? func.length : n;
8175       return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
8176     }
8177
8178     /**
8179      * Creates a function that invokes `func`, with the `this` binding and arguments
8180      * of the created function, while it's called less than `n` times. Subsequent
8181      * calls to the created function return the result of the last `func` invocation.
8182      *
8183      * @static
8184      * @memberOf _
8185      * @category Function
8186      * @param {number} n The number of calls at which `func` is no longer invoked.
8187      * @param {Function} func The function to restrict.
8188      * @returns {Function} Returns the new restricted function.
8189      * @example
8190      *
8191      * jQuery(element).on('click', _.before(5, addContactToList));
8192      * // => allows adding up to 4 contacts to the list
8193      */
8194     function before(n, func) {
8195       var result;
8196       if (typeof func != 'function') {
8197         throw new TypeError(FUNC_ERROR_TEXT);
8198       }
8199       n = toInteger(n);
8200       return function() {
8201         if (--n > 0) {
8202           result = func.apply(this, arguments);
8203         }
8204         if (n <= 1) {
8205           func = undefined;
8206         }
8207         return result;
8208       };
8209     }
8210
8211     /**
8212      * Creates a function that invokes `func` with the `this` binding of `thisArg`
8213      * and prepends any additional `_.bind` arguments to those provided to the
8214      * bound function.
8215      *
8216      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
8217      * may be used as a placeholder for partially applied arguments.
8218      *
8219      * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
8220      * property of bound functions.
8221      *
8222      * @static
8223      * @memberOf _
8224      * @category Function
8225      * @param {Function} func The function to bind.
8226      * @param {*} thisArg The `this` binding of `func`.
8227      * @param {...*} [partials] The arguments to be partially applied.
8228      * @returns {Function} Returns the new bound function.
8229      * @example
8230      *
8231      * var greet = function(greeting, punctuation) {
8232      *   return greeting + ' ' + this.user + punctuation;
8233      * };
8234      *
8235      * var object = { 'user': 'fred' };
8236      *
8237      * var bound = _.bind(greet, object, 'hi');
8238      * bound('!');
8239      * // => 'hi fred!'
8240      *
8241      * // using placeholders
8242      * var bound = _.bind(greet, object, _, '!');
8243      * bound('hi');
8244      * // => 'hi fred!'
8245      */
8246     var bind = rest(function(func, thisArg, partials) {
8247       var bitmask = BIND_FLAG;
8248       if (partials.length) {
8249         var holders = replaceHolders(partials, bind.placeholder);
8250         bitmask |= PARTIAL_FLAG;
8251       }
8252       return createWrapper(func, bitmask, thisArg, partials, holders);
8253     });
8254
8255     /**
8256      * Creates a function that invokes the method at `object[key]` and prepends
8257      * any additional `_.bindKey` arguments to those provided to the bound function.
8258      *
8259      * This method differs from `_.bind` by allowing bound functions to reference
8260      * methods that may be redefined or don't yet exist.
8261      * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
8262      * for more details.
8263      *
8264      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
8265      * builds, may be used as a placeholder for partially applied arguments.
8266      *
8267      * @static
8268      * @memberOf _
8269      * @category Function
8270      * @param {Object} object The object to invoke the method on.
8271      * @param {string} key The key of the method.
8272      * @param {...*} [partials] The arguments to be partially applied.
8273      * @returns {Function} Returns the new bound function.
8274      * @example
8275      *
8276      * var object = {
8277      *   'user': 'fred',
8278      *   'greet': function(greeting, punctuation) {
8279      *     return greeting + ' ' + this.user + punctuation;
8280      *   }
8281      * };
8282      *
8283      * var bound = _.bindKey(object, 'greet', 'hi');
8284      * bound('!');
8285      * // => 'hi fred!'
8286      *
8287      * object.greet = function(greeting, punctuation) {
8288      *   return greeting + 'ya ' + this.user + punctuation;
8289      * };
8290      *
8291      * bound('!');
8292      * // => 'hiya fred!'
8293      *
8294      * // using placeholders
8295      * var bound = _.bindKey(object, 'greet', _, '!');
8296      * bound('hi');
8297      * // => 'hiya fred!'
8298      */
8299     var bindKey = rest(function(object, key, partials) {
8300       var bitmask = BIND_FLAG | BIND_KEY_FLAG;
8301       if (partials.length) {
8302         var holders = replaceHolders(partials, bindKey.placeholder);
8303         bitmask |= PARTIAL_FLAG;
8304       }
8305       return createWrapper(key, bitmask, object, partials, holders);
8306     });
8307
8308     /**
8309      * Creates a function that accepts arguments of `func` and either invokes
8310      * `func` returning its result, if at least `arity` number of arguments have
8311      * been provided, or returns a function that accepts the remaining `func`
8312      * arguments, and so on. The arity of `func` may be specified if `func.length`
8313      * is not sufficient.
8314      *
8315      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
8316      * may be used as a placeholder for provided arguments.
8317      *
8318      * **Note:** This method doesn't set the "length" property of curried functions.
8319      *
8320      * @static
8321      * @memberOf _
8322      * @category Function
8323      * @param {Function} func The function to curry.
8324      * @param {number} [arity=func.length] The arity of `func`.
8325      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8326      * @returns {Function} Returns the new curried function.
8327      * @example
8328      *
8329      * var abc = function(a, b, c) {
8330      *   return [a, b, c];
8331      * };
8332      *
8333      * var curried = _.curry(abc);
8334      *
8335      * curried(1)(2)(3);
8336      * // => [1, 2, 3]
8337      *
8338      * curried(1, 2)(3);
8339      * // => [1, 2, 3]
8340      *
8341      * curried(1, 2, 3);
8342      * // => [1, 2, 3]
8343      *
8344      * // using placeholders
8345      * curried(1)(_, 3)(2);
8346      * // => [1, 2, 3]
8347      */
8348     function curry(func, arity, guard) {
8349       arity = guard ? undefined : arity;
8350       var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8351       result.placeholder = curry.placeholder;
8352       return result;
8353     }
8354
8355     /**
8356      * This method is like `_.curry` except that arguments are applied to `func`
8357      * in the manner of `_.partialRight` instead of `_.partial`.
8358      *
8359      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
8360      * builds, may be used as a placeholder for provided arguments.
8361      *
8362      * **Note:** This method doesn't set the "length" property of curried functions.
8363      *
8364      * @static
8365      * @memberOf _
8366      * @category Function
8367      * @param {Function} func The function to curry.
8368      * @param {number} [arity=func.length] The arity of `func`.
8369      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8370      * @returns {Function} Returns the new curried function.
8371      * @example
8372      *
8373      * var abc = function(a, b, c) {
8374      *   return [a, b, c];
8375      * };
8376      *
8377      * var curried = _.curryRight(abc);
8378      *
8379      * curried(3)(2)(1);
8380      * // => [1, 2, 3]
8381      *
8382      * curried(2, 3)(1);
8383      * // => [1, 2, 3]
8384      *
8385      * curried(1, 2, 3);
8386      * // => [1, 2, 3]
8387      *
8388      * // using placeholders
8389      * curried(3)(1, _)(2);
8390      * // => [1, 2, 3]
8391      */
8392     function curryRight(func, arity, guard) {
8393       arity = guard ? undefined : arity;
8394       var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8395       result.placeholder = curryRight.placeholder;
8396       return result;
8397     }
8398
8399     /**
8400      * Creates a debounced function that delays invoking `func` until after `wait`
8401      * milliseconds have elapsed since the last time the debounced function was
8402      * invoked. The debounced function comes with a `cancel` method to cancel
8403      * delayed `func` invocations and a `flush` method to immediately invoke them.
8404      * Provide an options object to indicate whether `func` should be invoked on
8405      * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
8406      * with the last arguments provided to the debounced function. Subsequent calls
8407      * to the debounced function return the result of the last `func` invocation.
8408      *
8409      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8410      * on the trailing edge of the timeout only if the the debounced function is
8411      * invoked more than once during the `wait` timeout.
8412      *
8413      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8414      * for details over the differences between `_.debounce` and `_.throttle`.
8415      *
8416      * @static
8417      * @memberOf _
8418      * @category Function
8419      * @param {Function} func The function to debounce.
8420      * @param {number} [wait=0] The number of milliseconds to delay.
8421      * @param {Object} [options] The options object.
8422      * @param {boolean} [options.leading=false] Specify invoking on the leading
8423      *  edge of the timeout.
8424      * @param {number} [options.maxWait] The maximum time `func` is allowed to be
8425      *  delayed before it's invoked.
8426      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
8427      *  edge of the timeout.
8428      * @returns {Function} Returns the new debounced function.
8429      * @example
8430      *
8431      * // avoid costly calculations while the window size is in flux
8432      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
8433      *
8434      * // invoke `sendMail` when clicked, debouncing subsequent calls
8435      * jQuery(element).on('click', _.debounce(sendMail, 300, {
8436      *   'leading': true,
8437      *   'trailing': false
8438      * }));
8439      *
8440      * // ensure `batchLog` is invoked once after 1 second of debounced calls
8441      * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
8442      * var source = new EventSource('/stream');
8443      * jQuery(source).on('message', debounced);
8444      *
8445      * // cancel a trailing debounced invocation
8446      * jQuery(window).on('popstate', debounced.cancel);
8447      */
8448     function debounce(func, wait, options) {
8449       var args,
8450           maxTimeoutId,
8451           result,
8452           stamp,
8453           thisArg,
8454           timeoutId,
8455           trailingCall,
8456           lastCalled = 0,
8457           leading = false,
8458           maxWait = false,
8459           trailing = true;
8460
8461       if (typeof func != 'function') {
8462         throw new TypeError(FUNC_ERROR_TEXT);
8463       }
8464       wait = toNumber(wait) || 0;
8465       if (isObject(options)) {
8466         leading = !!options.leading;
8467         maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
8468         trailing = 'trailing' in options ? !!options.trailing : trailing;
8469       }
8470
8471       function cancel() {
8472         if (timeoutId) {
8473           clearTimeout(timeoutId);
8474         }
8475         if (maxTimeoutId) {
8476           clearTimeout(maxTimeoutId);
8477         }
8478         lastCalled = 0;
8479         args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
8480       }
8481
8482       function complete(isCalled, id) {
8483         if (id) {
8484           clearTimeout(id);
8485         }
8486         maxTimeoutId = timeoutId = trailingCall = undefined;
8487         if (isCalled) {
8488           lastCalled = now();
8489           result = func.apply(thisArg, args);
8490           if (!timeoutId && !maxTimeoutId) {
8491             args = thisArg = undefined;
8492           }
8493         }
8494       }
8495
8496       function delayed() {
8497         var remaining = wait - (now() - stamp);
8498         if (remaining <= 0 || remaining > wait) {
8499           complete(trailingCall, maxTimeoutId);
8500         } else {
8501           timeoutId = setTimeout(delayed, remaining);
8502         }
8503       }
8504
8505       function flush() {
8506         if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
8507           result = func.apply(thisArg, args);
8508         }
8509         cancel();
8510         return result;
8511       }
8512
8513       function maxDelayed() {
8514         complete(trailing, timeoutId);
8515       }
8516
8517       function debounced() {
8518         args = arguments;
8519         stamp = now();
8520         thisArg = this;
8521         trailingCall = trailing && (timeoutId || !leading);
8522
8523         if (maxWait === false) {
8524           var leadingCall = leading && !timeoutId;
8525         } else {
8526           if (!maxTimeoutId && !leading) {
8527             lastCalled = stamp;
8528           }
8529           var remaining = maxWait - (stamp - lastCalled),
8530               isCalled = remaining <= 0 || remaining > maxWait;
8531
8532           if (isCalled) {
8533             if (maxTimeoutId) {
8534               maxTimeoutId = clearTimeout(maxTimeoutId);
8535             }
8536             lastCalled = stamp;
8537             result = func.apply(thisArg, args);
8538           }
8539           else if (!maxTimeoutId) {
8540             maxTimeoutId = setTimeout(maxDelayed, remaining);
8541           }
8542         }
8543         if (isCalled && timeoutId) {
8544           timeoutId = clearTimeout(timeoutId);
8545         }
8546         else if (!timeoutId && wait !== maxWait) {
8547           timeoutId = setTimeout(delayed, wait);
8548         }
8549         if (leadingCall) {
8550           isCalled = true;
8551           result = func.apply(thisArg, args);
8552         }
8553         if (isCalled && !timeoutId && !maxTimeoutId) {
8554           args = thisArg = undefined;
8555         }
8556         return result;
8557       }
8558       debounced.cancel = cancel;
8559       debounced.flush = flush;
8560       return debounced;
8561     }
8562
8563     /**
8564      * Defers invoking the `func` until the current call stack has cleared. Any
8565      * additional arguments are provided to `func` when it's invoked.
8566      *
8567      * @static
8568      * @memberOf _
8569      * @category Function
8570      * @param {Function} func The function to defer.
8571      * @param {...*} [args] The arguments to invoke `func` with.
8572      * @returns {number} Returns the timer id.
8573      * @example
8574      *
8575      * _.defer(function(text) {
8576      *   console.log(text);
8577      * }, 'deferred');
8578      * // logs 'deferred' after one or more milliseconds
8579      */
8580     var defer = rest(function(func, args) {
8581       return baseDelay(func, 1, args);
8582     });
8583
8584     /**
8585      * Invokes `func` after `wait` milliseconds. Any additional arguments are
8586      * provided to `func` when it's invoked.
8587      *
8588      * @static
8589      * @memberOf _
8590      * @category Function
8591      * @param {Function} func The function to delay.
8592      * @param {number} wait The number of milliseconds to delay invocation.
8593      * @param {...*} [args] The arguments to invoke `func` with.
8594      * @returns {number} Returns the timer id.
8595      * @example
8596      *
8597      * _.delay(function(text) {
8598      *   console.log(text);
8599      * }, 1000, 'later');
8600      * // => logs 'later' after one second
8601      */
8602     var delay = rest(function(func, wait, args) {
8603       return baseDelay(func, toNumber(wait) || 0, args);
8604     });
8605
8606     /**
8607      * Creates a function that invokes `func` with arguments reversed.
8608      *
8609      * @static
8610      * @memberOf _
8611      * @category Function
8612      * @param {Function} func The function to flip arguments for.
8613      * @returns {Function} Returns the new function.
8614      * @example
8615      *
8616      * var flipped = _.flip(function() {
8617      *   return _.toArray(arguments);
8618      * });
8619      *
8620      * flipped('a', 'b', 'c', 'd');
8621      * // => ['d', 'c', 'b', 'a']
8622      */
8623     function flip(func) {
8624       return createWrapper(func, FLIP_FLAG);
8625     }
8626
8627     /**
8628      * Creates a function that memoizes the result of `func`. If `resolver` is
8629      * provided it determines the cache key for storing the result based on the
8630      * arguments provided to the memoized function. By default, the first argument
8631      * provided to the memoized function is used as the map cache key. The `func`
8632      * is invoked with the `this` binding of the memoized function.
8633      *
8634      * **Note:** The cache is exposed as the `cache` property on the memoized
8635      * function. Its creation may be customized by replacing the `_.memoize.Cache`
8636      * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
8637      * method interface of `delete`, `get`, `has`, and `set`.
8638      *
8639      * @static
8640      * @memberOf _
8641      * @category Function
8642      * @param {Function} func The function to have its output memoized.
8643      * @param {Function} [resolver] The function to resolve the cache key.
8644      * @returns {Function} Returns the new memoizing function.
8645      * @example
8646      *
8647      * var object = { 'a': 1, 'b': 2 };
8648      * var other = { 'c': 3, 'd': 4 };
8649      *
8650      * var values = _.memoize(_.values);
8651      * values(object);
8652      * // => [1, 2]
8653      *
8654      * values(other);
8655      * // => [3, 4]
8656      *
8657      * object.a = 2;
8658      * values(object);
8659      * // => [1, 2]
8660      *
8661      * // modifying the result cache
8662      * values.cache.set(object, ['a', 'b']);
8663      * values(object);
8664      * // => ['a', 'b']
8665      *
8666      * // replacing `_.memoize.Cache`
8667      * _.memoize.Cache = WeakMap;
8668      */
8669     function memoize(func, resolver) {
8670       if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
8671         throw new TypeError(FUNC_ERROR_TEXT);
8672       }
8673       var memoized = function() {
8674         var args = arguments,
8675             key = resolver ? resolver.apply(this, args) : args[0],
8676             cache = memoized.cache;
8677
8678         if (cache.has(key)) {
8679           return cache.get(key);
8680         }
8681         var result = func.apply(this, args);
8682         memoized.cache = cache.set(key, result);
8683         return result;
8684       };
8685       memoized.cache = new memoize.Cache;
8686       return memoized;
8687     }
8688
8689     /**
8690      * Creates a function that negates the result of the predicate `func`. The
8691      * `func` predicate is invoked with the `this` binding and arguments of the
8692      * created function.
8693      *
8694      * @static
8695      * @memberOf _
8696      * @category Function
8697      * @param {Function} predicate The predicate to negate.
8698      * @returns {Function} Returns the new function.
8699      * @example
8700      *
8701      * function isEven(n) {
8702      *   return n % 2 == 0;
8703      * }
8704      *
8705      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
8706      * // => [1, 3, 5]
8707      */
8708     function negate(predicate) {
8709       if (typeof predicate != 'function') {
8710         throw new TypeError(FUNC_ERROR_TEXT);
8711       }
8712       return function() {
8713         return !predicate.apply(this, arguments);
8714       };
8715     }
8716
8717     /**
8718      * Creates a function that is restricted to invoking `func` once. Repeat calls
8719      * to the function return the value of the first invocation. The `func` is
8720      * invoked with the `this` binding and arguments of the created function.
8721      *
8722      * @static
8723      * @memberOf _
8724      * @category Function
8725      * @param {Function} func The function to restrict.
8726      * @returns {Function} Returns the new restricted function.
8727      * @example
8728      *
8729      * var initialize = _.once(createApplication);
8730      * initialize();
8731      * initialize();
8732      * // `initialize` invokes `createApplication` once
8733      */
8734     function once(func) {
8735       return before(2, func);
8736     }
8737
8738     /**
8739      * Creates a function that invokes `func` with arguments transformed by
8740      * corresponding `transforms`.
8741      *
8742      * @static
8743      * @memberOf _
8744      * @category Function
8745      * @param {Function} func The function to wrap.
8746      * @param {...(Function|Function[])} [transforms] The functions to transform
8747      * arguments, specified individually or in arrays.
8748      * @returns {Function} Returns the new function.
8749      * @example
8750      *
8751      * function doubled(n) {
8752      *   return n * 2;
8753      * }
8754      *
8755      * function square(n) {
8756      *   return n * n;
8757      * }
8758      *
8759      * var func = _.overArgs(function(x, y) {
8760      *   return [x, y];
8761      * }, square, doubled);
8762      *
8763      * func(9, 3);
8764      * // => [81, 6]
8765      *
8766      * func(10, 5);
8767      * // => [100, 10]
8768      */
8769     var overArgs = rest(function(func, transforms) {
8770       transforms = arrayMap(baseFlatten(transforms), getIteratee());
8771
8772       var funcsLength = transforms.length;
8773       return rest(function(args) {
8774         var index = -1,
8775             length = nativeMin(args.length, funcsLength);
8776
8777         while (++index < length) {
8778           args[index] = transforms[index].call(this, args[index]);
8779         }
8780         return apply(func, this, args);
8781       });
8782     });
8783
8784     /**
8785      * Creates a function that invokes `func` with `partial` arguments prepended
8786      * to those provided to the new function. This method is like `_.bind` except
8787      * it does **not** alter the `this` binding.
8788      *
8789      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
8790      * builds, may be used as a placeholder for partially applied arguments.
8791      *
8792      * **Note:** This method doesn't set the "length" property of partially
8793      * applied functions.
8794      *
8795      * @static
8796      * @memberOf _
8797      * @category Function
8798      * @param {Function} func The function to partially apply arguments to.
8799      * @param {...*} [partials] The arguments to be partially applied.
8800      * @returns {Function} Returns the new partially applied function.
8801      * @example
8802      *
8803      * var greet = function(greeting, name) {
8804      *   return greeting + ' ' + name;
8805      * };
8806      *
8807      * var sayHelloTo = _.partial(greet, 'hello');
8808      * sayHelloTo('fred');
8809      * // => 'hello fred'
8810      *
8811      * // using placeholders
8812      * var greetFred = _.partial(greet, _, 'fred');
8813      * greetFred('hi');
8814      * // => 'hi fred'
8815      */
8816     var partial = rest(function(func, partials) {
8817       var holders = replaceHolders(partials, partial.placeholder);
8818       return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
8819     });
8820
8821     /**
8822      * This method is like `_.partial` except that partially applied arguments
8823      * are appended to those provided to the new function.
8824      *
8825      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
8826      * builds, may be used as a placeholder for partially applied arguments.
8827      *
8828      * **Note:** This method doesn't set the "length" property of partially
8829      * applied functions.
8830      *
8831      * @static
8832      * @memberOf _
8833      * @category Function
8834      * @param {Function} func The function to partially apply arguments to.
8835      * @param {...*} [partials] The arguments to be partially applied.
8836      * @returns {Function} Returns the new partially applied function.
8837      * @example
8838      *
8839      * var greet = function(greeting, name) {
8840      *   return greeting + ' ' + name;
8841      * };
8842      *
8843      * var greetFred = _.partialRight(greet, 'fred');
8844      * greetFred('hi');
8845      * // => 'hi fred'
8846      *
8847      * // using placeholders
8848      * var sayHelloTo = _.partialRight(greet, 'hello', _);
8849      * sayHelloTo('fred');
8850      * // => 'hello fred'
8851      */
8852     var partialRight = rest(function(func, partials) {
8853       var holders = replaceHolders(partials, partialRight.placeholder);
8854       return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
8855     });
8856
8857     /**
8858      * Creates a function that invokes `func` with arguments arranged according
8859      * to the specified indexes where the argument value at the first index is
8860      * provided as the first argument, the argument value at the second index is
8861      * provided as the second argument, and so on.
8862      *
8863      * @static
8864      * @memberOf _
8865      * @category Function
8866      * @param {Function} func The function to rearrange arguments for.
8867      * @param {...(number|number[])} indexes The arranged argument indexes,
8868      *  specified individually or in arrays.
8869      * @returns {Function} Returns the new function.
8870      * @example
8871      *
8872      * var rearged = _.rearg(function(a, b, c) {
8873      *   return [a, b, c];
8874      * }, 2, 0, 1);
8875      *
8876      * rearged('b', 'c', 'a')
8877      * // => ['a', 'b', 'c']
8878      */
8879     var rearg = rest(function(func, indexes) {
8880       return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
8881     });
8882
8883     /**
8884      * Creates a function that invokes `func` with the `this` binding of the
8885      * created function and arguments from `start` and beyond provided as an array.
8886      *
8887      * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
8888      *
8889      * @static
8890      * @memberOf _
8891      * @category Function
8892      * @param {Function} func The function to apply a rest parameter to.
8893      * @param {number} [start=func.length-1] The start position of the rest parameter.
8894      * @returns {Function} Returns the new function.
8895      * @example
8896      *
8897      * var say = _.rest(function(what, names) {
8898      *   return what + ' ' + _.initial(names).join(', ') +
8899      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
8900      * });
8901      *
8902      * say('hello', 'fred', 'barney', 'pebbles');
8903      * // => 'hello fred, barney, & pebbles'
8904      */
8905     function rest(func, start) {
8906       if (typeof func != 'function') {
8907         throw new TypeError(FUNC_ERROR_TEXT);
8908       }
8909       start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
8910       return function() {
8911         var args = arguments,
8912             index = -1,
8913             length = nativeMax(args.length - start, 0),
8914             array = Array(length);
8915
8916         while (++index < length) {
8917           array[index] = args[start + index];
8918         }
8919         switch (start) {
8920           case 0: return func.call(this, array);
8921           case 1: return func.call(this, args[0], array);
8922           case 2: return func.call(this, args[0], args[1], array);
8923         }
8924         var otherArgs = Array(start + 1);
8925         index = -1;
8926         while (++index < start) {
8927           otherArgs[index] = args[index];
8928         }
8929         otherArgs[start] = array;
8930         return apply(func, this, otherArgs);
8931       };
8932     }
8933
8934     /**
8935      * Creates a function that invokes `func` with the `this` binding of the created
8936      * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
8937      *
8938      * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
8939      *
8940      * @static
8941      * @memberOf _
8942      * @category Function
8943      * @param {Function} func The function to spread arguments over.
8944      * @returns {Function} Returns the new function.
8945      * @example
8946      *
8947      * var say = _.spread(function(who, what) {
8948      *   return who + ' says ' + what;
8949      * });
8950      *
8951      * say(['fred', 'hello']);
8952      * // => 'fred says hello'
8953      *
8954      * // with a Promise
8955      * var numbers = Promise.all([
8956      *   Promise.resolve(40),
8957      *   Promise.resolve(36)
8958      * ]);
8959      *
8960      * numbers.then(_.spread(function(x, y) {
8961      *   return x + y;
8962      * }));
8963      * // => a Promise of 76
8964      */
8965     function spread(func) {
8966       if (typeof func != 'function') {
8967         throw new TypeError(FUNC_ERROR_TEXT);
8968       }
8969       return function(array) {
8970         return apply(func, this, array);
8971       };
8972     }
8973
8974     /**
8975      * Creates a throttled function that only invokes `func` at most once per
8976      * every `wait` milliseconds. The throttled function comes with a `cancel`
8977      * method to cancel delayed `func` invocations and a `flush` method to
8978      * immediately invoke them. Provide an options object to indicate whether
8979      * `func` should be invoked on the leading and/or trailing edge of the `wait`
8980      * timeout. The `func` is invoked with the last arguments provided to the
8981      * throttled function. Subsequent calls to the throttled function return the
8982      * result of the last `func` invocation.
8983      *
8984      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8985      * on the trailing edge of the timeout only if the the throttled function is
8986      * invoked more than once during the `wait` timeout.
8987      *
8988      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8989      * for details over the differences between `_.throttle` and `_.debounce`.
8990      *
8991      * @static
8992      * @memberOf _
8993      * @category Function
8994      * @param {Function} func The function to throttle.
8995      * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
8996      * @param {Object} [options] The options object.
8997      * @param {boolean} [options.leading=true] Specify invoking on the leading
8998      *  edge of the timeout.
8999      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
9000      *  edge of the timeout.
9001      * @returns {Function} Returns the new throttled function.
9002      * @example
9003      *
9004      * // avoid excessively updating the position while scrolling
9005      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
9006      *
9007      * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
9008      * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
9009      * jQuery(element).on('click', throttled);
9010      *
9011      * // cancel a trailing throttled invocation
9012      * jQuery(window).on('popstate', throttled.cancel);
9013      */
9014     function throttle(func, wait, options) {
9015       var leading = true,
9016           trailing = true;
9017
9018       if (typeof func != 'function') {
9019         throw new TypeError(FUNC_ERROR_TEXT);
9020       }
9021       if (isObject(options)) {
9022         leading = 'leading' in options ? !!options.leading : leading;
9023         trailing = 'trailing' in options ? !!options.trailing : trailing;
9024       }
9025       return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing });
9026     }
9027
9028     /**
9029      * Creates a function that accepts up to one argument, ignoring any
9030      * additional arguments.
9031      *
9032      * @static
9033      * @memberOf _
9034      * @category Function
9035      * @param {Function} func The function to cap arguments for.
9036      * @returns {Function} Returns the new function.
9037      * @example
9038      *
9039      * _.map(['6', '8', '10'], _.unary(parseInt));
9040      * // => [6, 8, 10]
9041      */
9042     function unary(func) {
9043       return ary(func, 1);
9044     }
9045
9046     /**
9047      * Creates a function that provides `value` to the wrapper function as its
9048      * first argument. Any additional arguments provided to the function are
9049      * appended to those provided to the wrapper function. The wrapper is invoked
9050      * with the `this` binding of the created function.
9051      *
9052      * @static
9053      * @memberOf _
9054      * @category Function
9055      * @param {*} value The value to wrap.
9056      * @param {Function} wrapper The wrapper function.
9057      * @returns {Function} Returns the new function.
9058      * @example
9059      *
9060      * var p = _.wrap(_.escape, function(func, text) {
9061      *   return '<p>' + func(text) + '</p>';
9062      * });
9063      *
9064      * p('fred, barney, & pebbles');
9065      * // => '<p>fred, barney, &amp; pebbles</p>'
9066      */
9067     function wrap(value, wrapper) {
9068       wrapper = wrapper == null ? identity : wrapper;
9069       return partial(wrapper, value);
9070     }
9071
9072     /*------------------------------------------------------------------------*/
9073
9074     /**
9075      * Creates a shallow clone of `value`.
9076      *
9077      * **Note:** This method is loosely based on the
9078      * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
9079      * and supports cloning arrays, array buffers, booleans, date objects, maps,
9080      * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
9081      * arrays. The own enumerable properties of `arguments` objects are cloned
9082      * as plain objects. An empty object is returned for uncloneable values such
9083      * as error objects, functions, DOM nodes, and WeakMaps.
9084      *
9085      * @static
9086      * @memberOf _
9087      * @category Lang
9088      * @param {*} value The value to clone.
9089      * @returns {*} Returns the cloned value.
9090      * @example
9091      *
9092      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9093      *
9094      * var shallow = _.clone(objects);
9095      * console.log(shallow[0] === objects[0]);
9096      * // => true
9097      */
9098     function clone(value) {
9099       return baseClone(value);
9100     }
9101
9102     /**
9103      * This method is like `_.clone` except that it accepts `customizer` which
9104      * is invoked to produce the cloned value. If `customizer` returns `undefined`
9105      * cloning is handled by the method instead. The `customizer` is invoked with
9106      * up to four arguments; (value [, index|key, object, stack]).
9107      *
9108      * @static
9109      * @memberOf _
9110      * @category Lang
9111      * @param {*} value The value to clone.
9112      * @param {Function} [customizer] The function to customize cloning.
9113      * @returns {*} Returns the cloned value.
9114      * @example
9115      *
9116      * function customizer(value) {
9117      *   if (_.isElement(value)) {
9118      *     return value.cloneNode(false);
9119      *   }
9120      * }
9121      *
9122      * var el = _.cloneWith(document.body, customizer);
9123      *
9124      * console.log(el === document.body);
9125      * // => false
9126      * console.log(el.nodeName);
9127      * // => 'BODY'
9128      * console.log(el.childNodes.length);
9129      * // => 0
9130      */
9131     function cloneWith(value, customizer) {
9132       return baseClone(value, false, customizer);
9133     }
9134
9135     /**
9136      * This method is like `_.clone` except that it recursively clones `value`.
9137      *
9138      * @static
9139      * @memberOf _
9140      * @category Lang
9141      * @param {*} value The value to recursively clone.
9142      * @returns {*} Returns the deep cloned value.
9143      * @example
9144      *
9145      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9146      *
9147      * var deep = _.cloneDeep(objects);
9148      * console.log(deep[0] === objects[0]);
9149      * // => false
9150      */
9151     function cloneDeep(value) {
9152       return baseClone(value, true);
9153     }
9154
9155     /**
9156      * This method is like `_.cloneWith` except that it recursively clones `value`.
9157      *
9158      * @static
9159      * @memberOf _
9160      * @category Lang
9161      * @param {*} value The value to recursively clone.
9162      * @param {Function} [customizer] The function to customize cloning.
9163      * @returns {*} Returns the deep cloned value.
9164      * @example
9165      *
9166      * function customizer(value) {
9167      *   if (_.isElement(value)) {
9168      *     return value.cloneNode(true);
9169      *   }
9170      * }
9171      *
9172      * var el = _.cloneDeepWith(document.body, customizer);
9173      *
9174      * console.log(el === document.body);
9175      * // => false
9176      * console.log(el.nodeName);
9177      * // => 'BODY'
9178      * console.log(el.childNodes.length);
9179      * // => 20
9180      */
9181     function cloneDeepWith(value, customizer) {
9182       return baseClone(value, true, customizer);
9183     }
9184
9185     /**
9186      * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
9187      * comparison between two values to determine if they are equivalent.
9188      *
9189      * @static
9190      * @memberOf _
9191      * @category Lang
9192      * @param {*} value The value to compare.
9193      * @param {*} other The other value to compare.
9194      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9195      * @example
9196      *
9197      * var object = { 'user': 'fred' };
9198      * var other = { 'user': 'fred' };
9199      *
9200      * _.eq(object, object);
9201      * // => true
9202      *
9203      * _.eq(object, other);
9204      * // => false
9205      *
9206      * _.eq('a', 'a');
9207      * // => true
9208      *
9209      * _.eq('a', Object('a'));
9210      * // => false
9211      *
9212      * _.eq(NaN, NaN);
9213      * // => true
9214      */
9215     function eq(value, other) {
9216       return value === other || (value !== value && other !== other);
9217     }
9218
9219     /**
9220      * Checks if `value` is greater than `other`.
9221      *
9222      * @static
9223      * @memberOf _
9224      * @category Lang
9225      * @param {*} value The value to compare.
9226      * @param {*} other The other value to compare.
9227      * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
9228      * @example
9229      *
9230      * _.gt(3, 1);
9231      * // => true
9232      *
9233      * _.gt(3, 3);
9234      * // => false
9235      *
9236      * _.gt(1, 3);
9237      * // => false
9238      */
9239     function gt(value, other) {
9240       return value > other;
9241     }
9242
9243     /**
9244      * Checks if `value` is greater than or equal to `other`.
9245      *
9246      * @static
9247      * @memberOf _
9248      * @category Lang
9249      * @param {*} value The value to compare.
9250      * @param {*} other The other value to compare.
9251      * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
9252      * @example
9253      *
9254      * _.gte(3, 1);
9255      * // => true
9256      *
9257      * _.gte(3, 3);
9258      * // => true
9259      *
9260      * _.gte(1, 3);
9261      * // => false
9262      */
9263     function gte(value, other) {
9264       return value >= other;
9265     }
9266
9267     /**
9268      * Checks if `value` is likely an `arguments` object.
9269      *
9270      * @static
9271      * @memberOf _
9272      * @category Lang
9273      * @param {*} value The value to check.
9274      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9275      * @example
9276      *
9277      * _.isArguments(function() { return arguments; }());
9278      * // => true
9279      *
9280      * _.isArguments([1, 2, 3]);
9281      * // => false
9282      */
9283     function isArguments(value) {
9284       // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
9285       return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
9286         (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
9287     }
9288
9289     /**
9290      * Checks if `value` is classified as an `Array` object.
9291      *
9292      * @static
9293      * @memberOf _
9294      * @type Function
9295      * @category Lang
9296      * @param {*} value The value to check.
9297      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9298      * @example
9299      *
9300      * _.isArray([1, 2, 3]);
9301      * // => true
9302      *
9303      * _.isArray(document.body.children);
9304      * // => false
9305      *
9306      * _.isArray('abc');
9307      * // => false
9308      *
9309      * _.isArray(_.noop);
9310      * // => false
9311      */
9312     var isArray = Array.isArray;
9313
9314     /**
9315      * Checks if `value` is array-like. A value is considered array-like if it's
9316      * not a function and has a `value.length` that's an integer greater than or
9317      * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
9318      *
9319      * @static
9320      * @memberOf _
9321      * @type Function
9322      * @category Lang
9323      * @param {*} value The value to check.
9324      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
9325      * @example
9326      *
9327      * _.isArrayLike([1, 2, 3]);
9328      * // => true
9329      *
9330      * _.isArrayLike(document.body.children);
9331      * // => true
9332      *
9333      * _.isArrayLike('abc');
9334      * // => true
9335      *
9336      * _.isArrayLike(_.noop);
9337      * // => false
9338      */
9339     function isArrayLike(value) {
9340       return value != null &&
9341         !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
9342     }
9343
9344     /**
9345      * This method is like `_.isArrayLike` except that it also checks if `value`
9346      * is an object.
9347      *
9348      * @static
9349      * @memberOf _
9350      * @type Function
9351      * @category Lang
9352      * @param {*} value The value to check.
9353      * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
9354      * @example
9355      *
9356      * _.isArrayLikeObject([1, 2, 3]);
9357      * // => true
9358      *
9359      * _.isArrayLikeObject(document.body.children);
9360      * // => true
9361      *
9362      * _.isArrayLikeObject('abc');
9363      * // => false
9364      *
9365      * _.isArrayLikeObject(_.noop);
9366      * // => false
9367      */
9368     function isArrayLikeObject(value) {
9369       return isObjectLike(value) && isArrayLike(value);
9370     }
9371
9372     /**
9373      * Checks if `value` is classified as a boolean primitive or object.
9374      *
9375      * @static
9376      * @memberOf _
9377      * @category Lang
9378      * @param {*} value The value to check.
9379      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9380      * @example
9381      *
9382      * _.isBoolean(false);
9383      * // => true
9384      *
9385      * _.isBoolean(null);
9386      * // => false
9387      */
9388     function isBoolean(value) {
9389       return value === true || value === false ||
9390         (isObjectLike(value) && objectToString.call(value) == boolTag);
9391     }
9392
9393     /**
9394      * Checks if `value` is classified as a `Date` object.
9395      *
9396      * @static
9397      * @memberOf _
9398      * @category Lang
9399      * @param {*} value The value to check.
9400      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9401      * @example
9402      *
9403      * _.isDate(new Date);
9404      * // => true
9405      *
9406      * _.isDate('Mon April 23 2012');
9407      * // => false
9408      */
9409     function isDate(value) {
9410       return isObjectLike(value) && objectToString.call(value) == dateTag;
9411     }
9412
9413     /**
9414      * Checks if `value` is likely a DOM element.
9415      *
9416      * @static
9417      * @memberOf _
9418      * @category Lang
9419      * @param {*} value The value to check.
9420      * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
9421      * @example
9422      *
9423      * _.isElement(document.body);
9424      * // => true
9425      *
9426      * _.isElement('<body>');
9427      * // => false
9428      */
9429     function isElement(value) {
9430       return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
9431     }
9432
9433     /**
9434      * Checks if `value` is empty. A value is considered empty unless it's an
9435      * `arguments` object, array, string, or jQuery-like collection with a length
9436      * greater than `0` or an object with own enumerable properties.
9437      *
9438      * @static
9439      * @memberOf _
9440      * @category Lang
9441      * @param {Array|Object|string} value The value to inspect.
9442      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
9443      * @example
9444      *
9445      * _.isEmpty(null);
9446      * // => true
9447      *
9448      * _.isEmpty(true);
9449      * // => true
9450      *
9451      * _.isEmpty(1);
9452      * // => true
9453      *
9454      * _.isEmpty([1, 2, 3]);
9455      * // => false
9456      *
9457      * _.isEmpty({ 'a': 1 });
9458      * // => false
9459      */
9460     function isEmpty(value) {
9461       return (!isObjectLike(value) || isFunction(value.splice))
9462         ? !size(value)
9463         : !keys(value).length;
9464     }
9465
9466     /**
9467      * Performs a deep comparison between two values to determine if they are
9468      * equivalent.
9469      *
9470      * **Note:** This method supports comparing arrays, array buffers, booleans,
9471      * date objects, error objects, maps, numbers, `Object` objects, regexes,
9472      * sets, strings, symbols, and typed arrays. `Object` objects are compared
9473      * by their own, not inherited, enumerable properties. Functions and DOM
9474      * nodes are **not** supported.
9475      *
9476      * @static
9477      * @memberOf _
9478      * @category Lang
9479      * @param {*} value The value to compare.
9480      * @param {*} other The other value to compare.
9481      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9482      * @example
9483      *
9484      * var object = { 'user': 'fred' };
9485      * var other = { 'user': 'fred' };
9486      *
9487      * _.isEqual(object, other);
9488      * // => true
9489      *
9490      * object === other;
9491      * // => false
9492      */
9493     function isEqual(value, other) {
9494       return baseIsEqual(value, other);
9495     }
9496
9497     /**
9498      * This method is like `_.isEqual` except that it accepts `customizer` which is
9499      * invoked to compare values. If `customizer` returns `undefined` comparisons are
9500      * handled by the method instead. The `customizer` is invoked with up to six arguments:
9501      * (objValue, othValue [, index|key, object, other, stack]).
9502      *
9503      * @static
9504      * @memberOf _
9505      * @category Lang
9506      * @param {*} value The value to compare.
9507      * @param {*} other The other value to compare.
9508      * @param {Function} [customizer] The function to customize comparisons.
9509      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9510      * @example
9511      *
9512      * function isGreeting(value) {
9513      *   return /^h(?:i|ello)$/.test(value);
9514      * }
9515      *
9516      * function customizer(objValue, othValue) {
9517      *   if (isGreeting(objValue) && isGreeting(othValue)) {
9518      *     return true;
9519      *   }
9520      * }
9521      *
9522      * var array = ['hello', 'goodbye'];
9523      * var other = ['hi', 'goodbye'];
9524      *
9525      * _.isEqualWith(array, other, customizer);
9526      * // => true
9527      */
9528     function isEqualWith(value, other, customizer) {
9529       customizer = typeof customizer == 'function' ? customizer : undefined;
9530       var result = customizer ? customizer(value, other) : undefined;
9531       return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
9532     }
9533
9534     /**
9535      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
9536      * `SyntaxError`, `TypeError`, or `URIError` object.
9537      *
9538      * @static
9539      * @memberOf _
9540      * @category Lang
9541      * @param {*} value The value to check.
9542      * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
9543      * @example
9544      *
9545      * _.isError(new Error);
9546      * // => true
9547      *
9548      * _.isError(Error);
9549      * // => false
9550      */
9551     function isError(value) {
9552       return isObjectLike(value) &&
9553         typeof value.message == 'string' && objectToString.call(value) == errorTag;
9554     }
9555
9556     /**
9557      * Checks if `value` is a finite primitive number.
9558      *
9559      * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
9560      *
9561      * @static
9562      * @memberOf _
9563      * @category Lang
9564      * @param {*} value The value to check.
9565      * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
9566      * @example
9567      *
9568      * _.isFinite(3);
9569      * // => true
9570      *
9571      * _.isFinite(Number.MAX_VALUE);
9572      * // => true
9573      *
9574      * _.isFinite(3.14);
9575      * // => true
9576      *
9577      * _.isFinite(Infinity);
9578      * // => false
9579      */
9580     function isFinite(value) {
9581       return typeof value == 'number' && nativeIsFinite(value);
9582     }
9583
9584     /**
9585      * Checks if `value` is classified as a `Function` object.
9586      *
9587      * @static
9588      * @memberOf _
9589      * @category Lang
9590      * @param {*} value The value to check.
9591      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9592      * @example
9593      *
9594      * _.isFunction(_);
9595      * // => true
9596      *
9597      * _.isFunction(/abc/);
9598      * // => false
9599      */
9600     function isFunction(value) {
9601       // The use of `Object#toString` avoids issues with the `typeof` operator
9602       // in Safari 8 which returns 'object' for typed array constructors, and
9603       // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
9604       var tag = isObject(value) ? objectToString.call(value) : '';
9605       return tag == funcTag || tag == genTag;
9606     }
9607
9608     /**
9609      * Checks if `value` is an integer.
9610      *
9611      * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
9612      *
9613      * @static
9614      * @memberOf _
9615      * @category Lang
9616      * @param {*} value The value to check.
9617      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
9618      * @example
9619      *
9620      * _.isInteger(3);
9621      * // => true
9622      *
9623      * _.isInteger(Number.MIN_VALUE);
9624      * // => false
9625      *
9626      * _.isInteger(Infinity);
9627      * // => false
9628      *
9629      * _.isInteger('3');
9630      * // => false
9631      */
9632     function isInteger(value) {
9633       return typeof value == 'number' && value == toInteger(value);
9634     }
9635
9636     /**
9637      * Checks if `value` is a valid array-like length.
9638      *
9639      * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
9640      *
9641      * @static
9642      * @memberOf _
9643      * @category Lang
9644      * @param {*} value The value to check.
9645      * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
9646      * @example
9647      *
9648      * _.isLength(3);
9649      * // => true
9650      *
9651      * _.isLength(Number.MIN_VALUE);
9652      * // => false
9653      *
9654      * _.isLength(Infinity);
9655      * // => false
9656      *
9657      * _.isLength('3');
9658      * // => false
9659      */
9660     function isLength(value) {
9661       return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
9662     }
9663
9664     /**
9665      * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
9666      * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
9667      *
9668      * @static
9669      * @memberOf _
9670      * @category Lang
9671      * @param {*} value The value to check.
9672      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
9673      * @example
9674      *
9675      * _.isObject({});
9676      * // => true
9677      *
9678      * _.isObject([1, 2, 3]);
9679      * // => true
9680      *
9681      * _.isObject(_.noop);
9682      * // => true
9683      *
9684      * _.isObject(null);
9685      * // => false
9686      */
9687     function isObject(value) {
9688       // Avoid a V8 JIT bug in Chrome 19-20.
9689       // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
9690       var type = typeof value;
9691       return !!value && (type == 'object' || type == 'function');
9692     }
9693
9694     /**
9695      * Checks if `value` is object-like. A value is object-like if it's not `null`
9696      * and has a `typeof` result of "object".
9697      *
9698      * @static
9699      * @memberOf _
9700      * @category Lang
9701      * @param {*} value The value to check.
9702      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
9703      * @example
9704      *
9705      * _.isObjectLike({});
9706      * // => true
9707      *
9708      * _.isObjectLike([1, 2, 3]);
9709      * // => true
9710      *
9711      * _.isObjectLike(_.noop);
9712      * // => false
9713      *
9714      * _.isObjectLike(null);
9715      * // => false
9716      */
9717     function isObjectLike(value) {
9718       return !!value && typeof value == 'object';
9719     }
9720
9721     /**
9722      * Performs a deep comparison between `object` and `source` to determine if
9723      * `object` contains equivalent property values.
9724      *
9725      * **Note:** This method supports comparing the same values as `_.isEqual`.
9726      *
9727      * @static
9728      * @memberOf _
9729      * @category Lang
9730      * @param {Object} object The object to inspect.
9731      * @param {Object} source The object of property values to match.
9732      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9733      * @example
9734      *
9735      * var object = { 'user': 'fred', 'age': 40 };
9736      *
9737      * _.isMatch(object, { 'age': 40 });
9738      * // => true
9739      *
9740      * _.isMatch(object, { 'age': 36 });
9741      * // => false
9742      */
9743     function isMatch(object, source) {
9744       return object === source || baseIsMatch(object, source, getMatchData(source));
9745     }
9746
9747     /**
9748      * This method is like `_.isMatch` except that it accepts `customizer` which
9749      * is invoked to compare values. If `customizer` returns `undefined` comparisons
9750      * are handled by the method instead. The `customizer` is invoked with five
9751      * arguments: (objValue, srcValue, index|key, object, source).
9752      *
9753      * @static
9754      * @memberOf _
9755      * @category Lang
9756      * @param {Object} object The object to inspect.
9757      * @param {Object} source The object of property values to match.
9758      * @param {Function} [customizer] The function to customize comparisons.
9759      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9760      * @example
9761      *
9762      * function isGreeting(value) {
9763      *   return /^h(?:i|ello)$/.test(value);
9764      * }
9765      *
9766      * function customizer(objValue, srcValue) {
9767      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
9768      *     return true;
9769      *   }
9770      * }
9771      *
9772      * var object = { 'greeting': 'hello' };
9773      * var source = { 'greeting': 'hi' };
9774      *
9775      * _.isMatchWith(object, source, customizer);
9776      * // => true
9777      */
9778     function isMatchWith(object, source, customizer) {
9779       customizer = typeof customizer == 'function' ? customizer : undefined;
9780       return baseIsMatch(object, source, getMatchData(source), customizer);
9781     }
9782
9783     /**
9784      * Checks if `value` is `NaN`.
9785      *
9786      * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
9787      * which returns `true` for `undefined` and other non-numeric values.
9788      *
9789      * @static
9790      * @memberOf _
9791      * @category Lang
9792      * @param {*} value The value to check.
9793      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
9794      * @example
9795      *
9796      * _.isNaN(NaN);
9797      * // => true
9798      *
9799      * _.isNaN(new Number(NaN));
9800      * // => true
9801      *
9802      * isNaN(undefined);
9803      * // => true
9804      *
9805      * _.isNaN(undefined);
9806      * // => false
9807      */
9808     function isNaN(value) {
9809       // An `NaN` primitive is the only value that is not equal to itself.
9810       // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
9811       return isNumber(value) && value != +value;
9812     }
9813
9814     /**
9815      * Checks if `value` is a native function.
9816      *
9817      * @static
9818      * @memberOf _
9819      * @category Lang
9820      * @param {*} value The value to check.
9821      * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
9822      * @example
9823      *
9824      * _.isNative(Array.prototype.push);
9825      * // => true
9826      *
9827      * _.isNative(_);
9828      * // => false
9829      */
9830     function isNative(value) {
9831       if (value == null) {
9832         return false;
9833       }
9834       if (isFunction(value)) {
9835         return reIsNative.test(funcToString.call(value));
9836       }
9837       return isObjectLike(value) &&
9838         (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
9839     }
9840
9841     /**
9842      * Checks if `value` is `null`.
9843      *
9844      * @static
9845      * @memberOf _
9846      * @category Lang
9847      * @param {*} value The value to check.
9848      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
9849      * @example
9850      *
9851      * _.isNull(null);
9852      * // => true
9853      *
9854      * _.isNull(void 0);
9855      * // => false
9856      */
9857     function isNull(value) {
9858       return value === null;
9859     }
9860
9861     /**
9862      * Checks if `value` is `null` or `undefined`.
9863      *
9864      * @static
9865      * @memberOf _
9866      * @category Lang
9867      * @param {*} value The value to check.
9868      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
9869      * @example
9870      *
9871      * _.isNil(null);
9872      * // => true
9873      *
9874      * _.isNil(void 0);
9875      * // => true
9876      *
9877      * _.isNil(NaN);
9878      * // => false
9879      */
9880     function isNil(value) {
9881       return value == null;
9882     }
9883
9884     /**
9885      * Checks if `value` is classified as a `Number` primitive or object.
9886      *
9887      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
9888      * as numbers, use the `_.isFinite` method.
9889      *
9890      * @static
9891      * @memberOf _
9892      * @category Lang
9893      * @param {*} value The value to check.
9894      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9895      * @example
9896      *
9897      * _.isNumber(3);
9898      * // => true
9899      *
9900      * _.isNumber(Number.MIN_VALUE);
9901      * // => true
9902      *
9903      * _.isNumber(Infinity);
9904      * // => true
9905      *
9906      * _.isNumber('3');
9907      * // => false
9908      */
9909     function isNumber(value) {
9910       return typeof value == 'number' ||
9911         (isObjectLike(value) && objectToString.call(value) == numberTag);
9912     }
9913
9914     /**
9915      * Checks if `value` is a plain object, that is, an object created by the
9916      * `Object` constructor or one with a `[[Prototype]]` of `null`.
9917      *
9918      * @static
9919      * @memberOf _
9920      * @category Lang
9921      * @param {*} value The value to check.
9922      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
9923      * @example
9924      *
9925      * function Foo() {
9926      *   this.a = 1;
9927      * }
9928      *
9929      * _.isPlainObject(new Foo);
9930      * // => false
9931      *
9932      * _.isPlainObject([1, 2, 3]);
9933      * // => false
9934      *
9935      * _.isPlainObject({ 'x': 0, 'y': 0 });
9936      * // => true
9937      *
9938      * _.isPlainObject(Object.create(null));
9939      * // => true
9940      */
9941     function isPlainObject(value) {
9942       if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
9943         return false;
9944       }
9945       var proto = objectProto;
9946       if (typeof value.constructor == 'function') {
9947         proto = getPrototypeOf(value);
9948       }
9949       if (proto === null) {
9950         return true;
9951       }
9952       var Ctor = proto.constructor;
9953       return (typeof Ctor == 'function' &&
9954         Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
9955     }
9956
9957     /**
9958      * Checks if `value` is classified as a `RegExp` object.
9959      *
9960      * @static
9961      * @memberOf _
9962      * @category Lang
9963      * @param {*} value The value to check.
9964      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9965      * @example
9966      *
9967      * _.isRegExp(/abc/);
9968      * // => true
9969      *
9970      * _.isRegExp('/abc/');
9971      * // => false
9972      */
9973     function isRegExp(value) {
9974       return isObject(value) && objectToString.call(value) == regexpTag;
9975     }
9976
9977     /**
9978      * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
9979      * double precision number which isn't the result of a rounded unsafe integer.
9980      *
9981      * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
9982      *
9983      * @static
9984      * @memberOf _
9985      * @category Lang
9986      * @param {*} value The value to check.
9987      * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
9988      * @example
9989      *
9990      * _.isSafeInteger(3);
9991      * // => true
9992      *
9993      * _.isSafeInteger(Number.MIN_VALUE);
9994      * // => false
9995      *
9996      * _.isSafeInteger(Infinity);
9997      * // => false
9998      *
9999      * _.isSafeInteger('3');
10000      * // => false
10001      */
10002     function isSafeInteger(value) {
10003       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
10004     }
10005
10006     /**
10007      * Checks if `value` is classified as a `String` primitive or object.
10008      *
10009      * @static
10010      * @memberOf _
10011      * @category Lang
10012      * @param {*} value The value to check.
10013      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10014      * @example
10015      *
10016      * _.isString('abc');
10017      * // => true
10018      *
10019      * _.isString(1);
10020      * // => false
10021      */
10022     function isString(value) {
10023       return typeof value == 'string' ||
10024         (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
10025     }
10026
10027     /**
10028      * Checks if `value` is classified as a `Symbol` primitive or object.
10029      *
10030      * @static
10031      * @memberOf _
10032      * @category Lang
10033      * @param {*} value The value to check.
10034      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10035      * @example
10036      *
10037      * _.isSymbol(Symbol.iterator);
10038      * // => true
10039      *
10040      * _.isSymbol('abc');
10041      * // => false
10042      */
10043     function isSymbol(value) {
10044       return typeof value == 'symbol' ||
10045         (isObjectLike(value) && objectToString.call(value) == symbolTag);
10046     }
10047
10048     /**
10049      * Checks if `value` is classified as a typed array.
10050      *
10051      * @static
10052      * @memberOf _
10053      * @category Lang
10054      * @param {*} value The value to check.
10055      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10056      * @example
10057      *
10058      * _.isTypedArray(new Uint8Array);
10059      * // => true
10060      *
10061      * _.isTypedArray([]);
10062      * // => false
10063      */
10064     function isTypedArray(value) {
10065       return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
10066     }
10067
10068     /**
10069      * Checks if `value` is `undefined`.
10070      *
10071      * @static
10072      * @memberOf _
10073      * @category Lang
10074      * @param {*} value The value to check.
10075      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
10076      * @example
10077      *
10078      * _.isUndefined(void 0);
10079      * // => true
10080      *
10081      * _.isUndefined(null);
10082      * // => false
10083      */
10084     function isUndefined(value) {
10085       return value === undefined;
10086     }
10087
10088     /**
10089      * Checks if `value` is less than `other`.
10090      *
10091      * @static
10092      * @memberOf _
10093      * @category Lang
10094      * @param {*} value The value to compare.
10095      * @param {*} other The other value to compare.
10096      * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
10097      * @example
10098      *
10099      * _.lt(1, 3);
10100      * // => true
10101      *
10102      * _.lt(3, 3);
10103      * // => false
10104      *
10105      * _.lt(3, 1);
10106      * // => false
10107      */
10108     function lt(value, other) {
10109       return value < other;
10110     }
10111
10112     /**
10113      * Checks if `value` is less than or equal to `other`.
10114      *
10115      * @static
10116      * @memberOf _
10117      * @category Lang
10118      * @param {*} value The value to compare.
10119      * @param {*} other The other value to compare.
10120      * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
10121      * @example
10122      *
10123      * _.lte(1, 3);
10124      * // => true
10125      *
10126      * _.lte(3, 3);
10127      * // => true
10128      *
10129      * _.lte(3, 1);
10130      * // => false
10131      */
10132     function lte(value, other) {
10133       return value <= other;
10134     }
10135
10136     /**
10137      * Converts `value` to an array.
10138      *
10139      * @static
10140      * @memberOf _
10141      * @category Lang
10142      * @param {*} value The value to convert.
10143      * @returns {Array} Returns the converted array.
10144      * @example
10145      *
10146      * _.toArray({ 'a': 1, 'b': 2 });
10147      * // => [1, 2]
10148      *
10149      * _.toArray('abc');
10150      * // => ['a', 'b', 'c']
10151      *
10152      * _.toArray(1);
10153      * // => []
10154      *
10155      * _.toArray(null);
10156      * // => []
10157      */
10158     function toArray(value) {
10159       if (!value) {
10160         return [];
10161       }
10162       if (isArrayLike(value)) {
10163         return isString(value) ? stringToArray(value) : copyArray(value);
10164       }
10165       if (iteratorSymbol && value[iteratorSymbol]) {
10166         return iteratorToArray(value[iteratorSymbol]());
10167       }
10168       var tag = getTag(value),
10169           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
10170
10171       return func(value);
10172     }
10173
10174     /**
10175      * Converts `value` to an integer.
10176      *
10177      * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
10178      *
10179      * @static
10180      * @memberOf _
10181      * @category Lang
10182      * @param {*} value The value to convert.
10183      * @returns {number} Returns the converted integer.
10184      * @example
10185      *
10186      * _.toInteger(3);
10187      * // => 3
10188      *
10189      * _.toInteger(Number.MIN_VALUE);
10190      * // => 0
10191      *
10192      * _.toInteger(Infinity);
10193      * // => 1.7976931348623157e+308
10194      *
10195      * _.toInteger('3');
10196      * // => 3
10197      */
10198     function toInteger(value) {
10199       if (!value) {
10200         return value === 0 ? value : 0;
10201       }
10202       value = toNumber(value);
10203       if (value === INFINITY || value === -INFINITY) {
10204         var sign = (value < 0 ? -1 : 1);
10205         return sign * MAX_INTEGER;
10206       }
10207       var remainder = value % 1;
10208       return value === value ? (remainder ? value - remainder : value) : 0;
10209     }
10210
10211     /**
10212      * Converts `value` to an integer suitable for use as the length of an
10213      * array-like object.
10214      *
10215      * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10216      *
10217      * @static
10218      * @memberOf _
10219      * @category Lang
10220      * @param {*} value The value to convert.
10221      * @returns {number} Returns the converted integer.
10222      * @example
10223      *
10224      * _.toLength(3);
10225      * // => 3
10226      *
10227      * _.toLength(Number.MIN_VALUE);
10228      * // => 0
10229      *
10230      * _.toLength(Infinity);
10231      * // => 4294967295
10232      *
10233      * _.toLength('3');
10234      * // => 3
10235      */
10236     function toLength(value) {
10237       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
10238     }
10239
10240     /**
10241      * Converts `value` to a number.
10242      *
10243      * @static
10244      * @memberOf _
10245      * @category Lang
10246      * @param {*} value The value to process.
10247      * @returns {number} Returns the number.
10248      * @example
10249      *
10250      * _.toNumber(3);
10251      * // => 3
10252      *
10253      * _.toNumber(Number.MIN_VALUE);
10254      * // => 5e-324
10255      *
10256      * _.toNumber(Infinity);
10257      * // => Infinity
10258      *
10259      * _.toNumber('3');
10260      * // => 3
10261      */
10262     function toNumber(value) {
10263       if (isObject(value)) {
10264         var other = isFunction(value.valueOf) ? value.valueOf() : value;
10265         value = isObject(other) ? (other + '') : other;
10266       }
10267       if (typeof value != 'string') {
10268         return value === 0 ? value : +value;
10269       }
10270       value = value.replace(reTrim, '');
10271       var isBinary = reIsBinary.test(value);
10272       return (isBinary || reIsOctal.test(value))
10273         ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
10274         : (reIsBadHex.test(value) ? NAN : +value);
10275     }
10276
10277     /**
10278      * Converts `value` to a plain object flattening inherited enumerable
10279      * properties of `value` to own properties of the plain object.
10280      *
10281      * @static
10282      * @memberOf _
10283      * @category Lang
10284      * @param {*} value The value to convert.
10285      * @returns {Object} Returns the converted plain object.
10286      * @example
10287      *
10288      * function Foo() {
10289      *   this.b = 2;
10290      * }
10291      *
10292      * Foo.prototype.c = 3;
10293      *
10294      * _.assign({ 'a': 1 }, new Foo);
10295      * // => { 'a': 1, 'b': 2 }
10296      *
10297      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
10298      * // => { 'a': 1, 'b': 2, 'c': 3 }
10299      */
10300     function toPlainObject(value) {
10301       return copyObject(value, keysIn(value));
10302     }
10303
10304     /**
10305      * Converts `value` to a safe integer. A safe integer can be compared and
10306      * represented correctly.
10307      *
10308      * @static
10309      * @memberOf _
10310      * @category Lang
10311      * @param {*} value The value to convert.
10312      * @returns {number} Returns the converted integer.
10313      * @example
10314      *
10315      * _.toSafeInteger(3);
10316      * // => 3
10317      *
10318      * _.toSafeInteger(Number.MIN_VALUE);
10319      * // => 0
10320      *
10321      * _.toSafeInteger(Infinity);
10322      * // => 9007199254740991
10323      *
10324      * _.toSafeInteger('3');
10325      * // => 3
10326      */
10327     function toSafeInteger(value) {
10328       return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
10329     }
10330
10331     /**
10332      * Converts `value` to a string if it's not one. An empty string is returned
10333      * for `null` and `undefined` values. The sign of `-0` is preserved.
10334      *
10335      * @static
10336      * @memberOf _
10337      * @category Lang
10338      * @param {*} value The value to process.
10339      * @returns {string} Returns the string.
10340      * @example
10341      *
10342      * _.toString(null);
10343      * // => ''
10344      *
10345      * _.toString(-0);
10346      * // => '-0'
10347      *
10348      * _.toString([1, 2, 3]);
10349      * // => '1,2,3'
10350      */
10351     function toString(value) {
10352       // Exit early for strings to avoid a performance hit in some environments.
10353       if (typeof value == 'string') {
10354         return value;
10355       }
10356       if (value == null) {
10357         return '';
10358       }
10359       if (isSymbol(value)) {
10360         return Symbol ? symbolToString.call(value) : '';
10361       }
10362       var result = (value + '');
10363       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
10364     }
10365
10366     /*------------------------------------------------------------------------*/
10367
10368     /**
10369      * Assigns own enumerable properties of source objects to the destination
10370      * object. Source objects are applied from left to right. Subsequent sources
10371      * overwrite property assignments of previous sources.
10372      *
10373      * **Note:** This method mutates `object` and is loosely based on
10374      * [`Object.assign`](https://mdn.io/Object/assign).
10375      *
10376      * @static
10377      * @memberOf _
10378      * @category Object
10379      * @param {Object} object The destination object.
10380      * @param {...Object} [sources] The source objects.
10381      * @returns {Object} Returns `object`.
10382      * @example
10383      *
10384      * function Foo() {
10385      *   this.c = 3;
10386      * }
10387      *
10388      * function Bar() {
10389      *   this.e = 5;
10390      * }
10391      *
10392      * Foo.prototype.d = 4;
10393      * Bar.prototype.f = 6;
10394      *
10395      * _.assign({ 'a': 1 }, new Foo, new Bar);
10396      * // => { 'a': 1, 'c': 3, 'e': 5 }
10397      */
10398     var assign = createAssigner(function(object, source) {
10399       copyObject(source, keys(source), object);
10400     });
10401
10402     /**
10403      * This method is like `_.assign` except that it iterates over own and
10404      * inherited source properties.
10405      *
10406      * **Note:** This method mutates `object`.
10407      *
10408      * @static
10409      * @memberOf _
10410      * @alias extend
10411      * @category Object
10412      * @param {Object} object The destination object.
10413      * @param {...Object} [sources] The source objects.
10414      * @returns {Object} Returns `object`.
10415      * @example
10416      *
10417      * function Foo() {
10418      *   this.b = 2;
10419      * }
10420      *
10421      * function Bar() {
10422      *   this.d = 4;
10423      * }
10424      *
10425      * Foo.prototype.c = 3;
10426      * Bar.prototype.e = 5;
10427      *
10428      * _.assignIn({ 'a': 1 }, new Foo, new Bar);
10429      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
10430      */
10431     var assignIn = createAssigner(function(object, source) {
10432       copyObject(source, keysIn(source), object);
10433     });
10434
10435     /**
10436      * This method is like `_.assignIn` except that it accepts `customizer` which
10437      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10438      * assignment is handled by the method instead. The `customizer` is invoked
10439      * with five arguments: (objValue, srcValue, key, object, source).
10440      *
10441      * **Note:** This method mutates `object`.
10442      *
10443      * @static
10444      * @memberOf _
10445      * @alias extendWith
10446      * @category Object
10447      * @param {Object} object The destination object.
10448      * @param {...Object} sources The source objects.
10449      * @param {Function} [customizer] The function to customize assigned values.
10450      * @returns {Object} Returns `object`.
10451      * @example
10452      *
10453      * function customizer(objValue, srcValue) {
10454      *   return _.isUndefined(objValue) ? srcValue : objValue;
10455      * }
10456      *
10457      * var defaults = _.partialRight(_.assignInWith, customizer);
10458      *
10459      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10460      * // => { 'a': 1, 'b': 2 }
10461      */
10462     var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
10463       copyObjectWith(source, keysIn(source), object, customizer);
10464     });
10465
10466     /**
10467      * This method is like `_.assign` except that it accepts `customizer` which
10468      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10469      * assignment is handled by the method instead. The `customizer` is invoked
10470      * with five arguments: (objValue, srcValue, key, object, source).
10471      *
10472      * **Note:** This method mutates `object`.
10473      *
10474      * @static
10475      * @memberOf _
10476      * @category Object
10477      * @param {Object} object The destination object.
10478      * @param {...Object} sources The source objects.
10479      * @param {Function} [customizer] The function to customize assigned values.
10480      * @returns {Object} Returns `object`.
10481      * @example
10482      *
10483      * function customizer(objValue, srcValue) {
10484      *   return _.isUndefined(objValue) ? srcValue : objValue;
10485      * }
10486      *
10487      * var defaults = _.partialRight(_.assignWith, customizer);
10488      *
10489      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10490      * // => { 'a': 1, 'b': 2 }
10491      */
10492     var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
10493       copyObjectWith(source, keys(source), object, customizer);
10494     });
10495
10496     /**
10497      * Creates an array of values corresponding to `paths` of `object`.
10498      *
10499      * @static
10500      * @memberOf _
10501      * @category Object
10502      * @param {Object} object The object to iterate over.
10503      * @param {...(string|string[])} [paths] The property paths of elements to pick,
10504      *  specified individually or in arrays.
10505      * @returns {Array} Returns the new array of picked elements.
10506      * @example
10507      *
10508      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
10509      *
10510      * _.at(object, ['a[0].b.c', 'a[1]']);
10511      * // => [3, 4]
10512      *
10513      * _.at(['a', 'b', 'c'], 0, 2);
10514      * // => ['a', 'c']
10515      */
10516     var at = rest(function(object, paths) {
10517       return baseAt(object, baseFlatten(paths));
10518     });
10519
10520     /**
10521      * Creates an object that inherits from the `prototype` object. If a `properties`
10522      * object is provided its own enumerable properties are assigned to the created object.
10523      *
10524      * @static
10525      * @memberOf _
10526      * @category Object
10527      * @param {Object} prototype The object to inherit from.
10528      * @param {Object} [properties] The properties to assign to the object.
10529      * @returns {Object} Returns the new object.
10530      * @example
10531      *
10532      * function Shape() {
10533      *   this.x = 0;
10534      *   this.y = 0;
10535      * }
10536      *
10537      * function Circle() {
10538      *   Shape.call(this);
10539      * }
10540      *
10541      * Circle.prototype = _.create(Shape.prototype, {
10542      *   'constructor': Circle
10543      * });
10544      *
10545      * var circle = new Circle;
10546      * circle instanceof Circle;
10547      * // => true
10548      *
10549      * circle instanceof Shape;
10550      * // => true
10551      */
10552     function create(prototype, properties) {
10553       var result = baseCreate(prototype);
10554       return properties ? baseAssign(result, properties) : result;
10555     }
10556
10557     /**
10558      * Assigns own and inherited enumerable properties of source objects to the
10559      * destination object for all destination properties that resolve to `undefined`.
10560      * Source objects are applied from left to right. Once a property is set,
10561      * additional values of the same property are ignored.
10562      *
10563      * **Note:** This method mutates `object`.
10564      *
10565      * @static
10566      * @memberOf _
10567      * @category Object
10568      * @param {Object} object The destination object.
10569      * @param {...Object} [sources] The source objects.
10570      * @returns {Object} Returns `object`.
10571      * @example
10572      *
10573      * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
10574      * // => { 'user': 'barney', 'age': 36 }
10575      */
10576     var defaults = rest(function(args) {
10577       args.push(undefined, assignInDefaults);
10578       return apply(assignInWith, undefined, args);
10579     });
10580
10581     /**
10582      * This method is like `_.defaults` except that it recursively assigns
10583      * default properties.
10584      *
10585      * **Note:** This method mutates `object`.
10586      *
10587      * @static
10588      * @memberOf _
10589      * @category Object
10590      * @param {Object} object The destination object.
10591      * @param {...Object} [sources] The source objects.
10592      * @returns {Object} Returns `object`.
10593      * @example
10594      *
10595      * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
10596      * // => { 'user': { 'name': 'barney', 'age': 36 } }
10597      *
10598      */
10599     var defaultsDeep = rest(function(args) {
10600       args.push(undefined, mergeDefaults);
10601       return apply(mergeWith, undefined, args);
10602     });
10603
10604     /**
10605      * This method is like `_.find` except that it returns the key of the first
10606      * element `predicate` returns truthy for instead of the element itself.
10607      *
10608      * @static
10609      * @memberOf _
10610      * @category Object
10611      * @param {Object} object The object to search.
10612      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10613      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10614      * @example
10615      *
10616      * var users = {
10617      *   'barney':  { 'age': 36, 'active': true },
10618      *   'fred':    { 'age': 40, 'active': false },
10619      *   'pebbles': { 'age': 1,  'active': true }
10620      * };
10621      *
10622      * _.findKey(users, function(o) { return o.age < 40; });
10623      * // => 'barney' (iteration order is not guaranteed)
10624      *
10625      * // using the `_.matches` iteratee shorthand
10626      * _.findKey(users, { 'age': 1, 'active': true });
10627      * // => 'pebbles'
10628      *
10629      * // using the `_.matchesProperty` iteratee shorthand
10630      * _.findKey(users, ['active', false]);
10631      * // => 'fred'
10632      *
10633      * // using the `_.property` iteratee shorthand
10634      * _.findKey(users, 'active');
10635      * // => 'barney'
10636      */
10637     function findKey(object, predicate) {
10638       return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
10639     }
10640
10641     /**
10642      * This method is like `_.findKey` except that it iterates over elements of
10643      * a collection in the opposite order.
10644      *
10645      * @static
10646      * @memberOf _
10647      * @category Object
10648      * @param {Object} object The object to search.
10649      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10650      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10651      * @example
10652      *
10653      * var users = {
10654      *   'barney':  { 'age': 36, 'active': true },
10655      *   'fred':    { 'age': 40, 'active': false },
10656      *   'pebbles': { 'age': 1,  'active': true }
10657      * };
10658      *
10659      * _.findLastKey(users, function(o) { return o.age < 40; });
10660      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
10661      *
10662      * // using the `_.matches` iteratee shorthand
10663      * _.findLastKey(users, { 'age': 36, 'active': true });
10664      * // => 'barney'
10665      *
10666      * // using the `_.matchesProperty` iteratee shorthand
10667      * _.findLastKey(users, ['active', false]);
10668      * // => 'fred'
10669      *
10670      * // using the `_.property` iteratee shorthand
10671      * _.findLastKey(users, 'active');
10672      * // => 'pebbles'
10673      */
10674     function findLastKey(object, predicate) {
10675       return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
10676     }
10677
10678     /**
10679      * Iterates over own and inherited enumerable properties of an object invoking
10680      * `iteratee` for each property. The iteratee is invoked with three arguments:
10681      * (value, key, object). Iteratee functions may exit iteration early by explicitly
10682      * returning `false`.
10683      *
10684      * @static
10685      * @memberOf _
10686      * @category Object
10687      * @param {Object} object The object to iterate over.
10688      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10689      * @returns {Object} Returns `object`.
10690      * @example
10691      *
10692      * function Foo() {
10693      *   this.a = 1;
10694      *   this.b = 2;
10695      * }
10696      *
10697      * Foo.prototype.c = 3;
10698      *
10699      * _.forIn(new Foo, function(value, key) {
10700      *   console.log(key);
10701      * });
10702      * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
10703      */
10704     function forIn(object, iteratee) {
10705       return object == null ? object : baseFor(object, toFunction(iteratee), keysIn);
10706     }
10707
10708     /**
10709      * This method is like `_.forIn` except that it iterates over properties of
10710      * `object` in the opposite order.
10711      *
10712      * @static
10713      * @memberOf _
10714      * @category Object
10715      * @param {Object} object The object to iterate over.
10716      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10717      * @returns {Object} Returns `object`.
10718      * @example
10719      *
10720      * function Foo() {
10721      *   this.a = 1;
10722      *   this.b = 2;
10723      * }
10724      *
10725      * Foo.prototype.c = 3;
10726      *
10727      * _.forInRight(new Foo, function(value, key) {
10728      *   console.log(key);
10729      * });
10730      * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
10731      */
10732     function forInRight(object, iteratee) {
10733       return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn);
10734     }
10735
10736     /**
10737      * Iterates over own enumerable properties of an object invoking `iteratee`
10738      * for each property. The iteratee is invoked with three arguments:
10739      * (value, key, object). Iteratee functions may exit iteration early by
10740      * explicitly returning `false`.
10741      *
10742      * @static
10743      * @memberOf _
10744      * @category Object
10745      * @param {Object} object The object to iterate over.
10746      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10747      * @returns {Object} Returns `object`.
10748      * @example
10749      *
10750      * function Foo() {
10751      *   this.a = 1;
10752      *   this.b = 2;
10753      * }
10754      *
10755      * Foo.prototype.c = 3;
10756      *
10757      * _.forOwn(new Foo, function(value, key) {
10758      *   console.log(key);
10759      * });
10760      * // => logs 'a' then 'b' (iteration order is not guaranteed)
10761      */
10762     function forOwn(object, iteratee) {
10763       return object && baseForOwn(object, toFunction(iteratee));
10764     }
10765
10766     /**
10767      * This method is like `_.forOwn` except that it iterates over properties of
10768      * `object` in the opposite order.
10769      *
10770      * @static
10771      * @memberOf _
10772      * @category Object
10773      * @param {Object} object The object to iterate over.
10774      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10775      * @returns {Object} Returns `object`.
10776      * @example
10777      *
10778      * function Foo() {
10779      *   this.a = 1;
10780      *   this.b = 2;
10781      * }
10782      *
10783      * Foo.prototype.c = 3;
10784      *
10785      * _.forOwnRight(new Foo, function(value, key) {
10786      *   console.log(key);
10787      * });
10788      * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
10789      */
10790     function forOwnRight(object, iteratee) {
10791       return object && baseForOwnRight(object, toFunction(iteratee));
10792     }
10793
10794     /**
10795      * Creates an array of function property names from own enumerable properties
10796      * of `object`.
10797      *
10798      * @static
10799      * @memberOf _
10800      * @category Object
10801      * @param {Object} object The object to inspect.
10802      * @returns {Array} Returns the new array of property names.
10803      * @example
10804      *
10805      * function Foo() {
10806      *   this.a = _.constant('a');
10807      *   this.b = _.constant('b');
10808      * }
10809      *
10810      * Foo.prototype.c = _.constant('c');
10811      *
10812      * _.functions(new Foo);
10813      * // => ['a', 'b']
10814      */
10815     function functions(object) {
10816       return object == null ? [] : baseFunctions(object, keys(object));
10817     }
10818
10819     /**
10820      * Creates an array of function property names from own and inherited
10821      * enumerable properties of `object`.
10822      *
10823      * @static
10824      * @memberOf _
10825      * @category Object
10826      * @param {Object} object The object to inspect.
10827      * @returns {Array} Returns the new array of property names.
10828      * @example
10829      *
10830      * function Foo() {
10831      *   this.a = _.constant('a');
10832      *   this.b = _.constant('b');
10833      * }
10834      *
10835      * Foo.prototype.c = _.constant('c');
10836      *
10837      * _.functionsIn(new Foo);
10838      * // => ['a', 'b', 'c']
10839      */
10840     function functionsIn(object) {
10841       return object == null ? [] : baseFunctions(object, keysIn(object));
10842     }
10843
10844     /**
10845      * Gets the value at `path` of `object`. If the resolved value is
10846      * `undefined` the `defaultValue` is used in its place.
10847      *
10848      * @static
10849      * @memberOf _
10850      * @category Object
10851      * @param {Object} object The object to query.
10852      * @param {Array|string} path The path of the property to get.
10853      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
10854      * @returns {*} Returns the resolved value.
10855      * @example
10856      *
10857      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
10858      *
10859      * _.get(object, 'a[0].b.c');
10860      * // => 3
10861      *
10862      * _.get(object, ['a', '0', 'b', 'c']);
10863      * // => 3
10864      *
10865      * _.get(object, 'a.b.c', 'default');
10866      * // => 'default'
10867      */
10868     function get(object, path, defaultValue) {
10869       var result = object == null ? undefined : baseGet(object, path);
10870       return result === undefined ? defaultValue : result;
10871     }
10872
10873     /**
10874      * Checks if `path` is a direct property of `object`.
10875      *
10876      * @static
10877      * @memberOf _
10878      * @category Object
10879      * @param {Object} object The object to query.
10880      * @param {Array|string} path The path to check.
10881      * @returns {boolean} Returns `true` if `path` exists, else `false`.
10882      * @example
10883      *
10884      * var object = { 'a': { 'b': { 'c': 3 } } };
10885      * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
10886      *
10887      * _.has(object, 'a');
10888      * // => true
10889      *
10890      * _.has(object, 'a.b.c');
10891      * // => true
10892      *
10893      * _.has(object, ['a', 'b', 'c']);
10894      * // => true
10895      *
10896      * _.has(other, 'a');
10897      * // => false
10898      */
10899     function has(object, path) {
10900       return hasPath(object, path, baseHas);
10901     }
10902
10903     /**
10904      * Checks if `path` is a direct or inherited property of `object`.
10905      *
10906      * @static
10907      * @memberOf _
10908      * @category Object
10909      * @param {Object} object The object to query.
10910      * @param {Array|string} path The path to check.
10911      * @returns {boolean} Returns `true` if `path` exists, else `false`.
10912      * @example
10913      *
10914      * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
10915      *
10916      * _.hasIn(object, 'a');
10917      * // => true
10918      *
10919      * _.hasIn(object, 'a.b.c');
10920      * // => true
10921      *
10922      * _.hasIn(object, ['a', 'b', 'c']);
10923      * // => true
10924      *
10925      * _.hasIn(object, 'b');
10926      * // => false
10927      */
10928     function hasIn(object, path) {
10929       return hasPath(object, path, baseHasIn);
10930     }
10931
10932     /**
10933      * Creates an object composed of the inverted keys and values of `object`.
10934      * If `object` contains duplicate values, subsequent values overwrite property
10935      * assignments of previous values unless `multiVal` is `true`.
10936      *
10937      * @static
10938      * @memberOf _
10939      * @category Object
10940      * @param {Object} object The object to invert.
10941      * @param {boolean} [multiVal] Allow multiple values per key.
10942      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
10943      * @returns {Object} Returns the new inverted object.
10944      * @example
10945      *
10946      * var object = { 'a': 1, 'b': 2, 'c': 1 };
10947      *
10948      * _.invert(object);
10949      * // => { '1': 'c', '2': 'b' }
10950      *
10951      * // with `multiVal`
10952      * _.invert(object, true);
10953      * // => { '1': ['a', 'c'], '2': ['b'] }
10954      */
10955     function invert(object, multiVal, guard) {
10956       return arrayReduce(keys(object), function(result, key) {
10957         var value = object[key];
10958         if (multiVal && !guard) {
10959           if (hasOwnProperty.call(result, value)) {
10960             result[value].push(key);
10961           } else {
10962             result[value] = [key];
10963           }
10964         }
10965         else {
10966           result[value] = key;
10967         }
10968         return result;
10969       }, {});
10970     }
10971
10972     /**
10973      * Invokes the method at `path` of `object`.
10974      *
10975      * @static
10976      * @memberOf _
10977      * @category Object
10978      * @param {Object} object The object to query.
10979      * @param {Array|string} path The path of the method to invoke.
10980      * @param {...*} [args] The arguments to invoke the method with.
10981      * @returns {*} Returns the result of the invoked method.
10982      * @example
10983      *
10984      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
10985      *
10986      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
10987      * // => [2, 3]
10988      */
10989     var invoke = rest(baseInvoke);
10990
10991     /**
10992      * Creates an array of the own enumerable property names of `object`.
10993      *
10994      * **Note:** Non-object values are coerced to objects. See the
10995      * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
10996      * for more details.
10997      *
10998      * @static
10999      * @memberOf _
11000      * @category Object
11001      * @param {Object} object The object to query.
11002      * @returns {Array} Returns the array of property names.
11003      * @example
11004      *
11005      * function Foo() {
11006      *   this.a = 1;
11007      *   this.b = 2;
11008      * }
11009      *
11010      * Foo.prototype.c = 3;
11011      *
11012      * _.keys(new Foo);
11013      * // => ['a', 'b'] (iteration order is not guaranteed)
11014      *
11015      * _.keys('hi');
11016      * // => ['0', '1']
11017      */
11018     function keys(object) {
11019       var isProto = isPrototype(object);
11020       if (!(isProto || isArrayLike(object))) {
11021         return baseKeys(object);
11022       }
11023       var indexes = indexKeys(object),
11024           skipIndexes = !!indexes,
11025           result = indexes || [],
11026           length = result.length;
11027
11028       for (var key in object) {
11029         if (baseHas(object, key) &&
11030             !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11031             !(isProto && key == 'constructor')) {
11032           result.push(key);
11033         }
11034       }
11035       return result;
11036     }
11037
11038     /**
11039      * Creates an array of the own and inherited enumerable property names of `object`.
11040      *
11041      * **Note:** Non-object values are coerced to objects.
11042      *
11043      * @static
11044      * @memberOf _
11045      * @category Object
11046      * @param {Object} object The object to query.
11047      * @returns {Array} Returns the array of property names.
11048      * @example
11049      *
11050      * function Foo() {
11051      *   this.a = 1;
11052      *   this.b = 2;
11053      * }
11054      *
11055      * Foo.prototype.c = 3;
11056      *
11057      * _.keysIn(new Foo);
11058      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
11059      */
11060     function keysIn(object) {
11061       var index = -1,
11062           isProto = isPrototype(object),
11063           props = baseKeysIn(object),
11064           propsLength = props.length,
11065           indexes = indexKeys(object),
11066           skipIndexes = !!indexes,
11067           result = indexes || [],
11068           length = result.length;
11069
11070       while (++index < propsLength) {
11071         var key = props[index];
11072         if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11073             !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
11074           result.push(key);
11075         }
11076       }
11077       return result;
11078     }
11079
11080     /**
11081      * The opposite of `_.mapValues`; this method creates an object with the
11082      * same values as `object` and keys generated by running each own enumerable
11083      * property of `object` through `iteratee`.
11084      *
11085      * @static
11086      * @memberOf _
11087      * @category Object
11088      * @param {Object} object The object to iterate over.
11089      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11090      * @returns {Object} Returns the new mapped object.
11091      * @example
11092      *
11093      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
11094      *   return key + value;
11095      * });
11096      * // => { 'a1': 1, 'b2': 2 }
11097      */
11098     function mapKeys(object, iteratee) {
11099       var result = {};
11100       iteratee = getIteratee(iteratee, 3);
11101
11102       baseForOwn(object, function(value, key, object) {
11103         result[iteratee(value, key, object)] = value;
11104       });
11105       return result;
11106     }
11107
11108     /**
11109      * Creates an object with the same keys as `object` and values generated by
11110      * running each own enumerable property of `object` through `iteratee`. The
11111      * iteratee function is invoked with three arguments: (value, key, object).
11112      *
11113      * @static
11114      * @memberOf _
11115      * @category Object
11116      * @param {Object} object The object to iterate over.
11117      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11118      * @returns {Object} Returns the new mapped object.
11119      * @example
11120      *
11121      * var users = {
11122      *   'fred':    { 'user': 'fred',    'age': 40 },
11123      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
11124      * };
11125      *
11126      * _.mapValues(users, function(o) { return o.age; });
11127      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11128      *
11129      * // using the `_.property` iteratee shorthand
11130      * _.mapValues(users, 'age');
11131      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11132      */
11133     function mapValues(object, iteratee) {
11134       var result = {};
11135       iteratee = getIteratee(iteratee, 3);
11136
11137       baseForOwn(object, function(value, key, object) {
11138         result[key] = iteratee(value, key, object);
11139       });
11140       return result;
11141     }
11142
11143     /**
11144      * Recursively merges own and inherited enumerable properties of source
11145      * objects into the destination object, skipping source properties that resolve
11146      * to `undefined`. Array and plain object properties are merged recursively.
11147      * Other objects and value types are overridden by assignment. Source objects
11148      * are applied from left to right. Subsequent sources overwrite property
11149      * assignments of previous sources.
11150      *
11151      * **Note:** This method mutates `object`.
11152      *
11153      * @static
11154      * @memberOf _
11155      * @category Object
11156      * @param {Object} object The destination object.
11157      * @param {...Object} [sources] The source objects.
11158      * @returns {Object} Returns `object`.
11159      * @example
11160      *
11161      * var users = {
11162      *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
11163      * };
11164      *
11165      * var ages = {
11166      *   'data': [{ 'age': 36 }, { 'age': 40 }]
11167      * };
11168      *
11169      * _.merge(users, ages);
11170      * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
11171      */
11172     var merge = createAssigner(function(object, source, srcIndex) {
11173       baseMerge(object, source, srcIndex);
11174     });
11175
11176     /**
11177      * This method is like `_.merge` except that it accepts `customizer` which
11178      * is invoked to produce the merged values of the destination and source
11179      * properties. If `customizer` returns `undefined` merging is handled by the
11180      * method instead. The `customizer` is invoked with seven arguments:
11181      * (objValue, srcValue, key, object, source, stack).
11182      *
11183      * @static
11184      * @memberOf _
11185      * @category Object
11186      * @param {Object} object The destination object.
11187      * @param {...Object} sources The source objects.
11188      * @param {Function} customizer The function to customize assigned values.
11189      * @returns {Object} Returns `object`.
11190      * @example
11191      *
11192      * function customizer(objValue, srcValue) {
11193      *   if (_.isArray(objValue)) {
11194      *     return objValue.concat(srcValue);
11195      *   }
11196      * }
11197      *
11198      * var object = {
11199      *   'fruits': ['apple'],
11200      *   'vegetables': ['beet']
11201      * };
11202      *
11203      * var other = {
11204      *   'fruits': ['banana'],
11205      *   'vegetables': ['carrot']
11206      * };
11207      *
11208      * _.mergeWith(object, other, customizer);
11209      * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
11210      */
11211     var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
11212       baseMerge(object, source, srcIndex, customizer);
11213     });
11214
11215     /**
11216      * The opposite of `_.pick`; this method creates an object composed of the
11217      * own and inherited enumerable properties of `object` that are not omitted.
11218      *
11219      * @static
11220      * @memberOf _
11221      * @category Object
11222      * @param {Object} object The source object.
11223      * @param {...(string|string[])} [props] The property names to omit, specified
11224      *  individually or in arrays..
11225      * @returns {Object} Returns the new object.
11226      * @example
11227      *
11228      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11229      *
11230      * _.omit(object, ['a', 'c']);
11231      * // => { 'b': '2' }
11232      */
11233     var omit = rest(function(object, props) {
11234       if (object == null) {
11235         return {};
11236       }
11237       props = arrayMap(baseFlatten(props), String);
11238       return basePick(object, baseDifference(keysIn(object), props));
11239     });
11240
11241     /**
11242      * The opposite of `_.pickBy`; this method creates an object composed of the
11243      * own and inherited enumerable properties of `object` that `predicate`
11244      * doesn't return truthy for.
11245      *
11246      * @static
11247      * @memberOf _
11248      * @category Object
11249      * @param {Object} object The source object.
11250      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11251      * @returns {Object} Returns the new object.
11252      * @example
11253      *
11254      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11255      *
11256      * _.omitBy(object, _.isNumber);
11257      * // => { 'b': '2' }
11258      */
11259     function omitBy(object, predicate) {
11260       predicate = getIteratee(predicate, 2);
11261       return basePickBy(object, function(value, key) {
11262         return !predicate(value, key);
11263       });
11264     }
11265
11266     /**
11267      * Creates an object composed of the picked `object` properties.
11268      *
11269      * @static
11270      * @memberOf _
11271      * @category Object
11272      * @param {Object} object The source object.
11273      * @param {...(string|string[])} [props] The property names to pick, specified
11274      *  individually or in arrays.
11275      * @returns {Object} Returns the new object.
11276      * @example
11277      *
11278      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11279      *
11280      * _.pick(object, ['a', 'c']);
11281      * // => { 'a': 1, 'c': 3 }
11282      */
11283     var pick = rest(function(object, props) {
11284       return object == null ? {} : basePick(object, baseFlatten(props));
11285     });
11286
11287     /**
11288      * Creates an object composed of the `object` properties `predicate` returns
11289      * truthy for. The predicate is invoked with one argument: (value).
11290      *
11291      * @static
11292      * @memberOf _
11293      * @category Object
11294      * @param {Object} object The source object.
11295      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11296      * @returns {Object} Returns the new object.
11297      * @example
11298      *
11299      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11300      *
11301      * _.pickBy(object, _.isNumber);
11302      * // => { 'a': 1, 'c': 3 }
11303      */
11304     function pickBy(object, predicate) {
11305       return object == null ? {} : basePickBy(object, getIteratee(predicate, 2));
11306     }
11307
11308     /**
11309      * This method is like `_.get` except that if the resolved value is a function
11310      * it's invoked with the `this` binding of its parent object and its result
11311      * is returned.
11312      *
11313      * @static
11314      * @memberOf _
11315      * @category Object
11316      * @param {Object} object The object to query.
11317      * @param {Array|string} path The path of the property to resolve.
11318      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11319      * @returns {*} Returns the resolved value.
11320      * @example
11321      *
11322      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
11323      *
11324      * _.result(object, 'a[0].b.c1');
11325      * // => 3
11326      *
11327      * _.result(object, 'a[0].b.c2');
11328      * // => 4
11329      *
11330      * _.result(object, 'a[0].b.c3', 'default');
11331      * // => 'default'
11332      *
11333      * _.result(object, 'a[0].b.c3', _.constant('default'));
11334      * // => 'default'
11335      */
11336     function result(object, path, defaultValue) {
11337       if (!isKey(path, object)) {
11338         path = baseToPath(path);
11339         var result = get(object, path);
11340         object = parent(object, path);
11341       } else {
11342         result = object == null ? undefined : object[path];
11343       }
11344       if (result === undefined) {
11345         result = defaultValue;
11346       }
11347       return isFunction(result) ? result.call(object) : result;
11348     }
11349
11350     /**
11351      * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
11352      * it's created. Arrays are created for missing index properties while objects
11353      * are created for all other missing properties. Use `_.setWith` to customize
11354      * `path` creation.
11355      *
11356      * @static
11357      * @memberOf _
11358      * @category Object
11359      * @param {Object} object The object to modify.
11360      * @param {Array|string} path The path of the property to set.
11361      * @param {*} value The value to set.
11362      * @returns {Object} Returns `object`.
11363      * @example
11364      *
11365      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11366      *
11367      * _.set(object, 'a[0].b.c', 4);
11368      * console.log(object.a[0].b.c);
11369      * // => 4
11370      *
11371      * _.set(object, 'x[0].y.z', 5);
11372      * console.log(object.x[0].y.z);
11373      * // => 5
11374      */
11375     function set(object, path, value) {
11376       return object == null ? object : baseSet(object, path, value);
11377     }
11378
11379     /**
11380      * This method is like `_.set` except that it accepts `customizer` which is
11381      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
11382      * path creation is handled by the method instead. The `customizer` is invoked
11383      * with three arguments: (nsValue, key, nsObject).
11384      *
11385      * @static
11386      * @memberOf _
11387      * @category Object
11388      * @param {Object} object The object to modify.
11389      * @param {Array|string} path The path of the property to set.
11390      * @param {*} value The value to set.
11391      * @param {Function} [customizer] The function to customize assigned values.
11392      * @returns {Object} Returns `object`.
11393      * @example
11394      *
11395      * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
11396      * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
11397      */
11398     function setWith(object, path, value, customizer) {
11399       customizer = typeof customizer == 'function' ? customizer : undefined;
11400       return object == null ? object : baseSet(object, path, value, customizer);
11401     }
11402
11403     /**
11404      * Creates an array of own enumerable key-value pairs for `object`.
11405      *
11406      * @static
11407      * @memberOf _
11408      * @category Object
11409      * @param {Object} object The object to query.
11410      * @returns {Array} Returns the new array of key-value pairs.
11411      * @example
11412      *
11413      * function Foo() {
11414      *   this.a = 1;
11415      *   this.b = 2;
11416      * }
11417      *
11418      * Foo.prototype.c = 3;
11419      *
11420      * _.toPairs(new Foo);
11421      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
11422      */
11423     function toPairs(object) {
11424       return baseToPairs(object, keys(object));
11425     }
11426
11427     /**
11428      * Creates an array of own and inherited enumerable key-value pairs for `object`.
11429      *
11430      * @static
11431      * @memberOf _
11432      * @category Object
11433      * @param {Object} object The object to query.
11434      * @returns {Array} Returns the new array of key-value pairs.
11435      * @example
11436      *
11437      * function Foo() {
11438      *   this.a = 1;
11439      *   this.b = 2;
11440      * }
11441      *
11442      * Foo.prototype.c = 3;
11443      *
11444      * _.toPairsIn(new Foo);
11445      * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
11446      */
11447     function toPairsIn(object) {
11448       return baseToPairs(object, keysIn(object));
11449     }
11450
11451     /**
11452      * An alternative to `_.reduce`; this method transforms `object` to a new
11453      * `accumulator` object which is the result of running each of its own enumerable
11454      * properties through `iteratee`, with each invocation potentially mutating
11455      * the `accumulator` object. The iteratee is invoked with four arguments:
11456      * (accumulator, value, key, object). Iteratee functions may exit iteration
11457      * early by explicitly returning `false`.
11458      *
11459      * @static
11460      * @memberOf _
11461      * @category Object
11462      * @param {Array|Object} object The object to iterate over.
11463      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11464      * @param {*} [accumulator] The custom accumulator value.
11465      * @returns {*} Returns the accumulated value.
11466      * @example
11467      *
11468      * _.transform([2, 3, 4], function(result, n) {
11469      *   result.push(n *= n);
11470      *   return n % 2 == 0;
11471      * });
11472      * // => [4, 9]
11473      *
11474      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
11475      *   (result[value] || (result[value] = [])).push(key);
11476      * });
11477      * // => { '1': ['a', 'c'], '2': ['b'] }
11478      */
11479     function transform(object, iteratee, accumulator) {
11480       var isArr = isArray(object) || isTypedArray(object);
11481       iteratee = getIteratee(iteratee, 4);
11482
11483       if (accumulator == null) {
11484         if (isArr || isObject(object)) {
11485           var Ctor = object.constructor;
11486           if (isArr) {
11487             accumulator = isArray(object) ? new Ctor : [];
11488           } else {
11489             accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
11490           }
11491         } else {
11492           accumulator = {};
11493         }
11494       }
11495       (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
11496         return iteratee(accumulator, value, index, object);
11497       });
11498       return accumulator;
11499     }
11500
11501     /**
11502      * Removes the property at `path` of `object`.
11503      *
11504      * @static
11505      * @memberOf _
11506      * @category Object
11507      * @param {Object} object The object to modify.
11508      * @param {Array|string} path The path of the property to unset.
11509      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
11510      * @example
11511      *
11512      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
11513      * _.unset(object, 'a[0].b.c');
11514      * // => true
11515      *
11516      * console.log(object);
11517      * // => { 'a': [{ 'b': {} }] };
11518      *
11519      * _.unset(object, 'a[0].b.c');
11520      * // => true
11521      *
11522      * console.log(object);
11523      * // => { 'a': [{ 'b': {} }] };
11524      */
11525     function unset(object, path) {
11526       return object == null ? true : baseUnset(object, path);
11527     }
11528
11529     /**
11530      * Creates an array of the own enumerable property values of `object`.
11531      *
11532      * **Note:** Non-object values are coerced to objects.
11533      *
11534      * @static
11535      * @memberOf _
11536      * @category Object
11537      * @param {Object} object The object to query.
11538      * @returns {Array} Returns the array of property values.
11539      * @example
11540      *
11541      * function Foo() {
11542      *   this.a = 1;
11543      *   this.b = 2;
11544      * }
11545      *
11546      * Foo.prototype.c = 3;
11547      *
11548      * _.values(new Foo);
11549      * // => [1, 2] (iteration order is not guaranteed)
11550      *
11551      * _.values('hi');
11552      * // => ['h', 'i']
11553      */
11554     function values(object) {
11555       return object ? baseValues(object, keys(object)) : [];
11556     }
11557
11558     /**
11559      * Creates an array of the own and inherited enumerable property values of `object`.
11560      *
11561      * **Note:** Non-object values are coerced to objects.
11562      *
11563      * @static
11564      * @memberOf _
11565      * @category Object
11566      * @param {Object} object The object to query.
11567      * @returns {Array} Returns the array of property values.
11568      * @example
11569      *
11570      * function Foo() {
11571      *   this.a = 1;
11572      *   this.b = 2;
11573      * }
11574      *
11575      * Foo.prototype.c = 3;
11576      *
11577      * _.valuesIn(new Foo);
11578      * // => [1, 2, 3] (iteration order is not guaranteed)
11579      */
11580     function valuesIn(object) {
11581       return object == null ? baseValues(object, keysIn(object)) : [];
11582     }
11583
11584     /*------------------------------------------------------------------------*/
11585
11586     /**
11587      * Clamps `number` within the inclusive `lower` and `upper` bounds.
11588      *
11589      * @static
11590      * @memberOf _
11591      * @category Number
11592      * @param {number} number The number to clamp.
11593      * @param {number} [lower] The lower bound.
11594      * @param {number} upper The upper bound.
11595      * @returns {number} Returns the clamped number.
11596      * @example
11597      *
11598      * _.clamp(-10, -5, 5);
11599      * // => -5
11600      *
11601      * _.clamp(10, -5, 5);
11602      * // => 5
11603      */
11604     function clamp(number, lower, upper) {
11605       if (upper === undefined) {
11606         upper = lower;
11607         lower = undefined;
11608       }
11609       if (upper !== undefined) {
11610         upper = toNumber(upper);
11611         upper = upper === upper ? upper : 0;
11612       }
11613       if (lower !== undefined) {
11614         lower = toNumber(lower);
11615         lower = lower === lower ? lower : 0;
11616       }
11617       return baseClamp(toNumber(number), lower, upper);
11618     }
11619
11620     /**
11621      * Checks if `n` is between `start` and up to but not including, `end`. If
11622      * `end` is not specified it's set to `start` with `start` then set to `0`.
11623      * If `start` is greater than `end` the params are swapped to support
11624      * negative ranges.
11625      *
11626      * @static
11627      * @memberOf _
11628      * @category Number
11629      * @param {number} number The number to check.
11630      * @param {number} [start=0] The start of the range.
11631      * @param {number} end The end of the range.
11632      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
11633      * @example
11634      *
11635      * _.inRange(3, 2, 4);
11636      * // => true
11637      *
11638      * _.inRange(4, 8);
11639      * // => true
11640      *
11641      * _.inRange(4, 2);
11642      * // => false
11643      *
11644      * _.inRange(2, 2);
11645      * // => false
11646      *
11647      * _.inRange(1.2, 2);
11648      * // => true
11649      *
11650      * _.inRange(5.2, 4);
11651      * // => false
11652      *
11653      * _.inRange(-3, -2, -6);
11654      * // => true
11655      */
11656     function inRange(number, start, end) {
11657       start = toNumber(start) || 0;
11658       if (end === undefined) {
11659         end = start;
11660         start = 0;
11661       } else {
11662         end = toNumber(end) || 0;
11663       }
11664       number = toNumber(number);
11665       return baseInRange(number, start, end);
11666     }
11667
11668     /**
11669      * Produces a random number between the inclusive `lower` and `upper` bounds.
11670      * If only one argument is provided a number between `0` and the given number
11671      * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
11672      * a floating-point number is returned instead of an integer.
11673      *
11674      * **Note:** JavaScript follows the IEEE-754 standard for resolving
11675      * floating-point values which can produce unexpected results.
11676      *
11677      * @static
11678      * @memberOf _
11679      * @category Number
11680      * @param {number} [lower=0] The lower bound.
11681      * @param {number} [upper=1] The upper bound.
11682      * @param {boolean} [floating] Specify returning a floating-point number.
11683      * @returns {number} Returns the random number.
11684      * @example
11685      *
11686      * _.random(0, 5);
11687      * // => an integer between 0 and 5
11688      *
11689      * _.random(5);
11690      * // => also an integer between 0 and 5
11691      *
11692      * _.random(5, true);
11693      * // => a floating-point number between 0 and 5
11694      *
11695      * _.random(1.2, 5.2);
11696      * // => a floating-point number between 1.2 and 5.2
11697      */
11698     function random(lower, upper, floating) {
11699       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
11700         upper = floating = undefined;
11701       }
11702       if (floating === undefined) {
11703         if (typeof upper == 'boolean') {
11704           floating = upper;
11705           upper = undefined;
11706         }
11707         else if (typeof lower == 'boolean') {
11708           floating = lower;
11709           lower = undefined;
11710         }
11711       }
11712       if (lower === undefined && upper === undefined) {
11713         lower = 0;
11714         upper = 1;
11715       }
11716       else {
11717         lower = toNumber(lower) || 0;
11718         if (upper === undefined) {
11719           upper = lower;
11720           lower = 0;
11721         } else {
11722           upper = toNumber(upper) || 0;
11723         }
11724       }
11725       if (lower > upper) {
11726         var temp = lower;
11727         lower = upper;
11728         upper = temp;
11729       }
11730       if (floating || lower % 1 || upper % 1) {
11731         var rand = nativeRandom();
11732         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
11733       }
11734       return baseRandom(lower, upper);
11735     }
11736
11737     /*------------------------------------------------------------------------*/
11738
11739     /**
11740      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
11741      *
11742      * @static
11743      * @memberOf _
11744      * @category String
11745      * @param {string} [string=''] The string to convert.
11746      * @returns {string} Returns the camel cased string.
11747      * @example
11748      *
11749      * _.camelCase('Foo Bar');
11750      * // => 'fooBar'
11751      *
11752      * _.camelCase('--foo-bar');
11753      * // => 'fooBar'
11754      *
11755      * _.camelCase('__foo_bar__');
11756      * // => 'fooBar'
11757      */
11758     var camelCase = createCompounder(function(result, word, index) {
11759       word = word.toLowerCase();
11760       return result + (index ? capitalize(word) : word);
11761     });
11762
11763     /**
11764      * Converts the first character of `string` to upper case and the remaining
11765      * to lower case.
11766      *
11767      * @static
11768      * @memberOf _
11769      * @category String
11770      * @param {string} [string=''] The string to capitalize.
11771      * @returns {string} Returns the capitalized string.
11772      * @example
11773      *
11774      * _.capitalize('FRED');
11775      * // => 'Fred'
11776      */
11777     function capitalize(string) {
11778       return upperFirst(toString(string).toLowerCase());
11779     }
11780
11781     /**
11782      * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
11783      * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
11784      *
11785      * @static
11786      * @memberOf _
11787      * @category String
11788      * @param {string} [string=''] The string to deburr.
11789      * @returns {string} Returns the deburred string.
11790      * @example
11791      *
11792      * _.deburr('déjà vu');
11793      * // => 'deja vu'
11794      */
11795     function deburr(string) {
11796       string = toString(string);
11797       return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
11798     }
11799
11800     /**
11801      * Checks if `string` ends with the given target string.
11802      *
11803      * @static
11804      * @memberOf _
11805      * @category String
11806      * @param {string} [string=''] The string to search.
11807      * @param {string} [target] The string to search for.
11808      * @param {number} [position=string.length] The position to search from.
11809      * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
11810      * @example
11811      *
11812      * _.endsWith('abc', 'c');
11813      * // => true
11814      *
11815      * _.endsWith('abc', 'b');
11816      * // => false
11817      *
11818      * _.endsWith('abc', 'b', 2);
11819      * // => true
11820      */
11821     function endsWith(string, target, position) {
11822       string = toString(string);
11823       target = typeof target == 'string' ? target : (target + '');
11824
11825       var length = string.length;
11826       position = position === undefined
11827         ? length
11828         : baseClamp(toInteger(position), 0, length);
11829
11830       position -= target.length;
11831       return position >= 0 && string.indexOf(target, position) == position;
11832     }
11833
11834     /**
11835      * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
11836      * their corresponding HTML entities.
11837      *
11838      * **Note:** No other characters are escaped. To escape additional
11839      * characters use a third-party library like [_he_](https://mths.be/he).
11840      *
11841      * Though the ">" character is escaped for symmetry, characters like
11842      * ">" and "/" don't need escaping in HTML and have no special meaning
11843      * unless they're part of a tag or unquoted attribute value.
11844      * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
11845      * (under "semi-related fun fact") for more details.
11846      *
11847      * Backticks are escaped because in IE < 9, they can break out of
11848      * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
11849      * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
11850      * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
11851      * for more details.
11852      *
11853      * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
11854      * to reduce XSS vectors.
11855      *
11856      * @static
11857      * @memberOf _
11858      * @category String
11859      * @param {string} [string=''] The string to escape.
11860      * @returns {string} Returns the escaped string.
11861      * @example
11862      *
11863      * _.escape('fred, barney, & pebbles');
11864      * // => 'fred, barney, &amp; pebbles'
11865      */
11866     function escape(string) {
11867       string = toString(string);
11868       return (string && reHasUnescapedHtml.test(string))
11869         ? string.replace(reUnescapedHtml, escapeHtmlChar)
11870         : string;
11871     }
11872
11873     /**
11874      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
11875      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
11876      *
11877      * @static
11878      * @memberOf _
11879      * @category String
11880      * @param {string} [string=''] The string to escape.
11881      * @returns {string} Returns the escaped string.
11882      * @example
11883      *
11884      * _.escapeRegExp('[lodash](https://lodash.com/)');
11885      * // => '\[lodash\]\(https://lodash\.com/\)'
11886      */
11887     function escapeRegExp(string) {
11888       string = toString(string);
11889       return (string && reHasRegExpChar.test(string))
11890         ? string.replace(reRegExpChar, '\\$&')
11891         : string;
11892     }
11893
11894     /**
11895      * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
11896      *
11897      * @static
11898      * @memberOf _
11899      * @category String
11900      * @param {string} [string=''] The string to convert.
11901      * @returns {string} Returns the kebab cased string.
11902      * @example
11903      *
11904      * _.kebabCase('Foo Bar');
11905      * // => 'foo-bar'
11906      *
11907      * _.kebabCase('fooBar');
11908      * // => 'foo-bar'
11909      *
11910      * _.kebabCase('__foo_bar__');
11911      * // => 'foo-bar'
11912      */
11913     var kebabCase = createCompounder(function(result, word, index) {
11914       return result + (index ? '-' : '') + word.toLowerCase();
11915     });
11916
11917     /**
11918      * Converts `string`, as space separated words, to lower case.
11919      *
11920      * @static
11921      * @memberOf _
11922      * @category String
11923      * @param {string} [string=''] The string to convert.
11924      * @returns {string} Returns the lower cased string.
11925      * @example
11926      *
11927      * _.lowerCase('--Foo-Bar');
11928      * // => 'foo bar'
11929      *
11930      * _.lowerCase('fooBar');
11931      * // => 'foo bar'
11932      *
11933      * _.lowerCase('__FOO_BAR__');
11934      * // => 'foo bar'
11935      */
11936     var lowerCase = createCompounder(function(result, word, index) {
11937       return result + (index ? ' ' : '') + word.toLowerCase();
11938     });
11939
11940     /**
11941      * Converts the first character of `string` to lower case.
11942      *
11943      * @static
11944      * @memberOf _
11945      * @category String
11946      * @param {string} [string=''] The string to convert.
11947      * @returns {string} Returns the converted string.
11948      * @example
11949      *
11950      * _.lowerFirst('Fred');
11951      * // => 'fred'
11952      *
11953      * _.lowerFirst('FRED');
11954      * // => 'fRED'
11955      */
11956     var lowerFirst = createCaseFirst('toLowerCase');
11957
11958     /**
11959      * Converts the first character of `string` to upper case.
11960      *
11961      * @static
11962      * @memberOf _
11963      * @category String
11964      * @param {string} [string=''] The string to convert.
11965      * @returns {string} Returns the converted string.
11966      * @example
11967      *
11968      * _.upperFirst('fred');
11969      * // => 'Fred'
11970      *
11971      * _.upperFirst('FRED');
11972      * // => 'FRED'
11973      */
11974     var upperFirst = createCaseFirst('toUpperCase');
11975
11976     /**
11977      * Pads `string` on the left and right sides if it's shorter than `length`.
11978      * Padding characters are truncated if they can't be evenly divided by `length`.
11979      *
11980      * @static
11981      * @memberOf _
11982      * @category String
11983      * @param {string} [string=''] The string to pad.
11984      * @param {number} [length=0] The padding length.
11985      * @param {string} [chars=' '] The string used as padding.
11986      * @returns {string} Returns the padded string.
11987      * @example
11988      *
11989      * _.pad('abc', 8);
11990      * // => '  abc   '
11991      *
11992      * _.pad('abc', 8, '_-');
11993      * // => '_-abc_-_'
11994      *
11995      * _.pad('abc', 3);
11996      * // => 'abc'
11997      */
11998     function pad(string, length, chars) {
11999       string = toString(string);
12000       length = toInteger(length);
12001
12002       var strLength = stringSize(string);
12003       if (!length || strLength >= length) {
12004         return string;
12005       }
12006       var mid = (length - strLength) / 2,
12007           leftLength = nativeFloor(mid),
12008           rightLength = nativeCeil(mid);
12009
12010       return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
12011     }
12012
12013     /**
12014      * Pads `string` on the right side if it's shorter than `length`. Padding
12015      * characters are truncated if they exceed `length`.
12016      *
12017      * @static
12018      * @memberOf _
12019      * @category String
12020      * @param {string} [string=''] The string to pad.
12021      * @param {number} [length=0] The padding length.
12022      * @param {string} [chars=' '] The string used as padding.
12023      * @returns {string} Returns the padded string.
12024      * @example
12025      *
12026      * _.padEnd('abc', 6);
12027      * // => 'abc   '
12028      *
12029      * _.padEnd('abc', 6, '_-');
12030      * // => 'abc_-_'
12031      *
12032      * _.padEnd('abc', 3);
12033      * // => 'abc'
12034      */
12035     function padEnd(string, length, chars) {
12036       string = toString(string);
12037       return string + createPadding(string, length, chars);
12038     }
12039
12040     /**
12041      * Pads `string` on the left side if it's shorter than `length`. Padding
12042      * characters are truncated if they exceed `length`.
12043      *
12044      * @static
12045      * @memberOf _
12046      * @category String
12047      * @param {string} [string=''] The string to pad.
12048      * @param {number} [length=0] The padding length.
12049      * @param {string} [chars=' '] The string used as padding.
12050      * @returns {string} Returns the padded string.
12051      * @example
12052      *
12053      * _.padStart('abc', 6);
12054      * // => '   abc'
12055      *
12056      * _.padStart('abc', 6, '_-');
12057      * // => '_-_abc'
12058      *
12059      * _.padStart('abc', 3);
12060      * // => 'abc'
12061      */
12062     function padStart(string, length, chars) {
12063       string = toString(string);
12064       return createPadding(string, length, chars) + string;
12065     }
12066
12067     /**
12068      * Converts `string` to an integer of the specified radix. If `radix` is
12069      * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
12070      * in which case a `radix` of `16` is used.
12071      *
12072      * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2)
12073      * of `parseInt`.
12074      *
12075      * @static
12076      * @memberOf _
12077      * @category String
12078      * @param {string} string The string to convert.
12079      * @param {number} [radix] The radix to interpret `value` by.
12080      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12081      * @returns {number} Returns the converted integer.
12082      * @example
12083      *
12084      * _.parseInt('08');
12085      * // => 8
12086      *
12087      * _.map(['6', '08', '10'], _.parseInt);
12088      * // => [6, 8, 10]
12089      */
12090     function parseInt(string, radix, guard) {
12091       // Chrome fails to trim leading <BOM> whitespace characters.
12092       // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
12093       if (guard || radix == null) {
12094         radix = 0;
12095       } else if (radix) {
12096         radix = +radix;
12097       }
12098       string = toString(string).replace(reTrim, '');
12099       return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
12100     }
12101
12102     /**
12103      * Repeats the given string `n` times.
12104      *
12105      * @static
12106      * @memberOf _
12107      * @category String
12108      * @param {string} [string=''] The string to repeat.
12109      * @param {number} [n=0] The number of times to repeat the string.
12110      * @returns {string} Returns the repeated string.
12111      * @example
12112      *
12113      * _.repeat('*', 3);
12114      * // => '***'
12115      *
12116      * _.repeat('abc', 2);
12117      * // => 'abcabc'
12118      *
12119      * _.repeat('abc', 0);
12120      * // => ''
12121      */
12122     function repeat(string, n) {
12123       string = toString(string);
12124       n = toInteger(n);
12125
12126       var result = '';
12127       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
12128         return result;
12129       }
12130       // Leverage the exponentiation by squaring algorithm for a faster repeat.
12131       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
12132       do {
12133         if (n % 2) {
12134           result += string;
12135         }
12136         n = nativeFloor(n / 2);
12137         string += string;
12138       } while (n);
12139
12140       return result;
12141     }
12142
12143     /**
12144      * Replaces matches for `pattern` in `string` with `replacement`.
12145      *
12146      * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
12147      *
12148      * @static
12149      * @memberOf _
12150      * @category String
12151      * @param {string} [string=''] The string to modify.
12152      * @param {RegExp|string} pattern The pattern to replace.
12153      * @param {Function|string} replacement The match replacement.
12154      * @returns {string} Returns the modified string.
12155      * @example
12156      *
12157      * _.replace('Hi Fred', 'Fred', 'Barney');
12158      * // => 'Hi Barney'
12159      */
12160     function replace() {
12161       var args = arguments,
12162           string = toString(args[0]);
12163
12164       return args.length < 3 ? string : string.replace(args[1], args[2]);
12165     }
12166
12167     /**
12168      * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
12169      *
12170      * @static
12171      * @memberOf _
12172      * @category String
12173      * @param {string} [string=''] The string to convert.
12174      * @returns {string} Returns the snake cased string.
12175      * @example
12176      *
12177      * _.snakeCase('Foo Bar');
12178      * // => 'foo_bar'
12179      *
12180      * _.snakeCase('fooBar');
12181      * // => 'foo_bar'
12182      *
12183      * _.snakeCase('--foo-bar');
12184      * // => 'foo_bar'
12185      */
12186     var snakeCase = createCompounder(function(result, word, index) {
12187       return result + (index ? '_' : '') + word.toLowerCase();
12188     });
12189
12190     /**
12191      * Splits `string` by `separator`.
12192      *
12193      * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
12194      *
12195      * @static
12196      * @memberOf _
12197      * @category String
12198      * @param {string} [string=''] The string to split.
12199      * @param {RegExp|string} separator The separator pattern to split by.
12200      * @param {number} [limit] The length to truncate results to.
12201      * @returns {Array} Returns the new array of string segments.
12202      * @example
12203      *
12204      * _.split('a-b-c', '-', 2);
12205      * // => ['a', 'b']
12206      */
12207     function split(string, separator, limit) {
12208       return toString(string).split(separator, limit);
12209     }
12210
12211     /**
12212      * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
12213      *
12214      * @static
12215      * @memberOf _
12216      * @category String
12217      * @param {string} [string=''] The string to convert.
12218      * @returns {string} Returns the start cased string.
12219      * @example
12220      *
12221      * _.startCase('--foo-bar');
12222      * // => 'Foo Bar'
12223      *
12224      * _.startCase('fooBar');
12225      * // => 'Foo Bar'
12226      *
12227      * _.startCase('__foo_bar__');
12228      * // => 'Foo Bar'
12229      */
12230     var startCase = createCompounder(function(result, word, index) {
12231       return result + (index ? ' ' : '') + capitalize(word);
12232     });
12233
12234     /**
12235      * Checks if `string` starts with the given target string.
12236      *
12237      * @static
12238      * @memberOf _
12239      * @category String
12240      * @param {string} [string=''] The string to search.
12241      * @param {string} [target] The string to search for.
12242      * @param {number} [position=0] The position to search from.
12243      * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
12244      * @example
12245      *
12246      * _.startsWith('abc', 'a');
12247      * // => true
12248      *
12249      * _.startsWith('abc', 'b');
12250      * // => false
12251      *
12252      * _.startsWith('abc', 'b', 1);
12253      * // => true
12254      */
12255     function startsWith(string, target, position) {
12256       string = toString(string);
12257       position = baseClamp(toInteger(position), 0, string.length);
12258       return string.lastIndexOf(target, position) == position;
12259     }
12260
12261     /**
12262      * Creates a compiled template function that can interpolate data properties
12263      * in "interpolate" delimiters, HTML-escape interpolated data properties in
12264      * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
12265      * properties may be accessed as free variables in the template. If a setting
12266      * object is provided it takes precedence over `_.templateSettings` values.
12267      *
12268      * **Note:** In the development build `_.template` utilizes
12269      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
12270      * for easier debugging.
12271      *
12272      * For more information on precompiling templates see
12273      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
12274      *
12275      * For more information on Chrome extension sandboxes see
12276      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
12277      *
12278      * @static
12279      * @memberOf _
12280      * @category String
12281      * @param {string} [string=''] The template string.
12282      * @param {Object} [options] The options object.
12283      * @param {RegExp} [options.escape] The HTML "escape" delimiter.
12284      * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
12285      * @param {Object} [options.imports] An object to import into the template as free variables.
12286      * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
12287      * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
12288      * @param {string} [options.variable] The data object variable name.
12289      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12290      * @returns {Function} Returns the compiled template function.
12291      * @example
12292      *
12293      * // using the "interpolate" delimiter to create a compiled template
12294      * var compiled = _.template('hello <%= user %>!');
12295      * compiled({ 'user': 'fred' });
12296      * // => 'hello fred!'
12297      *
12298      * // using the HTML "escape" delimiter to escape data property values
12299      * var compiled = _.template('<b><%- value %></b>');
12300      * compiled({ 'value': '<script>' });
12301      * // => '<b>&lt;script&gt;</b>'
12302      *
12303      * // using the "evaluate" delimiter to execute JavaScript and generate HTML
12304      * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
12305      * compiled({ 'users': ['fred', 'barney'] });
12306      * // => '<li>fred</li><li>barney</li>'
12307      *
12308      * // using the internal `print` function in "evaluate" delimiters
12309      * var compiled = _.template('<% print("hello " + user); %>!');
12310      * compiled({ 'user': 'barney' });
12311      * // => 'hello barney!'
12312      *
12313      * // using the ES delimiter as an alternative to the default "interpolate" delimiter
12314      * var compiled = _.template('hello ${ user }!');
12315      * compiled({ 'user': 'pebbles' });
12316      * // => 'hello pebbles!'
12317      *
12318      * // using custom template delimiters
12319      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
12320      * var compiled = _.template('hello {{ user }}!');
12321      * compiled({ 'user': 'mustache' });
12322      * // => 'hello mustache!'
12323      *
12324      * // using backslashes to treat delimiters as plain text
12325      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
12326      * compiled({ 'value': 'ignored' });
12327      * // => '<%- value %>'
12328      *
12329      * // using the `imports` option to import `jQuery` as `jq`
12330      * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
12331      * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
12332      * compiled({ 'users': ['fred', 'barney'] });
12333      * // => '<li>fred</li><li>barney</li>'
12334      *
12335      * // using the `sourceURL` option to specify a custom sourceURL for the template
12336      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
12337      * compiled(data);
12338      * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
12339      *
12340      * // using the `variable` option to ensure a with-statement isn't used in the compiled template
12341      * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
12342      * compiled.source;
12343      * // => function(data) {
12344      * //   var __t, __p = '';
12345      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
12346      * //   return __p;
12347      * // }
12348      *
12349      * // using the `source` property to inline compiled templates for meaningful
12350      * // line numbers in error messages and a stack trace
12351      * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
12352      *   var JST = {\
12353      *     "main": ' + _.template(mainText).source + '\
12354      *   };\
12355      * ');
12356      */
12357     function template(string, options, guard) {
12358       // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
12359       // and Laura Doktorova's doT.js (https://github.com/olado/doT).
12360       var settings = lodash.templateSettings;
12361
12362       if (guard && isIterateeCall(string, options, guard)) {
12363         options = undefined;
12364       }
12365       string = toString(string);
12366       options = assignInWith({}, options, settings, assignInDefaults);
12367
12368       var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
12369           importsKeys = keys(imports),
12370           importsValues = baseValues(imports, importsKeys);
12371
12372       var isEscaping,
12373           isEvaluating,
12374           index = 0,
12375           interpolate = options.interpolate || reNoMatch,
12376           source = "__p += '";
12377
12378       // Compile the regexp to match each delimiter.
12379       var reDelimiters = RegExp(
12380         (options.escape || reNoMatch).source + '|' +
12381         interpolate.source + '|' +
12382         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
12383         (options.evaluate || reNoMatch).source + '|$'
12384       , 'g');
12385
12386       // Use a sourceURL for easier debugging.
12387       var sourceURL = '//# sourceURL=' +
12388         ('sourceURL' in options
12389           ? options.sourceURL
12390           : ('lodash.templateSources[' + (++templateCounter) + ']')
12391         ) + '\n';
12392
12393       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
12394         interpolateValue || (interpolateValue = esTemplateValue);
12395
12396         // Escape characters that can't be included in string literals.
12397         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
12398
12399         // Replace delimiters with snippets.
12400         if (escapeValue) {
12401           isEscaping = true;
12402           source += "' +\n__e(" + escapeValue + ") +\n'";
12403         }
12404         if (evaluateValue) {
12405           isEvaluating = true;
12406           source += "';\n" + evaluateValue + ";\n__p += '";
12407         }
12408         if (interpolateValue) {
12409           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
12410         }
12411         index = offset + match.length;
12412
12413         // The JS engine embedded in Adobe products needs `match` returned in
12414         // order to produce the correct `offset` value.
12415         return match;
12416       });
12417
12418       source += "';\n";
12419
12420       // If `variable` is not specified wrap a with-statement around the generated
12421       // code to add the data object to the top of the scope chain.
12422       var variable = options.variable;
12423       if (!variable) {
12424         source = 'with (obj) {\n' + source + '\n}\n';
12425       }
12426       // Cleanup code by stripping empty strings.
12427       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
12428         .replace(reEmptyStringMiddle, '$1')
12429         .replace(reEmptyStringTrailing, '$1;');
12430
12431       // Frame code as the function body.
12432       source = 'function(' + (variable || 'obj') + ') {\n' +
12433         (variable
12434           ? ''
12435           : 'obj || (obj = {});\n'
12436         ) +
12437         "var __t, __p = ''" +
12438         (isEscaping
12439            ? ', __e = _.escape'
12440            : ''
12441         ) +
12442         (isEvaluating
12443           ? ', __j = Array.prototype.join;\n' +
12444             "function print() { __p += __j.call(arguments, '') }\n"
12445           : ';\n'
12446         ) +
12447         source +
12448         'return __p\n}';
12449
12450       var result = attempt(function() {
12451         return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);
12452       });
12453
12454       // Provide the compiled function's source by its `toString` method or
12455       // the `source` property as a convenience for inlining compiled templates.
12456       result.source = source;
12457       if (isError(result)) {
12458         throw result;
12459       }
12460       return result;
12461     }
12462
12463     /**
12464      * Converts `string`, as a whole, to lower case.
12465      *
12466      * @static
12467      * @memberOf _
12468      * @category String
12469      * @param {string} [string=''] The string to convert.
12470      * @returns {string} Returns the lower cased string.
12471      * @example
12472      *
12473      * _.toLower('--Foo-Bar');
12474      * // => '--foo-bar'
12475      *
12476      * _.toLower('fooBar');
12477      * // => 'foobar'
12478      *
12479      * _.toLower('__FOO_BAR__');
12480      * // => '__foo_bar__'
12481      */
12482     function toLower(value) {
12483       return toString(value).toLowerCase();
12484     }
12485
12486     /**
12487      * Converts `string`, as a whole, to upper case.
12488      *
12489      * @static
12490      * @memberOf _
12491      * @category String
12492      * @param {string} [string=''] The string to convert.
12493      * @returns {string} Returns the upper cased string.
12494      * @example
12495      *
12496      * _.toUpper('--foo-bar');
12497      * // => '--FOO-BAR'
12498      *
12499      * _.toUpper('fooBar');
12500      * // => 'FOOBAR'
12501      *
12502      * _.toUpper('__foo_bar__');
12503      * // => '__FOO_BAR__'
12504      */
12505     function toUpper(value) {
12506       return toString(value).toUpperCase();
12507     }
12508
12509     /**
12510      * Removes leading and trailing whitespace or specified characters from `string`.
12511      *
12512      * @static
12513      * @memberOf _
12514      * @category String
12515      * @param {string} [string=''] The string to trim.
12516      * @param {string} [chars=whitespace] The characters to trim.
12517      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12518      * @returns {string} Returns the trimmed string.
12519      * @example
12520      *
12521      * _.trim('  abc  ');
12522      * // => 'abc'
12523      *
12524      * _.trim('-_-abc-_-', '_-');
12525      * // => 'abc'
12526      *
12527      * _.map(['  foo  ', '  bar  '], _.trim);
12528      * // => ['foo', 'bar']
12529      */
12530     function trim(string, chars, guard) {
12531       string = toString(string);
12532       if (!string) {
12533         return string;
12534       }
12535       if (guard || chars === undefined) {
12536         return string.replace(reTrim, '');
12537       }
12538       chars = (chars + '');
12539       if (!chars) {
12540         return string;
12541       }
12542       var strSymbols = stringToArray(string),
12543           chrSymbols = stringToArray(chars);
12544
12545       return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join('');
12546     }
12547
12548     /**
12549      * Removes trailing whitespace or specified characters from `string`.
12550      *
12551      * @static
12552      * @memberOf _
12553      * @category String
12554      * @param {string} [string=''] The string to trim.
12555      * @param {string} [chars=whitespace] The characters to trim.
12556      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12557      * @returns {string} Returns the trimmed string.
12558      * @example
12559      *
12560      * _.trimEnd('  abc  ');
12561      * // => '  abc'
12562      *
12563      * _.trimEnd('-_-abc-_-', '_-');
12564      * // => '-_-abc'
12565      */
12566     function trimEnd(string, chars, guard) {
12567       string = toString(string);
12568       if (!string) {
12569         return string;
12570       }
12571       if (guard || chars === undefined) {
12572         return string.replace(reTrimEnd, '');
12573       }
12574       chars = (chars + '');
12575       if (!chars) {
12576         return string;
12577       }
12578       var strSymbols = stringToArray(string);
12579       return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join('');
12580     }
12581
12582     /**
12583      * Removes leading whitespace or specified characters from `string`.
12584      *
12585      * @static
12586      * @memberOf _
12587      * @category String
12588      * @param {string} [string=''] The string to trim.
12589      * @param {string} [chars=whitespace] The characters to trim.
12590      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12591      * @returns {string} Returns the trimmed string.
12592      * @example
12593      *
12594      * _.trimStart('  abc  ');
12595      * // => 'abc  '
12596      *
12597      * _.trimStart('-_-abc-_-', '_-');
12598      * // => 'abc-_-'
12599      */
12600     function trimStart(string, chars, guard) {
12601       string = toString(string);
12602       if (!string) {
12603         return string;
12604       }
12605       if (guard || chars === undefined) {
12606         return string.replace(reTrimStart, '');
12607       }
12608       chars = (chars + '');
12609       if (!chars) {
12610         return string;
12611       }
12612       var strSymbols = stringToArray(string);
12613       return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).join('');
12614     }
12615
12616     /**
12617      * Truncates `string` if it's longer than the given maximum string length.
12618      * The last characters of the truncated string are replaced with the omission
12619      * string which defaults to "...".
12620      *
12621      * @static
12622      * @memberOf _
12623      * @category String
12624      * @param {string} [string=''] The string to truncate.
12625      * @param {Object} [options] The options object.
12626      * @param {number} [options.length=30] The maximum string length.
12627      * @param {string} [options.omission='...'] The string to indicate text is omitted.
12628      * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
12629      * @returns {string} Returns the truncated string.
12630      * @example
12631      *
12632      * _.truncate('hi-diddly-ho there, neighborino');
12633      * // => 'hi-diddly-ho there, neighbo...'
12634      *
12635      * _.truncate('hi-diddly-ho there, neighborino', {
12636      *   'length': 24,
12637      *   'separator': ' '
12638      * });
12639      * // => 'hi-diddly-ho there,...'
12640      *
12641      * _.truncate('hi-diddly-ho there, neighborino', {
12642      *   'length': 24,
12643      *   'separator': /,? +/
12644      * });
12645      * // => 'hi-diddly-ho there...'
12646      *
12647      * _.truncate('hi-diddly-ho there, neighborino', {
12648      *   'omission': ' [...]'
12649      * });
12650      * // => 'hi-diddly-ho there, neig [...]'
12651      */
12652     function truncate(string, options) {
12653       var length = DEFAULT_TRUNC_LENGTH,
12654           omission = DEFAULT_TRUNC_OMISSION;
12655
12656       if (isObject(options)) {
12657         var separator = 'separator' in options ? options.separator : separator;
12658         length = 'length' in options ? toInteger(options.length) : length;
12659         omission = 'omission' in options ? toString(options.omission) : omission;
12660       }
12661       string = toString(string);
12662
12663       var strLength = string.length;
12664       if (reHasComplexSymbol.test(string)) {
12665         var strSymbols = stringToArray(string);
12666         strLength = strSymbols.length;
12667       }
12668       if (length >= strLength) {
12669         return string;
12670       }
12671       var end = length - stringSize(omission);
12672       if (end < 1) {
12673         return omission;
12674       }
12675       var result = strSymbols
12676         ? strSymbols.slice(0, end).join('')
12677         : string.slice(0, end);
12678
12679       if (separator === undefined) {
12680         return result + omission;
12681       }
12682       if (strSymbols) {
12683         end += (result.length - end);
12684       }
12685       if (isRegExp(separator)) {
12686         if (string.slice(end).search(separator)) {
12687           var match,
12688               substring = result;
12689
12690           if (!separator.global) {
12691             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
12692           }
12693           separator.lastIndex = 0;
12694           while ((match = separator.exec(substring))) {
12695             var newEnd = match.index;
12696           }
12697           result = result.slice(0, newEnd === undefined ? end : newEnd);
12698         }
12699       } else if (string.indexOf(separator, end) != end) {
12700         var index = result.lastIndexOf(separator);
12701         if (index > -1) {
12702           result = result.slice(0, index);
12703         }
12704       }
12705       return result + omission;
12706     }
12707
12708     /**
12709      * The inverse of `_.escape`; this method converts the HTML entities
12710      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their
12711      * corresponding characters.
12712      *
12713      * **Note:** No other HTML entities are unescaped. To unescape additional HTML
12714      * entities use a third-party library like [_he_](https://mths.be/he).
12715      *
12716      * @static
12717      * @memberOf _
12718      * @category String
12719      * @param {string} [string=''] The string to unescape.
12720      * @returns {string} Returns the unescaped string.
12721      * @example
12722      *
12723      * _.unescape('fred, barney, &amp; pebbles');
12724      * // => 'fred, barney, & pebbles'
12725      */
12726     function unescape(string) {
12727       string = toString(string);
12728       return (string && reHasEscapedHtml.test(string))
12729         ? string.replace(reEscapedHtml, unescapeHtmlChar)
12730         : string;
12731     }
12732
12733     /**
12734      * Converts `string`, as space separated words, to upper case.
12735      *
12736      * @static
12737      * @memberOf _
12738      * @category String
12739      * @param {string} [string=''] The string to convert.
12740      * @returns {string} Returns the upper cased string.
12741      * @example
12742      *
12743      * _.upperCase('--foo-bar');
12744      * // => 'FOO BAR'
12745      *
12746      * _.upperCase('fooBar');
12747      * // => 'FOO BAR'
12748      *
12749      * _.upperCase('__foo_bar__');
12750      * // => 'FOO BAR'
12751      */
12752     var upperCase = createCompounder(function(result, word, index) {
12753       return result + (index ? ' ' : '') + word.toUpperCase();
12754     });
12755
12756     /**
12757      * Splits `string` into an array of its words.
12758      *
12759      * @static
12760      * @memberOf _
12761      * @category String
12762      * @param {string} [string=''] The string to inspect.
12763      * @param {RegExp|string} [pattern] The pattern to match words.
12764      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12765      * @returns {Array} Returns the words of `string`.
12766      * @example
12767      *
12768      * _.words('fred, barney, & pebbles');
12769      * // => ['fred', 'barney', 'pebbles']
12770      *
12771      * _.words('fred, barney, & pebbles', /[^, ]+/g);
12772      * // => ['fred', 'barney', '&', 'pebbles']
12773      */
12774     function words(string, pattern, guard) {
12775       string = toString(string);
12776       pattern = guard ? undefined : pattern;
12777
12778       if (pattern === undefined) {
12779         pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
12780       }
12781       return string.match(pattern) || [];
12782     }
12783
12784     /*------------------------------------------------------------------------*/
12785
12786     /**
12787      * Attempts to invoke `func`, returning either the result or the caught error
12788      * object. Any additional arguments are provided to `func` when it's invoked.
12789      *
12790      * @static
12791      * @memberOf _
12792      * @category Util
12793      * @param {Function} func The function to attempt.
12794      * @returns {*} Returns the `func` result or error object.
12795      * @example
12796      *
12797      * // avoid throwing errors for invalid selectors
12798      * var elements = _.attempt(function(selector) {
12799      *   return document.querySelectorAll(selector);
12800      * }, '>_>');
12801      *
12802      * if (_.isError(elements)) {
12803      *   elements = [];
12804      * }
12805      */
12806     var attempt = rest(function(func, args) {
12807       try {
12808         return apply(func, undefined, args);
12809       } catch (e) {
12810         return isError(e) ? e : new Error(e);
12811       }
12812     });
12813
12814     /**
12815      * Binds methods of an object to the object itself, overwriting the existing
12816      * method.
12817      *
12818      * **Note:** This method doesn't set the "length" property of bound functions.
12819      *
12820      * @static
12821      * @memberOf _
12822      * @category Util
12823      * @param {Object} object The object to bind and assign the bound methods to.
12824      * @param {...(string|string[])} methodNames The object method names to bind,
12825      *  specified individually or in arrays.
12826      * @returns {Object} Returns `object`.
12827      * @example
12828      *
12829      * var view = {
12830      *   'label': 'docs',
12831      *   'onClick': function() {
12832      *     console.log('clicked ' + this.label);
12833      *   }
12834      * };
12835      *
12836      * _.bindAll(view, 'onClick');
12837      * jQuery(element).on('click', view.onClick);
12838      * // => logs 'clicked docs' when clicked
12839      */
12840     var bindAll = rest(function(object, methodNames) {
12841       arrayEach(baseFlatten(methodNames), function(key) {
12842         object[key] = bind(object[key], object);
12843       });
12844       return object;
12845     });
12846
12847     /**
12848      * Creates a function that iterates over `pairs` invoking the corresponding
12849      * function of the first predicate to return truthy. The predicate-function
12850      * pairs are invoked with the `this` binding and arguments of the created
12851      * function.
12852      *
12853      * @static
12854      * @memberOf _
12855      * @category Util
12856      * @param {Array} pairs The predicate-function pairs.
12857      * @returns {Function} Returns the new function.
12858      * @example
12859      *
12860      * var func = _.cond([
12861      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
12862      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
12863      *   [_.constant(true),                _.constant('no match')]
12864      * ]);
12865      *
12866      * func({ 'a': 1, 'b': 2 });
12867      * // => 'matches A'
12868      *
12869      * func({ 'a': 0, 'b': 1 });
12870      * // => 'matches B'
12871      *
12872      * func({ 'a': '1', 'b': '2' });
12873      * // => 'no match'
12874      */
12875     function cond(pairs) {
12876       var length = pairs ? pairs.length : 0,
12877           toIteratee = getIteratee();
12878
12879       pairs = !length ? [] : arrayMap(pairs, function(pair) {
12880         if (typeof pair[1] != 'function') {
12881           throw new TypeError(FUNC_ERROR_TEXT);
12882         }
12883         return [toIteratee(pair[0]), pair[1]];
12884       });
12885
12886       return rest(function(args) {
12887         var index = -1;
12888         while (++index < length) {
12889           var pair = pairs[index];
12890           if (apply(pair[0], this, args)) {
12891             return apply(pair[1], this, args);
12892           }
12893         }
12894       });
12895     }
12896
12897     /**
12898      * Creates a function that invokes the predicate properties of `source` with
12899      * the corresponding property values of a given object, returning `true` if
12900      * all predicates return truthy, else `false`.
12901      *
12902      * @static
12903      * @memberOf _
12904      * @category Util
12905      * @param {Object} source The object of property predicates to conform to.
12906      * @returns {Function} Returns the new function.
12907      * @example
12908      *
12909      * var users = [
12910      *   { 'user': 'barney', 'age': 36 },
12911      *   { 'user': 'fred',   'age': 40 }
12912      * ];
12913      *
12914      * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
12915      * // => [{ 'user': 'fred', 'age': 40 }]
12916      */
12917     function conforms(source) {
12918       return baseConforms(baseClone(source, true));
12919     }
12920
12921     /**
12922      * Creates a function that returns `value`.
12923      *
12924      * @static
12925      * @memberOf _
12926      * @category Util
12927      * @param {*} value The value to return from the new function.
12928      * @returns {Function} Returns the new function.
12929      * @example
12930      *
12931      * var object = { 'user': 'fred' };
12932      * var getter = _.constant(object);
12933      *
12934      * getter() === object;
12935      * // => true
12936      */
12937     function constant(value) {
12938       return function() {
12939         return value;
12940       };
12941     }
12942
12943     /**
12944      * Creates a function that returns the result of invoking the provided
12945      * functions with the `this` binding of the created function, where each
12946      * successive invocation is supplied the return value of the previous.
12947      *
12948      * @static
12949      * @memberOf _
12950      * @category Util
12951      * @param {...(Function|Function[])} [funcs] Functions to invoke.
12952      * @returns {Function} Returns the new function.
12953      * @example
12954      *
12955      * function square(n) {
12956      *   return n * n;
12957      * }
12958      *
12959      * var addSquare = _.flow(_.add, square);
12960      * addSquare(1, 2);
12961      * // => 9
12962      */
12963     var flow = createFlow();
12964
12965     /**
12966      * This method is like `_.flow` except that it creates a function that
12967      * invokes the provided functions from right to left.
12968      *
12969      * @static
12970      * @memberOf _
12971      * @category Util
12972      * @param {...(Function|Function[])} [funcs] Functions to invoke.
12973      * @returns {Function} Returns the new function.
12974      * @example
12975      *
12976      * function square(n) {
12977      *   return n * n;
12978      * }
12979      *
12980      * var addSquare = _.flowRight(square, _.add);
12981      * addSquare(1, 2);
12982      * // => 9
12983      */
12984     var flowRight = createFlow(true);
12985
12986     /**
12987      * This method returns the first argument provided to it.
12988      *
12989      * @static
12990      * @memberOf _
12991      * @category Util
12992      * @param {*} value Any value.
12993      * @returns {*} Returns `value`.
12994      * @example
12995      *
12996      * var object = { 'user': 'fred' };
12997      *
12998      * _.identity(object) === object;
12999      * // => true
13000      */
13001     function identity(value) {
13002       return value;
13003     }
13004
13005     /**
13006      * Creates a function that invokes `func` with the arguments of the created
13007      * function. If `func` is a property name the created callback returns the
13008      * property value for a given element. If `func` is an object the created
13009      * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`.
13010      *
13011      * @static
13012      * @memberOf _
13013      * @category Util
13014      * @param {*} [func=_.identity] The value to convert to a callback.
13015      * @returns {Function} Returns the callback.
13016      * @example
13017      *
13018      * var users = [
13019      *   { 'user': 'barney', 'age': 36 },
13020      *   { 'user': 'fred',   'age': 40 }
13021      * ];
13022      *
13023      * // create custom iteratee shorthands
13024      * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
13025      *   var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
13026      *   return !p ? callback(func) : function(object) {
13027      *     return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
13028      *   };
13029      * });
13030      *
13031      * _.filter(users, 'age > 36');
13032      * // => [{ 'user': 'fred', 'age': 40 }]
13033      */
13034     function iteratee(func) {
13035       return (isObjectLike(func) && !isArray(func))
13036         ? matches(func)
13037         : baseIteratee(func);
13038     }
13039
13040     /**
13041      * Creates a function that performs a deep partial comparison between a given
13042      * object and `source`, returning `true` if the given object has equivalent
13043      * property values, else `false`.
13044      *
13045      * **Note:** This method supports comparing the same values as `_.isEqual`.
13046      *
13047      * @static
13048      * @memberOf _
13049      * @category Util
13050      * @param {Object} source The object of property values to match.
13051      * @returns {Function} Returns the new function.
13052      * @example
13053      *
13054      * var users = [
13055      *   { 'user': 'barney', 'age': 36, 'active': true },
13056      *   { 'user': 'fred',   'age': 40, 'active': false }
13057      * ];
13058      *
13059      * _.filter(users, _.matches({ 'age': 40, 'active': false }));
13060      * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
13061      */
13062     function matches(source) {
13063       return baseMatches(baseClone(source, true));
13064     }
13065
13066     /**
13067      * Creates a function that performs a deep partial comparison between the
13068      * value at `path` of a given object to `srcValue`, returning `true` if the
13069      * object value is equivalent, else `false`.
13070      *
13071      * **Note:** This method supports comparing the same values as `_.isEqual`.
13072      *
13073      * @static
13074      * @memberOf _
13075      * @category Util
13076      * @param {Array|string} path The path of the property to get.
13077      * @param {*} srcValue The value to match.
13078      * @returns {Function} Returns the new function.
13079      * @example
13080      *
13081      * var users = [
13082      *   { 'user': 'barney' },
13083      *   { 'user': 'fred' }
13084      * ];
13085      *
13086      * _.find(users, _.matchesProperty('user', 'fred'));
13087      * // => { 'user': 'fred' }
13088      */
13089     function matchesProperty(path, srcValue) {
13090       return baseMatchesProperty(path, baseClone(srcValue, true));
13091     }
13092
13093     /**
13094      * Creates a function that invokes the method at `path` of a given object.
13095      * Any additional arguments are provided to the invoked method.
13096      *
13097      * @static
13098      * @memberOf _
13099      * @category Util
13100      * @param {Array|string} path The path of the method to invoke.
13101      * @param {...*} [args] The arguments to invoke the method with.
13102      * @returns {Function} Returns the new function.
13103      * @example
13104      *
13105      * var objects = [
13106      *   { 'a': { 'b': { 'c': _.constant(2) } } },
13107      *   { 'a': { 'b': { 'c': _.constant(1) } } }
13108      * ];
13109      *
13110      * _.map(objects, _.method('a.b.c'));
13111      * // => [2, 1]
13112      *
13113      * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
13114      * // => [1, 2]
13115      */
13116     var method = rest(function(path, args) {
13117       return function(object) {
13118         return baseInvoke(object, path, args);
13119       };
13120     });
13121
13122     /**
13123      * The opposite of `_.method`; this method creates a function that invokes
13124      * the method at a given path of `object`. Any additional arguments are
13125      * provided to the invoked method.
13126      *
13127      * @static
13128      * @memberOf _
13129      * @category Util
13130      * @param {Object} object The object to query.
13131      * @param {...*} [args] The arguments to invoke the method with.
13132      * @returns {Function} Returns the new function.
13133      * @example
13134      *
13135      * var array = _.times(3, _.constant),
13136      *     object = { 'a': array, 'b': array, 'c': array };
13137      *
13138      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
13139      * // => [2, 0]
13140      *
13141      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
13142      * // => [2, 0]
13143      */
13144     var methodOf = rest(function(object, args) {
13145       return function(path) {
13146         return baseInvoke(object, path, args);
13147       };
13148     });
13149
13150     /**
13151      * Adds all own enumerable function properties of a source object to the
13152      * destination object. If `object` is a function then methods are added to
13153      * its prototype as well.
13154      *
13155      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
13156      * avoid conflicts caused by modifying the original.
13157      *
13158      * @static
13159      * @memberOf _
13160      * @category Util
13161      * @param {Function|Object} [object=lodash] The destination object.
13162      * @param {Object} source The object of functions to add.
13163      * @param {Object} [options] The options object.
13164      * @param {boolean} [options.chain=true] Specify whether the functions added
13165      *  are chainable.
13166      * @returns {Function|Object} Returns `object`.
13167      * @example
13168      *
13169      * function vowels(string) {
13170      *   return _.filter(string, function(v) {
13171      *     return /[aeiou]/i.test(v);
13172      *   });
13173      * }
13174      *
13175      * _.mixin({ 'vowels': vowels });
13176      * _.vowels('fred');
13177      * // => ['e']
13178      *
13179      * _('fred').vowels().value();
13180      * // => ['e']
13181      *
13182      * _.mixin({ 'vowels': vowels }, { 'chain': false });
13183      * _('fred').vowels();
13184      * // => ['e']
13185      */
13186     function mixin(object, source, options) {
13187       var props = keys(source),
13188           methodNames = baseFunctions(source, props);
13189
13190       if (options == null &&
13191           !(isObject(source) && (methodNames.length || !props.length))) {
13192         options = source;
13193         source = object;
13194         object = this;
13195         methodNames = baseFunctions(source, keys(source));
13196       }
13197       var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
13198           isFunc = isFunction(object);
13199
13200       arrayEach(methodNames, function(methodName) {
13201         var func = source[methodName];
13202         object[methodName] = func;
13203         if (isFunc) {
13204           object.prototype[methodName] = function() {
13205             var chainAll = this.__chain__;
13206             if (chain || chainAll) {
13207               var result = object(this.__wrapped__),
13208                   actions = result.__actions__ = copyArray(this.__actions__);
13209
13210               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
13211               result.__chain__ = chainAll;
13212               return result;
13213             }
13214             return func.apply(object, arrayPush([this.value()], arguments));
13215           };
13216         }
13217       });
13218
13219       return object;
13220     }
13221
13222     /**
13223      * Reverts the `_` variable to its previous value and returns a reference to
13224      * the `lodash` function.
13225      *
13226      * @static
13227      * @memberOf _
13228      * @category Util
13229      * @returns {Function} Returns the `lodash` function.
13230      * @example
13231      *
13232      * var lodash = _.noConflict();
13233      */
13234     function noConflict() {
13235       if (root._ === this) {
13236         root._ = oldDash;
13237       }
13238       return this;
13239     }
13240
13241     /**
13242      * A no-operation function that returns `undefined` regardless of the
13243      * arguments it receives.
13244      *
13245      * @static
13246      * @memberOf _
13247      * @category Util
13248      * @example
13249      *
13250      * var object = { 'user': 'fred' };
13251      *
13252      * _.noop(object) === undefined;
13253      * // => true
13254      */
13255     function noop() {
13256       // No operation performed.
13257     }
13258
13259     /**
13260      * Creates a function that returns its nth argument.
13261      *
13262      * @static
13263      * @memberOf _
13264      * @category Util
13265      * @param {number} [n=0] The index of the argument to return.
13266      * @returns {Function} Returns the new function.
13267      * @example
13268      *
13269      * var func = _.nthArg(1);
13270      *
13271      * func('a', 'b', 'c');
13272      * // => 'b'
13273      */
13274     function nthArg(n) {
13275       n = toInteger(n);
13276       return function() {
13277         return arguments[n];
13278       };
13279     }
13280
13281     /**
13282      * Creates a function that invokes `iteratees` with the arguments provided
13283      * to the created function and returns their results.
13284      *
13285      * @static
13286      * @memberOf _
13287      * @category Util
13288      * @param {...(Function|Function[])} iteratees The iteratees to invoke.
13289      * @returns {Function} Returns the new function.
13290      * @example
13291      *
13292      * var func = _.over(Math.max, Math.min);
13293      *
13294      * func(1, 2, 3, 4);
13295      * // => [4, 1]
13296      */
13297     var over = createOver(arrayMap);
13298
13299     /**
13300      * Creates a function that checks if **all** of the `predicates` return
13301      * truthy when invoked with the arguments provided to the created function.
13302      *
13303      * @static
13304      * @memberOf _
13305      * @category Util
13306      * @param {...(Function|Function[])} predicates The predicates to check.
13307      * @returns {Function} Returns the new function.
13308      * @example
13309      *
13310      * var func = _.overEvery(Boolean, isFinite);
13311      *
13312      * func('1');
13313      * // => true
13314      *
13315      * func(null);
13316      * // => false
13317      *
13318      * func(NaN);
13319      * // => false
13320      */
13321     var overEvery = createOver(arrayEvery);
13322
13323     /**
13324      * Creates a function that checks if **any** of the `predicates` return
13325      * truthy when invoked with the arguments provided to the created function.
13326      *
13327      * @static
13328      * @memberOf _
13329      * @category Util
13330      * @param {...(Function|Function[])} predicates The predicates to check.
13331      * @returns {Function} Returns the new function.
13332      * @example
13333      *
13334      * var func = _.overSome(Boolean, isFinite);
13335      *
13336      * func('1');
13337      * // => true
13338      *
13339      * func(null);
13340      * // => true
13341      *
13342      * func(NaN);
13343      * // => false
13344      */
13345     var overSome = createOver(arraySome);
13346
13347     /**
13348      * Creates a function that returns the value at `path` of a given object.
13349      *
13350      * @static
13351      * @memberOf _
13352      * @category Util
13353      * @param {Array|string} path The path of the property to get.
13354      * @returns {Function} Returns the new function.
13355      * @example
13356      *
13357      * var objects = [
13358      *   { 'a': { 'b': { 'c': 2 } } },
13359      *   { 'a': { 'b': { 'c': 1 } } }
13360      * ];
13361      *
13362      * _.map(objects, _.property('a.b.c'));
13363      * // => [2, 1]
13364      *
13365      * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
13366      * // => [1, 2]
13367      */
13368     function property(path) {
13369       return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
13370     }
13371
13372     /**
13373      * The opposite of `_.property`; this method creates a function that returns
13374      * the value at a given path of `object`.
13375      *
13376      * @static
13377      * @memberOf _
13378      * @category Util
13379      * @param {Object} object The object to query.
13380      * @returns {Function} Returns the new function.
13381      * @example
13382      *
13383      * var array = [0, 1, 2],
13384      *     object = { 'a': array, 'b': array, 'c': array };
13385      *
13386      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
13387      * // => [2, 0]
13388      *
13389      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
13390      * // => [2, 0]
13391      */
13392     function propertyOf(object) {
13393       return function(path) {
13394         return object == null ? undefined : baseGet(object, path);
13395       };
13396     }
13397
13398     /**
13399      * Creates an array of numbers (positive and/or negative) progressing from
13400      * `start` up to, but not including, `end`. A step of `-1` is used if a negative
13401      * `start` is specified without an `end` or `step`. If `end` is not specified
13402      * it's set to `start` with `start` then set to `0`.
13403      *
13404      * **Note:** JavaScript follows the IEEE-754 standard for resolving
13405      * floating-point values which can produce unexpected results.
13406      *
13407      * @static
13408      * @memberOf _
13409      * @category Util
13410      * @param {number} [start=0] The start of the range.
13411      * @param {number} end The end of the range.
13412      * @param {number} [step=1] The value to increment or decrement by.
13413      * @returns {Array} Returns the new array of numbers.
13414      * @example
13415      *
13416      * _.range(4);
13417      * // => [0, 1, 2, 3]
13418      *
13419      * _.range(-4);
13420      * // => [0, -1, -2, -3]
13421      *
13422      * _.range(1, 5);
13423      * // => [1, 2, 3, 4]
13424      *
13425      * _.range(0, 20, 5);
13426      * // => [0, 5, 10, 15]
13427      *
13428      * _.range(0, -4, -1);
13429      * // => [0, -1, -2, -3]
13430      *
13431      * _.range(1, 4, 0);
13432      * // => [1, 1, 1]
13433      *
13434      * _.range(0);
13435      * // => []
13436      */
13437     var range = createRange();
13438
13439     /**
13440      * This method is like `_.range` except that it populates values in
13441      * descending order.
13442      *
13443      * @static
13444      * @memberOf _
13445      * @category Util
13446      * @param {number} [start=0] The start of the range.
13447      * @param {number} end The end of the range.
13448      * @param {number} [step=1] The value to increment or decrement by.
13449      * @returns {Array} Returns the new array of numbers.
13450      * @example
13451      *
13452      * _.rangeRight(4);
13453      * // => [3, 2, 1, 0]
13454      *
13455      * _.rangeRight(-4);
13456      * // => [-3, -2, -1, 0]
13457      *
13458      * _.rangeRight(1, 5);
13459      * // => [4, 3, 2, 1]
13460      *
13461      * _.rangeRight(0, 20, 5);
13462      * // => [15, 10, 5, 0]
13463      *
13464      * _.rangeRight(0, -4, -1);
13465      * // => [-3, -2, -1, 0]
13466      *
13467      * _.rangeRight(1, 4, 0);
13468      * // => [1, 1, 1]
13469      *
13470      * _.rangeRight(0);
13471      * // => []
13472      */
13473     var rangeRight = createRange(true);
13474
13475     /**
13476      * Invokes the iteratee function `n` times, returning an array of the results
13477      * of each invocation. The iteratee is invoked with one argument; (index).
13478      *
13479      * @static
13480      * @memberOf _
13481      * @category Util
13482      * @param {number} n The number of times to invoke `iteratee`.
13483      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13484      * @returns {Array} Returns the array of results.
13485      * @example
13486      *
13487      * _.times(3, String);
13488      * // => ['0', '1', '2']
13489      *
13490      *  _.times(4, _.constant(true));
13491      * // => [true, true, true, true]
13492      */
13493     function times(n, iteratee) {
13494       n = toInteger(n);
13495       if (n < 1 || n > MAX_SAFE_INTEGER) {
13496         return [];
13497       }
13498       var index = MAX_ARRAY_LENGTH,
13499           length = nativeMin(n, MAX_ARRAY_LENGTH);
13500
13501       iteratee = toFunction(iteratee);
13502       n -= MAX_ARRAY_LENGTH;
13503
13504       var result = baseTimes(length, iteratee);
13505       while (++index < n) {
13506         iteratee(index);
13507       }
13508       return result;
13509     }
13510
13511     /**
13512      * Converts `value` to a property path array.
13513      *
13514      * @static
13515      * @memberOf _
13516      * @category Util
13517      * @param {*} value The value to convert.
13518      * @returns {Array} Returns the new property path array.
13519      * @example
13520      *
13521      * _.toPath('a.b.c');
13522      * // => ['a', 'b', 'c']
13523      *
13524      * _.toPath('a[0].b.c');
13525      * // => ['a', '0', 'b', 'c']
13526      *
13527      * var path = ['a', 'b', 'c'],
13528      *     newPath = _.toPath(path);
13529      *
13530      * console.log(newPath);
13531      * // => ['a', 'b', 'c']
13532      *
13533      * console.log(path === newPath);
13534      * // => false
13535      */
13536     function toPath(value) {
13537       return isArray(value) ? arrayMap(value, String) : stringToPath(value);
13538     }
13539
13540     /**
13541      * Generates a unique ID. If `prefix` is provided the ID is appended to it.
13542      *
13543      * @static
13544      * @memberOf _
13545      * @category Util
13546      * @param {string} [prefix] The value to prefix the ID with.
13547      * @returns {string} Returns the unique ID.
13548      * @example
13549      *
13550      * _.uniqueId('contact_');
13551      * // => 'contact_104'
13552      *
13553      * _.uniqueId();
13554      * // => '105'
13555      */
13556     function uniqueId(prefix) {
13557       var id = ++idCounter;
13558       return toString(prefix) + id;
13559     }
13560
13561     /*------------------------------------------------------------------------*/
13562
13563     /**
13564      * Adds two numbers.
13565      *
13566      * @static
13567      * @memberOf _
13568      * @category Math
13569      * @param {number} augend The first number in an addition.
13570      * @param {number} addend The second number in an addition.
13571      * @returns {number} Returns the total.
13572      * @example
13573      *
13574      * _.add(6, 4);
13575      * // => 10
13576      */
13577     function add(augend, addend) {
13578       var result;
13579       if (augend !== undefined) {
13580         result = augend;
13581       }
13582       if (addend !== undefined) {
13583         result = result === undefined ? addend : (result + addend);
13584       }
13585       return result;
13586     }
13587
13588     /**
13589      * Computes `number` rounded up to `precision`.
13590      *
13591      * @static
13592      * @memberOf _
13593      * @category Math
13594      * @param {number} number The number to round up.
13595      * @param {number} [precision=0] The precision to round up to.
13596      * @returns {number} Returns the rounded up number.
13597      * @example
13598      *
13599      * _.ceil(4.006);
13600      * // => 5
13601      *
13602      * _.ceil(6.004, 2);
13603      * // => 6.01
13604      *
13605      * _.ceil(6040, -2);
13606      * // => 6100
13607      */
13608     var ceil = createRound('ceil');
13609
13610     /**
13611      * Computes `number` rounded down to `precision`.
13612      *
13613      * @static
13614      * @memberOf _
13615      * @category Math
13616      * @param {number} number The number to round down.
13617      * @param {number} [precision=0] The precision to round down to.
13618      * @returns {number} Returns the rounded down number.
13619      * @example
13620      *
13621      * _.floor(4.006);
13622      * // => 4
13623      *
13624      * _.floor(0.046, 2);
13625      * // => 0.04
13626      *
13627      * _.floor(4060, -2);
13628      * // => 4000
13629      */
13630     var floor = createRound('floor');
13631
13632     /**
13633      * Computes the maximum value of `array`. If `array` is empty or falsey
13634      * `undefined` is returned.
13635      *
13636      * @static
13637      * @memberOf _
13638      * @category Math
13639      * @param {Array} array The array to iterate over.
13640      * @returns {*} Returns the maximum value.
13641      * @example
13642      *
13643      * _.max([4, 2, 8, 6]);
13644      * // => 8
13645      *
13646      * _.max([]);
13647      * // => undefined
13648      */
13649     function max(array) {
13650       return (array && array.length)
13651         ? baseExtremum(array, identity, gt)
13652         : undefined;
13653     }
13654
13655     /**
13656      * This method is like `_.max` except that it accepts `iteratee` which is
13657      * invoked for each element in `array` to generate the criterion by which
13658      * the value is ranked. The iteratee is invoked with one argument: (value).
13659      *
13660      * @static
13661      * @memberOf _
13662      * @category Math
13663      * @param {Array} array The array to iterate over.
13664      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13665      * @returns {*} Returns the maximum value.
13666      * @example
13667      *
13668      * var objects = [{ 'n': 1 }, { 'n': 2 }];
13669      *
13670      * _.maxBy(objects, function(o) { return o.n; });
13671      * // => { 'n': 2 }
13672      *
13673      * // using the `_.property` iteratee shorthand
13674      * _.maxBy(objects, 'n');
13675      * // => { 'n': 2 }
13676      */
13677     function maxBy(array, iteratee) {
13678       return (array && array.length)
13679         ? baseExtremum(array, getIteratee(iteratee), gt)
13680         : undefined;
13681     }
13682
13683     /**
13684      * Computes the mean of the values in `array`.
13685      *
13686      * @static
13687      * @memberOf _
13688      * @category Math
13689      * @param {Array} array The array to iterate over.
13690      * @returns {number} Returns the mean.
13691      * @example
13692      *
13693      * _.mean([4, 2, 8, 6]);
13694      * // => 5
13695      */
13696     function mean(array) {
13697       return sum(array) / (array ? array.length : 0);
13698     }
13699
13700     /**
13701      * Computes the minimum value of `array`. If `array` is empty or falsey
13702      * `undefined` is returned.
13703      *
13704      * @static
13705      * @memberOf _
13706      * @category Math
13707      * @param {Array} array The array to iterate over.
13708      * @returns {*} Returns the minimum value.
13709      * @example
13710      *
13711      * _.min([4, 2, 8, 6]);
13712      * // => 2
13713      *
13714      * _.min([]);
13715      * // => undefined
13716      */
13717     function min(array) {
13718       return (array && array.length)
13719         ? baseExtremum(array, identity, lt)
13720         : undefined;
13721     }
13722
13723     /**
13724      * This method is like `_.min` except that it accepts `iteratee` which is
13725      * invoked for each element in `array` to generate the criterion by which
13726      * the value is ranked. The iteratee is invoked with one argument: (value).
13727      *
13728      * @static
13729      * @memberOf _
13730      * @category Math
13731      * @param {Array} array The array to iterate over.
13732      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13733      * @returns {*} Returns the minimum value.
13734      * @example
13735      *
13736      * var objects = [{ 'n': 1 }, { 'n': 2 }];
13737      *
13738      * _.minBy(objects, function(o) { return o.n; });
13739      * // => { 'n': 1 }
13740      *
13741      * // using the `_.property` iteratee shorthand
13742      * _.minBy(objects, 'n');
13743      * // => { 'n': 1 }
13744      */
13745     function minBy(array, iteratee) {
13746       return (array && array.length)
13747         ? baseExtremum(array, getIteratee(iteratee), lt)
13748         : undefined;
13749     }
13750
13751     /**
13752      * Computes `number` rounded to `precision`.
13753      *
13754      * @static
13755      * @memberOf _
13756      * @category Math
13757      * @param {number} number The number to round.
13758      * @param {number} [precision=0] The precision to round to.
13759      * @returns {number} Returns the rounded number.
13760      * @example
13761      *
13762      * _.round(4.006);
13763      * // => 4
13764      *
13765      * _.round(4.006, 2);
13766      * // => 4.01
13767      *
13768      * _.round(4060, -2);
13769      * // => 4100
13770      */
13771     var round = createRound('round');
13772
13773     /**
13774      * Subtract two numbers.
13775      *
13776      * @static
13777      * @memberOf _
13778      * @category Math
13779      * @param {number} minuend The first number in a subtraction.
13780      * @param {number} subtrahend The second number in a subtraction.
13781      * @returns {number} Returns the difference.
13782      * @example
13783      *
13784      * _.subtract(6, 4);
13785      * // => 2
13786      */
13787     function subtract(minuend, subtrahend) {
13788       var result;
13789       if (minuend !== undefined) {
13790         result = minuend;
13791       }
13792       if (subtrahend !== undefined) {
13793         result = result === undefined ? subtrahend : (result - subtrahend);
13794       }
13795       return result;
13796     }
13797
13798     /**
13799      * Computes the sum of the values in `array`.
13800      *
13801      * @static
13802      * @memberOf _
13803      * @category Math
13804      * @param {Array} array The array to iterate over.
13805      * @returns {number} Returns the sum.
13806      * @example
13807      *
13808      * _.sum([4, 2, 8, 6]);
13809      * // => 20
13810      */
13811     function sum(array) {
13812       return (array && array.length)
13813         ? baseSum(array, identity)
13814         : undefined;
13815     }
13816
13817     /**
13818      * This method is like `_.sum` except that it accepts `iteratee` which is
13819      * invoked for each element in `array` to generate the value to be summed.
13820      * The iteratee is invoked with one argument: (value).
13821      *
13822      * @static
13823      * @memberOf _
13824      * @category Math
13825      * @param {Array} array The array to iterate over.
13826      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13827      * @returns {number} Returns the sum.
13828      * @example
13829      *
13830      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
13831      *
13832      * _.sumBy(objects, function(o) { return o.n; });
13833      * // => 20
13834      *
13835      * // using the `_.property` iteratee shorthand
13836      * _.sumBy(objects, 'n');
13837      * // => 20
13838      */
13839     function sumBy(array, iteratee) {
13840       return (array && array.length)
13841         ? baseSum(array, getIteratee(iteratee))
13842         : undefined;
13843     }
13844
13845     /*------------------------------------------------------------------------*/
13846
13847     // Ensure wrappers are instances of `baseLodash`.
13848     lodash.prototype = baseLodash.prototype;
13849
13850     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
13851     LodashWrapper.prototype.constructor = LodashWrapper;
13852
13853     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
13854     LazyWrapper.prototype.constructor = LazyWrapper;
13855
13856     // Avoid inheriting from `Object.prototype` when possible.
13857     Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
13858
13859     // Add functions to the `MapCache`.
13860     MapCache.prototype.clear = mapClear;
13861     MapCache.prototype['delete'] = mapDelete;
13862     MapCache.prototype.get = mapGet;
13863     MapCache.prototype.has = mapHas;
13864     MapCache.prototype.set = mapSet;
13865
13866     // Add functions to the `SetCache`.
13867     SetCache.prototype.push = cachePush;
13868
13869     // Add functions to the `Stack` cache.
13870     Stack.prototype.clear = stackClear;
13871     Stack.prototype['delete'] = stackDelete;
13872     Stack.prototype.get = stackGet;
13873     Stack.prototype.has = stackHas;
13874     Stack.prototype.set = stackSet;
13875
13876     // Assign cache to `_.memoize`.
13877     memoize.Cache = MapCache;
13878
13879     // Add functions that return wrapped values when chaining.
13880     lodash.after = after;
13881     lodash.ary = ary;
13882     lodash.assign = assign;
13883     lodash.assignIn = assignIn;
13884     lodash.assignInWith = assignInWith;
13885     lodash.assignWith = assignWith;
13886     lodash.at = at;
13887     lodash.before = before;
13888     lodash.bind = bind;
13889     lodash.bindAll = bindAll;
13890     lodash.bindKey = bindKey;
13891     lodash.chain = chain;
13892     lodash.chunk = chunk;
13893     lodash.compact = compact;
13894     lodash.concat = concat;
13895     lodash.cond = cond;
13896     lodash.conforms = conforms;
13897     lodash.constant = constant;
13898     lodash.countBy = countBy;
13899     lodash.create = create;
13900     lodash.curry = curry;
13901     lodash.curryRight = curryRight;
13902     lodash.debounce = debounce;
13903     lodash.defaults = defaults;
13904     lodash.defaultsDeep = defaultsDeep;
13905     lodash.defer = defer;
13906     lodash.delay = delay;
13907     lodash.difference = difference;
13908     lodash.differenceBy = differenceBy;
13909     lodash.differenceWith = differenceWith;
13910     lodash.drop = drop;
13911     lodash.dropRight = dropRight;
13912     lodash.dropRightWhile = dropRightWhile;
13913     lodash.dropWhile = dropWhile;
13914     lodash.fill = fill;
13915     lodash.filter = filter;
13916     lodash.flatMap = flatMap;
13917     lodash.flatten = flatten;
13918     lodash.flattenDeep = flattenDeep;
13919     lodash.flip = flip;
13920     lodash.flow = flow;
13921     lodash.flowRight = flowRight;
13922     lodash.fromPairs = fromPairs;
13923     lodash.functions = functions;
13924     lodash.functionsIn = functionsIn;
13925     lodash.groupBy = groupBy;
13926     lodash.initial = initial;
13927     lodash.intersection = intersection;
13928     lodash.intersectionBy = intersectionBy;
13929     lodash.intersectionWith = intersectionWith;
13930     lodash.invert = invert;
13931     lodash.invokeMap = invokeMap;
13932     lodash.iteratee = iteratee;
13933     lodash.keyBy = keyBy;
13934     lodash.keys = keys;
13935     lodash.keysIn = keysIn;
13936     lodash.map = map;
13937     lodash.mapKeys = mapKeys;
13938     lodash.mapValues = mapValues;
13939     lodash.matches = matches;
13940     lodash.matchesProperty = matchesProperty;
13941     lodash.memoize = memoize;
13942     lodash.merge = merge;
13943     lodash.mergeWith = mergeWith;
13944     lodash.method = method;
13945     lodash.methodOf = methodOf;
13946     lodash.mixin = mixin;
13947     lodash.negate = negate;
13948     lodash.nthArg = nthArg;
13949     lodash.omit = omit;
13950     lodash.omitBy = omitBy;
13951     lodash.once = once;
13952     lodash.orderBy = orderBy;
13953     lodash.over = over;
13954     lodash.overArgs = overArgs;
13955     lodash.overEvery = overEvery;
13956     lodash.overSome = overSome;
13957     lodash.partial = partial;
13958     lodash.partialRight = partialRight;
13959     lodash.partition = partition;
13960     lodash.pick = pick;
13961     lodash.pickBy = pickBy;
13962     lodash.property = property;
13963     lodash.propertyOf = propertyOf;
13964     lodash.pull = pull;
13965     lodash.pullAll = pullAll;
13966     lodash.pullAllBy = pullAllBy;
13967     lodash.pullAt = pullAt;
13968     lodash.range = range;
13969     lodash.rangeRight = rangeRight;
13970     lodash.rearg = rearg;
13971     lodash.reject = reject;
13972     lodash.remove = remove;
13973     lodash.rest = rest;
13974     lodash.reverse = reverse;
13975     lodash.sampleSize = sampleSize;
13976     lodash.set = set;
13977     lodash.setWith = setWith;
13978     lodash.shuffle = shuffle;
13979     lodash.slice = slice;
13980     lodash.sortBy = sortBy;
13981     lodash.sortedUniq = sortedUniq;
13982     lodash.sortedUniqBy = sortedUniqBy;
13983     lodash.split = split;
13984     lodash.spread = spread;
13985     lodash.tail = tail;
13986     lodash.take = take;
13987     lodash.takeRight = takeRight;
13988     lodash.takeRightWhile = takeRightWhile;
13989     lodash.takeWhile = takeWhile;
13990     lodash.tap = tap;
13991     lodash.throttle = throttle;
13992     lodash.thru = thru;
13993     lodash.toArray = toArray;
13994     lodash.toPairs = toPairs;
13995     lodash.toPairsIn = toPairsIn;
13996     lodash.toPath = toPath;
13997     lodash.toPlainObject = toPlainObject;
13998     lodash.transform = transform;
13999     lodash.unary = unary;
14000     lodash.union = union;
14001     lodash.unionBy = unionBy;
14002     lodash.unionWith = unionWith;
14003     lodash.uniq = uniq;
14004     lodash.uniqBy = uniqBy;
14005     lodash.uniqWith = uniqWith;
14006     lodash.unset = unset;
14007     lodash.unzip = unzip;
14008     lodash.unzipWith = unzipWith;
14009     lodash.values = values;
14010     lodash.valuesIn = valuesIn;
14011     lodash.without = without;
14012     lodash.words = words;
14013     lodash.wrap = wrap;
14014     lodash.xor = xor;
14015     lodash.xorBy = xorBy;
14016     lodash.xorWith = xorWith;
14017     lodash.zip = zip;
14018     lodash.zipObject = zipObject;
14019     lodash.zipWith = zipWith;
14020
14021     // Add aliases.
14022     lodash.extend = assignIn;
14023     lodash.extendWith = assignInWith;
14024
14025     // Add functions to `lodash.prototype`.
14026     mixin(lodash, lodash);
14027
14028     /*------------------------------------------------------------------------*/
14029
14030     // Add functions that return unwrapped values when chaining.
14031     lodash.add = add;
14032     lodash.attempt = attempt;
14033     lodash.camelCase = camelCase;
14034     lodash.capitalize = capitalize;
14035     lodash.ceil = ceil;
14036     lodash.clamp = clamp;
14037     lodash.clone = clone;
14038     lodash.cloneDeep = cloneDeep;
14039     lodash.cloneDeepWith = cloneDeepWith;
14040     lodash.cloneWith = cloneWith;
14041     lodash.deburr = deburr;
14042     lodash.endsWith = endsWith;
14043     lodash.eq = eq;
14044     lodash.escape = escape;
14045     lodash.escapeRegExp = escapeRegExp;
14046     lodash.every = every;
14047     lodash.find = find;
14048     lodash.findIndex = findIndex;
14049     lodash.findKey = findKey;
14050     lodash.findLast = findLast;
14051     lodash.findLastIndex = findLastIndex;
14052     lodash.findLastKey = findLastKey;
14053     lodash.floor = floor;
14054     lodash.forEach = forEach;
14055     lodash.forEachRight = forEachRight;
14056     lodash.forIn = forIn;
14057     lodash.forInRight = forInRight;
14058     lodash.forOwn = forOwn;
14059     lodash.forOwnRight = forOwnRight;
14060     lodash.get = get;
14061     lodash.gt = gt;
14062     lodash.gte = gte;
14063     lodash.has = has;
14064     lodash.hasIn = hasIn;
14065     lodash.head = head;
14066     lodash.identity = identity;
14067     lodash.includes = includes;
14068     lodash.indexOf = indexOf;
14069     lodash.inRange = inRange;
14070     lodash.invoke = invoke;
14071     lodash.isArguments = isArguments;
14072     lodash.isArray = isArray;
14073     lodash.isArrayLike = isArrayLike;
14074     lodash.isArrayLikeObject = isArrayLikeObject;
14075     lodash.isBoolean = isBoolean;
14076     lodash.isDate = isDate;
14077     lodash.isElement = isElement;
14078     lodash.isEmpty = isEmpty;
14079     lodash.isEqual = isEqual;
14080     lodash.isEqualWith = isEqualWith;
14081     lodash.isError = isError;
14082     lodash.isFinite = isFinite;
14083     lodash.isFunction = isFunction;
14084     lodash.isInteger = isInteger;
14085     lodash.isLength = isLength;
14086     lodash.isMatch = isMatch;
14087     lodash.isMatchWith = isMatchWith;
14088     lodash.isNaN = isNaN;
14089     lodash.isNative = isNative;
14090     lodash.isNil = isNil;
14091     lodash.isNull = isNull;
14092     lodash.isNumber = isNumber;
14093     lodash.isObject = isObject;
14094     lodash.isObjectLike = isObjectLike;
14095     lodash.isPlainObject = isPlainObject;
14096     lodash.isRegExp = isRegExp;
14097     lodash.isSafeInteger = isSafeInteger;
14098     lodash.isString = isString;
14099     lodash.isSymbol = isSymbol;
14100     lodash.isTypedArray = isTypedArray;
14101     lodash.isUndefined = isUndefined;
14102     lodash.join = join;
14103     lodash.kebabCase = kebabCase;
14104     lodash.last = last;
14105     lodash.lastIndexOf = lastIndexOf;
14106     lodash.lowerCase = lowerCase;
14107     lodash.lowerFirst = lowerFirst;
14108     lodash.lt = lt;
14109     lodash.lte = lte;
14110     lodash.max = max;
14111     lodash.maxBy = maxBy;
14112     lodash.mean = mean;
14113     lodash.min = min;
14114     lodash.minBy = minBy;
14115     lodash.noConflict = noConflict;
14116     lodash.noop = noop;
14117     lodash.now = now;
14118     lodash.pad = pad;
14119     lodash.padEnd = padEnd;
14120     lodash.padStart = padStart;
14121     lodash.parseInt = parseInt;
14122     lodash.random = random;
14123     lodash.reduce = reduce;
14124     lodash.reduceRight = reduceRight;
14125     lodash.repeat = repeat;
14126     lodash.replace = replace;
14127     lodash.result = result;
14128     lodash.round = round;
14129     lodash.runInContext = runInContext;
14130     lodash.sample = sample;
14131     lodash.size = size;
14132     lodash.snakeCase = snakeCase;
14133     lodash.some = some;
14134     lodash.sortedIndex = sortedIndex;
14135     lodash.sortedIndexBy = sortedIndexBy;
14136     lodash.sortedIndexOf = sortedIndexOf;
14137     lodash.sortedLastIndex = sortedLastIndex;
14138     lodash.sortedLastIndexBy = sortedLastIndexBy;
14139     lodash.sortedLastIndexOf = sortedLastIndexOf;
14140     lodash.startCase = startCase;
14141     lodash.startsWith = startsWith;
14142     lodash.subtract = subtract;
14143     lodash.sum = sum;
14144     lodash.sumBy = sumBy;
14145     lodash.template = template;
14146     lodash.times = times;
14147     lodash.toInteger = toInteger;
14148     lodash.toLength = toLength;
14149     lodash.toLower = toLower;
14150     lodash.toNumber = toNumber;
14151     lodash.toSafeInteger = toSafeInteger;
14152     lodash.toString = toString;
14153     lodash.toUpper = toUpper;
14154     lodash.trim = trim;
14155     lodash.trimEnd = trimEnd;
14156     lodash.trimStart = trimStart;
14157     lodash.truncate = truncate;
14158     lodash.unescape = unescape;
14159     lodash.uniqueId = uniqueId;
14160     lodash.upperCase = upperCase;
14161     lodash.upperFirst = upperFirst;
14162
14163     // Add aliases.
14164     lodash.each = forEach;
14165     lodash.eachRight = forEachRight;
14166     lodash.first = head;
14167
14168     mixin(lodash, (function() {
14169       var source = {};
14170       baseForOwn(lodash, function(func, methodName) {
14171         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
14172           source[methodName] = func;
14173         }
14174       });
14175       return source;
14176     }()), { 'chain': false });
14177
14178     /*------------------------------------------------------------------------*/
14179
14180     /**
14181      * The semantic version number.
14182      *
14183      * @static
14184      * @memberOf _
14185      * @type string
14186      */
14187     lodash.VERSION = VERSION;
14188
14189     // Assign default placeholders.
14190     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
14191       lodash[methodName].placeholder = lodash;
14192     });
14193
14194     // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
14195     arrayEach(['drop', 'take'], function(methodName, index) {
14196       LazyWrapper.prototype[methodName] = function(n) {
14197         var filtered = this.__filtered__;
14198         if (filtered && !index) {
14199           return new LazyWrapper(this);
14200         }
14201         n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
14202
14203         var result = this.clone();
14204         if (filtered) {
14205           result.__takeCount__ = nativeMin(n, result.__takeCount__);
14206         } else {
14207           result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
14208         }
14209         return result;
14210       };
14211
14212       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
14213         return this.reverse()[methodName](n).reverse();
14214       };
14215     });
14216
14217     // Add `LazyWrapper` methods that accept an `iteratee` value.
14218     arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
14219       var type = index + 1,
14220           isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
14221
14222       LazyWrapper.prototype[methodName] = function(iteratee) {
14223         var result = this.clone();
14224         result.__iteratees__.push({ 'iteratee': getIteratee(iteratee, 3), 'type': type });
14225         result.__filtered__ = result.__filtered__ || isFilter;
14226         return result;
14227       };
14228     });
14229
14230     // Add `LazyWrapper` methods for `_.head` and `_.last`.
14231     arrayEach(['head', 'last'], function(methodName, index) {
14232       var takeName = 'take' + (index ? 'Right' : '');
14233
14234       LazyWrapper.prototype[methodName] = function() {
14235         return this[takeName](1).value()[0];
14236       };
14237     });
14238
14239     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
14240     arrayEach(['initial', 'tail'], function(methodName, index) {
14241       var dropName = 'drop' + (index ? '' : 'Right');
14242
14243       LazyWrapper.prototype[methodName] = function() {
14244         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
14245       };
14246     });
14247
14248     LazyWrapper.prototype.compact = function() {
14249       return this.filter(identity);
14250     };
14251
14252     LazyWrapper.prototype.find = function(predicate) {
14253       return this.filter(predicate).head();
14254     };
14255
14256     LazyWrapper.prototype.findLast = function(predicate) {
14257       return this.reverse().find(predicate);
14258     };
14259
14260     LazyWrapper.prototype.invokeMap = rest(function(path, args) {
14261       if (typeof path == 'function') {
14262         return new LazyWrapper(this);
14263       }
14264       return this.map(function(value) {
14265         return baseInvoke(value, path, args);
14266       });
14267     });
14268
14269     LazyWrapper.prototype.reject = function(predicate) {
14270       predicate = getIteratee(predicate, 3);
14271       return this.filter(function(value) {
14272         return !predicate(value);
14273       });
14274     };
14275
14276     LazyWrapper.prototype.slice = function(start, end) {
14277       start = toInteger(start);
14278
14279       var result = this;
14280       if (result.__filtered__ && (start > 0 || end < 0)) {
14281         return new LazyWrapper(result);
14282       }
14283       if (start < 0) {
14284         result = result.takeRight(-start);
14285       } else if (start) {
14286         result = result.drop(start);
14287       }
14288       if (end !== undefined) {
14289         end = toInteger(end);
14290         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
14291       }
14292       return result;
14293     };
14294
14295     LazyWrapper.prototype.takeRightWhile = function(predicate) {
14296       return this.reverse().takeWhile(predicate).reverse();
14297     };
14298
14299     LazyWrapper.prototype.toArray = function() {
14300       return this.take(MAX_ARRAY_LENGTH);
14301     };
14302
14303     // Add `LazyWrapper` methods to `lodash.prototype`.
14304     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14305       var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
14306           isTaker = /^(?:head|last)$/.test(methodName),
14307           lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
14308           retUnwrapped = isTaker || /^find/.test(methodName);
14309
14310       if (!lodashFunc) {
14311         return;
14312       }
14313       lodash.prototype[methodName] = function() {
14314         var value = this.__wrapped__,
14315             args = isTaker ? [1] : arguments,
14316             isLazy = value instanceof LazyWrapper,
14317             iteratee = args[0],
14318             useLazy = isLazy || isArray(value);
14319
14320         var interceptor = function(value) {
14321           var result = lodashFunc.apply(lodash, arrayPush([value], args));
14322           return (isTaker && chainAll) ? result[0] : result;
14323         };
14324
14325         if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
14326           // Avoid lazy use if the iteratee has a "length" value other than `1`.
14327           isLazy = useLazy = false;
14328         }
14329         var chainAll = this.__chain__,
14330             isHybrid = !!this.__actions__.length,
14331             isUnwrapped = retUnwrapped && !chainAll,
14332             onlyLazy = isLazy && !isHybrid;
14333
14334         if (!retUnwrapped && useLazy) {
14335           value = onlyLazy ? value : new LazyWrapper(this);
14336           var result = func.apply(value, args);
14337           result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
14338           return new LodashWrapper(result, chainAll);
14339         }
14340         if (isUnwrapped && onlyLazy) {
14341           return func.apply(this, args);
14342         }
14343         result = this.thru(interceptor);
14344         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
14345       };
14346     });
14347
14348     // Add `Array` and `String` methods to `lodash.prototype`.
14349     arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
14350       var func = arrayProto[methodName],
14351           chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
14352           retUnwrapped = /^(?:pop|shift)$/.test(methodName);
14353
14354       lodash.prototype[methodName] = function() {
14355         var args = arguments;
14356         if (retUnwrapped && !this.__chain__) {
14357           return func.apply(this.value(), args);
14358         }
14359         return this[chainName](function(value) {
14360           return func.apply(value, args);
14361         });
14362       };
14363     });
14364
14365     // Map minified function names to their real names.
14366     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14367       var lodashFunc = lodash[methodName];
14368       if (lodashFunc) {
14369         var key = (lodashFunc.name + ''),
14370             names = realNames[key] || (realNames[key] = []);
14371
14372         names.push({ 'name': methodName, 'func': lodashFunc });
14373       }
14374     });
14375
14376     realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];
14377
14378     // Add functions to the lazy wrapper.
14379     LazyWrapper.prototype.clone = lazyClone;
14380     LazyWrapper.prototype.reverse = lazyReverse;
14381     LazyWrapper.prototype.value = lazyValue;
14382
14383     // Add chaining functions to the `lodash` wrapper.
14384     lodash.prototype.at = wrapperAt;
14385     lodash.prototype.chain = wrapperChain;
14386     lodash.prototype.commit = wrapperCommit;
14387     lodash.prototype.flatMap = wrapperFlatMap;
14388     lodash.prototype.next = wrapperNext;
14389     lodash.prototype.plant = wrapperPlant;
14390     lodash.prototype.reverse = wrapperReverse;
14391     lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
14392
14393     if (iteratorSymbol) {
14394       lodash.prototype[iteratorSymbol] = wrapperToIterator;
14395     }
14396     return lodash;
14397   }
14398
14399   /*--------------------------------------------------------------------------*/
14400
14401   // Export lodash.
14402   var _ = runInContext();
14403
14404   // Expose lodash on the free variable `window` or `self` when available. This
14405   // prevents errors in cases where lodash is loaded by a script tag in the presence
14406   // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
14407   (freeWindow || freeSelf || {})._ = _;
14408
14409   // Some AMD build optimizers like r.js check for condition patterns like the following:
14410   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
14411     // Define as an anonymous module so, through path mapping, it can be
14412     // referenced as the "underscore" module.
14413     define(function() {
14414       return _;
14415     });
14416   }
14417   // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
14418   else if (freeExports && freeModule) {
14419     // Export for Node.js.
14420     if (moduleExports) {
14421       (freeModule.exports = _)._ = _;
14422     }
14423     // Export for CommonJS support.
14424     freeExports._ = _;
14425   }
14426   else {
14427     // Export to the global object.
14428     root._ = _;
14429   }
14430 }.call(this));