[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/dist/vendor/ -> lodash.js (source)

   1  /**
   2   * @license
   3   * Lodash <https://lodash.com/>
   4   * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
   5   * Released under MIT license <https://lodash.com/license>
   6   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
   7   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
   8   */
   9  ;(function() {
  10  
  11    /** Used as a safe reference for `undefined` in pre-ES5 environments. */
  12    var undefined;
  13  
  14    /** Used as the semantic version number. */
  15    var VERSION = '4.17.19';
  16  
  17    /** Used as the size to enable large array optimizations. */
  18    var LARGE_ARRAY_SIZE = 200;
  19  
  20    /** Error message constants. */
  21    var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
  22        FUNC_ERROR_TEXT = 'Expected a function';
  23  
  24    /** Used to stand-in for `undefined` hash values. */
  25    var HASH_UNDEFINED = '__lodash_hash_undefined__';
  26  
  27    /** Used as the maximum memoize cache size. */
  28    var MAX_MEMOIZE_SIZE = 500;
  29  
  30    /** Used as the internal argument placeholder. */
  31    var PLACEHOLDER = '__lodash_placeholder__';
  32  
  33    /** Used to compose bitmasks for cloning. */
  34    var CLONE_DEEP_FLAG = 1,
  35        CLONE_FLAT_FLAG = 2,
  36        CLONE_SYMBOLS_FLAG = 4;
  37  
  38    /** Used to compose bitmasks for value comparisons. */
  39    var COMPARE_PARTIAL_FLAG = 1,
  40        COMPARE_UNORDERED_FLAG = 2;
  41  
  42    /** Used to compose bitmasks for function metadata. */
  43    var WRAP_BIND_FLAG = 1,
  44        WRAP_BIND_KEY_FLAG = 2,
  45        WRAP_CURRY_BOUND_FLAG = 4,
  46        WRAP_CURRY_FLAG = 8,
  47        WRAP_CURRY_RIGHT_FLAG = 16,
  48        WRAP_PARTIAL_FLAG = 32,
  49        WRAP_PARTIAL_RIGHT_FLAG = 64,
  50        WRAP_ARY_FLAG = 128,
  51        WRAP_REARG_FLAG = 256,
  52        WRAP_FLIP_FLAG = 512;
  53  
  54    /** Used as default options for `_.truncate`. */
  55    var DEFAULT_TRUNC_LENGTH = 30,
  56        DEFAULT_TRUNC_OMISSION = '...';
  57  
  58    /** Used to detect hot functions by number of calls within a span of milliseconds. */
  59    var HOT_COUNT = 800,
  60        HOT_SPAN = 16;
  61  
  62    /** Used to indicate the type of lazy iteratees. */
  63    var LAZY_FILTER_FLAG = 1,
  64        LAZY_MAP_FLAG = 2,
  65        LAZY_WHILE_FLAG = 3;
  66  
  67    /** Used as references for various `Number` constants. */
  68    var INFINITY = 1 / 0,
  69        MAX_SAFE_INTEGER = 9007199254740991,
  70        MAX_INTEGER = 1.7976931348623157e+308,
  71        NAN = 0 / 0;
  72  
  73    /** Used as references for the maximum length and index of an array. */
  74    var MAX_ARRAY_LENGTH = 4294967295,
  75        MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
  76        HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
  77  
  78    /** Used to associate wrap methods with their bit flags. */
  79    var wrapFlags = [
  80      ['ary', WRAP_ARY_FLAG],
  81      ['bind', WRAP_BIND_FLAG],
  82      ['bindKey', WRAP_BIND_KEY_FLAG],
  83      ['curry', WRAP_CURRY_FLAG],
  84      ['curryRight', WRAP_CURRY_RIGHT_FLAG],
  85      ['flip', WRAP_FLIP_FLAG],
  86      ['partial', WRAP_PARTIAL_FLAG],
  87      ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
  88      ['rearg', WRAP_REARG_FLAG]
  89    ];
  90  
  91    /** `Object#toString` result references. */
  92    var argsTag = '[object Arguments]',
  93        arrayTag = '[object Array]',
  94        asyncTag = '[object AsyncFunction]',
  95        boolTag = '[object Boolean]',
  96        dateTag = '[object Date]',
  97        domExcTag = '[object DOMException]',
  98        errorTag = '[object Error]',
  99        funcTag = '[object Function]',
 100        genTag = '[object GeneratorFunction]',
 101        mapTag = '[object Map]',
 102        numberTag = '[object Number]',
 103        nullTag = '[object Null]',
 104        objectTag = '[object Object]',
 105        promiseTag = '[object Promise]',
 106        proxyTag = '[object Proxy]',
 107        regexpTag = '[object RegExp]',
 108        setTag = '[object Set]',
 109        stringTag = '[object String]',
 110        symbolTag = '[object Symbol]',
 111        undefinedTag = '[object Undefined]',
 112        weakMapTag = '[object WeakMap]',
 113        weakSetTag = '[object WeakSet]';
 114  
 115    var arrayBufferTag = '[object ArrayBuffer]',
 116        dataViewTag = '[object DataView]',
 117        float32Tag = '[object Float32Array]',
 118        float64Tag = '[object Float64Array]',
 119        int8Tag = '[object Int8Array]',
 120        int16Tag = '[object Int16Array]',
 121        int32Tag = '[object Int32Array]',
 122        uint8Tag = '[object Uint8Array]',
 123        uint8ClampedTag = '[object Uint8ClampedArray]',
 124        uint16Tag = '[object Uint16Array]',
 125        uint32Tag = '[object Uint32Array]';
 126  
 127    /** Used to match empty string literals in compiled template source. */
 128    var reEmptyStringLeading = /\b__p \+= '';/g,
 129        reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
 130        reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
 131  
 132    /** Used to match HTML entities and HTML characters. */
 133    var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
 134        reUnescapedHtml = /[&<>"']/g,
 135        reHasEscapedHtml = RegExp(reEscapedHtml.source),
 136        reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
 137  
 138    /** Used to match template delimiters. */
 139    var reEscape = /<%-([\s\S]+?)%>/g,
 140        reEvaluate = /<%([\s\S]+?)%>/g,
 141        reInterpolate = /<%=([\s\S]+?)%>/g;
 142  
 143    /** Used to match property names within property paths. */
 144    var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
 145        reIsPlainProp = /^\w*$/,
 146        rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
 147  
 148    /**
 149     * Used to match `RegExp`
 150     * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
 151     */
 152    var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
 153        reHasRegExpChar = RegExp(reRegExpChar.source);
 154  
 155    /** Used to match leading and trailing whitespace. */
 156    var reTrim = /^\s+|\s+$/g,
 157        reTrimStart = /^\s+/,
 158        reTrimEnd = /\s+$/;
 159  
 160    /** Used to match wrap detail comments. */
 161    var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
 162        reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
 163        reSplitDetails = /,? & /;
 164  
 165    /** Used to match words composed of alphanumeric characters. */
 166    var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
 167  
 168    /** Used to match backslashes in property paths. */
 169    var reEscapeChar = /\\(\\)?/g;
 170  
 171    /**
 172     * Used to match
 173     * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
 174     */
 175    var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
 176  
 177    /** Used to match `RegExp` flags from their coerced string values. */
 178    var reFlags = /\w*$/;
 179  
 180    /** Used to detect bad signed hexadecimal string values. */
 181    var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
 182  
 183    /** Used to detect binary string values. */
 184    var reIsBinary = /^0b[01]+$/i;
 185  
 186    /** Used to detect host constructors (Safari). */
 187    var reIsHostCtor = /^\[object .+?Constructor\]$/;
 188  
 189    /** Used to detect octal string values. */
 190    var reIsOctal = /^0o[0-7]+$/i;
 191  
 192    /** Used to detect unsigned integer values. */
 193    var reIsUint = /^(?:0|[1-9]\d*)$/;
 194  
 195    /** Used to match Latin Unicode letters (excluding mathematical operators). */
 196    var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
 197  
 198    /** Used to ensure capturing order of template delimiters. */
 199    var reNoMatch = /($^)/;
 200  
 201    /** Used to match unescaped characters in compiled string literals. */
 202    var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
 203  
 204    /** Used to compose unicode character classes. */
 205    var rsAstralRange = '\\ud800-\\udfff',
 206        rsComboMarksRange = '\\u0300-\\u036f',
 207        reComboHalfMarksRange = '\\ufe20-\\ufe2f',
 208        rsComboSymbolsRange = '\\u20d0-\\u20ff',
 209        rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
 210        rsDingbatRange = '\\u2700-\\u27bf',
 211        rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
 212        rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
 213        rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
 214        rsPunctuationRange = '\\u2000-\\u206f',
 215        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',
 216        rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
 217        rsVarRange = '\\ufe0e\\ufe0f',
 218        rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
 219  
 220    /** Used to compose unicode capture groups. */
 221    var rsApos = "['\u2019]",
 222        rsAstral = '[' + rsAstralRange + ']',
 223        rsBreak = '[' + rsBreakRange + ']',
 224        rsCombo = '[' + rsComboRange + ']',
 225        rsDigits = '\\d+',
 226        rsDingbat = '[' + rsDingbatRange + ']',
 227        rsLower = '[' + rsLowerRange + ']',
 228        rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
 229        rsFitz = '\\ud83c[\\udffb-\\udfff]',
 230        rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
 231        rsNonAstral = '[^' + rsAstralRange + ']',
 232        rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
 233        rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
 234        rsUpper = '[' + rsUpperRange + ']',
 235        rsZWJ = '\\u200d';
 236  
 237    /** Used to compose unicode regexes. */
 238    var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
 239        rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
 240        rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
 241        rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
 242        reOptMod = rsModifier + '?',
 243        rsOptVar = '[' + rsVarRange + ']?',
 244        rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
 245        rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
 246        rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
 247        rsSeq = rsOptVar + reOptMod + rsOptJoin,
 248        rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
 249        rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
 250  
 251    /** Used to match apostrophes. */
 252    var reApos = RegExp(rsApos, 'g');
 253  
 254    /**
 255     * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
 256     * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
 257     */
 258    var reComboMark = RegExp(rsCombo, 'g');
 259  
 260    /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
 261    var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
 262  
 263    /** Used to match complex or compound words. */
 264    var reUnicodeWord = RegExp([
 265      rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
 266      rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
 267      rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
 268      rsUpper + '+' + rsOptContrUpper,
 269      rsOrdUpper,
 270      rsOrdLower,
 271      rsDigits,
 272      rsEmoji
 273    ].join('|'), 'g');
 274  
 275    /** 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/). */
 276    var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
 277  
 278    /** Used to detect strings that need a more robust regexp to match words. */
 279    var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
 280  
 281    /** Used to assign default `context` object properties. */
 282    var contextProps = [
 283      'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
 284      'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
 285      'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
 286      'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
 287      '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
 288    ];
 289  
 290    /** Used to make template sourceURLs easier to identify. */
 291    var templateCounter = -1;
 292  
 293    /** Used to identify `toStringTag` values of typed arrays. */
 294    var typedArrayTags = {};
 295    typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
 296    typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
 297    typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
 298    typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
 299    typedArrayTags[uint32Tag] = true;
 300    typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
 301    typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
 302    typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
 303    typedArrayTags[errorTag] = typedArrayTags[funcTag] =
 304    typedArrayTags[mapTag] = typedArrayTags[numberTag] =
 305    typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
 306    typedArrayTags[setTag] = typedArrayTags[stringTag] =
 307    typedArrayTags[weakMapTag] = false;
 308  
 309    /** Used to identify `toStringTag` values supported by `_.clone`. */
 310    var cloneableTags = {};
 311    cloneableTags[argsTag] = cloneableTags[arrayTag] =
 312    cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
 313    cloneableTags[boolTag] = cloneableTags[dateTag] =
 314    cloneableTags[float32Tag] = cloneableTags[float64Tag] =
 315    cloneableTags[int8Tag] = cloneableTags[int16Tag] =
 316    cloneableTags[int32Tag] = cloneableTags[mapTag] =
 317    cloneableTags[numberTag] = cloneableTags[objectTag] =
 318    cloneableTags[regexpTag] = cloneableTags[setTag] =
 319    cloneableTags[stringTag] = cloneableTags[symbolTag] =
 320    cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
 321    cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
 322    cloneableTags[errorTag] = cloneableTags[funcTag] =
 323    cloneableTags[weakMapTag] = false;
 324  
 325    /** Used to map Latin Unicode letters to basic Latin letters. */
 326    var deburredLetters = {
 327      // Latin-1 Supplement block.
 328      '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
 329      '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
 330      '\xc7': 'C',  '\xe7': 'c',
 331      '\xd0': 'D',  '\xf0': 'd',
 332      '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
 333      '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
 334      '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
 335      '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
 336      '\xd1': 'N',  '\xf1': 'n',
 337      '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
 338      '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
 339      '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
 340      '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
 341      '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
 342      '\xc6': 'Ae', '\xe6': 'ae',
 343      '\xde': 'Th', '\xfe': 'th',
 344      '\xdf': 'ss',
 345      // Latin Extended-A block.
 346      '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
 347      '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
 348      '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
 349      '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
 350      '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
 351      '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
 352      '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
 353      '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
 354      '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
 355      '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
 356      '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
 357      '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
 358      '\u0134': 'J',  '\u0135': 'j',
 359      '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
 360      '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
 361      '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
 362      '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
 363      '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
 364      '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
 365      '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
 366      '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
 367      '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
 368      '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
 369      '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
 370      '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
 371      '\u0163': 't',  '\u0165': 't', '\u0167': 't',
 372      '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
 373      '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
 374      '\u0174': 'W',  '\u0175': 'w',
 375      '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
 376      '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
 377      '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
 378      '\u0132': 'IJ', '\u0133': 'ij',
 379      '\u0152': 'Oe', '\u0153': 'oe',
 380      '\u0149': "'n", '\u017f': 's'
 381    };
 382  
 383    /** Used to map characters to HTML entities. */
 384    var htmlEscapes = {
 385      '&': '&amp;',
 386      '<': '&lt;',
 387      '>': '&gt;',
 388      '"': '&quot;',
 389      "'": '&#39;'
 390    };
 391  
 392    /** Used to map HTML entities to characters. */
 393    var htmlUnescapes = {
 394      '&amp;': '&',
 395      '&lt;': '<',
 396      '&gt;': '>',
 397      '&quot;': '"',
 398      '&#39;': "'"
 399    };
 400  
 401    /** Used to escape characters for inclusion in compiled string literals. */
 402    var stringEscapes = {
 403      '\\': '\\',
 404      "'": "'",
 405      '\n': 'n',
 406      '\r': 'r',
 407      '\u2028': 'u2028',
 408      '\u2029': 'u2029'
 409    };
 410  
 411    /** Built-in method references without a dependency on `root`. */
 412    var freeParseFloat = parseFloat,
 413        freeParseInt = parseInt;
 414  
 415    /** Detect free variable `global` from Node.js. */
 416    var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
 417  
 418    /** Detect free variable `self`. */
 419    var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
 420  
 421    /** Used as a reference to the global object. */
 422    var root = freeGlobal || freeSelf || Function('return this')();
 423  
 424    /** Detect free variable `exports`. */
 425    var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
 426  
 427    /** Detect free variable `module`. */
 428    var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
 429  
 430    /** Detect the popular CommonJS extension `module.exports`. */
 431    var moduleExports = freeModule && freeModule.exports === freeExports;
 432  
 433    /** Detect free variable `process` from Node.js. */
 434    var freeProcess = moduleExports && freeGlobal.process;
 435  
 436    /** Used to access faster Node.js helpers. */
 437    var nodeUtil = (function() {
 438      try {
 439        // Use `util.types` for Node.js 10+.
 440        var types = freeModule && freeModule.require && freeModule.require('util').types;
 441  
 442        if (types) {
 443          return types;
 444        }
 445  
 446        // Legacy `process.binding('util')` for Node.js < 10.
 447        return freeProcess && freeProcess.binding && freeProcess.binding('util');
 448      } catch (e) {}
 449    }());
 450  
 451    /* Node.js helper references. */
 452    var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
 453        nodeIsDate = nodeUtil && nodeUtil.isDate,
 454        nodeIsMap = nodeUtil && nodeUtil.isMap,
 455        nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
 456        nodeIsSet = nodeUtil && nodeUtil.isSet,
 457        nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
 458  
 459    /*--------------------------------------------------------------------------*/
 460  
 461    /**
 462     * A faster alternative to `Function#apply`, this function invokes `func`
 463     * with the `this` binding of `thisArg` and the arguments of `args`.
 464     *
 465     * @private
 466     * @param {Function} func The function to invoke.
 467     * @param {*} thisArg The `this` binding of `func`.
 468     * @param {Array} args The arguments to invoke `func` with.
 469     * @returns {*} Returns the result of `func`.
 470     */
 471    function apply(func, thisArg, args) {
 472      switch (args.length) {
 473        case 0: return func.call(thisArg);
 474        case 1: return func.call(thisArg, args[0]);
 475        case 2: return func.call(thisArg, args[0], args[1]);
 476        case 3: return func.call(thisArg, args[0], args[1], args[2]);
 477      }
 478      return func.apply(thisArg, args);
 479    }
 480  
 481    /**
 482     * A specialized version of `baseAggregator` for arrays.
 483     *
 484     * @private
 485     * @param {Array} [array] The array to iterate over.
 486     * @param {Function} setter The function to set `accumulator` values.
 487     * @param {Function} iteratee The iteratee to transform keys.
 488     * @param {Object} accumulator The initial aggregated object.
 489     * @returns {Function} Returns `accumulator`.
 490     */
 491    function arrayAggregator(array, setter, iteratee, accumulator) {
 492      var index = -1,
 493          length = array == null ? 0 : array.length;
 494  
 495      while (++index < length) {
 496        var value = array[index];
 497        setter(accumulator, value, iteratee(value), array);
 498      }
 499      return accumulator;
 500    }
 501  
 502    /**
 503     * A specialized version of `_.forEach` for arrays without support for
 504     * iteratee shorthands.
 505     *
 506     * @private
 507     * @param {Array} [array] The array to iterate over.
 508     * @param {Function} iteratee The function invoked per iteration.
 509     * @returns {Array} Returns `array`.
 510     */
 511    function arrayEach(array, iteratee) {
 512      var index = -1,
 513          length = array == null ? 0 : array.length;
 514  
 515      while (++index < length) {
 516        if (iteratee(array[index], index, array) === false) {
 517          break;
 518        }
 519      }
 520      return array;
 521    }
 522  
 523    /**
 524     * A specialized version of `_.forEachRight` for arrays without support for
 525     * iteratee shorthands.
 526     *
 527     * @private
 528     * @param {Array} [array] The array to iterate over.
 529     * @param {Function} iteratee The function invoked per iteration.
 530     * @returns {Array} Returns `array`.
 531     */
 532    function arrayEachRight(array, iteratee) {
 533      var length = array == null ? 0 : array.length;
 534  
 535      while (length--) {
 536        if (iteratee(array[length], length, array) === false) {
 537          break;
 538        }
 539      }
 540      return array;
 541    }
 542  
 543    /**
 544     * A specialized version of `_.every` for arrays without support for
 545     * iteratee shorthands.
 546     *
 547     * @private
 548     * @param {Array} [array] The array to iterate over.
 549     * @param {Function} predicate The function invoked per iteration.
 550     * @returns {boolean} Returns `true` if all elements pass the predicate check,
 551     *  else `false`.
 552     */
 553    function arrayEvery(array, predicate) {
 554      var index = -1,
 555          length = array == null ? 0 : array.length;
 556  
 557      while (++index < length) {
 558        if (!predicate(array[index], index, array)) {
 559          return false;
 560        }
 561      }
 562      return true;
 563    }
 564  
 565    /**
 566     * A specialized version of `_.filter` for arrays without support for
 567     * iteratee shorthands.
 568     *
 569     * @private
 570     * @param {Array} [array] The array to iterate over.
 571     * @param {Function} predicate The function invoked per iteration.
 572     * @returns {Array} Returns the new filtered array.
 573     */
 574    function arrayFilter(array, predicate) {
 575      var index = -1,
 576          length = array == null ? 0 : array.length,
 577          resIndex = 0,
 578          result = [];
 579  
 580      while (++index < length) {
 581        var value = array[index];
 582        if (predicate(value, index, array)) {
 583          result[resIndex++] = value;
 584        }
 585      }
 586      return result;
 587    }
 588  
 589    /**
 590     * A specialized version of `_.includes` for arrays without support for
 591     * specifying an index to search from.
 592     *
 593     * @private
 594     * @param {Array} [array] The array to inspect.
 595     * @param {*} target The value to search for.
 596     * @returns {boolean} Returns `true` if `target` is found, else `false`.
 597     */
 598    function arrayIncludes(array, value) {
 599      var length = array == null ? 0 : array.length;
 600      return !!length && baseIndexOf(array, value, 0) > -1;
 601    }
 602  
 603    /**
 604     * This function is like `arrayIncludes` except that it accepts a comparator.
 605     *
 606     * @private
 607     * @param {Array} [array] The array to inspect.
 608     * @param {*} target The value to search for.
 609     * @param {Function} comparator The comparator invoked per element.
 610     * @returns {boolean} Returns `true` if `target` is found, else `false`.
 611     */
 612    function arrayIncludesWith(array, value, comparator) {
 613      var index = -1,
 614          length = array == null ? 0 : array.length;
 615  
 616      while (++index < length) {
 617        if (comparator(value, array[index])) {
 618          return true;
 619        }
 620      }
 621      return false;
 622    }
 623  
 624    /**
 625     * A specialized version of `_.map` for arrays without support for iteratee
 626     * shorthands.
 627     *
 628     * @private
 629     * @param {Array} [array] The array to iterate over.
 630     * @param {Function} iteratee The function invoked per iteration.
 631     * @returns {Array} Returns the new mapped array.
 632     */
 633    function arrayMap(array, iteratee) {
 634      var index = -1,
 635          length = array == null ? 0 : array.length,
 636          result = Array(length);
 637  
 638      while (++index < length) {
 639        result[index] = iteratee(array[index], index, array);
 640      }
 641      return result;
 642    }
 643  
 644    /**
 645     * Appends the elements of `values` to `array`.
 646     *
 647     * @private
 648     * @param {Array} array The array to modify.
 649     * @param {Array} values The values to append.
 650     * @returns {Array} Returns `array`.
 651     */
 652    function arrayPush(array, values) {
 653      var index = -1,
 654          length = values.length,
 655          offset = array.length;
 656  
 657      while (++index < length) {
 658        array[offset + index] = values[index];
 659      }
 660      return array;
 661    }
 662  
 663    /**
 664     * A specialized version of `_.reduce` for arrays without support for
 665     * iteratee shorthands.
 666     *
 667     * @private
 668     * @param {Array} [array] The array to iterate over.
 669     * @param {Function} iteratee The function invoked per iteration.
 670     * @param {*} [accumulator] The initial value.
 671     * @param {boolean} [initAccum] Specify using the first element of `array` as
 672     *  the initial value.
 673     * @returns {*} Returns the accumulated value.
 674     */
 675    function arrayReduce(array, iteratee, accumulator, initAccum) {
 676      var index = -1,
 677          length = array == null ? 0 : array.length;
 678  
 679      if (initAccum && length) {
 680        accumulator = array[++index];
 681      }
 682      while (++index < length) {
 683        accumulator = iteratee(accumulator, array[index], index, array);
 684      }
 685      return accumulator;
 686    }
 687  
 688    /**
 689     * A specialized version of `_.reduceRight` for arrays without support for
 690     * iteratee shorthands.
 691     *
 692     * @private
 693     * @param {Array} [array] The array to iterate over.
 694     * @param {Function} iteratee The function invoked per iteration.
 695     * @param {*} [accumulator] The initial value.
 696     * @param {boolean} [initAccum] Specify using the last element of `array` as
 697     *  the initial value.
 698     * @returns {*} Returns the accumulated value.
 699     */
 700    function arrayReduceRight(array, iteratee, accumulator, initAccum) {
 701      var length = array == null ? 0 : array.length;
 702      if (initAccum && length) {
 703        accumulator = array[--length];
 704      }
 705      while (length--) {
 706        accumulator = iteratee(accumulator, array[length], length, array);
 707      }
 708      return accumulator;
 709    }
 710  
 711    /**
 712     * A specialized version of `_.some` for arrays without support for iteratee
 713     * shorthands.
 714     *
 715     * @private
 716     * @param {Array} [array] The array to iterate over.
 717     * @param {Function} predicate The function invoked per iteration.
 718     * @returns {boolean} Returns `true` if any element passes the predicate check,
 719     *  else `false`.
 720     */
 721    function arraySome(array, predicate) {
 722      var index = -1,
 723          length = array == null ? 0 : array.length;
 724  
 725      while (++index < length) {
 726        if (predicate(array[index], index, array)) {
 727          return true;
 728        }
 729      }
 730      return false;
 731    }
 732  
 733    /**
 734     * Gets the size of an ASCII `string`.
 735     *
 736     * @private
 737     * @param {string} string The string inspect.
 738     * @returns {number} Returns the string size.
 739     */
 740    var asciiSize = baseProperty('length');
 741  
 742    /**
 743     * Converts an ASCII `string` to an array.
 744     *
 745     * @private
 746     * @param {string} string The string to convert.
 747     * @returns {Array} Returns the converted array.
 748     */
 749    function asciiToArray(string) {
 750      return string.split('');
 751    }
 752  
 753    /**
 754     * Splits an ASCII `string` into an array of its words.
 755     *
 756     * @private
 757     * @param {string} The string to inspect.
 758     * @returns {Array} Returns the words of `string`.
 759     */
 760    function asciiWords(string) {
 761      return string.match(reAsciiWord) || [];
 762    }
 763  
 764    /**
 765     * The base implementation of methods like `_.findKey` and `_.findLastKey`,
 766     * without support for iteratee shorthands, which iterates over `collection`
 767     * using `eachFunc`.
 768     *
 769     * @private
 770     * @param {Array|Object} collection The collection to inspect.
 771     * @param {Function} predicate The function invoked per iteration.
 772     * @param {Function} eachFunc The function to iterate over `collection`.
 773     * @returns {*} Returns the found element or its key, else `undefined`.
 774     */
 775    function baseFindKey(collection, predicate, eachFunc) {
 776      var result;
 777      eachFunc(collection, function(value, key, collection) {
 778        if (predicate(value, key, collection)) {
 779          result = key;
 780          return false;
 781        }
 782      });
 783      return result;
 784    }
 785  
 786    /**
 787     * The base implementation of `_.findIndex` and `_.findLastIndex` without
 788     * support for iteratee shorthands.
 789     *
 790     * @private
 791     * @param {Array} array The array to inspect.
 792     * @param {Function} predicate The function invoked per iteration.
 793     * @param {number} fromIndex The index to search from.
 794     * @param {boolean} [fromRight] Specify iterating from right to left.
 795     * @returns {number} Returns the index of the matched value, else `-1`.
 796     */
 797    function baseFindIndex(array, predicate, fromIndex, fromRight) {
 798      var length = array.length,
 799          index = fromIndex + (fromRight ? 1 : -1);
 800  
 801      while ((fromRight ? index-- : ++index < length)) {
 802        if (predicate(array[index], index, array)) {
 803          return index;
 804        }
 805      }
 806      return -1;
 807    }
 808  
 809    /**
 810     * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
 811     *
 812     * @private
 813     * @param {Array} array The array to inspect.
 814     * @param {*} value The value to search for.
 815     * @param {number} fromIndex The index to search from.
 816     * @returns {number} Returns the index of the matched value, else `-1`.
 817     */
 818    function baseIndexOf(array, value, fromIndex) {
 819      return value === value
 820        ? strictIndexOf(array, value, fromIndex)
 821        : baseFindIndex(array, baseIsNaN, fromIndex);
 822    }
 823  
 824    /**
 825     * This function is like `baseIndexOf` except that it accepts a comparator.
 826     *
 827     * @private
 828     * @param {Array} array The array to inspect.
 829     * @param {*} value The value to search for.
 830     * @param {number} fromIndex The index to search from.
 831     * @param {Function} comparator The comparator invoked per element.
 832     * @returns {number} Returns the index of the matched value, else `-1`.
 833     */
 834    function baseIndexOfWith(array, value, fromIndex, comparator) {
 835      var index = fromIndex - 1,
 836          length = array.length;
 837  
 838      while (++index < length) {
 839        if (comparator(array[index], value)) {
 840          return index;
 841        }
 842      }
 843      return -1;
 844    }
 845  
 846    /**
 847     * The base implementation of `_.isNaN` without support for number objects.
 848     *
 849     * @private
 850     * @param {*} value The value to check.
 851     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
 852     */
 853    function baseIsNaN(value) {
 854      return value !== value;
 855    }
 856  
 857    /**
 858     * The base implementation of `_.mean` and `_.meanBy` without support for
 859     * iteratee shorthands.
 860     *
 861     * @private
 862     * @param {Array} array The array to iterate over.
 863     * @param {Function} iteratee The function invoked per iteration.
 864     * @returns {number} Returns the mean.
 865     */
 866    function baseMean(array, iteratee) {
 867      var length = array == null ? 0 : array.length;
 868      return length ? (baseSum(array, iteratee) / length) : NAN;
 869    }
 870  
 871    /**
 872     * The base implementation of `_.property` without support for deep paths.
 873     *
 874     * @private
 875     * @param {string} key The key of the property to get.
 876     * @returns {Function} Returns the new accessor function.
 877     */
 878    function baseProperty(key) {
 879      return function(object) {
 880        return object == null ? undefined : object[key];
 881      };
 882    }
 883  
 884    /**
 885     * The base implementation of `_.propertyOf` without support for deep paths.
 886     *
 887     * @private
 888     * @param {Object} object The object to query.
 889     * @returns {Function} Returns the new accessor function.
 890     */
 891    function basePropertyOf(object) {
 892      return function(key) {
 893        return object == null ? undefined : object[key];
 894      };
 895    }
 896  
 897    /**
 898     * The base implementation of `_.reduce` and `_.reduceRight`, without support
 899     * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
 900     *
 901     * @private
 902     * @param {Array|Object} collection The collection to iterate over.
 903     * @param {Function} iteratee The function invoked per iteration.
 904     * @param {*} accumulator The initial value.
 905     * @param {boolean} initAccum Specify using the first or last element of
 906     *  `collection` as the initial value.
 907     * @param {Function} eachFunc The function to iterate over `collection`.
 908     * @returns {*} Returns the accumulated value.
 909     */
 910    function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
 911      eachFunc(collection, function(value, index, collection) {
 912        accumulator = initAccum
 913          ? (initAccum = false, value)
 914          : iteratee(accumulator, value, index, collection);
 915      });
 916      return accumulator;
 917    }
 918  
 919    /**
 920     * The base implementation of `_.sortBy` which uses `comparer` to define the
 921     * sort order of `array` and replaces criteria objects with their corresponding
 922     * values.
 923     *
 924     * @private
 925     * @param {Array} array The array to sort.
 926     * @param {Function} comparer The function to define sort order.
 927     * @returns {Array} Returns `array`.
 928     */
 929    function baseSortBy(array, comparer) {
 930      var length = array.length;
 931  
 932      array.sort(comparer);
 933      while (length--) {
 934        array[length] = array[length].value;
 935      }
 936      return array;
 937    }
 938  
 939    /**
 940     * The base implementation of `_.sum` and `_.sumBy` without support for
 941     * iteratee shorthands.
 942     *
 943     * @private
 944     * @param {Array} array The array to iterate over.
 945     * @param {Function} iteratee The function invoked per iteration.
 946     * @returns {number} Returns the sum.
 947     */
 948    function baseSum(array, iteratee) {
 949      var result,
 950          index = -1,
 951          length = array.length;
 952  
 953      while (++index < length) {
 954        var current = iteratee(array[index]);
 955        if (current !== undefined) {
 956          result = result === undefined ? current : (result + current);
 957        }
 958      }
 959      return result;
 960    }
 961  
 962    /**
 963     * The base implementation of `_.times` without support for iteratee shorthands
 964     * or max array length checks.
 965     *
 966     * @private
 967     * @param {number} n The number of times to invoke `iteratee`.
 968     * @param {Function} iteratee The function invoked per iteration.
 969     * @returns {Array} Returns the array of results.
 970     */
 971    function baseTimes(n, iteratee) {
 972      var index = -1,
 973          result = Array(n);
 974  
 975      while (++index < n) {
 976        result[index] = iteratee(index);
 977      }
 978      return result;
 979    }
 980  
 981    /**
 982     * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
 983     * of key-value pairs for `object` corresponding to the property names of `props`.
 984     *
 985     * @private
 986     * @param {Object} object The object to query.
 987     * @param {Array} props The property names to get values for.
 988     * @returns {Object} Returns the key-value pairs.
 989     */
 990    function baseToPairs(object, props) {
 991      return arrayMap(props, function(key) {
 992        return [key, object[key]];
 993      });
 994    }
 995  
 996    /**
 997     * The base implementation of `_.unary` without support for storing metadata.
 998     *
 999     * @private
1000     * @param {Function} func The function to cap arguments for.
1001     * @returns {Function} Returns the new capped function.
1002     */
1003    function baseUnary(func) {
1004      return function(value) {
1005        return func(value);
1006      };
1007    }
1008  
1009    /**
1010     * The base implementation of `_.values` and `_.valuesIn` which creates an
1011     * array of `object` property values corresponding to the property names
1012     * of `props`.
1013     *
1014     * @private
1015     * @param {Object} object The object to query.
1016     * @param {Array} props The property names to get values for.
1017     * @returns {Object} Returns the array of property values.
1018     */
1019    function baseValues(object, props) {
1020      return arrayMap(props, function(key) {
1021        return object[key];
1022      });
1023    }
1024  
1025    /**
1026     * Checks if a `cache` value for `key` exists.
1027     *
1028     * @private
1029     * @param {Object} cache The cache to query.
1030     * @param {string} key The key of the entry to check.
1031     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1032     */
1033    function cacheHas(cache, key) {
1034      return cache.has(key);
1035    }
1036  
1037    /**
1038     * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
1039     * that is not found in the character symbols.
1040     *
1041     * @private
1042     * @param {Array} strSymbols The string symbols to inspect.
1043     * @param {Array} chrSymbols The character symbols to find.
1044     * @returns {number} Returns the index of the first unmatched string symbol.
1045     */
1046    function charsStartIndex(strSymbols, chrSymbols) {
1047      var index = -1,
1048          length = strSymbols.length;
1049  
1050      while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1051      return index;
1052    }
1053  
1054    /**
1055     * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
1056     * that is not found in the character symbols.
1057     *
1058     * @private
1059     * @param {Array} strSymbols The string symbols to inspect.
1060     * @param {Array} chrSymbols The character symbols to find.
1061     * @returns {number} Returns the index of the last unmatched string symbol.
1062     */
1063    function charsEndIndex(strSymbols, chrSymbols) {
1064      var index = strSymbols.length;
1065  
1066      while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1067      return index;
1068    }
1069  
1070    /**
1071     * Gets the number of `placeholder` occurrences in `array`.
1072     *
1073     * @private
1074     * @param {Array} array The array to inspect.
1075     * @param {*} placeholder The placeholder to search for.
1076     * @returns {number} Returns the placeholder count.
1077     */
1078    function countHolders(array, placeholder) {
1079      var length = array.length,
1080          result = 0;
1081  
1082      while (length--) {
1083        if (array[length] === placeholder) {
1084          ++result;
1085        }
1086      }
1087      return result;
1088    }
1089  
1090    /**
1091     * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
1092     * letters to basic Latin letters.
1093     *
1094     * @private
1095     * @param {string} letter The matched letter to deburr.
1096     * @returns {string} Returns the deburred letter.
1097     */
1098    var deburrLetter = basePropertyOf(deburredLetters);
1099  
1100    /**
1101     * Used by `_.escape` to convert characters to HTML entities.
1102     *
1103     * @private
1104     * @param {string} chr The matched character to escape.
1105     * @returns {string} Returns the escaped character.
1106     */
1107    var escapeHtmlChar = basePropertyOf(htmlEscapes);
1108  
1109    /**
1110     * Used by `_.template` to escape characters for inclusion in compiled string literals.
1111     *
1112     * @private
1113     * @param {string} chr The matched character to escape.
1114     * @returns {string} Returns the escaped character.
1115     */
1116    function escapeStringChar(chr) {
1117      return '\\' + stringEscapes[chr];
1118    }
1119  
1120    /**
1121     * Gets the value at `key` of `object`.
1122     *
1123     * @private
1124     * @param {Object} [object] The object to query.
1125     * @param {string} key The key of the property to get.
1126     * @returns {*} Returns the property value.
1127     */
1128    function getValue(object, key) {
1129      return object == null ? undefined : object[key];
1130    }
1131  
1132    /**
1133     * Checks if `string` contains Unicode symbols.
1134     *
1135     * @private
1136     * @param {string} string The string to inspect.
1137     * @returns {boolean} Returns `true` if a symbol is found, else `false`.
1138     */
1139    function hasUnicode(string) {
1140      return reHasUnicode.test(string);
1141    }
1142  
1143    /**
1144     * Checks if `string` contains a word composed of Unicode symbols.
1145     *
1146     * @private
1147     * @param {string} string The string to inspect.
1148     * @returns {boolean} Returns `true` if a word is found, else `false`.
1149     */
1150    function hasUnicodeWord(string) {
1151      return reHasUnicodeWord.test(string);
1152    }
1153  
1154    /**
1155     * Converts `iterator` to an array.
1156     *
1157     * @private
1158     * @param {Object} iterator The iterator to convert.
1159     * @returns {Array} Returns the converted array.
1160     */
1161    function iteratorToArray(iterator) {
1162      var data,
1163          result = [];
1164  
1165      while (!(data = iterator.next()).done) {
1166        result.push(data.value);
1167      }
1168      return result;
1169    }
1170  
1171    /**
1172     * Converts `map` to its key-value pairs.
1173     *
1174     * @private
1175     * @param {Object} map The map to convert.
1176     * @returns {Array} Returns the key-value pairs.
1177     */
1178    function mapToArray(map) {
1179      var index = -1,
1180          result = Array(map.size);
1181  
1182      map.forEach(function(value, key) {
1183        result[++index] = [key, value];
1184      });
1185      return result;
1186    }
1187  
1188    /**
1189     * Creates a unary function that invokes `func` with its argument transformed.
1190     *
1191     * @private
1192     * @param {Function} func The function to wrap.
1193     * @param {Function} transform The argument transform.
1194     * @returns {Function} Returns the new function.
1195     */
1196    function overArg(func, transform) {
1197      return function(arg) {
1198        return func(transform(arg));
1199      };
1200    }
1201  
1202    /**
1203     * Replaces all `placeholder` elements in `array` with an internal placeholder
1204     * and returns an array of their indexes.
1205     *
1206     * @private
1207     * @param {Array} array The array to modify.
1208     * @param {*} placeholder The placeholder to replace.
1209     * @returns {Array} Returns the new array of placeholder indexes.
1210     */
1211    function replaceHolders(array, placeholder) {
1212      var index = -1,
1213          length = array.length,
1214          resIndex = 0,
1215          result = [];
1216  
1217      while (++index < length) {
1218        var value = array[index];
1219        if (value === placeholder || value === PLACEHOLDER) {
1220          array[index] = PLACEHOLDER;
1221          result[resIndex++] = index;
1222        }
1223      }
1224      return result;
1225    }
1226  
1227    /**
1228     * Converts `set` to an array of its values.
1229     *
1230     * @private
1231     * @param {Object} set The set to convert.
1232     * @returns {Array} Returns the values.
1233     */
1234    function setToArray(set) {
1235      var index = -1,
1236          result = Array(set.size);
1237  
1238      set.forEach(function(value) {
1239        result[++index] = value;
1240      });
1241      return result;
1242    }
1243  
1244    /**
1245     * Converts `set` to its value-value pairs.
1246     *
1247     * @private
1248     * @param {Object} set The set to convert.
1249     * @returns {Array} Returns the value-value pairs.
1250     */
1251    function setToPairs(set) {
1252      var index = -1,
1253          result = Array(set.size);
1254  
1255      set.forEach(function(value) {
1256        result[++index] = [value, value];
1257      });
1258      return result;
1259    }
1260  
1261    /**
1262     * A specialized version of `_.indexOf` which performs strict equality
1263     * comparisons of values, i.e. `===`.
1264     *
1265     * @private
1266     * @param {Array} array The array to inspect.
1267     * @param {*} value The value to search for.
1268     * @param {number} fromIndex The index to search from.
1269     * @returns {number} Returns the index of the matched value, else `-1`.
1270     */
1271    function strictIndexOf(array, value, fromIndex) {
1272      var index = fromIndex - 1,
1273          length = array.length;
1274  
1275      while (++index < length) {
1276        if (array[index] === value) {
1277          return index;
1278        }
1279      }
1280      return -1;
1281    }
1282  
1283    /**
1284     * A specialized version of `_.lastIndexOf` which performs strict equality
1285     * comparisons of values, i.e. `===`.
1286     *
1287     * @private
1288     * @param {Array} array The array to inspect.
1289     * @param {*} value The value to search for.
1290     * @param {number} fromIndex The index to search from.
1291     * @returns {number} Returns the index of the matched value, else `-1`.
1292     */
1293    function strictLastIndexOf(array, value, fromIndex) {
1294      var index = fromIndex + 1;
1295      while (index--) {
1296        if (array[index] === value) {
1297          return index;
1298        }
1299      }
1300      return index;
1301    }
1302  
1303    /**
1304     * Gets the number of symbols in `string`.
1305     *
1306     * @private
1307     * @param {string} string The string to inspect.
1308     * @returns {number} Returns the string size.
1309     */
1310    function stringSize(string) {
1311      return hasUnicode(string)
1312        ? unicodeSize(string)
1313        : asciiSize(string);
1314    }
1315  
1316    /**
1317     * Converts `string` to an array.
1318     *
1319     * @private
1320     * @param {string} string The string to convert.
1321     * @returns {Array} Returns the converted array.
1322     */
1323    function stringToArray(string) {
1324      return hasUnicode(string)
1325        ? unicodeToArray(string)
1326        : asciiToArray(string);
1327    }
1328  
1329    /**
1330     * Used by `_.unescape` to convert HTML entities to characters.
1331     *
1332     * @private
1333     * @param {string} chr The matched character to unescape.
1334     * @returns {string} Returns the unescaped character.
1335     */
1336    var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
1337  
1338    /**
1339     * Gets the size of a Unicode `string`.
1340     *
1341     * @private
1342     * @param {string} string The string inspect.
1343     * @returns {number} Returns the string size.
1344     */
1345    function unicodeSize(string) {
1346      var result = reUnicode.lastIndex = 0;
1347      while (reUnicode.test(string)) {
1348        ++result;
1349      }
1350      return result;
1351    }
1352  
1353    /**
1354     * Converts a Unicode `string` to an array.
1355     *
1356     * @private
1357     * @param {string} string The string to convert.
1358     * @returns {Array} Returns the converted array.
1359     */
1360    function unicodeToArray(string) {
1361      return string.match(reUnicode) || [];
1362    }
1363  
1364    /**
1365     * Splits a Unicode `string` into an array of its words.
1366     *
1367     * @private
1368     * @param {string} The string to inspect.
1369     * @returns {Array} Returns the words of `string`.
1370     */
1371    function unicodeWords(string) {
1372      return string.match(reUnicodeWord) || [];
1373    }
1374  
1375    /*--------------------------------------------------------------------------*/
1376  
1377    /**
1378     * Create a new pristine `lodash` function using the `context` object.
1379     *
1380     * @static
1381     * @memberOf _
1382     * @since 1.1.0
1383     * @category Util
1384     * @param {Object} [context=root] The context object.
1385     * @returns {Function} Returns a new `lodash` function.
1386     * @example
1387     *
1388     * _.mixin({ 'foo': _.constant('foo') });
1389     *
1390     * var lodash = _.runInContext();
1391     * lodash.mixin({ 'bar': lodash.constant('bar') });
1392     *
1393     * _.isFunction(_.foo);
1394     * // => true
1395     * _.isFunction(_.bar);
1396     * // => false
1397     *
1398     * lodash.isFunction(lodash.foo);
1399     * // => false
1400     * lodash.isFunction(lodash.bar);
1401     * // => true
1402     *
1403     * // Create a suped-up `defer` in Node.js.
1404     * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1405     */
1406    var runInContext = (function runInContext(context) {
1407      context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
1408  
1409      /** Built-in constructor references. */
1410      var Array = context.Array,
1411          Date = context.Date,
1412          Error = context.Error,
1413          Function = context.Function,
1414          Math = context.Math,
1415          Object = context.Object,
1416          RegExp = context.RegExp,
1417          String = context.String,
1418          TypeError = context.TypeError;
1419  
1420      /** Used for built-in method references. */
1421      var arrayProto = Array.prototype,
1422          funcProto = Function.prototype,
1423          objectProto = Object.prototype;
1424  
1425      /** Used to detect overreaching core-js shims. */
1426      var coreJsData = context['__core-js_shared__'];
1427  
1428      /** Used to resolve the decompiled source of functions. */
1429      var funcToString = funcProto.toString;
1430  
1431      /** Used to check objects for own properties. */
1432      var hasOwnProperty = objectProto.hasOwnProperty;
1433  
1434      /** Used to generate unique IDs. */
1435      var idCounter = 0;
1436  
1437      /** Used to detect methods masquerading as native. */
1438      var maskSrcKey = (function() {
1439        var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
1440        return uid ? ('Symbol(src)_1.' + uid) : '';
1441      }());
1442  
1443      /**
1444       * Used to resolve the
1445       * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
1446       * of values.
1447       */
1448      var nativeObjectToString = objectProto.toString;
1449  
1450      /** Used to infer the `Object` constructor. */
1451      var objectCtorString = funcToString.call(Object);
1452  
1453      /** Used to restore the original `_` reference in `_.noConflict`. */
1454      var oldDash = root._;
1455  
1456      /** Used to detect if a method is native. */
1457      var reIsNative = RegExp('^' +
1458        funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1459        .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1460      );
1461  
1462      /** Built-in value references. */
1463      var Buffer = moduleExports ? context.Buffer : undefined,
1464          Symbol = context.Symbol,
1465          Uint8Array = context.Uint8Array,
1466          allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
1467          getPrototype = overArg(Object.getPrototypeOf, Object),
1468          objectCreate = Object.create,
1469          propertyIsEnumerable = objectProto.propertyIsEnumerable,
1470          splice = arrayProto.splice,
1471          spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
1472          symIterator = Symbol ? Symbol.iterator : undefined,
1473          symToStringTag = Symbol ? Symbol.toStringTag : undefined;
1474  
1475      var defineProperty = (function() {
1476        try {
1477          var func = getNative(Object, 'defineProperty');
1478          func({}, '', {});
1479          return func;
1480        } catch (e) {}
1481      }());
1482  
1483      /** Mocked built-ins. */
1484      var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
1485          ctxNow = Date && Date.now !== root.Date.now && Date.now,
1486          ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
1487  
1488      /* Built-in method references for those with the same name as other `lodash` methods. */
1489      var nativeCeil = Math.ceil,
1490          nativeFloor = Math.floor,
1491          nativeGetSymbols = Object.getOwnPropertySymbols,
1492          nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
1493          nativeIsFinite = context.isFinite,
1494          nativeJoin = arrayProto.join,
1495          nativeKeys = overArg(Object.keys, Object),
1496          nativeMax = Math.max,
1497          nativeMin = Math.min,
1498          nativeNow = Date.now,
1499          nativeParseInt = context.parseInt,
1500          nativeRandom = Math.random,
1501          nativeReverse = arrayProto.reverse;
1502  
1503      /* Built-in method references that are verified to be native. */
1504      var DataView = getNative(context, 'DataView'),
1505          Map = getNative(context, 'Map'),
1506          Promise = getNative(context, 'Promise'),
1507          Set = getNative(context, 'Set'),
1508          WeakMap = getNative(context, 'WeakMap'),
1509          nativeCreate = getNative(Object, 'create');
1510  
1511      /** Used to store function metadata. */
1512      var metaMap = WeakMap && new WeakMap;
1513  
1514      /** Used to lookup unminified function names. */
1515      var realNames = {};
1516  
1517      /** Used to detect maps, sets, and weakmaps. */
1518      var dataViewCtorString = toSource(DataView),
1519          mapCtorString = toSource(Map),
1520          promiseCtorString = toSource(Promise),
1521          setCtorString = toSource(Set),
1522          weakMapCtorString = toSource(WeakMap);
1523  
1524      /** Used to convert symbols to primitives and strings. */
1525      var symbolProto = Symbol ? Symbol.prototype : undefined,
1526          symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
1527          symbolToString = symbolProto ? symbolProto.toString : undefined;
1528  
1529      /*------------------------------------------------------------------------*/
1530  
1531      /**
1532       * Creates a `lodash` object which wraps `value` to enable implicit method
1533       * chain sequences. Methods that operate on and return arrays, collections,
1534       * and functions can be chained together. Methods that retrieve a single value
1535       * or may return a primitive value will automatically end the chain sequence
1536       * and return the unwrapped value. Otherwise, the value must be unwrapped
1537       * with `_#value`.
1538       *
1539       * Explicit chain sequences, which must be unwrapped with `_#value`, may be
1540       * enabled using `_.chain`.
1541       *
1542       * The execution of chained methods is lazy, that is, it's deferred until
1543       * `_#value` is implicitly or explicitly called.
1544       *
1545       * Lazy evaluation allows several methods to support shortcut fusion.
1546       * Shortcut fusion is an optimization to merge iteratee calls; this avoids
1547       * the creation of intermediate arrays and can greatly reduce the number of
1548       * iteratee executions. Sections of a chain sequence qualify for shortcut
1549       * fusion if the section is applied to an array and iteratees accept only
1550       * one argument. The heuristic for whether a section qualifies for shortcut
1551       * fusion is subject to change.
1552       *
1553       * Chaining is supported in custom builds as long as the `_#value` method is
1554       * directly or indirectly included in the build.
1555       *
1556       * In addition to lodash methods, wrappers have `Array` and `String` methods.
1557       *
1558       * The wrapper `Array` methods are:
1559       * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1560       *
1561       * The wrapper `String` methods are:
1562       * `replace` and `split`
1563       *
1564       * The wrapper methods that support shortcut fusion are:
1565       * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1566       * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1567       * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1568       *
1569       * The chainable wrapper methods are:
1570       * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1571       * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1572       * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1573       * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
1574       * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
1575       * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
1576       * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
1577       * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
1578       * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
1579       * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
1580       * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
1581       * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
1582       * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
1583       * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
1584       * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
1585       * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
1586       * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
1587       * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
1588       * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
1589       * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
1590       * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
1591       * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
1592       * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
1593       * `zipObject`, `zipObjectDeep`, and `zipWith`
1594       *
1595       * The wrapper methods that are **not** chainable by default are:
1596       * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1597       * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
1598       * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
1599       * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
1600       * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
1601       * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1602       * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1603       * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
1604       * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
1605       * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
1606       * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
1607       * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
1608       * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
1609       * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
1610       * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
1611       * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
1612       * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
1613       * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
1614       * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
1615       * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
1616       * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
1617       * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
1618       * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
1619       * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
1620       * `upperFirst`, `value`, and `words`
1621       *
1622       * @name _
1623       * @constructor
1624       * @category Seq
1625       * @param {*} value The value to wrap in a `lodash` instance.
1626       * @returns {Object} Returns the new `lodash` wrapper instance.
1627       * @example
1628       *
1629       * function square(n) {
1630       *   return n * n;
1631       * }
1632       *
1633       * var wrapped = _([1, 2, 3]);
1634       *
1635       * // Returns an unwrapped value.
1636       * wrapped.reduce(_.add);
1637       * // => 6
1638       *
1639       * // Returns a wrapped value.
1640       * var squares = wrapped.map(square);
1641       *
1642       * _.isArray(squares);
1643       * // => false
1644       *
1645       * _.isArray(squares.value());
1646       * // => true
1647       */
1648      function lodash(value) {
1649        if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1650          if (value instanceof LodashWrapper) {
1651            return value;
1652          }
1653          if (hasOwnProperty.call(value, '__wrapped__')) {
1654            return wrapperClone(value);
1655          }
1656        }
1657        return new LodashWrapper(value);
1658      }
1659  
1660      /**
1661       * The base implementation of `_.create` without support for assigning
1662       * properties to the created object.
1663       *
1664       * @private
1665       * @param {Object} proto The object to inherit from.
1666       * @returns {Object} Returns the new object.
1667       */
1668      var baseCreate = (function() {
1669        function object() {}
1670        return function(proto) {
1671          if (!isObject(proto)) {
1672            return {};
1673          }
1674          if (objectCreate) {
1675            return objectCreate(proto);
1676          }
1677          object.prototype = proto;
1678          var result = new object;
1679          object.prototype = undefined;
1680          return result;
1681        };
1682      }());
1683  
1684      /**
1685       * The function whose prototype chain sequence wrappers inherit from.
1686       *
1687       * @private
1688       */
1689      function baseLodash() {
1690        // No operation performed.
1691      }
1692  
1693      /**
1694       * The base constructor for creating `lodash` wrapper objects.
1695       *
1696       * @private
1697       * @param {*} value The value to wrap.
1698       * @param {boolean} [chainAll] Enable explicit method chain sequences.
1699       */
1700      function LodashWrapper(value, chainAll) {
1701        this.__wrapped__ = value;
1702        this.__actions__ = [];
1703        this.__chain__ = !!chainAll;
1704        this.__index__ = 0;
1705        this.__values__ = undefined;
1706      }
1707  
1708      /**
1709       * By default, the template delimiters used by lodash are like those in
1710       * embedded Ruby (ERB) as well as ES2015 template strings. Change the
1711       * following template settings to use alternative delimiters.
1712       *
1713       * @static
1714       * @memberOf _
1715       * @type {Object}
1716       */
1717      lodash.templateSettings = {
1718  
1719        /**
1720         * Used to detect `data` property values to be HTML-escaped.
1721         *
1722         * @memberOf _.templateSettings
1723         * @type {RegExp}
1724         */
1725        'escape': reEscape,
1726  
1727        /**
1728         * Used to detect code to be evaluated.
1729         *
1730         * @memberOf _.templateSettings
1731         * @type {RegExp}
1732         */
1733        'evaluate': reEvaluate,
1734  
1735        /**
1736         * Used to detect `data` property values to inject.
1737         *
1738         * @memberOf _.templateSettings
1739         * @type {RegExp}
1740         */
1741        'interpolate': reInterpolate,
1742  
1743        /**
1744         * Used to reference the data object in the template text.
1745         *
1746         * @memberOf _.templateSettings
1747         * @type {string}
1748         */
1749        'variable': '',
1750  
1751        /**
1752         * Used to import variables into the compiled template.
1753         *
1754         * @memberOf _.templateSettings
1755         * @type {Object}
1756         */
1757        'imports': {
1758  
1759          /**
1760           * A reference to the `lodash` function.
1761           *
1762           * @memberOf _.templateSettings.imports
1763           * @type {Function}
1764           */
1765          '_': lodash
1766        }
1767      };
1768  
1769      // Ensure wrappers are instances of `baseLodash`.
1770      lodash.prototype = baseLodash.prototype;
1771      lodash.prototype.constructor = lodash;
1772  
1773      LodashWrapper.prototype = baseCreate(baseLodash.prototype);
1774      LodashWrapper.prototype.constructor = LodashWrapper;
1775  
1776      /*------------------------------------------------------------------------*/
1777  
1778      /**
1779       * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1780       *
1781       * @private
1782       * @constructor
1783       * @param {*} value The value to wrap.
1784       */
1785      function LazyWrapper(value) {
1786        this.__wrapped__ = value;
1787        this.__actions__ = [];
1788        this.__dir__ = 1;
1789        this.__filtered__ = false;
1790        this.__iteratees__ = [];
1791        this.__takeCount__ = MAX_ARRAY_LENGTH;
1792        this.__views__ = [];
1793      }
1794  
1795      /**
1796       * Creates a clone of the lazy wrapper object.
1797       *
1798       * @private
1799       * @name clone
1800       * @memberOf LazyWrapper
1801       * @returns {Object} Returns the cloned `LazyWrapper` object.
1802       */
1803      function lazyClone() {
1804        var result = new LazyWrapper(this.__wrapped__);
1805        result.__actions__ = copyArray(this.__actions__);
1806        result.__dir__ = this.__dir__;
1807        result.__filtered__ = this.__filtered__;
1808        result.__iteratees__ = copyArray(this.__iteratees__);
1809        result.__takeCount__ = this.__takeCount__;
1810        result.__views__ = copyArray(this.__views__);
1811        return result;
1812      }
1813  
1814      /**
1815       * Reverses the direction of lazy iteration.
1816       *
1817       * @private
1818       * @name reverse
1819       * @memberOf LazyWrapper
1820       * @returns {Object} Returns the new reversed `LazyWrapper` object.
1821       */
1822      function lazyReverse() {
1823        if (this.__filtered__) {
1824          var result = new LazyWrapper(this);
1825          result.__dir__ = -1;
1826          result.__filtered__ = true;
1827        } else {
1828          result = this.clone();
1829          result.__dir__ *= -1;
1830        }
1831        return result;
1832      }
1833  
1834      /**
1835       * Extracts the unwrapped value from its lazy wrapper.
1836       *
1837       * @private
1838       * @name value
1839       * @memberOf LazyWrapper
1840       * @returns {*} Returns the unwrapped value.
1841       */
1842      function lazyValue() {
1843        var array = this.__wrapped__.value(),
1844            dir = this.__dir__,
1845            isArr = isArray(array),
1846            isRight = dir < 0,
1847            arrLength = isArr ? array.length : 0,
1848            view = getView(0, arrLength, this.__views__),
1849            start = view.start,
1850            end = view.end,
1851            length = end - start,
1852            index = isRight ? end : (start - 1),
1853            iteratees = this.__iteratees__,
1854            iterLength = iteratees.length,
1855            resIndex = 0,
1856            takeCount = nativeMin(length, this.__takeCount__);
1857  
1858        if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
1859          return baseWrapperValue(array, this.__actions__);
1860        }
1861        var result = [];
1862  
1863        outer:
1864        while (length-- && resIndex < takeCount) {
1865          index += dir;
1866  
1867          var iterIndex = -1,
1868              value = array[index];
1869  
1870          while (++iterIndex < iterLength) {
1871            var data = iteratees[iterIndex],
1872                iteratee = data.iteratee,
1873                type = data.type,
1874                computed = iteratee(value);
1875  
1876            if (type == LAZY_MAP_FLAG) {
1877              value = computed;
1878            } else if (!computed) {
1879              if (type == LAZY_FILTER_FLAG) {
1880                continue outer;
1881              } else {
1882                break outer;
1883              }
1884            }
1885          }
1886          result[resIndex++] = value;
1887        }
1888        return result;
1889      }
1890  
1891      // Ensure `LazyWrapper` is an instance of `baseLodash`.
1892      LazyWrapper.prototype = baseCreate(baseLodash.prototype);
1893      LazyWrapper.prototype.constructor = LazyWrapper;
1894  
1895      /*------------------------------------------------------------------------*/
1896  
1897      /**
1898       * Creates a hash object.
1899       *
1900       * @private
1901       * @constructor
1902       * @param {Array} [entries] The key-value pairs to cache.
1903       */
1904      function Hash(entries) {
1905        var index = -1,
1906            length = entries == null ? 0 : entries.length;
1907  
1908        this.clear();
1909        while (++index < length) {
1910          var entry = entries[index];
1911          this.set(entry[0], entry[1]);
1912        }
1913      }
1914  
1915      /**
1916       * Removes all key-value entries from the hash.
1917       *
1918       * @private
1919       * @name clear
1920       * @memberOf Hash
1921       */
1922      function hashClear() {
1923        this.__data__ = nativeCreate ? nativeCreate(null) : {};
1924        this.size = 0;
1925      }
1926  
1927      /**
1928       * Removes `key` and its value from the hash.
1929       *
1930       * @private
1931       * @name delete
1932       * @memberOf Hash
1933       * @param {Object} hash The hash to modify.
1934       * @param {string} key The key of the value to remove.
1935       * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1936       */
1937      function hashDelete(key) {
1938        var result = this.has(key) && delete this.__data__[key];
1939        this.size -= result ? 1 : 0;
1940        return result;
1941      }
1942  
1943      /**
1944       * Gets the hash value for `key`.
1945       *
1946       * @private
1947       * @name get
1948       * @memberOf Hash
1949       * @param {string} key The key of the value to get.
1950       * @returns {*} Returns the entry value.
1951       */
1952      function hashGet(key) {
1953        var data = this.__data__;
1954        if (nativeCreate) {
1955          var result = data[key];
1956          return result === HASH_UNDEFINED ? undefined : result;
1957        }
1958        return hasOwnProperty.call(data, key) ? data[key] : undefined;
1959      }
1960  
1961      /**
1962       * Checks if a hash value for `key` exists.
1963       *
1964       * @private
1965       * @name has
1966       * @memberOf Hash
1967       * @param {string} key The key of the entry to check.
1968       * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1969       */
1970      function hashHas(key) {
1971        var data = this.__data__;
1972        return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
1973      }
1974  
1975      /**
1976       * Sets the hash `key` to `value`.
1977       *
1978       * @private
1979       * @name set
1980       * @memberOf Hash
1981       * @param {string} key The key of the value to set.
1982       * @param {*} value The value to set.
1983       * @returns {Object} Returns the hash instance.
1984       */
1985      function hashSet(key, value) {
1986        var data = this.__data__;
1987        this.size += this.has(key) ? 0 : 1;
1988        data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1989        return this;
1990      }
1991  
1992      // Add methods to `Hash`.
1993      Hash.prototype.clear = hashClear;
1994      Hash.prototype['delete'] = hashDelete;
1995      Hash.prototype.get = hashGet;
1996      Hash.prototype.has = hashHas;
1997      Hash.prototype.set = hashSet;
1998  
1999      /*------------------------------------------------------------------------*/
2000  
2001      /**
2002       * Creates an list cache object.
2003       *
2004       * @private
2005       * @constructor
2006       * @param {Array} [entries] The key-value pairs to cache.
2007       */
2008      function ListCache(entries) {
2009        var index = -1,
2010            length = entries == null ? 0 : entries.length;
2011  
2012        this.clear();
2013        while (++index < length) {
2014          var entry = entries[index];
2015          this.set(entry[0], entry[1]);
2016        }
2017      }
2018  
2019      /**
2020       * Removes all key-value entries from the list cache.
2021       *
2022       * @private
2023       * @name clear
2024       * @memberOf ListCache
2025       */
2026      function listCacheClear() {
2027        this.__data__ = [];
2028        this.size = 0;
2029      }
2030  
2031      /**
2032       * Removes `key` and its value from the list cache.
2033       *
2034       * @private
2035       * @name delete
2036       * @memberOf ListCache
2037       * @param {string} key The key of the value to remove.
2038       * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2039       */
2040      function listCacheDelete(key) {
2041        var data = this.__data__,
2042            index = assocIndexOf(data, key);
2043  
2044        if (index < 0) {
2045          return false;
2046        }
2047        var lastIndex = data.length - 1;
2048        if (index == lastIndex) {
2049          data.pop();
2050        } else {
2051          splice.call(data, index, 1);
2052        }
2053        --this.size;
2054        return true;
2055      }
2056  
2057      /**
2058       * Gets the list cache value for `key`.
2059       *
2060       * @private
2061       * @name get
2062       * @memberOf ListCache
2063       * @param {string} key The key of the value to get.
2064       * @returns {*} Returns the entry value.
2065       */
2066      function listCacheGet(key) {
2067        var data = this.__data__,
2068            index = assocIndexOf(data, key);
2069  
2070        return index < 0 ? undefined : data[index][1];
2071      }
2072  
2073      /**
2074       * Checks if a list cache value for `key` exists.
2075       *
2076       * @private
2077       * @name has
2078       * @memberOf ListCache
2079       * @param {string} key The key of the entry to check.
2080       * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2081       */
2082      function listCacheHas(key) {
2083        return assocIndexOf(this.__data__, key) > -1;
2084      }
2085  
2086      /**
2087       * Sets the list cache `key` to `value`.
2088       *
2089       * @private
2090       * @name set
2091       * @memberOf ListCache
2092       * @param {string} key The key of the value to set.
2093       * @param {*} value The value to set.
2094       * @returns {Object} Returns the list cache instance.
2095       */
2096      function listCacheSet(key, value) {
2097        var data = this.__data__,
2098            index = assocIndexOf(data, key);
2099  
2100        if (index < 0) {
2101          ++this.size;
2102          data.push([key, value]);
2103        } else {
2104          data[index][1] = value;
2105        }
2106        return this;
2107      }
2108  
2109      // Add methods to `ListCache`.
2110      ListCache.prototype.clear = listCacheClear;
2111      ListCache.prototype['delete'] = listCacheDelete;
2112      ListCache.prototype.get = listCacheGet;
2113      ListCache.prototype.has = listCacheHas;
2114      ListCache.prototype.set = listCacheSet;
2115  
2116      /*------------------------------------------------------------------------*/
2117  
2118      /**
2119       * Creates a map cache object to store key-value pairs.
2120       *
2121       * @private
2122       * @constructor
2123       * @param {Array} [entries] The key-value pairs to cache.
2124       */
2125      function MapCache(entries) {
2126        var index = -1,
2127            length = entries == null ? 0 : entries.length;
2128  
2129        this.clear();
2130        while (++index < length) {
2131          var entry = entries[index];
2132          this.set(entry[0], entry[1]);
2133        }
2134      }
2135  
2136      /**
2137       * Removes all key-value entries from the map.
2138       *
2139       * @private
2140       * @name clear
2141       * @memberOf MapCache
2142       */
2143      function mapCacheClear() {
2144        this.size = 0;
2145        this.__data__ = {
2146          'hash': new Hash,
2147          'map': new (Map || ListCache),
2148          'string': new Hash
2149        };
2150      }
2151  
2152      /**
2153       * Removes `key` and its value from the map.
2154       *
2155       * @private
2156       * @name delete
2157       * @memberOf MapCache
2158       * @param {string} key The key of the value to remove.
2159       * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2160       */
2161      function mapCacheDelete(key) {
2162        var result = getMapData(this, key)['delete'](key);
2163        this.size -= result ? 1 : 0;
2164        return result;
2165      }
2166  
2167      /**
2168       * Gets the map value for `key`.
2169       *
2170       * @private
2171       * @name get
2172       * @memberOf MapCache
2173       * @param {string} key The key of the value to get.
2174       * @returns {*} Returns the entry value.
2175       */
2176      function mapCacheGet(key) {
2177        return getMapData(this, key).get(key);
2178      }
2179  
2180      /**
2181       * Checks if a map value for `key` exists.
2182       *
2183       * @private
2184       * @name has
2185       * @memberOf MapCache
2186       * @param {string} key The key of the entry to check.
2187       * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2188       */
2189      function mapCacheHas(key) {
2190        return getMapData(this, key).has(key);
2191      }
2192  
2193      /**
2194       * Sets the map `key` to `value`.
2195       *
2196       * @private
2197       * @name set
2198       * @memberOf MapCache
2199       * @param {string} key The key of the value to set.
2200       * @param {*} value The value to set.
2201       * @returns {Object} Returns the map cache instance.
2202       */
2203      function mapCacheSet(key, value) {
2204        var data = getMapData(this, key),
2205            size = data.size;
2206  
2207        data.set(key, value);
2208        this.size += data.size == size ? 0 : 1;
2209        return this;
2210      }
2211  
2212      // Add methods to `MapCache`.
2213      MapCache.prototype.clear = mapCacheClear;
2214      MapCache.prototype['delete'] = mapCacheDelete;
2215      MapCache.prototype.get = mapCacheGet;
2216      MapCache.prototype.has = mapCacheHas;
2217      MapCache.prototype.set = mapCacheSet;
2218  
2219      /*------------------------------------------------------------------------*/
2220  
2221      /**
2222       *
2223       * Creates an array cache object to store unique values.
2224       *
2225       * @private
2226       * @constructor
2227       * @param {Array} [values] The values to cache.
2228       */
2229      function SetCache(values) {
2230        var index = -1,
2231            length = values == null ? 0 : values.length;
2232  
2233        this.__data__ = new MapCache;
2234        while (++index < length) {
2235          this.add(values[index]);
2236        }
2237      }
2238  
2239      /**
2240       * Adds `value` to the array cache.
2241       *
2242       * @private
2243       * @name add
2244       * @memberOf SetCache
2245       * @alias push
2246       * @param {*} value The value to cache.
2247       * @returns {Object} Returns the cache instance.
2248       */
2249      function setCacheAdd(value) {
2250        this.__data__.set(value, HASH_UNDEFINED);
2251        return this;
2252      }
2253  
2254      /**
2255       * Checks if `value` is in the array cache.
2256       *
2257       * @private
2258       * @name has
2259       * @memberOf SetCache
2260       * @param {*} value The value to search for.
2261       * @returns {number} Returns `true` if `value` is found, else `false`.
2262       */
2263      function setCacheHas(value) {
2264        return this.__data__.has(value);
2265      }
2266  
2267      // Add methods to `SetCache`.
2268      SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
2269      SetCache.prototype.has = setCacheHas;
2270  
2271      /*------------------------------------------------------------------------*/
2272  
2273      /**
2274       * Creates a stack cache object to store key-value pairs.
2275       *
2276       * @private
2277       * @constructor
2278       * @param {Array} [entries] The key-value pairs to cache.
2279       */
2280      function Stack(entries) {
2281        var data = this.__data__ = new ListCache(entries);
2282        this.size = data.size;
2283      }
2284  
2285      /**
2286       * Removes all key-value entries from the stack.
2287       *
2288       * @private
2289       * @name clear
2290       * @memberOf Stack
2291       */
2292      function stackClear() {
2293        this.__data__ = new ListCache;
2294        this.size = 0;
2295      }
2296  
2297      /**
2298       * Removes `key` and its value from the stack.
2299       *
2300       * @private
2301       * @name delete
2302       * @memberOf Stack
2303       * @param {string} key The key of the value to remove.
2304       * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2305       */
2306      function stackDelete(key) {
2307        var data = this.__data__,
2308            result = data['delete'](key);
2309  
2310        this.size = data.size;
2311        return result;
2312      }
2313  
2314      /**
2315       * Gets the stack value for `key`.
2316       *
2317       * @private
2318       * @name get
2319       * @memberOf Stack
2320       * @param {string} key The key of the value to get.
2321       * @returns {*} Returns the entry value.
2322       */
2323      function stackGet(key) {
2324        return this.__data__.get(key);
2325      }
2326  
2327      /**
2328       * Checks if a stack value for `key` exists.
2329       *
2330       * @private
2331       * @name has
2332       * @memberOf Stack
2333       * @param {string} key The key of the entry to check.
2334       * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2335       */
2336      function stackHas(key) {
2337        return this.__data__.has(key);
2338      }
2339  
2340      /**
2341       * Sets the stack `key` to `value`.
2342       *
2343       * @private
2344       * @name set
2345       * @memberOf Stack
2346       * @param {string} key The key of the value to set.
2347       * @param {*} value The value to set.
2348       * @returns {Object} Returns the stack cache instance.
2349       */
2350      function stackSet(key, value) {
2351        var data = this.__data__;
2352        if (data instanceof ListCache) {
2353          var pairs = data.__data__;
2354          if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2355            pairs.push([key, value]);
2356            this.size = ++data.size;
2357            return this;
2358          }
2359          data = this.__data__ = new MapCache(pairs);
2360        }
2361        data.set(key, value);
2362        this.size = data.size;
2363        return this;
2364      }
2365  
2366      // Add methods to `Stack`.
2367      Stack.prototype.clear = stackClear;
2368      Stack.prototype['delete'] = stackDelete;
2369      Stack.prototype.get = stackGet;
2370      Stack.prototype.has = stackHas;
2371      Stack.prototype.set = stackSet;
2372  
2373      /*------------------------------------------------------------------------*/
2374  
2375      /**
2376       * Creates an array of the enumerable property names of the array-like `value`.
2377       *
2378       * @private
2379       * @param {*} value The value to query.
2380       * @param {boolean} inherited Specify returning inherited property names.
2381       * @returns {Array} Returns the array of property names.
2382       */
2383      function arrayLikeKeys(value, inherited) {
2384        var isArr = isArray(value),
2385            isArg = !isArr && isArguments(value),
2386            isBuff = !isArr && !isArg && isBuffer(value),
2387            isType = !isArr && !isArg && !isBuff && isTypedArray(value),
2388            skipIndexes = isArr || isArg || isBuff || isType,
2389            result = skipIndexes ? baseTimes(value.length, String) : [],
2390            length = result.length;
2391  
2392        for (var key in value) {
2393          if ((inherited || hasOwnProperty.call(value, key)) &&
2394              !(skipIndexes && (
2395                 // Safari 9 has enumerable `arguments.length` in strict mode.
2396                 key == 'length' ||
2397                 // Node.js 0.10 has enumerable non-index properties on buffers.
2398                 (isBuff && (key == 'offset' || key == 'parent')) ||
2399                 // PhantomJS 2 has enumerable non-index properties on typed arrays.
2400                 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
2401                 // Skip index properties.
2402                 isIndex(key, length)
2403              ))) {
2404            result.push(key);
2405          }
2406        }
2407        return result;
2408      }
2409  
2410      /**
2411       * A specialized version of `_.sample` for arrays.
2412       *
2413       * @private
2414       * @param {Array} array The array to sample.
2415       * @returns {*} Returns the random element.
2416       */
2417      function arraySample(array) {
2418        var length = array.length;
2419        return length ? array[baseRandom(0, length - 1)] : undefined;
2420      }
2421  
2422      /**
2423       * A specialized version of `_.sampleSize` for arrays.
2424       *
2425       * @private
2426       * @param {Array} array The array to sample.
2427       * @param {number} n The number of elements to sample.
2428       * @returns {Array} Returns the random elements.
2429       */
2430      function arraySampleSize(array, n) {
2431        return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
2432      }
2433  
2434      /**
2435       * A specialized version of `_.shuffle` for arrays.
2436       *
2437       * @private
2438       * @param {Array} array The array to shuffle.
2439       * @returns {Array} Returns the new shuffled array.
2440       */
2441      function arrayShuffle(array) {
2442        return shuffleSelf(copyArray(array));
2443      }
2444  
2445      /**
2446       * This function is like `assignValue` except that it doesn't assign
2447       * `undefined` values.
2448       *
2449       * @private
2450       * @param {Object} object The object to modify.
2451       * @param {string} key The key of the property to assign.
2452       * @param {*} value The value to assign.
2453       */
2454      function assignMergeValue(object, key, value) {
2455        if ((value !== undefined && !eq(object[key], value)) ||
2456            (value === undefined && !(key in object))) {
2457          baseAssignValue(object, key, value);
2458        }
2459      }
2460  
2461      /**
2462       * Assigns `value` to `key` of `object` if the existing value is not equivalent
2463       * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
2464       * for equality comparisons.
2465       *
2466       * @private
2467       * @param {Object} object The object to modify.
2468       * @param {string} key The key of the property to assign.
2469       * @param {*} value The value to assign.
2470       */
2471      function assignValue(object, key, value) {
2472        var objValue = object[key];
2473        if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2474            (value === undefined && !(key in object))) {
2475          baseAssignValue(object, key, value);
2476        }
2477      }
2478  
2479      /**
2480       * Gets the index at which the `key` is found in `array` of key-value pairs.
2481       *
2482       * @private
2483       * @param {Array} array The array to inspect.
2484       * @param {*} key The key to search for.
2485       * @returns {number} Returns the index of the matched value, else `-1`.
2486       */
2487      function assocIndexOf(array, key) {
2488        var length = array.length;
2489        while (length--) {
2490          if (eq(array[length][0], key)) {
2491            return length;
2492          }
2493        }
2494        return -1;
2495      }
2496  
2497      /**
2498       * Aggregates elements of `collection` on `accumulator` with keys transformed
2499       * by `iteratee` and values set by `setter`.
2500       *
2501       * @private
2502       * @param {Array|Object} collection The collection to iterate over.
2503       * @param {Function} setter The function to set `accumulator` values.
2504       * @param {Function} iteratee The iteratee to transform keys.
2505       * @param {Object} accumulator The initial aggregated object.
2506       * @returns {Function} Returns `accumulator`.
2507       */
2508      function baseAggregator(collection, setter, iteratee, accumulator) {
2509        baseEach(collection, function(value, key, collection) {
2510          setter(accumulator, value, iteratee(value), collection);
2511        });
2512        return accumulator;
2513      }
2514  
2515      /**
2516       * The base implementation of `_.assign` without support for multiple sources
2517       * or `customizer` functions.
2518       *
2519       * @private
2520       * @param {Object} object The destination object.
2521       * @param {Object} source The source object.
2522       * @returns {Object} Returns `object`.
2523       */
2524      function baseAssign(object, source) {
2525        return object && copyObject(source, keys(source), object);
2526      }
2527  
2528      /**
2529       * The base implementation of `_.assignIn` without support for multiple sources
2530       * or `customizer` functions.
2531       *
2532       * @private
2533       * @param {Object} object The destination object.
2534       * @param {Object} source The source object.
2535       * @returns {Object} Returns `object`.
2536       */
2537      function baseAssignIn(object, source) {
2538        return object && copyObject(source, keysIn(source), object);
2539      }
2540  
2541      /**
2542       * The base implementation of `assignValue` and `assignMergeValue` without
2543       * value checks.
2544       *
2545       * @private
2546       * @param {Object} object The object to modify.
2547       * @param {string} key The key of the property to assign.
2548       * @param {*} value The value to assign.
2549       */
2550      function baseAssignValue(object, key, value) {
2551        if (key == '__proto__' && defineProperty) {
2552          defineProperty(object, key, {
2553            'configurable': true,
2554            'enumerable': true,
2555            'value': value,
2556            'writable': true
2557          });
2558        } else {
2559          object[key] = value;
2560        }
2561      }
2562  
2563      /**
2564       * The base implementation of `_.at` without support for individual paths.
2565       *
2566       * @private
2567       * @param {Object} object The object to iterate over.
2568       * @param {string[]} paths The property paths to pick.
2569       * @returns {Array} Returns the picked elements.
2570       */
2571      function baseAt(object, paths) {
2572        var index = -1,
2573            length = paths.length,
2574            result = Array(length),
2575            skip = object == null;
2576  
2577        while (++index < length) {
2578          result[index] = skip ? undefined : get(object, paths[index]);
2579        }
2580        return result;
2581      }
2582  
2583      /**
2584       * The base implementation of `_.clamp` which doesn't coerce arguments.
2585       *
2586       * @private
2587       * @param {number} number The number to clamp.
2588       * @param {number} [lower] The lower bound.
2589       * @param {number} upper The upper bound.
2590       * @returns {number} Returns the clamped number.
2591       */
2592      function baseClamp(number, lower, upper) {
2593        if (number === number) {
2594          if (upper !== undefined) {
2595            number = number <= upper ? number : upper;
2596          }
2597          if (lower !== undefined) {
2598            number = number >= lower ? number : lower;
2599          }
2600        }
2601        return number;
2602      }
2603  
2604      /**
2605       * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2606       * traversed objects.
2607       *
2608       * @private
2609       * @param {*} value The value to clone.
2610       * @param {boolean} bitmask The bitmask flags.
2611       *  1 - Deep clone
2612       *  2 - Flatten inherited properties
2613       *  4 - Clone symbols
2614       * @param {Function} [customizer] The function to customize cloning.
2615       * @param {string} [key] The key of `value`.
2616       * @param {Object} [object] The parent object of `value`.
2617       * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2618       * @returns {*} Returns the cloned value.
2619       */
2620      function baseClone(value, bitmask, customizer, key, object, stack) {
2621        var result,
2622            isDeep = bitmask & CLONE_DEEP_FLAG,
2623            isFlat = bitmask & CLONE_FLAT_FLAG,
2624            isFull = bitmask & CLONE_SYMBOLS_FLAG;
2625  
2626        if (customizer) {
2627          result = object ? customizer(value, key, object, stack) : customizer(value);
2628        }
2629        if (result !== undefined) {
2630          return result;
2631        }
2632        if (!isObject(value)) {
2633          return value;
2634        }
2635        var isArr = isArray(value);
2636        if (isArr) {
2637          result = initCloneArray(value);
2638          if (!isDeep) {
2639            return copyArray(value, result);
2640          }
2641        } else {
2642          var tag = getTag(value),
2643              isFunc = tag == funcTag || tag == genTag;
2644  
2645          if (isBuffer(value)) {
2646            return cloneBuffer(value, isDeep);
2647          }
2648          if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2649            result = (isFlat || isFunc) ? {} : initCloneObject(value);
2650            if (!isDeep) {
2651              return isFlat
2652                ? copySymbolsIn(value, baseAssignIn(result, value))
2653                : copySymbols(value, baseAssign(result, value));
2654            }
2655          } else {
2656            if (!cloneableTags[tag]) {
2657              return object ? value : {};
2658            }
2659            result = initCloneByTag(value, tag, isDeep);
2660          }
2661        }
2662        // Check for circular references and return its corresponding clone.
2663        stack || (stack = new Stack);
2664        var stacked = stack.get(value);
2665        if (stacked) {
2666          return stacked;
2667        }
2668        stack.set(value, result);
2669  
2670        if (isSet(value)) {
2671          value.forEach(function(subValue) {
2672            result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
2673          });
2674        } else if (isMap(value)) {
2675          value.forEach(function(subValue, key) {
2676            result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
2677          });
2678        }
2679  
2680        var keysFunc = isFull
2681          ? (isFlat ? getAllKeysIn : getAllKeys)
2682          : (isFlat ? keysIn : keys);
2683  
2684        var props = isArr ? undefined : keysFunc(value);
2685        arrayEach(props || value, function(subValue, key) {
2686          if (props) {
2687            key = subValue;
2688            subValue = value[key];
2689          }
2690          // Recursively populate clone (susceptible to call stack limits).
2691          assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
2692        });
2693        return result;
2694      }
2695  
2696      /**
2697       * The base implementation of `_.conforms` which doesn't clone `source`.
2698       *
2699       * @private
2700       * @param {Object} source The object of property predicates to conform to.
2701       * @returns {Function} Returns the new spec function.
2702       */
2703      function baseConforms(source) {
2704        var props = keys(source);
2705        return function(object) {
2706          return baseConformsTo(object, source, props);
2707        };
2708      }
2709  
2710      /**
2711       * The base implementation of `_.conformsTo` which accepts `props` to check.
2712       *
2713       * @private
2714       * @param {Object} object The object to inspect.
2715       * @param {Object} source The object of property predicates to conform to.
2716       * @returns {boolean} Returns `true` if `object` conforms, else `false`.
2717       */
2718      function baseConformsTo(object, source, props) {
2719        var length = props.length;
2720        if (object == null) {
2721          return !length;
2722        }
2723        object = Object(object);
2724        while (length--) {
2725          var key = props[length],
2726              predicate = source[key],
2727              value = object[key];
2728  
2729          if ((value === undefined && !(key in object)) || !predicate(value)) {
2730            return false;
2731          }
2732        }
2733        return true;
2734      }
2735  
2736      /**
2737       * The base implementation of `_.delay` and `_.defer` which accepts `args`
2738       * to provide to `func`.
2739       *
2740       * @private
2741       * @param {Function} func The function to delay.
2742       * @param {number} wait The number of milliseconds to delay invocation.
2743       * @param {Array} args The arguments to provide to `func`.
2744       * @returns {number|Object} Returns the timer id or timeout object.
2745       */
2746      function baseDelay(func, wait, args) {
2747        if (typeof func != 'function') {
2748          throw new TypeError(FUNC_ERROR_TEXT);
2749        }
2750        return setTimeout(function() { func.apply(undefined, args); }, wait);
2751      }
2752  
2753      /**
2754       * The base implementation of methods like `_.difference` without support
2755       * for excluding multiple arrays or iteratee shorthands.
2756       *
2757       * @private
2758       * @param {Array} array The array to inspect.
2759       * @param {Array} values The values to exclude.
2760       * @param {Function} [iteratee] The iteratee invoked per element.
2761       * @param {Function} [comparator] The comparator invoked per element.
2762       * @returns {Array} Returns the new array of filtered values.
2763       */
2764      function baseDifference(array, values, iteratee, comparator) {
2765        var index = -1,
2766            includes = arrayIncludes,
2767            isCommon = true,
2768            length = array.length,
2769            result = [],
2770            valuesLength = values.length;
2771  
2772        if (!length) {
2773          return result;
2774        }
2775        if (iteratee) {
2776          values = arrayMap(values, baseUnary(iteratee));
2777        }
2778        if (comparator) {
2779          includes = arrayIncludesWith;
2780          isCommon = false;
2781        }
2782        else if (values.length >= LARGE_ARRAY_SIZE) {
2783          includes = cacheHas;
2784          isCommon = false;
2785          values = new SetCache(values);
2786        }
2787        outer:
2788        while (++index < length) {
2789          var value = array[index],
2790              computed = iteratee == null ? value : iteratee(value);
2791  
2792          value = (comparator || value !== 0) ? value : 0;
2793          if (isCommon && computed === computed) {
2794            var valuesIndex = valuesLength;
2795            while (valuesIndex--) {
2796              if (values[valuesIndex] === computed) {
2797                continue outer;
2798              }
2799            }
2800            result.push(value);
2801          }
2802          else if (!includes(values, computed, comparator)) {
2803            result.push(value);
2804          }
2805        }
2806        return result;
2807      }
2808  
2809      /**
2810       * The base implementation of `_.forEach` without support for iteratee shorthands.
2811       *
2812       * @private
2813       * @param {Array|Object} collection The collection to iterate over.
2814       * @param {Function} iteratee The function invoked per iteration.
2815       * @returns {Array|Object} Returns `collection`.
2816       */
2817      var baseEach = createBaseEach(baseForOwn);
2818  
2819      /**
2820       * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2821       *
2822       * @private
2823       * @param {Array|Object} collection The collection to iterate over.
2824       * @param {Function} iteratee The function invoked per iteration.
2825       * @returns {Array|Object} Returns `collection`.
2826       */
2827      var baseEachRight = createBaseEach(baseForOwnRight, true);
2828  
2829      /**
2830       * The base implementation of `_.every` without support for iteratee shorthands.
2831       *
2832       * @private
2833       * @param {Array|Object} collection The collection to iterate over.
2834       * @param {Function} predicate The function invoked per iteration.
2835       * @returns {boolean} Returns `true` if all elements pass the predicate check,
2836       *  else `false`
2837       */
2838      function baseEvery(collection, predicate) {
2839        var result = true;
2840        baseEach(collection, function(value, index, collection) {
2841          result = !!predicate(value, index, collection);
2842          return result;
2843        });
2844        return result;
2845      }
2846  
2847      /**
2848       * The base implementation of methods like `_.max` and `_.min` which accepts a
2849       * `comparator` to determine the extremum value.
2850       *
2851       * @private
2852       * @param {Array} array The array to iterate over.
2853       * @param {Function} iteratee The iteratee invoked per iteration.
2854       * @param {Function} comparator The comparator used to compare values.
2855       * @returns {*} Returns the extremum value.
2856       */
2857      function baseExtremum(array, iteratee, comparator) {
2858        var index = -1,
2859            length = array.length;
2860  
2861        while (++index < length) {
2862          var value = array[index],
2863              current = iteratee(value);
2864  
2865          if (current != null && (computed === undefined
2866                ? (current === current && !isSymbol(current))
2867                : comparator(current, computed)
2868              )) {
2869            var computed = current,
2870                result = value;
2871          }
2872        }
2873        return result;
2874      }
2875  
2876      /**
2877       * The base implementation of `_.fill` without an iteratee call guard.
2878       *
2879       * @private
2880       * @param {Array} array The array to fill.
2881       * @param {*} value The value to fill `array` with.
2882       * @param {number} [start=0] The start position.
2883       * @param {number} [end=array.length] The end position.
2884       * @returns {Array} Returns `array`.
2885       */
2886      function baseFill(array, value, start, end) {
2887        var length = array.length;
2888  
2889        start = toInteger(start);
2890        if (start < 0) {
2891          start = -start > length ? 0 : (length + start);
2892        }
2893        end = (end === undefined || end > length) ? length : toInteger(end);
2894        if (end < 0) {
2895          end += length;
2896        }
2897        end = start > end ? 0 : toLength(end);
2898        while (start < end) {
2899          array[start++] = value;
2900        }
2901        return array;
2902      }
2903  
2904      /**
2905       * The base implementation of `_.filter` without support for iteratee shorthands.
2906       *
2907       * @private
2908       * @param {Array|Object} collection The collection to iterate over.
2909       * @param {Function} predicate The function invoked per iteration.
2910       * @returns {Array} Returns the new filtered array.
2911       */
2912      function baseFilter(collection, predicate) {
2913        var result = [];
2914        baseEach(collection, function(value, index, collection) {
2915          if (predicate(value, index, collection)) {
2916            result.push(value);
2917          }
2918        });
2919        return result;
2920      }
2921  
2922      /**
2923       * The base implementation of `_.flatten` with support for restricting flattening.
2924       *
2925       * @private
2926       * @param {Array} array The array to flatten.
2927       * @param {number} depth The maximum recursion depth.
2928       * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2929       * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2930       * @param {Array} [result=[]] The initial result value.
2931       * @returns {Array} Returns the new flattened array.
2932       */
2933      function baseFlatten(array, depth, predicate, isStrict, result) {
2934        var index = -1,
2935            length = array.length;
2936  
2937        predicate || (predicate = isFlattenable);
2938        result || (result = []);
2939  
2940        while (++index < length) {
2941          var value = array[index];
2942          if (depth > 0 && predicate(value)) {
2943            if (depth > 1) {
2944              // Recursively flatten arrays (susceptible to call stack limits).
2945              baseFlatten(value, depth - 1, predicate, isStrict, result);
2946            } else {
2947              arrayPush(result, value);
2948            }
2949          } else if (!isStrict) {
2950            result[result.length] = value;
2951          }
2952        }
2953        return result;
2954      }
2955  
2956      /**
2957       * The base implementation of `baseForOwn` which iterates over `object`
2958       * properties returned by `keysFunc` and invokes `iteratee` for each property.
2959       * Iteratee functions may exit iteration early by explicitly returning `false`.
2960       *
2961       * @private
2962       * @param {Object} object The object to iterate over.
2963       * @param {Function} iteratee The function invoked per iteration.
2964       * @param {Function} keysFunc The function to get the keys of `object`.
2965       * @returns {Object} Returns `object`.
2966       */
2967      var baseFor = createBaseFor();
2968  
2969      /**
2970       * This function is like `baseFor` except that it iterates over properties
2971       * in the opposite order.
2972       *
2973       * @private
2974       * @param {Object} object The object to iterate over.
2975       * @param {Function} iteratee The function invoked per iteration.
2976       * @param {Function} keysFunc The function to get the keys of `object`.
2977       * @returns {Object} Returns `object`.
2978       */
2979      var baseForRight = createBaseFor(true);
2980  
2981      /**
2982       * The base implementation of `_.forOwn` without support for iteratee shorthands.
2983       *
2984       * @private
2985       * @param {Object} object The object to iterate over.
2986       * @param {Function} iteratee The function invoked per iteration.
2987       * @returns {Object} Returns `object`.
2988       */
2989      function baseForOwn(object, iteratee) {
2990        return object && baseFor(object, iteratee, keys);
2991      }
2992  
2993      /**
2994       * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2995       *
2996       * @private
2997       * @param {Object} object The object to iterate over.
2998       * @param {Function} iteratee The function invoked per iteration.
2999       * @returns {Object} Returns `object`.
3000       */
3001      function baseForOwnRight(object, iteratee) {
3002        return object && baseForRight(object, iteratee, keys);
3003      }
3004  
3005      /**
3006       * The base implementation of `_.functions` which creates an array of
3007       * `object` function property names filtered from `props`.
3008       *
3009       * @private
3010       * @param {Object} object The object to inspect.
3011       * @param {Array} props The property names to filter.
3012       * @returns {Array} Returns the function names.
3013       */
3014      function baseFunctions(object, props) {
3015        return arrayFilter(props, function(key) {
3016          return isFunction(object[key]);
3017        });
3018      }
3019  
3020      /**
3021       * The base implementation of `_.get` without support for default values.
3022       *
3023       * @private
3024       * @param {Object} object The object to query.
3025       * @param {Array|string} path The path of the property to get.
3026       * @returns {*} Returns the resolved value.
3027       */
3028      function baseGet(object, path) {
3029        path = castPath(path, object);
3030  
3031        var index = 0,
3032            length = path.length;
3033  
3034        while (object != null && index < length) {
3035          object = object[toKey(path[index++])];
3036        }
3037        return (index && index == length) ? object : undefined;
3038      }
3039  
3040      /**
3041       * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
3042       * `keysFunc` and `symbolsFunc` to get the enumerable property names and
3043       * symbols of `object`.
3044       *
3045       * @private
3046       * @param {Object} object The object to query.
3047       * @param {Function} keysFunc The function to get the keys of `object`.
3048       * @param {Function} symbolsFunc The function to get the symbols of `object`.
3049       * @returns {Array} Returns the array of property names and symbols.
3050       */
3051      function baseGetAllKeys(object, keysFunc, symbolsFunc) {
3052        var result = keysFunc(object);
3053        return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
3054      }
3055  
3056      /**
3057       * The base implementation of `getTag` without fallbacks for buggy environments.
3058       *
3059       * @private
3060       * @param {*} value The value to query.
3061       * @returns {string} Returns the `toStringTag`.
3062       */
3063      function baseGetTag(value) {
3064        if (value == null) {
3065          return value === undefined ? undefinedTag : nullTag;
3066        }
3067        return (symToStringTag && symToStringTag in Object(value))
3068          ? getRawTag(value)
3069          : objectToString(value);
3070      }
3071  
3072      /**
3073       * The base implementation of `_.gt` which doesn't coerce arguments.
3074       *
3075       * @private
3076       * @param {*} value The value to compare.
3077       * @param {*} other The other value to compare.
3078       * @returns {boolean} Returns `true` if `value` is greater than `other`,
3079       *  else `false`.
3080       */
3081      function baseGt(value, other) {
3082        return value > other;
3083      }
3084  
3085      /**
3086       * The base implementation of `_.has` without support for deep paths.
3087       *
3088       * @private
3089       * @param {Object} [object] The object to query.
3090       * @param {Array|string} key The key to check.
3091       * @returns {boolean} Returns `true` if `key` exists, else `false`.
3092       */
3093      function baseHas(object, key) {
3094        return object != null && hasOwnProperty.call(object, key);
3095      }
3096  
3097      /**
3098       * The base implementation of `_.hasIn` without support for deep paths.
3099       *
3100       * @private
3101       * @param {Object} [object] The object to query.
3102       * @param {Array|string} key The key to check.
3103       * @returns {boolean} Returns `true` if `key` exists, else `false`.
3104       */
3105      function baseHasIn(object, key) {
3106        return object != null && key in Object(object);
3107      }
3108  
3109      /**
3110       * The base implementation of `_.inRange` which doesn't coerce arguments.
3111       *
3112       * @private
3113       * @param {number} number The number to check.
3114       * @param {number} start The start of the range.
3115       * @param {number} end The end of the range.
3116       * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
3117       */
3118      function baseInRange(number, start, end) {
3119        return number >= nativeMin(start, end) && number < nativeMax(start, end);
3120      }
3121  
3122      /**
3123       * The base implementation of methods like `_.intersection`, without support
3124       * for iteratee shorthands, that accepts an array of arrays to inspect.
3125       *
3126       * @private
3127       * @param {Array} arrays The arrays to inspect.
3128       * @param {Function} [iteratee] The iteratee invoked per element.
3129       * @param {Function} [comparator] The comparator invoked per element.
3130       * @returns {Array} Returns the new array of shared values.
3131       */
3132      function baseIntersection(arrays, iteratee, comparator) {
3133        var includes = comparator ? arrayIncludesWith : arrayIncludes,
3134            length = arrays[0].length,
3135            othLength = arrays.length,
3136            othIndex = othLength,
3137            caches = Array(othLength),
3138            maxLength = Infinity,
3139            result = [];
3140  
3141        while (othIndex--) {
3142          var array = arrays[othIndex];
3143          if (othIndex && iteratee) {
3144            array = arrayMap(array, baseUnary(iteratee));
3145          }
3146          maxLength = nativeMin(array.length, maxLength);
3147          caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
3148            ? new SetCache(othIndex && array)
3149            : undefined;
3150        }
3151        array = arrays[0];
3152  
3153        var index = -1,
3154            seen = caches[0];
3155  
3156        outer:
3157        while (++index < length && result.length < maxLength) {
3158          var value = array[index],
3159              computed = iteratee ? iteratee(value) : value;
3160  
3161          value = (comparator || value !== 0) ? value : 0;
3162          if (!(seen
3163                ? cacheHas(seen, computed)
3164                : includes(result, computed, comparator)
3165              )) {
3166            othIndex = othLength;
3167            while (--othIndex) {
3168              var cache = caches[othIndex];
3169              if (!(cache
3170                    ? cacheHas(cache, computed)
3171                    : includes(arrays[othIndex], computed, comparator))
3172                  ) {
3173                continue outer;
3174              }
3175            }
3176            if (seen) {
3177              seen.push(computed);
3178            }
3179            result.push(value);
3180          }
3181        }
3182        return result;
3183      }
3184  
3185      /**
3186       * The base implementation of `_.invert` and `_.invertBy` which inverts
3187       * `object` with values transformed by `iteratee` and set by `setter`.
3188       *
3189       * @private
3190       * @param {Object} object The object to iterate over.
3191       * @param {Function} setter The function to set `accumulator` values.
3192       * @param {Function} iteratee The iteratee to transform values.
3193       * @param {Object} accumulator The initial inverted object.
3194       * @returns {Function} Returns `accumulator`.
3195       */
3196      function baseInverter(object, setter, iteratee, accumulator) {
3197        baseForOwn(object, function(value, key, object) {
3198          setter(accumulator, iteratee(value), key, object);
3199        });
3200        return accumulator;
3201      }
3202  
3203      /**
3204       * The base implementation of `_.invoke` without support for individual
3205       * method arguments.
3206       *
3207       * @private
3208       * @param {Object} object The object to query.
3209       * @param {Array|string} path The path of the method to invoke.
3210       * @param {Array} args The arguments to invoke the method with.
3211       * @returns {*} Returns the result of the invoked method.
3212       */
3213      function baseInvoke(object, path, args) {
3214        path = castPath(path, object);
3215        object = parent(object, path);
3216        var func = object == null ? object : object[toKey(last(path))];
3217        return func == null ? undefined : apply(func, object, args);
3218      }
3219  
3220      /**
3221       * The base implementation of `_.isArguments`.
3222       *
3223       * @private
3224       * @param {*} value The value to check.
3225       * @returns {boolean} Returns `true` if `value` is an `arguments` object,
3226       */
3227      function baseIsArguments(value) {
3228        return isObjectLike(value) && baseGetTag(value) == argsTag;
3229      }
3230  
3231      /**
3232       * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
3233       *
3234       * @private
3235       * @param {*} value The value to check.
3236       * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
3237       */
3238      function baseIsArrayBuffer(value) {
3239        return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
3240      }
3241  
3242      /**
3243       * The base implementation of `_.isDate` without Node.js optimizations.
3244       *
3245       * @private
3246       * @param {*} value The value to check.
3247       * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
3248       */
3249      function baseIsDate(value) {
3250        return isObjectLike(value) && baseGetTag(value) == dateTag;
3251      }
3252  
3253      /**
3254       * The base implementation of `_.isEqual` which supports partial comparisons
3255       * and tracks traversed objects.
3256       *
3257       * @private
3258       * @param {*} value The value to compare.
3259       * @param {*} other The other value to compare.
3260       * @param {boolean} bitmask The bitmask flags.
3261       *  1 - Unordered comparison
3262       *  2 - Partial comparison
3263       * @param {Function} [customizer] The function to customize comparisons.
3264       * @param {Object} [stack] Tracks traversed `value` and `other` objects.
3265       * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3266       */
3267      function baseIsEqual(value, other, bitmask, customizer, stack) {
3268        if (value === other) {
3269          return true;
3270        }
3271        if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
3272          return value !== value && other !== other;
3273        }
3274        return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
3275      }
3276  
3277      /**
3278       * A specialized version of `baseIsEqual` for arrays and objects which performs
3279       * deep comparisons and tracks traversed objects enabling objects with circular
3280       * references to be compared.
3281       *
3282       * @private
3283       * @param {Object} object The object to compare.
3284       * @param {Object} other The other object to compare.
3285       * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
3286       * @param {Function} customizer The function to customize comparisons.
3287       * @param {Function} equalFunc The function to determine equivalents of values.
3288       * @param {Object} [stack] Tracks traversed `object` and `other` objects.
3289       * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
3290       */
3291      function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
3292        var objIsArr = isArray(object),
3293            othIsArr = isArray(other),
3294            objTag = objIsArr ? arrayTag : getTag(object),
3295            othTag = othIsArr ? arrayTag : getTag(other);
3296  
3297        objTag = objTag == argsTag ? objectTag : objTag;
3298        othTag = othTag == argsTag ? objectTag : othTag;
3299  
3300        var objIsObj = objTag == objectTag,
3301            othIsObj = othTag == objectTag,
3302            isSameTag = objTag == othTag;
3303  
3304        if (isSameTag && isBuffer(object)) {
3305          if (!isBuffer(other)) {
3306            return false;
3307          }
3308          objIsArr = true;
3309          objIsObj = false;
3310        }
3311        if (isSameTag && !objIsObj) {
3312          stack || (stack = new Stack);
3313          return (objIsArr || isTypedArray(object))
3314            ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
3315            : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
3316        }
3317        if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
3318          var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
3319              othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
3320  
3321          if (objIsWrapped || othIsWrapped) {
3322            var objUnwrapped = objIsWrapped ? object.value() : object,
3323                othUnwrapped = othIsWrapped ? other.value() : other;
3324  
3325            stack || (stack = new Stack);
3326            return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
3327          }
3328        }
3329        if (!isSameTag) {
3330          return false;
3331        }
3332        stack || (stack = new Stack);
3333        return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
3334      }
3335  
3336      /**
3337       * The base implementation of `_.isMap` without Node.js optimizations.
3338       *
3339       * @private
3340       * @param {*} value The value to check.
3341       * @returns {boolean} Returns `true` if `value` is a map, else `false`.
3342       */
3343      function baseIsMap(value) {
3344        return isObjectLike(value) && getTag(value) == mapTag;
3345      }
3346  
3347      /**
3348       * The base implementation of `_.isMatch` without support for iteratee shorthands.
3349       *
3350       * @private
3351       * @param {Object} object The object to inspect.
3352       * @param {Object} source The object of property values to match.
3353       * @param {Array} matchData The property names, values, and compare flags to match.
3354       * @param {Function} [customizer] The function to customize comparisons.
3355       * @returns {boolean} Returns `true` if `object` is a match, else `false`.
3356       */
3357      function baseIsMatch(object, source, matchData, customizer) {
3358        var index = matchData.length,
3359            length = index,
3360            noCustomizer = !customizer;
3361  
3362        if (object == null) {
3363          return !length;
3364        }
3365        object = Object(object);
3366        while (index--) {
3367          var data = matchData[index];
3368          if ((noCustomizer && data[2])
3369                ? data[1] !== object[data[0]]
3370                : !(data[0] in object)
3371              ) {
3372            return false;
3373          }
3374        }
3375        while (++index < length) {
3376          data = matchData[index];
3377          var key = data[0],
3378              objValue = object[key],
3379              srcValue = data[1];
3380  
3381          if (noCustomizer && data[2]) {
3382            if (objValue === undefined && !(key in object)) {
3383              return false;
3384            }
3385          } else {
3386            var stack = new Stack;
3387            if (customizer) {
3388              var result = customizer(objValue, srcValue, key, object, source, stack);
3389            }
3390            if (!(result === undefined
3391                  ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
3392                  : result
3393                )) {
3394              return false;
3395            }
3396          }
3397        }
3398        return true;
3399      }
3400  
3401      /**
3402       * The base implementation of `_.isNative` without bad shim checks.
3403       *
3404       * @private
3405       * @param {*} value The value to check.
3406       * @returns {boolean} Returns `true` if `value` is a native function,
3407       *  else `false`.
3408       */
3409      function baseIsNative(value) {
3410        if (!isObject(value) || isMasked(value)) {
3411          return false;
3412        }
3413        var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
3414        return pattern.test(toSource(value));
3415      }
3416  
3417      /**
3418       * The base implementation of `_.isRegExp` without Node.js optimizations.
3419       *
3420       * @private
3421       * @param {*} value The value to check.
3422       * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
3423       */
3424      function baseIsRegExp(value) {
3425        return isObjectLike(value) && baseGetTag(value) == regexpTag;
3426      }
3427  
3428      /**
3429       * The base implementation of `_.isSet` without Node.js optimizations.
3430       *
3431       * @private
3432       * @param {*} value The value to check.
3433       * @returns {boolean} Returns `true` if `value` is a set, else `false`.
3434       */
3435      function baseIsSet(value) {
3436        return isObjectLike(value) && getTag(value) == setTag;
3437      }
3438  
3439      /**
3440       * The base implementation of `_.isTypedArray` without Node.js optimizations.
3441       *
3442       * @private
3443       * @param {*} value The value to check.
3444       * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
3445       */
3446      function baseIsTypedArray(value) {
3447        return isObjectLike(value) &&
3448          isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
3449      }
3450  
3451      /**
3452       * The base implementation of `_.iteratee`.
3453       *
3454       * @private
3455       * @param {*} [value=_.identity] The value to convert to an iteratee.
3456       * @returns {Function} Returns the iteratee.
3457       */
3458      function baseIteratee(value) {
3459        // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
3460        // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
3461        if (typeof value == 'function') {
3462          return value;
3463        }
3464        if (value == null) {
3465          return identity;
3466        }
3467        if (typeof value == 'object') {
3468          return isArray(value)
3469            ? baseMatchesProperty(value[0], value[1])
3470            : baseMatches(value);
3471        }
3472        return property(value);
3473      }
3474  
3475      /**
3476       * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
3477       *
3478       * @private
3479       * @param {Object} object The object to query.
3480       * @returns {Array} Returns the array of property names.
3481       */
3482      function baseKeys(object) {
3483        if (!isPrototype(object)) {
3484          return nativeKeys(object);
3485        }
3486        var result = [];
3487        for (var key in Object(object)) {
3488          if (hasOwnProperty.call(object, key) && key != 'constructor') {
3489            result.push(key);
3490          }
3491        }
3492        return result;
3493      }
3494  
3495      /**
3496       * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
3497       *
3498       * @private
3499       * @param {Object} object The object to query.
3500       * @returns {Array} Returns the array of property names.
3501       */
3502      function baseKeysIn(object) {
3503        if (!isObject(object)) {
3504          return nativeKeysIn(object);
3505        }
3506        var isProto = isPrototype(object),
3507            result = [];
3508  
3509        for (var key in object) {
3510          if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
3511            result.push(key);
3512          }
3513        }
3514        return result;
3515      }
3516  
3517      /**
3518       * The base implementation of `_.lt` which doesn't coerce arguments.
3519       *
3520       * @private
3521       * @param {*} value The value to compare.
3522       * @param {*} other The other value to compare.
3523       * @returns {boolean} Returns `true` if `value` is less than `other`,
3524       *  else `false`.
3525       */
3526      function baseLt(value, other) {
3527        return value < other;
3528      }
3529  
3530      /**
3531       * The base implementation of `_.map` without support for iteratee shorthands.
3532       *
3533       * @private
3534       * @param {Array|Object} collection The collection to iterate over.
3535       * @param {Function} iteratee The function invoked per iteration.
3536       * @returns {Array} Returns the new mapped array.
3537       */
3538      function baseMap(collection, iteratee) {
3539        var index = -1,
3540            result = isArrayLike(collection) ? Array(collection.length) : [];
3541  
3542        baseEach(collection, function(value, key, collection) {
3543          result[++index] = iteratee(value, key, collection);
3544        });
3545        return result;
3546      }
3547  
3548      /**
3549       * The base implementation of `_.matches` which doesn't clone `source`.
3550       *
3551       * @private
3552       * @param {Object} source The object of property values to match.
3553       * @returns {Function} Returns the new spec function.
3554       */
3555      function baseMatches(source) {
3556        var matchData = getMatchData(source);
3557        if (matchData.length == 1 && matchData[0][2]) {
3558          return matchesStrictComparable(matchData[0][0], matchData[0][1]);
3559        }
3560        return function(object) {
3561          return object === source || baseIsMatch(object, source, matchData);
3562        };
3563      }
3564  
3565      /**
3566       * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3567       *
3568       * @private
3569       * @param {string} path The path of the property to get.
3570       * @param {*} srcValue The value to match.
3571       * @returns {Function} Returns the new spec function.
3572       */
3573      function baseMatchesProperty(path, srcValue) {
3574        if (isKey(path) && isStrictComparable(srcValue)) {
3575          return matchesStrictComparable(toKey(path), srcValue);
3576        }
3577        return function(object) {
3578          var objValue = get(object, path);
3579          return (objValue === undefined && objValue === srcValue)
3580            ? hasIn(object, path)
3581            : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
3582        };
3583      }
3584  
3585      /**
3586       * The base implementation of `_.merge` without support for multiple sources.
3587       *
3588       * @private
3589       * @param {Object} object The destination object.
3590       * @param {Object} source The source object.
3591       * @param {number} srcIndex The index of `source`.
3592       * @param {Function} [customizer] The function to customize merged values.
3593       * @param {Object} [stack] Tracks traversed source values and their merged
3594       *  counterparts.
3595       */
3596      function baseMerge(object, source, srcIndex, customizer, stack) {
3597        if (object === source) {
3598          return;
3599        }
3600        baseFor(source, function(srcValue, key) {
3601          stack || (stack = new Stack);
3602          if (isObject(srcValue)) {
3603            baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3604          }
3605          else {
3606            var newValue = customizer
3607              ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
3608              : undefined;
3609  
3610            if (newValue === undefined) {
3611              newValue = srcValue;
3612            }
3613            assignMergeValue(object, key, newValue);
3614          }
3615        }, keysIn);
3616      }
3617  
3618      /**
3619       * A specialized version of `baseMerge` for arrays and objects which performs
3620       * deep merges and tracks traversed objects enabling objects with circular
3621       * references to be merged.
3622       *
3623       * @private
3624       * @param {Object} object The destination object.
3625       * @param {Object} source The source object.
3626       * @param {string} key The key of the value to merge.
3627       * @param {number} srcIndex The index of `source`.
3628       * @param {Function} mergeFunc The function to merge values.
3629       * @param {Function} [customizer] The function to customize assigned values.
3630       * @param {Object} [stack] Tracks traversed source values and their merged
3631       *  counterparts.
3632       */
3633      function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3634        var objValue = safeGet(object, key),
3635            srcValue = safeGet(source, key),
3636            stacked = stack.get(srcValue);
3637  
3638        if (stacked) {
3639          assignMergeValue(object, key, stacked);
3640          return;
3641        }
3642        var newValue = customizer
3643          ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3644          : undefined;
3645  
3646        var isCommon = newValue === undefined;
3647  
3648        if (isCommon) {
3649          var isArr = isArray(srcValue),
3650              isBuff = !isArr && isBuffer(srcValue),
3651              isTyped = !isArr && !isBuff && isTypedArray(srcValue);
3652  
3653          newValue = srcValue;
3654          if (isArr || isBuff || isTyped) {
3655            if (isArray(objValue)) {
3656              newValue = objValue;
3657            }
3658            else if (isArrayLikeObject(objValue)) {
3659              newValue = copyArray(objValue);
3660            }
3661            else if (isBuff) {
3662              isCommon = false;
3663              newValue = cloneBuffer(srcValue, true);
3664            }
3665            else if (isTyped) {
3666              isCommon = false;
3667              newValue = cloneTypedArray(srcValue, true);
3668            }
3669            else {
3670              newValue = [];
3671            }
3672          }
3673          else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3674            newValue = objValue;
3675            if (isArguments(objValue)) {
3676              newValue = toPlainObject(objValue);
3677            }
3678            else if (!isObject(objValue) || isFunction(objValue)) {
3679              newValue = initCloneObject(srcValue);
3680            }
3681          }
3682          else {
3683            isCommon = false;
3684          }
3685        }
3686        if (isCommon) {
3687          // Recursively merge objects and arrays (susceptible to call stack limits).
3688          stack.set(srcValue, newValue);
3689          mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3690          stack['delete'](srcValue);
3691        }
3692        assignMergeValue(object, key, newValue);
3693      }
3694  
3695      /**
3696       * The base implementation of `_.nth` which doesn't coerce arguments.
3697       *
3698       * @private
3699       * @param {Array} array The array to query.
3700       * @param {number} n The index of the element to return.
3701       * @returns {*} Returns the nth element of `array`.
3702       */
3703      function baseNth(array, n) {
3704        var length = array.length;
3705        if (!length) {
3706          return;
3707        }
3708        n += n < 0 ? length : 0;
3709        return isIndex(n, length) ? array[n] : undefined;
3710      }
3711  
3712      /**
3713       * The base implementation of `_.orderBy` without param guards.
3714       *
3715       * @private
3716       * @param {Array|Object} collection The collection to iterate over.
3717       * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3718       * @param {string[]} orders The sort orders of `iteratees`.
3719       * @returns {Array} Returns the new sorted array.
3720       */
3721      function baseOrderBy(collection, iteratees, orders) {
3722        if (iteratees.length) {
3723          iteratees = arrayMap(iteratees, function(iteratee) {
3724            if (isArray(iteratee)) {
3725              return function(value) {
3726                return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
3727              }
3728            }
3729            return iteratee;
3730          });
3731        } else {
3732          iteratees = [identity];
3733        }
3734  
3735        var index = -1;
3736        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
3737  
3738        var result = baseMap(collection, function(value, key, collection) {
3739          var criteria = arrayMap(iteratees, function(iteratee) {
3740            return iteratee(value);
3741          });
3742          return { 'criteria': criteria, 'index': ++index, 'value': value };
3743        });
3744  
3745        return baseSortBy(result, function(object, other) {
3746          return compareMultiple(object, other, orders);
3747        });
3748      }
3749  
3750      /**
3751       * The base implementation of `_.pick` without support for individual
3752       * property identifiers.
3753       *
3754       * @private
3755       * @param {Object} object The source object.
3756       * @param {string[]} paths The property paths to pick.
3757       * @returns {Object} Returns the new object.
3758       */
3759      function basePick(object, paths) {
3760        return basePickBy(object, paths, function(value, path) {
3761          return hasIn(object, path);
3762        });
3763      }
3764  
3765      /**
3766       * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3767       *
3768       * @private
3769       * @param {Object} object The source object.
3770       * @param {string[]} paths The property paths to pick.
3771       * @param {Function} predicate The function invoked per property.
3772       * @returns {Object} Returns the new object.
3773       */
3774      function basePickBy(object, paths, predicate) {
3775        var index = -1,
3776            length = paths.length,
3777            result = {};
3778  
3779        while (++index < length) {
3780          var path = paths[index],
3781              value = baseGet(object, path);
3782  
3783          if (predicate(value, path)) {
3784            baseSet(result, castPath(path, object), value);
3785          }
3786        }
3787        return result;
3788      }
3789  
3790      /**
3791       * A specialized version of `baseProperty` which supports deep paths.
3792       *
3793       * @private
3794       * @param {Array|string} path The path of the property to get.
3795       * @returns {Function} Returns the new accessor function.
3796       */
3797      function basePropertyDeep(path) {
3798        return function(object) {
3799          return baseGet(object, path);
3800        };
3801      }
3802  
3803      /**
3804       * The base implementation of `_.pullAllBy` without support for iteratee
3805       * shorthands.
3806       *
3807       * @private
3808       * @param {Array} array The array to modify.
3809       * @param {Array} values The values to remove.
3810       * @param {Function} [iteratee] The iteratee invoked per element.
3811       * @param {Function} [comparator] The comparator invoked per element.
3812       * @returns {Array} Returns `array`.
3813       */
3814      function basePullAll(array, values, iteratee, comparator) {
3815        var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
3816            index = -1,
3817            length = values.length,
3818            seen = array;
3819  
3820        if (array === values) {
3821          values = copyArray(values);
3822        }
3823        if (iteratee) {
3824          seen = arrayMap(array, baseUnary(iteratee));
3825        }
3826        while (++index < length) {
3827          var fromIndex = 0,
3828              value = values[index],
3829              computed = iteratee ? iteratee(value) : value;
3830  
3831          while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
3832            if (seen !== array) {
3833              splice.call(seen, fromIndex, 1);
3834            }
3835            splice.call(array, fromIndex, 1);
3836          }
3837        }
3838        return array;
3839      }
3840  
3841      /**
3842       * The base implementation of `_.pullAt` without support for individual
3843       * indexes or capturing the removed elements.
3844       *
3845       * @private
3846       * @param {Array} array The array to modify.
3847       * @param {number[]} indexes The indexes of elements to remove.
3848       * @returns {Array} Returns `array`.
3849       */
3850      function basePullAt(array, indexes) {
3851        var length = array ? indexes.length : 0,
3852            lastIndex = length - 1;
3853  
3854        while (length--) {
3855          var index = indexes[length];
3856          if (length == lastIndex || index !== previous) {
3857            var previous = index;
3858            if (isIndex(index)) {
3859              splice.call(array, index, 1);
3860            } else {
3861              baseUnset(array, index);
3862            }
3863          }
3864        }
3865        return array;
3866      }
3867  
3868      /**
3869       * The base implementation of `_.random` without support for returning
3870       * floating-point numbers.
3871       *
3872       * @private
3873       * @param {number} lower The lower bound.
3874       * @param {number} upper The upper bound.
3875       * @returns {number} Returns the random number.
3876       */
3877      function baseRandom(lower, upper) {
3878        return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3879      }
3880  
3881      /**
3882       * The base implementation of `_.range` and `_.rangeRight` which doesn't
3883       * coerce arguments.
3884       *
3885       * @private
3886       * @param {number} start The start of the range.
3887       * @param {number} end The end of the range.
3888       * @param {number} step The value to increment or decrement by.
3889       * @param {boolean} [fromRight] Specify iterating from right to left.
3890       * @returns {Array} Returns the range of numbers.
3891       */
3892      function baseRange(start, end, step, fromRight) {
3893        var index = -1,
3894            length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3895            result = Array(length);
3896  
3897        while (length--) {
3898          result[fromRight ? length : ++index] = start;
3899          start += step;
3900        }
3901        return result;
3902      }
3903  
3904      /**
3905       * The base implementation of `_.repeat` which doesn't coerce arguments.
3906       *
3907       * @private
3908       * @param {string} string The string to repeat.
3909       * @param {number} n The number of times to repeat the string.
3910       * @returns {string} Returns the repeated string.
3911       */
3912      function baseRepeat(string, n) {
3913        var result = '';
3914        if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
3915          return result;
3916        }
3917        // Leverage the exponentiation by squaring algorithm for a faster repeat.
3918        // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
3919        do {
3920          if (n % 2) {
3921            result += string;
3922          }
3923          n = nativeFloor(n / 2);
3924          if (n) {
3925            string += string;
3926          }
3927        } while (n);
3928  
3929        return result;
3930      }
3931  
3932      /**
3933       * The base implementation of `_.rest` which doesn't validate or coerce arguments.
3934       *
3935       * @private
3936       * @param {Function} func The function to apply a rest parameter to.
3937       * @param {number} [start=func.length-1] The start position of the rest parameter.
3938       * @returns {Function} Returns the new function.
3939       */
3940      function baseRest(func, start) {
3941        return setToString(overRest(func, start, identity), func + '');
3942      }
3943  
3944      /**
3945       * The base implementation of `_.sample`.
3946       *
3947       * @private
3948       * @param {Array|Object} collection The collection to sample.
3949       * @returns {*} Returns the random element.
3950       */
3951      function baseSample(collection) {
3952        return arraySample(values(collection));
3953      }
3954  
3955      /**
3956       * The base implementation of `_.sampleSize` without param guards.
3957       *
3958       * @private
3959       * @param {Array|Object} collection The collection to sample.
3960       * @param {number} n The number of elements to sample.
3961       * @returns {Array} Returns the random elements.
3962       */
3963      function baseSampleSize(collection, n) {
3964        var array = values(collection);
3965        return shuffleSelf(array, baseClamp(n, 0, array.length));
3966      }
3967  
3968      /**
3969       * The base implementation of `_.set`.
3970       *
3971       * @private
3972       * @param {Object} object The object to modify.
3973       * @param {Array|string} path The path of the property to set.
3974       * @param {*} value The value to set.
3975       * @param {Function} [customizer] The function to customize path creation.
3976       * @returns {Object} Returns `object`.
3977       */
3978      function baseSet(object, path, value, customizer) {
3979        if (!isObject(object)) {
3980          return object;
3981        }
3982        path = castPath(path, object);
3983  
3984        var index = -1,
3985            length = path.length,
3986            lastIndex = length - 1,
3987            nested = object;
3988  
3989        while (nested != null && ++index < length) {
3990          var key = toKey(path[index]),
3991              newValue = value;
3992  
3993          if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
3994            return object;
3995          }
3996  
3997          if (index != lastIndex) {
3998            var objValue = nested[key];
3999            newValue = customizer ? customizer(objValue, key, nested) : undefined;
4000            if (newValue === undefined) {
4001              newValue = isObject(objValue)
4002                ? objValue
4003                : (isIndex(path[index + 1]) ? [] : {});
4004            }
4005          }
4006          assignValue(nested, key, newValue);
4007          nested = nested[key];
4008        }
4009        return object;
4010      }
4011  
4012      /**
4013       * The base implementation of `setData` without support for hot loop shorting.
4014       *
4015       * @private
4016       * @param {Function} func The function to associate metadata with.
4017       * @param {*} data The metadata.
4018       * @returns {Function} Returns `func`.
4019       */
4020      var baseSetData = !metaMap ? identity : function(func, data) {
4021        metaMap.set(func, data);
4022        return func;
4023      };
4024  
4025      /**
4026       * The base implementation of `setToString` without support for hot loop shorting.
4027       *
4028       * @private
4029       * @param {Function} func The function to modify.
4030       * @param {Function} string The `toString` result.
4031       * @returns {Function} Returns `func`.
4032       */
4033      var baseSetToString = !defineProperty ? identity : function(func, string) {
4034        return defineProperty(func, 'toString', {
4035          'configurable': true,
4036          'enumerable': false,
4037          'value': constant(string),
4038          'writable': true
4039        });
4040      };
4041  
4042      /**
4043       * The base implementation of `_.shuffle`.
4044       *
4045       * @private
4046       * @param {Array|Object} collection The collection to shuffle.
4047       * @returns {Array} Returns the new shuffled array.
4048       */
4049      function baseShuffle(collection) {
4050        return shuffleSelf(values(collection));
4051      }
4052  
4053      /**
4054       * The base implementation of `_.slice` without an iteratee call guard.
4055       *
4056       * @private
4057       * @param {Array} array The array to slice.
4058       * @param {number} [start=0] The start position.
4059       * @param {number} [end=array.length] The end position.
4060       * @returns {Array} Returns the slice of `array`.
4061       */
4062      function baseSlice(array, start, end) {
4063        var index = -1,
4064            length = array.length;
4065  
4066        if (start < 0) {
4067          start = -start > length ? 0 : (length + start);
4068        }
4069        end = end > length ? length : end;
4070        if (end < 0) {
4071          end += length;
4072        }
4073        length = start > end ? 0 : ((end - start) >>> 0);
4074        start >>>= 0;
4075  
4076        var result = Array(length);
4077        while (++index < length) {
4078          result[index] = array[index + start];
4079        }
4080        return result;
4081      }
4082  
4083      /**
4084       * The base implementation of `_.some` without support for iteratee shorthands.
4085       *
4086       * @private
4087       * @param {Array|Object} collection The collection to iterate over.
4088       * @param {Function} predicate The function invoked per iteration.
4089       * @returns {boolean} Returns `true` if any element passes the predicate check,
4090       *  else `false`.
4091       */
4092      function baseSome(collection, predicate) {
4093        var result;
4094  
4095        baseEach(collection, function(value, index, collection) {
4096          result = predicate(value, index, collection);
4097          return !result;
4098        });
4099        return !!result;
4100      }
4101  
4102      /**
4103       * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
4104       * performs a binary search of `array` to determine the index at which `value`
4105       * should be inserted into `array` in order to maintain its sort order.
4106       *
4107       * @private
4108       * @param {Array} array The sorted array to inspect.
4109       * @param {*} value The value to evaluate.
4110       * @param {boolean} [retHighest] Specify returning the highest qualified index.
4111       * @returns {number} Returns the index at which `value` should be inserted
4112       *  into `array`.
4113       */
4114      function baseSortedIndex(array, value, retHighest) {
4115        var low = 0,
4116            high = array == null ? low : array.length;
4117  
4118        if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
4119          while (low < high) {
4120            var mid = (low + high) >>> 1,
4121                computed = array[mid];
4122  
4123            if (computed !== null && !isSymbol(computed) &&
4124                (retHighest ? (computed <= value) : (computed < value))) {
4125              low = mid + 1;
4126            } else {
4127              high = mid;
4128            }
4129          }
4130          return high;
4131        }
4132        return baseSortedIndexBy(array, value, identity, retHighest);
4133      }
4134  
4135      /**
4136       * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
4137       * which invokes `iteratee` for `value` and each element of `array` to compute
4138       * their sort ranking. The iteratee is invoked with one argument; (value).
4139       *
4140       * @private
4141       * @param {Array} array The sorted array to inspect.
4142       * @param {*} value The value to evaluate.
4143       * @param {Function} iteratee The iteratee invoked per element.
4144       * @param {boolean} [retHighest] Specify returning the highest qualified index.
4145       * @returns {number} Returns the index at which `value` should be inserted
4146       *  into `array`.
4147       */
4148      function baseSortedIndexBy(array, value, iteratee, retHighest) {
4149        var low = 0,
4150            high = array == null ? 0 : array.length;
4151        if (high === 0) {
4152          return 0;
4153        }
4154  
4155        value = iteratee(value);
4156        var valIsNaN = value !== value,
4157            valIsNull = value === null,
4158            valIsSymbol = isSymbol(value),
4159            valIsUndefined = value === undefined;
4160  
4161        while (low < high) {
4162          var mid = nativeFloor((low + high) / 2),
4163              computed = iteratee(array[mid]),
4164              othIsDefined = computed !== undefined,
4165              othIsNull = computed === null,
4166              othIsReflexive = computed === computed,
4167              othIsSymbol = isSymbol(computed);
4168  
4169          if (valIsNaN) {
4170            var setLow = retHighest || othIsReflexive;
4171          } else if (valIsUndefined) {
4172            setLow = othIsReflexive && (retHighest || othIsDefined);
4173          } else if (valIsNull) {
4174            setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
4175          } else if (valIsSymbol) {
4176            setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
4177          } else if (othIsNull || othIsSymbol) {
4178            setLow = false;
4179          } else {
4180            setLow = retHighest ? (computed <= value) : (computed < value);
4181          }
4182          if (setLow) {
4183            low = mid + 1;
4184          } else {
4185            high = mid;
4186          }
4187        }
4188        return nativeMin(high, MAX_ARRAY_INDEX);
4189      }
4190  
4191      /**
4192       * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
4193       * support for iteratee shorthands.
4194       *
4195       * @private
4196       * @param {Array} array The array to inspect.
4197       * @param {Function} [iteratee] The iteratee invoked per element.
4198       * @returns {Array} Returns the new duplicate free array.
4199       */
4200      function baseSortedUniq(array, iteratee) {
4201        var index = -1,
4202            length = array.length,
4203            resIndex = 0,
4204            result = [];
4205  
4206        while (++index < length) {
4207          var value = array[index],
4208              computed = iteratee ? iteratee(value) : value;
4209  
4210          if (!index || !eq(computed, seen)) {
4211            var seen = computed;
4212            result[resIndex++] = value === 0 ? 0 : value;
4213          }
4214        }
4215        return result;
4216      }
4217  
4218      /**
4219       * The base implementation of `_.toNumber` which doesn't ensure correct
4220       * conversions of binary, hexadecimal, or octal string values.
4221       *
4222       * @private
4223       * @param {*} value The value to process.
4224       * @returns {number} Returns the number.
4225       */
4226      function baseToNumber(value) {
4227        if (typeof value == 'number') {
4228          return value;
4229        }
4230        if (isSymbol(value)) {
4231          return NAN;
4232        }
4233        return +value;
4234      }
4235  
4236      /**
4237       * The base implementation of `_.toString` which doesn't convert nullish
4238       * values to empty strings.
4239       *
4240       * @private
4241       * @param {*} value The value to process.
4242       * @returns {string} Returns the string.
4243       */
4244      function baseToString(value) {
4245        // Exit early for strings to avoid a performance hit in some environments.
4246        if (typeof value == 'string') {
4247          return value;
4248        }
4249        if (isArray(value)) {
4250          // Recursively convert values (susceptible to call stack limits).
4251          return arrayMap(value, baseToString) + '';
4252        }
4253        if (isSymbol(value)) {
4254          return symbolToString ? symbolToString.call(value) : '';
4255        }
4256        var result = (value + '');
4257        return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
4258      }
4259  
4260      /**
4261       * The base implementation of `_.uniqBy` without support for iteratee shorthands.
4262       *
4263       * @private
4264       * @param {Array} array The array to inspect.
4265       * @param {Function} [iteratee] The iteratee invoked per element.
4266       * @param {Function} [comparator] The comparator invoked per element.
4267       * @returns {Array} Returns the new duplicate free array.
4268       */
4269      function baseUniq(array, iteratee, comparator) {
4270        var index = -1,
4271            includes = arrayIncludes,
4272            length = array.length,
4273            isCommon = true,
4274            result = [],
4275            seen = result;
4276  
4277        if (comparator) {
4278          isCommon = false;
4279          includes = arrayIncludesWith;
4280        }
4281        else if (length >= LARGE_ARRAY_SIZE) {
4282          var set = iteratee ? null : createSet(array);
4283          if (set) {
4284            return setToArray(set);
4285          }
4286          isCommon = false;
4287          includes = cacheHas;
4288          seen = new SetCache;
4289        }
4290        else {
4291          seen = iteratee ? [] : result;
4292        }
4293        outer:
4294        while (++index < length) {
4295          var value = array[index],
4296              computed = iteratee ? iteratee(value) : value;
4297  
4298          value = (comparator || value !== 0) ? value : 0;
4299          if (isCommon && computed === computed) {
4300            var seenIndex = seen.length;
4301            while (seenIndex--) {
4302              if (seen[seenIndex] === computed) {
4303                continue outer;
4304              }
4305            }
4306            if (iteratee) {
4307              seen.push(computed);
4308            }
4309            result.push(value);
4310          }
4311          else if (!includes(seen, computed, comparator)) {
4312            if (seen !== result) {
4313              seen.push(computed);
4314            }
4315            result.push(value);
4316          }
4317        }
4318        return result;
4319      }
4320  
4321      /**
4322       * The base implementation of `_.unset`.
4323       *
4324       * @private
4325       * @param {Object} object The object to modify.
4326       * @param {Array|string} path The property path to unset.
4327       * @returns {boolean} Returns `true` if the property is deleted, else `false`.
4328       */
4329      function baseUnset(object, path) {
4330        path = castPath(path, object);
4331        object = parent(object, path);
4332        return object == null || delete object[toKey(last(path))];
4333      }
4334  
4335      /**
4336       * The base implementation of `_.update`.
4337       *
4338       * @private
4339       * @param {Object} object The object to modify.
4340       * @param {Array|string} path The path of the property to update.
4341       * @param {Function} updater The function to produce the updated value.
4342       * @param {Function} [customizer] The function to customize path creation.
4343       * @returns {Object} Returns `object`.
4344       */
4345      function baseUpdate(object, path, updater, customizer) {
4346        return baseSet(object, path, updater(baseGet(object, path)), customizer);
4347      }
4348  
4349      /**
4350       * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
4351       * without support for iteratee shorthands.
4352       *
4353       * @private
4354       * @param {Array} array The array to query.
4355       * @param {Function} predicate The function invoked per iteration.
4356       * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
4357       * @param {boolean} [fromRight] Specify iterating from right to left.
4358       * @returns {Array} Returns the slice of `array`.
4359       */
4360      function baseWhile(array, predicate, isDrop, fromRight) {
4361        var length = array.length,
4362            index = fromRight ? length : -1;
4363  
4364        while ((fromRight ? index-- : ++index < length) &&
4365          predicate(array[index], index, array)) {}
4366  
4367        return isDrop
4368          ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
4369          : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
4370      }
4371  
4372      /**
4373       * The base implementation of `wrapperValue` which returns the result of
4374       * performing a sequence of actions on the unwrapped `value`, where each
4375       * successive action is supplied the return value of the previous.
4376       *
4377       * @private
4378       * @param {*} value The unwrapped value.
4379       * @param {Array} actions Actions to perform to resolve the unwrapped value.
4380       * @returns {*} Returns the resolved value.
4381       */
4382      function baseWrapperValue(value, actions) {
4383        var result = value;
4384        if (result instanceof LazyWrapper) {
4385          result = result.value();
4386        }
4387        return arrayReduce(actions, function(result, action) {
4388          return action.func.apply(action.thisArg, arrayPush([result], action.args));
4389        }, result);
4390      }
4391  
4392      /**
4393       * The base implementation of methods like `_.xor`, without support for
4394       * iteratee shorthands, that accepts an array of arrays to inspect.
4395       *
4396       * @private
4397       * @param {Array} arrays The arrays to inspect.
4398       * @param {Function} [iteratee] The iteratee invoked per element.
4399       * @param {Function} [comparator] The comparator invoked per element.
4400       * @returns {Array} Returns the new array of values.
4401       */
4402      function baseXor(arrays, iteratee, comparator) {
4403        var length = arrays.length;
4404        if (length < 2) {
4405          return length ? baseUniq(arrays[0]) : [];
4406        }
4407        var index = -1,
4408            result = Array(length);
4409  
4410        while (++index < length) {
4411          var array = arrays[index],
4412              othIndex = -1;
4413  
4414          while (++othIndex < length) {
4415            if (othIndex != index) {
4416              result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
4417            }
4418          }
4419        }
4420        return baseUniq(baseFlatten(result, 1), iteratee, comparator);
4421      }
4422  
4423      /**
4424       * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
4425       *
4426       * @private
4427       * @param {Array} props The property identifiers.
4428       * @param {Array} values The property values.
4429       * @param {Function} assignFunc The function to assign values.
4430       * @returns {Object} Returns the new object.
4431       */
4432      function baseZipObject(props, values, assignFunc) {
4433        var index = -1,
4434            length = props.length,
4435            valsLength = values.length,
4436            result = {};
4437  
4438        while (++index < length) {
4439          var value = index < valsLength ? values[index] : undefined;
4440          assignFunc(result, props[index], value);
4441        }
4442        return result;
4443      }
4444  
4445      /**
4446       * Casts `value` to an empty array if it's not an array like object.
4447       *
4448       * @private
4449       * @param {*} value The value to inspect.
4450       * @returns {Array|Object} Returns the cast array-like object.
4451       */
4452      function castArrayLikeObject(value) {
4453        return isArrayLikeObject(value) ? value : [];
4454      }
4455  
4456      /**
4457       * Casts `value` to `identity` if it's not a function.
4458       *
4459       * @private
4460       * @param {*} value The value to inspect.
4461       * @returns {Function} Returns cast function.
4462       */
4463      function castFunction(value) {
4464        return typeof value == 'function' ? value : identity;
4465      }
4466  
4467      /**
4468       * Casts `value` to a path array if it's not one.
4469       *
4470       * @private
4471       * @param {*} value The value to inspect.
4472       * @param {Object} [object] The object to query keys on.
4473       * @returns {Array} Returns the cast property path array.
4474       */
4475      function castPath(value, object) {
4476        if (isArray(value)) {
4477          return value;
4478        }
4479        return isKey(value, object) ? [value] : stringToPath(toString(value));
4480      }
4481  
4482      /**
4483       * A `baseRest` alias which can be replaced with `identity` by module
4484       * replacement plugins.
4485       *
4486       * @private
4487       * @type {Function}
4488       * @param {Function} func The function to apply a rest parameter to.
4489       * @returns {Function} Returns the new function.
4490       */
4491      var castRest = baseRest;
4492  
4493      /**
4494       * Casts `array` to a slice if it's needed.
4495       *
4496       * @private
4497       * @param {Array} array The array to inspect.
4498       * @param {number} start The start position.
4499       * @param {number} [end=array.length] The end position.
4500       * @returns {Array} Returns the cast slice.
4501       */
4502      function castSlice(array, start, end) {
4503        var length = array.length;
4504        end = end === undefined ? length : end;
4505        return (!start && end >= length) ? array : baseSlice(array, start, end);
4506      }
4507  
4508      /**
4509       * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
4510       *
4511       * @private
4512       * @param {number|Object} id The timer id or timeout object of the timer to clear.
4513       */
4514      var clearTimeout = ctxClearTimeout || function(id) {
4515        return root.clearTimeout(id);
4516      };
4517  
4518      /**
4519       * Creates a clone of  `buffer`.
4520       *
4521       * @private
4522       * @param {Buffer} buffer The buffer to clone.
4523       * @param {boolean} [isDeep] Specify a deep clone.
4524       * @returns {Buffer} Returns the cloned buffer.
4525       */
4526      function cloneBuffer(buffer, isDeep) {
4527        if (isDeep) {
4528          return buffer.slice();
4529        }
4530        var length = buffer.length,
4531            result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
4532  
4533        buffer.copy(result);
4534        return result;
4535      }
4536  
4537      /**
4538       * Creates a clone of `arrayBuffer`.
4539       *
4540       * @private
4541       * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
4542       * @returns {ArrayBuffer} Returns the cloned array buffer.
4543       */
4544      function cloneArrayBuffer(arrayBuffer) {
4545        var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
4546        new Uint8Array(result).set(new Uint8Array(arrayBuffer));
4547        return result;
4548      }
4549  
4550      /**
4551       * Creates a clone of `dataView`.
4552       *
4553       * @private
4554       * @param {Object} dataView The data view to clone.
4555       * @param {boolean} [isDeep] Specify a deep clone.
4556       * @returns {Object} Returns the cloned data view.
4557       */
4558      function cloneDataView(dataView, isDeep) {
4559        var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
4560        return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
4561      }
4562  
4563      /**
4564       * Creates a clone of `regexp`.
4565       *
4566       * @private
4567       * @param {Object} regexp The regexp to clone.
4568       * @returns {Object} Returns the cloned regexp.
4569       */
4570      function cloneRegExp(regexp) {
4571        var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
4572        result.lastIndex = regexp.lastIndex;
4573        return result;
4574      }
4575  
4576      /**
4577       * Creates a clone of the `symbol` object.
4578       *
4579       * @private
4580       * @param {Object} symbol The symbol object to clone.
4581       * @returns {Object} Returns the cloned symbol object.
4582       */
4583      function cloneSymbol(symbol) {
4584        return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
4585      }
4586  
4587      /**
4588       * Creates a clone of `typedArray`.
4589       *
4590       * @private
4591       * @param {Object} typedArray The typed array to clone.
4592       * @param {boolean} [isDeep] Specify a deep clone.
4593       * @returns {Object} Returns the cloned typed array.
4594       */
4595      function cloneTypedArray(typedArray, isDeep) {
4596        var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
4597        return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
4598      }
4599  
4600      /**
4601       * Compares values to sort them in ascending order.
4602       *
4603       * @private
4604       * @param {*} value The value to compare.
4605       * @param {*} other The other value to compare.
4606       * @returns {number} Returns the sort order indicator for `value`.
4607       */
4608      function compareAscending(value, other) {
4609        if (value !== other) {
4610          var valIsDefined = value !== undefined,
4611              valIsNull = value === null,
4612              valIsReflexive = value === value,
4613              valIsSymbol = isSymbol(value);
4614  
4615          var othIsDefined = other !== undefined,
4616              othIsNull = other === null,
4617              othIsReflexive = other === other,
4618              othIsSymbol = isSymbol(other);
4619  
4620          if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
4621              (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
4622              (valIsNull && othIsDefined && othIsReflexive) ||
4623              (!valIsDefined && othIsReflexive) ||
4624              !valIsReflexive) {
4625            return 1;
4626          }
4627          if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
4628              (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
4629              (othIsNull && valIsDefined && valIsReflexive) ||
4630              (!othIsDefined && valIsReflexive) ||
4631              !othIsReflexive) {
4632            return -1;
4633          }
4634        }
4635        return 0;
4636      }
4637  
4638      /**
4639       * Used by `_.orderBy` to compare multiple properties of a value to another
4640       * and stable sort them.
4641       *
4642       * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
4643       * specify an order of "desc" for descending or "asc" for ascending sort order
4644       * of corresponding values.
4645       *
4646       * @private
4647       * @param {Object} object The object to compare.
4648       * @param {Object} other The other object to compare.
4649       * @param {boolean[]|string[]} orders The order to sort by for each property.
4650       * @returns {number} Returns the sort order indicator for `object`.
4651       */
4652      function compareMultiple(object, other, orders) {
4653        var index = -1,
4654            objCriteria = object.criteria,
4655            othCriteria = other.criteria,
4656            length = objCriteria.length,
4657            ordersLength = orders.length;
4658  
4659        while (++index < length) {
4660          var result = compareAscending(objCriteria[index], othCriteria[index]);
4661          if (result) {
4662            if (index >= ordersLength) {
4663              return result;
4664            }
4665            var order = orders[index];
4666            return result * (order == 'desc' ? -1 : 1);
4667          }
4668        }
4669        // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
4670        // that causes it, under certain circumstances, to provide the same value for
4671        // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
4672        // for more details.
4673        //
4674        // This also ensures a stable sort in V8 and other engines.
4675        // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
4676        return object.index - other.index;
4677      }
4678  
4679      /**
4680       * Creates an array that is the composition of partially applied arguments,
4681       * placeholders, and provided arguments into a single array of arguments.
4682       *
4683       * @private
4684       * @param {Array} args The provided arguments.
4685       * @param {Array} partials The arguments to prepend to those provided.
4686       * @param {Array} holders The `partials` placeholder indexes.
4687       * @params {boolean} [isCurried] Specify composing for a curried function.
4688       * @returns {Array} Returns the new array of composed arguments.
4689       */
4690      function composeArgs(args, partials, holders, isCurried) {
4691        var argsIndex = -1,
4692            argsLength = args.length,
4693            holdersLength = holders.length,
4694            leftIndex = -1,
4695            leftLength = partials.length,
4696            rangeLength = nativeMax(argsLength - holdersLength, 0),
4697            result = Array(leftLength + rangeLength),
4698            isUncurried = !isCurried;
4699  
4700        while (++leftIndex < leftLength) {
4701          result[leftIndex] = partials[leftIndex];
4702        }
4703        while (++argsIndex < holdersLength) {
4704          if (isUncurried || argsIndex < argsLength) {
4705            result[holders[argsIndex]] = args[argsIndex];
4706          }
4707        }
4708        while (rangeLength--) {
4709          result[leftIndex++] = args[argsIndex++];
4710        }
4711        return result;
4712      }
4713  
4714      /**
4715       * This function is like `composeArgs` except that the arguments composition
4716       * is tailored for `_.partialRight`.
4717       *
4718       * @private
4719       * @param {Array} args The provided arguments.
4720       * @param {Array} partials The arguments to append to those provided.
4721       * @param {Array} holders The `partials` placeholder indexes.
4722       * @params {boolean} [isCurried] Specify composing for a curried function.
4723       * @returns {Array} Returns the new array of composed arguments.
4724       */
4725      function composeArgsRight(args, partials, holders, isCurried) {
4726        var argsIndex = -1,
4727            argsLength = args.length,
4728            holdersIndex = -1,
4729            holdersLength = holders.length,
4730            rightIndex = -1,
4731            rightLength = partials.length,
4732            rangeLength = nativeMax(argsLength - holdersLength, 0),
4733            result = Array(rangeLength + rightLength),
4734            isUncurried = !isCurried;
4735  
4736        while (++argsIndex < rangeLength) {
4737          result[argsIndex] = args[argsIndex];
4738        }
4739        var offset = argsIndex;
4740        while (++rightIndex < rightLength) {
4741          result[offset + rightIndex] = partials[rightIndex];
4742        }
4743        while (++holdersIndex < holdersLength) {
4744          if (isUncurried || argsIndex < argsLength) {
4745            result[offset + holders[holdersIndex]] = args[argsIndex++];
4746          }
4747        }
4748        return result;
4749      }
4750  
4751      /**
4752       * Copies the values of `source` to `array`.
4753       *
4754       * @private
4755       * @param {Array} source The array to copy values from.
4756       * @param {Array} [array=[]] The array to copy values to.
4757       * @returns {Array} Returns `array`.
4758       */
4759      function copyArray(source, array) {
4760        var index = -1,
4761            length = source.length;
4762  
4763        array || (array = Array(length));
4764        while (++index < length) {
4765          array[index] = source[index];
4766        }
4767        return array;
4768      }
4769  
4770      /**
4771       * Copies properties of `source` to `object`.
4772       *
4773       * @private
4774       * @param {Object} source The object to copy properties from.
4775       * @param {Array} props The property identifiers to copy.
4776       * @param {Object} [object={}] The object to copy properties to.
4777       * @param {Function} [customizer] The function to customize copied values.
4778       * @returns {Object} Returns `object`.
4779       */
4780      function copyObject(source, props, object, customizer) {
4781        var isNew = !object;
4782        object || (object = {});
4783  
4784        var index = -1,
4785            length = props.length;
4786  
4787        while (++index < length) {
4788          var key = props[index];
4789  
4790          var newValue = customizer
4791            ? customizer(object[key], source[key], key, object, source)
4792            : undefined;
4793  
4794          if (newValue === undefined) {
4795            newValue = source[key];
4796          }
4797          if (isNew) {
4798            baseAssignValue(object, key, newValue);
4799          } else {
4800            assignValue(object, key, newValue);
4801          }
4802        }
4803        return object;
4804      }
4805  
4806      /**
4807       * Copies own symbols of `source` to `object`.
4808       *
4809       * @private
4810       * @param {Object} source The object to copy symbols from.
4811       * @param {Object} [object={}] The object to copy symbols to.
4812       * @returns {Object} Returns `object`.
4813       */
4814      function copySymbols(source, object) {
4815        return copyObject(source, getSymbols(source), object);
4816      }
4817  
4818      /**
4819       * Copies own and inherited symbols of `source` to `object`.
4820       *
4821       * @private
4822       * @param {Object} source The object to copy symbols from.
4823       * @param {Object} [object={}] The object to copy symbols to.
4824       * @returns {Object} Returns `object`.
4825       */
4826      function copySymbolsIn(source, object) {
4827        return copyObject(source, getSymbolsIn(source), object);
4828      }
4829  
4830      /**
4831       * Creates a function like `_.groupBy`.
4832       *
4833       * @private
4834       * @param {Function} setter The function to set accumulator values.
4835       * @param {Function} [initializer] The accumulator object initializer.
4836       * @returns {Function} Returns the new aggregator function.
4837       */
4838      function createAggregator(setter, initializer) {
4839        return function(collection, iteratee) {
4840          var func = isArray(collection) ? arrayAggregator : baseAggregator,
4841              accumulator = initializer ? initializer() : {};
4842  
4843          return func(collection, setter, getIteratee(iteratee, 2), accumulator);
4844        };
4845      }
4846  
4847      /**
4848       * Creates a function like `_.assign`.
4849       *
4850       * @private
4851       * @param {Function} assigner The function to assign values.
4852       * @returns {Function} Returns the new assigner function.
4853       */
4854      function createAssigner(assigner) {
4855        return baseRest(function(object, sources) {
4856          var index = -1,
4857              length = sources.length,
4858              customizer = length > 1 ? sources[length - 1] : undefined,
4859              guard = length > 2 ? sources[2] : undefined;
4860  
4861          customizer = (assigner.length > 3 && typeof customizer == 'function')
4862            ? (length--, customizer)
4863            : undefined;
4864  
4865          if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4866            customizer = length < 3 ? undefined : customizer;
4867            length = 1;
4868          }
4869          object = Object(object);
4870          while (++index < length) {
4871            var source = sources[index];
4872            if (source) {
4873              assigner(object, source, index, customizer);
4874            }
4875          }
4876          return object;
4877        });
4878      }
4879  
4880      /**
4881       * Creates a `baseEach` or `baseEachRight` function.
4882       *
4883       * @private
4884       * @param {Function} eachFunc The function to iterate over a collection.
4885       * @param {boolean} [fromRight] Specify iterating from right to left.
4886       * @returns {Function} Returns the new base function.
4887       */
4888      function createBaseEach(eachFunc, fromRight) {
4889        return function(collection, iteratee) {
4890          if (collection == null) {
4891            return collection;
4892          }
4893          if (!isArrayLike(collection)) {
4894            return eachFunc(collection, iteratee);
4895          }
4896          var length = collection.length,
4897              index = fromRight ? length : -1,
4898              iterable = Object(collection);
4899  
4900          while ((fromRight ? index-- : ++index < length)) {
4901            if (iteratee(iterable[index], index, iterable) === false) {
4902              break;
4903            }
4904          }
4905          return collection;
4906        };
4907      }
4908  
4909      /**
4910       * Creates a base function for methods like `_.forIn` and `_.forOwn`.
4911       *
4912       * @private
4913       * @param {boolean} [fromRight] Specify iterating from right to left.
4914       * @returns {Function} Returns the new base function.
4915       */
4916      function createBaseFor(fromRight) {
4917        return function(object, iteratee, keysFunc) {
4918          var index = -1,
4919              iterable = Object(object),
4920              props = keysFunc(object),
4921              length = props.length;
4922  
4923          while (length--) {
4924            var key = props[fromRight ? length : ++index];
4925            if (iteratee(iterable[key], key, iterable) === false) {
4926              break;
4927            }
4928          }
4929          return object;
4930        };
4931      }
4932  
4933      /**
4934       * Creates a function that wraps `func` to invoke it with the optional `this`
4935       * binding of `thisArg`.
4936       *
4937       * @private
4938       * @param {Function} func The function to wrap.
4939       * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
4940       * @param {*} [thisArg] The `this` binding of `func`.
4941       * @returns {Function} Returns the new wrapped function.
4942       */
4943      function createBind(func, bitmask, thisArg) {
4944        var isBind = bitmask & WRAP_BIND_FLAG,
4945            Ctor = createCtor(func);
4946  
4947        function wrapper() {
4948          var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4949          return fn.apply(isBind ? thisArg : this, arguments);
4950        }
4951        return wrapper;
4952      }
4953  
4954      /**
4955       * Creates a function like `_.lowerFirst`.
4956       *
4957       * @private
4958       * @param {string} methodName The name of the `String` case method to use.
4959       * @returns {Function} Returns the new case function.
4960       */
4961      function createCaseFirst(methodName) {
4962        return function(string) {
4963          string = toString(string);
4964  
4965          var strSymbols = hasUnicode(string)
4966            ? stringToArray(string)
4967            : undefined;
4968  
4969          var chr = strSymbols
4970            ? strSymbols[0]
4971            : string.charAt(0);
4972  
4973          var trailing = strSymbols
4974            ? castSlice(strSymbols, 1).join('')
4975            : string.slice(1);
4976  
4977          return chr[methodName]() + trailing;
4978        };
4979      }
4980  
4981      /**
4982       * Creates a function like `_.camelCase`.
4983       *
4984       * @private
4985       * @param {Function} callback The function to combine each word.
4986       * @returns {Function} Returns the new compounder function.
4987       */
4988      function createCompounder(callback) {
4989        return function(string) {
4990          return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
4991        };
4992      }
4993  
4994      /**
4995       * Creates a function that produces an instance of `Ctor` regardless of
4996       * whether it was invoked as part of a `new` expression or by `call` or `apply`.
4997       *
4998       * @private
4999       * @param {Function} Ctor The constructor to wrap.
5000       * @returns {Function} Returns the new wrapped function.
5001       */
5002      function createCtor(Ctor) {
5003        return function() {
5004          // Use a `switch` statement to work with class constructors. See
5005          // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
5006          // for more details.
5007          var args = arguments;
5008          switch (args.length) {
5009            case 0: return new Ctor;
5010            case 1: return new Ctor(args[0]);
5011            case 2: return new Ctor(args[0], args[1]);
5012            case 3: return new Ctor(args[0], args[1], args[2]);
5013            case 4: return new Ctor(args[0], args[1], args[2], args[3]);
5014            case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
5015            case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
5016            case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
5017          }
5018          var thisBinding = baseCreate(Ctor.prototype),
5019              result = Ctor.apply(thisBinding, args);
5020  
5021          // Mimic the constructor's `return` behavior.
5022          // See https://es5.github.io/#x13.2.2 for more details.
5023          return isObject(result) ? result : thisBinding;
5024        };
5025      }
5026  
5027      /**
5028       * Creates a function that wraps `func` to enable currying.
5029       *
5030       * @private
5031       * @param {Function} func The function to wrap.
5032       * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5033       * @param {number} arity The arity of `func`.
5034       * @returns {Function} Returns the new wrapped function.
5035       */
5036      function createCurry(func, bitmask, arity) {
5037        var Ctor = createCtor(func);
5038  
5039        function wrapper() {
5040          var length = arguments.length,
5041              args = Array(length),
5042              index = length,
5043              placeholder = getHolder(wrapper);
5044  
5045          while (index--) {
5046            args[index] = arguments[index];
5047          }
5048          var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
5049            ? []
5050            : replaceHolders(args, placeholder);
5051  
5052          length -= holders.length;
5053          if (length < arity) {
5054            return createRecurry(
5055              func, bitmask, createHybrid, wrapper.placeholder, undefined,
5056              args, holders, undefined, undefined, arity - length);
5057          }
5058          var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5059          return apply(fn, this, args);
5060        }
5061        return wrapper;
5062      }
5063  
5064      /**
5065       * Creates a `_.find` or `_.findLast` function.
5066       *
5067       * @private
5068       * @param {Function} findIndexFunc The function to find the collection index.
5069       * @returns {Function} Returns the new find function.
5070       */
5071      function createFind(findIndexFunc) {
5072        return function(collection, predicate, fromIndex) {
5073          var iterable = Object(collection);
5074          if (!isArrayLike(collection)) {
5075            var iteratee = getIteratee(predicate, 3);
5076            collection = keys(collection);
5077            predicate = function(key) { return iteratee(iterable[key], key, iterable); };
5078          }
5079          var index = findIndexFunc(collection, predicate, fromIndex);
5080          return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
5081        };
5082      }
5083  
5084      /**
5085       * Creates a `_.flow` or `_.flowRight` function.
5086       *
5087       * @private
5088       * @param {boolean} [fromRight] Specify iterating from right to left.
5089       * @returns {Function} Returns the new flow function.
5090       */
5091      function createFlow(fromRight) {
5092        return flatRest(function(funcs) {
5093          var length = funcs.length,
5094              index = length,
5095              prereq = LodashWrapper.prototype.thru;
5096  
5097          if (fromRight) {
5098            funcs.reverse();
5099          }
5100          while (index--) {
5101            var func = funcs[index];
5102            if (typeof func != 'function') {
5103              throw new TypeError(FUNC_ERROR_TEXT);
5104            }
5105            if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
5106              var wrapper = new LodashWrapper([], true);
5107            }
5108          }
5109          index = wrapper ? index : length;
5110          while (++index < length) {
5111            func = funcs[index];
5112  
5113            var funcName = getFuncName(func),
5114                data = funcName == 'wrapper' ? getData(func) : undefined;
5115  
5116            if (data && isLaziable(data[0]) &&
5117                  data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
5118                  !data[4].length && data[9] == 1
5119                ) {
5120              wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
5121            } else {
5122              wrapper = (func.length == 1 && isLaziable(func))
5123                ? wrapper[funcName]()
5124                : wrapper.thru(func);
5125            }
5126          }
5127          return function() {
5128            var args = arguments,
5129                value = args[0];
5130  
5131            if (wrapper && args.length == 1 && isArray(value)) {
5132              return wrapper.plant(value).value();
5133            }
5134            var index = 0,
5135                result = length ? funcs[index].apply(this, args) : value;
5136  
5137            while (++index < length) {
5138              result = funcs[index].call(this, result);
5139            }
5140            return result;
5141          };
5142        });
5143      }
5144  
5145      /**
5146       * Creates a function that wraps `func` to invoke it with optional `this`
5147       * binding of `thisArg`, partial application, and currying.
5148       *
5149       * @private
5150       * @param {Function|string} func The function or method name to wrap.
5151       * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5152       * @param {*} [thisArg] The `this` binding of `func`.
5153       * @param {Array} [partials] The arguments to prepend to those provided to
5154       *  the new function.
5155       * @param {Array} [holders] The `partials` placeholder indexes.
5156       * @param {Array} [partialsRight] The arguments to append to those provided
5157       *  to the new function.
5158       * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
5159       * @param {Array} [argPos] The argument positions of the new function.
5160       * @param {number} [ary] The arity cap of `func`.
5161       * @param {number} [arity] The arity of `func`.
5162       * @returns {Function} Returns the new wrapped function.
5163       */
5164      function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
5165        var isAry = bitmask & WRAP_ARY_FLAG,
5166            isBind = bitmask & WRAP_BIND_FLAG,
5167            isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
5168            isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
5169            isFlip = bitmask & WRAP_FLIP_FLAG,
5170            Ctor = isBindKey ? undefined : createCtor(func);
5171  
5172        function wrapper() {
5173          var length = arguments.length,
5174              args = Array(length),
5175              index = length;
5176  
5177          while (index--) {
5178            args[index] = arguments[index];
5179          }
5180          if (isCurried) {
5181            var placeholder = getHolder(wrapper),
5182                holdersCount = countHolders(args, placeholder);
5183          }
5184          if (partials) {
5185            args = composeArgs(args, partials, holders, isCurried);
5186          }
5187          if (partialsRight) {
5188            args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
5189          }
5190          length -= holdersCount;
5191          if (isCurried && length < arity) {
5192            var newHolders = replaceHolders(args, placeholder);
5193            return createRecurry(
5194              func, bitmask, createHybrid, wrapper.placeholder, thisArg,
5195              args, newHolders, argPos, ary, arity - length
5196            );
5197          }
5198          var thisBinding = isBind ? thisArg : this,
5199              fn = isBindKey ? thisBinding[func] : func;
5200  
5201          length = args.length;
5202          if (argPos) {
5203            args = reorder(args, argPos);
5204          } else if (isFlip && length > 1) {
5205            args.reverse();
5206          }
5207          if (isAry && ary < length) {
5208            args.length = ary;
5209          }
5210          if (this && this !== root && this instanceof wrapper) {
5211            fn = Ctor || createCtor(fn);
5212          }
5213          return fn.apply(thisBinding, args);
5214        }
5215        return wrapper;
5216      }
5217  
5218      /**
5219       * Creates a function like `_.invertBy`.
5220       *
5221       * @private
5222       * @param {Function} setter The function to set accumulator values.
5223       * @param {Function} toIteratee The function to resolve iteratees.
5224       * @returns {Function} Returns the new inverter function.
5225       */
5226      function createInverter(setter, toIteratee) {
5227        return function(object, iteratee) {
5228          return baseInverter(object, setter, toIteratee(iteratee), {});
5229        };
5230      }
5231  
5232      /**
5233       * Creates a function that performs a mathematical operation on two values.
5234       *
5235       * @private
5236       * @param {Function} operator The function to perform the operation.
5237       * @param {number} [defaultValue] The value used for `undefined` arguments.
5238       * @returns {Function} Returns the new mathematical operation function.
5239       */
5240      function createMathOperation(operator, defaultValue) {
5241        return function(value, other) {
5242          var result;
5243          if (value === undefined && other === undefined) {
5244            return defaultValue;
5245          }
5246          if (value !== undefined) {
5247            result = value;
5248          }
5249          if (other !== undefined) {
5250            if (result === undefined) {
5251              return other;
5252            }
5253            if (typeof value == 'string' || typeof other == 'string') {
5254              value = baseToString(value);
5255              other = baseToString(other);
5256            } else {
5257              value = baseToNumber(value);
5258              other = baseToNumber(other);
5259            }
5260            result = operator(value, other);
5261          }
5262          return result;
5263        };
5264      }
5265  
5266      /**
5267       * Creates a function like `_.over`.
5268       *
5269       * @private
5270       * @param {Function} arrayFunc The function to iterate over iteratees.
5271       * @returns {Function} Returns the new over function.
5272       */
5273      function createOver(arrayFunc) {
5274        return flatRest(function(iteratees) {
5275          iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
5276          return baseRest(function(args) {
5277            var thisArg = this;
5278            return arrayFunc(iteratees, function(iteratee) {
5279              return apply(iteratee, thisArg, args);
5280            });
5281          });
5282        });
5283      }
5284  
5285      /**
5286       * Creates the padding for `string` based on `length`. The `chars` string
5287       * is truncated if the number of characters exceeds `length`.
5288       *
5289       * @private
5290       * @param {number} length The padding length.
5291       * @param {string} [chars=' '] The string used as padding.
5292       * @returns {string} Returns the padding for `string`.
5293       */
5294      function createPadding(length, chars) {
5295        chars = chars === undefined ? ' ' : baseToString(chars);
5296  
5297        var charsLength = chars.length;
5298        if (charsLength < 2) {
5299          return charsLength ? baseRepeat(chars, length) : chars;
5300        }
5301        var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
5302        return hasUnicode(chars)
5303          ? castSlice(stringToArray(result), 0, length).join('')
5304          : result.slice(0, length);
5305      }
5306  
5307      /**
5308       * Creates a function that wraps `func` to invoke it with the `this` binding
5309       * of `thisArg` and `partials` prepended to the arguments it receives.
5310       *
5311       * @private
5312       * @param {Function} func The function to wrap.
5313       * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5314       * @param {*} thisArg The `this` binding of `func`.
5315       * @param {Array} partials The arguments to prepend to those provided to
5316       *  the new function.
5317       * @returns {Function} Returns the new wrapped function.
5318       */
5319      function createPartial(func, bitmask, thisArg, partials) {
5320        var isBind = bitmask & WRAP_BIND_FLAG,
5321            Ctor = createCtor(func);
5322  
5323        function wrapper() {
5324          var argsIndex = -1,
5325              argsLength = arguments.length,
5326              leftIndex = -1,
5327              leftLength = partials.length,
5328              args = Array(leftLength + argsLength),
5329              fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5330  
5331          while (++leftIndex < leftLength) {
5332            args[leftIndex] = partials[leftIndex];
5333          }
5334          while (argsLength--) {
5335            args[leftIndex++] = arguments[++argsIndex];
5336          }
5337          return apply(fn, isBind ? thisArg : this, args);
5338        }
5339        return wrapper;
5340      }
5341  
5342      /**
5343       * Creates a `_.range` or `_.rangeRight` function.
5344       *
5345       * @private
5346       * @param {boolean} [fromRight] Specify iterating from right to left.
5347       * @returns {Function} Returns the new range function.
5348       */
5349      function createRange(fromRight) {
5350        return function(start, end, step) {
5351          if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
5352            end = step = undefined;
5353          }
5354          // Ensure the sign of `-0` is preserved.
5355          start = toFinite(start);
5356          if (end === undefined) {
5357            end = start;
5358            start = 0;
5359          } else {
5360            end = toFinite(end);
5361          }
5362          step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
5363          return baseRange(start, end, step, fromRight);
5364        };
5365      }
5366  
5367      /**
5368       * Creates a function that performs a relational operation on two values.
5369       *
5370       * @private
5371       * @param {Function} operator The function to perform the operation.
5372       * @returns {Function} Returns the new relational operation function.
5373       */
5374      function createRelationalOperation(operator) {
5375        return function(value, other) {
5376          if (!(typeof value == 'string' && typeof other == 'string')) {
5377            value = toNumber(value);
5378            other = toNumber(other);
5379          }
5380          return operator(value, other);
5381        };
5382      }
5383  
5384      /**
5385       * Creates a function that wraps `func` to continue currying.
5386       *
5387       * @private
5388       * @param {Function} func The function to wrap.
5389       * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5390       * @param {Function} wrapFunc The function to create the `func` wrapper.
5391       * @param {*} placeholder The placeholder value.
5392       * @param {*} [thisArg] The `this` binding of `func`.
5393       * @param {Array} [partials] The arguments to prepend to those provided to
5394       *  the new function.
5395       * @param {Array} [holders] The `partials` placeholder indexes.
5396       * @param {Array} [argPos] The argument positions of the new function.
5397       * @param {number} [ary] The arity cap of `func`.
5398       * @param {number} [arity] The arity of `func`.
5399       * @returns {Function} Returns the new wrapped function.
5400       */
5401      function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
5402        var isCurry = bitmask & WRAP_CURRY_FLAG,
5403            newHolders = isCurry ? holders : undefined,
5404            newHoldersRight = isCurry ? undefined : holders,
5405            newPartials = isCurry ? partials : undefined,
5406            newPartialsRight = isCurry ? undefined : partials;
5407  
5408        bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
5409        bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
5410  
5411        if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
5412          bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
5413        }
5414        var newData = [
5415          func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
5416          newHoldersRight, argPos, ary, arity
5417        ];
5418  
5419        var result = wrapFunc.apply(undefined, newData);
5420        if (isLaziable(func)) {
5421          setData(result, newData);
5422        }
5423        result.placeholder = placeholder;
5424        return setWrapToString(result, func, bitmask);
5425      }
5426  
5427      /**
5428       * Creates a function like `_.round`.
5429       *
5430       * @private
5431       * @param {string} methodName The name of the `Math` method to use when rounding.
5432       * @returns {Function} Returns the new round function.
5433       */
5434      function createRound(methodName) {
5435        var func = Math[methodName];
5436        return function(number, precision) {
5437          number = toNumber(number);
5438          precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
5439          if (precision && nativeIsFinite(number)) {
5440            // Shift with exponential notation to avoid floating-point issues.
5441            // See [MDN](https://mdn.io/round#Examples) for more details.
5442            var pair = (toString(number) + 'e').split('e'),
5443                value = func(pair[0] + 'e' + (+pair[1] + precision));
5444  
5445            pair = (toString(value) + 'e').split('e');
5446            return +(pair[0] + 'e' + (+pair[1] - precision));
5447          }
5448          return func(number);
5449        };
5450      }
5451  
5452      /**
5453       * Creates a set object of `values`.
5454       *
5455       * @private
5456       * @param {Array} values The values to add to the set.
5457       * @returns {Object} Returns the new set.
5458       */
5459      var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
5460        return new Set(values);
5461      };
5462  
5463      /**
5464       * Creates a `_.toPairs` or `_.toPairsIn` function.
5465       *
5466       * @private
5467       * @param {Function} keysFunc The function to get the keys of a given object.
5468       * @returns {Function} Returns the new pairs function.
5469       */
5470      function createToPairs(keysFunc) {
5471        return function(object) {
5472          var tag = getTag(object);
5473          if (tag == mapTag) {
5474            return mapToArray(object);
5475          }
5476          if (tag == setTag) {
5477            return setToPairs(object);
5478          }
5479          return baseToPairs(object, keysFunc(object));
5480        };
5481      }
5482  
5483      /**
5484       * Creates a function that either curries or invokes `func` with optional
5485       * `this` binding and partially applied arguments.
5486       *
5487       * @private
5488       * @param {Function|string} func The function or method name to wrap.
5489       * @param {number} bitmask The bitmask flags.
5490       *    1 - `_.bind`
5491       *    2 - `_.bindKey`
5492       *    4 - `_.curry` or `_.curryRight` of a bound function
5493       *    8 - `_.curry`
5494       *   16 - `_.curryRight`
5495       *   32 - `_.partial`
5496       *   64 - `_.partialRight`
5497       *  128 - `_.rearg`
5498       *  256 - `_.ary`
5499       *  512 - `_.flip`
5500       * @param {*} [thisArg] The `this` binding of `func`.
5501       * @param {Array} [partials] The arguments to be partially applied.
5502       * @param {Array} [holders] The `partials` placeholder indexes.
5503       * @param {Array} [argPos] The argument positions of the new function.
5504       * @param {number} [ary] The arity cap of `func`.
5505       * @param {number} [arity] The arity of `func`.
5506       * @returns {Function} Returns the new wrapped function.
5507       */
5508      function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5509        var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
5510        if (!isBindKey && typeof func != 'function') {
5511          throw new TypeError(FUNC_ERROR_TEXT);
5512        }
5513        var length = partials ? partials.length : 0;
5514        if (!length) {
5515          bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
5516          partials = holders = undefined;
5517        }
5518        ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5519        arity = arity === undefined ? arity : toInteger(arity);
5520        length -= holders ? holders.length : 0;
5521  
5522        if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
5523          var partialsRight = partials,
5524              holdersRight = holders;
5525  
5526          partials = holders = undefined;
5527        }
5528        var data = isBindKey ? undefined : getData(func);
5529  
5530        var newData = [
5531          func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
5532          argPos, ary, arity
5533        ];
5534  
5535        if (data) {
5536          mergeData(newData, data);
5537        }
5538        func = newData[0];
5539        bitmask = newData[1];
5540        thisArg = newData[2];
5541        partials = newData[3];
5542        holders = newData[4];
5543        arity = newData[9] = newData[9] === undefined
5544          ? (isBindKey ? 0 : func.length)
5545          : nativeMax(newData[9] - length, 0);
5546  
5547        if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
5548          bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
5549        }
5550        if (!bitmask || bitmask == WRAP_BIND_FLAG) {
5551          var result = createBind(func, bitmask, thisArg);
5552        } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
5553          result = createCurry(func, bitmask, arity);
5554        } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
5555          result = createPartial(func, bitmask, thisArg, partials);
5556        } else {
5557          result = createHybrid.apply(undefined, newData);
5558        }
5559        var setter = data ? baseSetData : setData;
5560        return setWrapToString(setter(result, newData), func, bitmask);
5561      }
5562  
5563      /**
5564       * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
5565       * of source objects to the destination object for all destination properties
5566       * that resolve to `undefined`.
5567       *
5568       * @private
5569       * @param {*} objValue The destination value.
5570       * @param {*} srcValue The source value.
5571       * @param {string} key The key of the property to assign.
5572       * @param {Object} object The parent object of `objValue`.
5573       * @returns {*} Returns the value to assign.
5574       */
5575      function customDefaultsAssignIn(objValue, srcValue, key, object) {
5576        if (objValue === undefined ||
5577            (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
5578          return srcValue;
5579        }
5580        return objValue;
5581      }
5582  
5583      /**
5584       * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
5585       * objects into destination objects that are passed thru.
5586       *
5587       * @private
5588       * @param {*} objValue The destination value.
5589       * @param {*} srcValue The source value.
5590       * @param {string} key The key of the property to merge.
5591       * @param {Object} object The parent object of `objValue`.
5592       * @param {Object} source The parent object of `srcValue`.
5593       * @param {Object} [stack] Tracks traversed source values and their merged
5594       *  counterparts.
5595       * @returns {*} Returns the value to assign.
5596       */
5597      function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
5598        if (isObject(objValue) && isObject(srcValue)) {
5599          // Recursively merge objects and arrays (susceptible to call stack limits).
5600          stack.set(srcValue, objValue);
5601          baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
5602          stack['delete'](srcValue);
5603        }
5604        return objValue;
5605      }
5606  
5607      /**
5608       * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
5609       * objects.
5610       *
5611       * @private
5612       * @param {*} value The value to inspect.
5613       * @param {string} key The key of the property to inspect.
5614       * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
5615       */
5616      function customOmitClone(value) {
5617        return isPlainObject(value) ? undefined : value;
5618      }
5619  
5620      /**
5621       * A specialized version of `baseIsEqualDeep` for arrays with support for
5622       * partial deep comparisons.
5623       *
5624       * @private
5625       * @param {Array} array The array to compare.
5626       * @param {Array} other The other array to compare.
5627       * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5628       * @param {Function} customizer The function to customize comparisons.
5629       * @param {Function} equalFunc The function to determine equivalents of values.
5630       * @param {Object} stack Tracks traversed `array` and `other` objects.
5631       * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
5632       */
5633      function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
5634        var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5635            arrLength = array.length,
5636            othLength = other.length;
5637  
5638        if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
5639          return false;
5640        }
5641        // Check that cyclic values are equal.
5642        var arrStacked = stack.get(array);
5643        var othStacked = stack.get(other);
5644        if (arrStacked && othStacked) {
5645          return arrStacked == other && othStacked == array;
5646        }
5647        var index = -1,
5648            result = true,
5649            seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
5650  
5651        stack.set(array, other);
5652        stack.set(other, array);
5653  
5654        // Ignore non-index properties.
5655        while (++index < arrLength) {
5656          var arrValue = array[index],
5657              othValue = other[index];
5658  
5659          if (customizer) {
5660            var compared = isPartial
5661              ? customizer(othValue, arrValue, index, other, array, stack)
5662              : customizer(arrValue, othValue, index, array, other, stack);
5663          }
5664          if (compared !== undefined) {
5665            if (compared) {
5666              continue;
5667            }
5668            result = false;
5669            break;
5670          }
5671          // Recursively compare arrays (susceptible to call stack limits).
5672          if (seen) {
5673            if (!arraySome(other, function(othValue, othIndex) {
5674                  if (!cacheHas(seen, othIndex) &&
5675                      (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
5676                    return seen.push(othIndex);
5677                  }
5678                })) {
5679              result = false;
5680              break;
5681            }
5682          } else if (!(
5683                arrValue === othValue ||
5684                  equalFunc(arrValue, othValue, bitmask, customizer, stack)
5685              )) {
5686            result = false;
5687            break;
5688          }
5689        }
5690        stack['delete'](array);
5691        stack['delete'](other);
5692        return result;
5693      }
5694  
5695      /**
5696       * A specialized version of `baseIsEqualDeep` for comparing objects of
5697       * the same `toStringTag`.
5698       *
5699       * **Note:** This function only supports comparing values with tags of
5700       * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5701       *
5702       * @private
5703       * @param {Object} object The object to compare.
5704       * @param {Object} other The other object to compare.
5705       * @param {string} tag The `toStringTag` of the objects to compare.
5706       * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5707       * @param {Function} customizer The function to customize comparisons.
5708       * @param {Function} equalFunc The function to determine equivalents of values.
5709       * @param {Object} stack Tracks traversed `object` and `other` objects.
5710       * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5711       */
5712      function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
5713        switch (tag) {
5714          case dataViewTag:
5715            if ((object.byteLength != other.byteLength) ||
5716                (object.byteOffset != other.byteOffset)) {
5717              return false;
5718            }
5719            object = object.buffer;
5720            other = other.buffer;
5721  
5722          case arrayBufferTag:
5723            if ((object.byteLength != other.byteLength) ||
5724                !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
5725              return false;
5726            }
5727            return true;
5728  
5729          case boolTag:
5730          case dateTag:
5731          case numberTag:
5732            // Coerce booleans to `1` or `0` and dates to milliseconds.
5733            // Invalid dates are coerced to `NaN`.
5734            return eq(+object, +other);
5735  
5736          case errorTag:
5737            return object.name == other.name && object.message == other.message;
5738  
5739          case regexpTag:
5740          case stringTag:
5741            // Coerce regexes to strings and treat strings, primitives and objects,
5742            // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
5743            // for more details.
5744            return object == (other + '');
5745  
5746          case mapTag:
5747            var convert = mapToArray;
5748  
5749          case setTag:
5750            var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
5751            convert || (convert = setToArray);
5752  
5753            if (object.size != other.size && !isPartial) {
5754              return false;
5755            }
5756            // Assume cyclic values are equal.
5757            var stacked = stack.get(object);
5758            if (stacked) {
5759              return stacked == other;
5760            }
5761            bitmask |= COMPARE_UNORDERED_FLAG;
5762  
5763            // Recursively compare objects (susceptible to call stack limits).
5764            stack.set(object, other);
5765            var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
5766            stack['delete'](object);
5767            return result;
5768  
5769          case symbolTag:
5770            if (symbolValueOf) {
5771              return symbolValueOf.call(object) == symbolValueOf.call(other);
5772            }
5773        }
5774        return false;
5775      }
5776  
5777      /**
5778       * A specialized version of `baseIsEqualDeep` for objects with support for
5779       * partial deep comparisons.
5780       *
5781       * @private
5782       * @param {Object} object The object to compare.
5783       * @param {Object} other The other object to compare.
5784       * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5785       * @param {Function} customizer The function to customize comparisons.
5786       * @param {Function} equalFunc The function to determine equivalents of values.
5787       * @param {Object} stack Tracks traversed `object` and `other` objects.
5788       * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5789       */
5790      function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
5791        var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5792            objProps = getAllKeys(object),
5793            objLength = objProps.length,
5794            othProps = getAllKeys(other),
5795            othLength = othProps.length;
5796  
5797        if (objLength != othLength && !isPartial) {
5798          return false;
5799        }
5800        var index = objLength;
5801        while (index--) {
5802          var key = objProps[index];
5803          if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
5804            return false;
5805          }
5806        }
5807        // Check that cyclic values are equal.
5808        var objStacked = stack.get(object);
5809        var othStacked = stack.get(other);
5810        if (objStacked && othStacked) {
5811          return objStacked == other && othStacked == object;
5812        }
5813        var result = true;
5814        stack.set(object, other);
5815        stack.set(other, object);
5816  
5817        var skipCtor = isPartial;
5818        while (++index < objLength) {
5819          key = objProps[index];
5820          var objValue = object[key],
5821              othValue = other[key];
5822  
5823          if (customizer) {
5824            var compared = isPartial
5825              ? customizer(othValue, objValue, key, other, object, stack)
5826              : customizer(objValue, othValue, key, object, other, stack);
5827          }
5828          // Recursively compare objects (susceptible to call stack limits).
5829          if (!(compared === undefined
5830                ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
5831                : compared
5832              )) {
5833            result = false;
5834            break;
5835          }
5836          skipCtor || (skipCtor = key == 'constructor');
5837        }
5838        if (result && !skipCtor) {
5839          var objCtor = object.constructor,
5840              othCtor = other.constructor;
5841  
5842          // Non `Object` object instances with different constructors are not equal.
5843          if (objCtor != othCtor &&
5844              ('constructor' in object && 'constructor' in other) &&
5845              !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
5846                typeof othCtor == 'function' && othCtor instanceof othCtor)) {
5847            result = false;
5848          }
5849        }
5850        stack['delete'](object);
5851        stack['delete'](other);
5852        return result;
5853      }
5854  
5855      /**
5856       * A specialized version of `baseRest` which flattens the rest array.
5857       *
5858       * @private
5859       * @param {Function} func The function to apply a rest parameter to.
5860       * @returns {Function} Returns the new function.
5861       */
5862      function flatRest(func) {
5863        return setToString(overRest(func, undefined, flatten), func + '');
5864      }
5865  
5866      /**
5867       * Creates an array of own enumerable property names and symbols of `object`.
5868       *
5869       * @private
5870       * @param {Object} object The object to query.
5871       * @returns {Array} Returns the array of property names and symbols.
5872       */
5873      function getAllKeys(object) {
5874        return baseGetAllKeys(object, keys, getSymbols);
5875      }
5876  
5877      /**
5878       * Creates an array of own and inherited enumerable property names and
5879       * symbols of `object`.
5880       *
5881       * @private
5882       * @param {Object} object The object to query.
5883       * @returns {Array} Returns the array of property names and symbols.
5884       */
5885      function getAllKeysIn(object) {
5886        return baseGetAllKeys(object, keysIn, getSymbolsIn);
5887      }
5888  
5889      /**
5890       * Gets metadata for `func`.
5891       *
5892       * @private
5893       * @param {Function} func The function to query.
5894       * @returns {*} Returns the metadata for `func`.
5895       */
5896      var getData = !metaMap ? noop : function(func) {
5897        return metaMap.get(func);
5898      };
5899  
5900      /**
5901       * Gets the name of `func`.
5902       *
5903       * @private
5904       * @param {Function} func The function to query.
5905       * @returns {string} Returns the function name.
5906       */
5907      function getFuncName(func) {
5908        var result = (func.name + ''),
5909            array = realNames[result],
5910            length = hasOwnProperty.call(realNames, result) ? array.length : 0;
5911  
5912        while (length--) {
5913          var data = array[length],
5914              otherFunc = data.func;
5915          if (otherFunc == null || otherFunc == func) {
5916            return data.name;
5917          }
5918        }
5919        return result;
5920      }
5921  
5922      /**
5923       * Gets the argument placeholder value for `func`.
5924       *
5925       * @private
5926       * @param {Function} func The function to inspect.
5927       * @returns {*} Returns the placeholder value.
5928       */
5929      function getHolder(func) {
5930        var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
5931        return object.placeholder;
5932      }
5933  
5934      /**
5935       * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
5936       * this function returns the custom method, otherwise it returns `baseIteratee`.
5937       * If arguments are provided, the chosen function is invoked with them and
5938       * its result is returned.
5939       *
5940       * @private
5941       * @param {*} [value] The value to convert to an iteratee.
5942       * @param {number} [arity] The arity of the created iteratee.
5943       * @returns {Function} Returns the chosen function or its result.
5944       */
5945      function getIteratee() {
5946        var result = lodash.iteratee || iteratee;
5947        result = result === iteratee ? baseIteratee : result;
5948        return arguments.length ? result(arguments[0], arguments[1]) : result;
5949      }
5950  
5951      /**
5952       * Gets the data for `map`.
5953       *
5954       * @private
5955       * @param {Object} map The map to query.
5956       * @param {string} key The reference key.
5957       * @returns {*} Returns the map data.
5958       */
5959      function getMapData(map, key) {
5960        var data = map.__data__;
5961        return isKeyable(key)
5962          ? data[typeof key == 'string' ? 'string' : 'hash']
5963          : data.map;
5964      }
5965  
5966      /**
5967       * Gets the property names, values, and compare flags of `object`.
5968       *
5969       * @private
5970       * @param {Object} object The object to query.
5971       * @returns {Array} Returns the match data of `object`.
5972       */
5973      function getMatchData(object) {
5974        var result = keys(object),
5975            length = result.length;
5976  
5977        while (length--) {
5978          var key = result[length],
5979              value = object[key];
5980  
5981          result[length] = [key, value, isStrictComparable(value)];
5982        }
5983        return result;
5984      }
5985  
5986      /**
5987       * Gets the native function at `key` of `object`.
5988       *
5989       * @private
5990       * @param {Object} object The object to query.
5991       * @param {string} key The key of the method to get.
5992       * @returns {*} Returns the function if it's native, else `undefined`.
5993       */
5994      function getNative(object, key) {
5995        var value = getValue(object, key);
5996        return baseIsNative(value) ? value : undefined;
5997      }
5998  
5999      /**
6000       * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
6001       *
6002       * @private
6003       * @param {*} value The value to query.
6004       * @returns {string} Returns the raw `toStringTag`.
6005       */
6006      function getRawTag(value) {
6007        var isOwn = hasOwnProperty.call(value, symToStringTag),
6008            tag = value[symToStringTag];
6009  
6010        try {
6011          value[symToStringTag] = undefined;
6012          var unmasked = true;
6013        } catch (e) {}
6014  
6015        var result = nativeObjectToString.call(value);
6016        if (unmasked) {
6017          if (isOwn) {
6018            value[symToStringTag] = tag;
6019          } else {
6020            delete value[symToStringTag];
6021          }
6022        }
6023        return result;
6024      }
6025  
6026      /**
6027       * Creates an array of the own enumerable symbols of `object`.
6028       *
6029       * @private
6030       * @param {Object} object The object to query.
6031       * @returns {Array} Returns the array of symbols.
6032       */
6033      var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
6034        if (object == null) {
6035          return [];
6036        }
6037        object = Object(object);
6038        return arrayFilter(nativeGetSymbols(object), function(symbol) {
6039          return propertyIsEnumerable.call(object, symbol);
6040        });
6041      };
6042  
6043      /**
6044       * Creates an array of the own and inherited enumerable symbols of `object`.
6045       *
6046       * @private
6047       * @param {Object} object The object to query.
6048       * @returns {Array} Returns the array of symbols.
6049       */
6050      var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
6051        var result = [];
6052        while (object) {
6053          arrayPush(result, getSymbols(object));
6054          object = getPrototype(object);
6055        }
6056        return result;
6057      };
6058  
6059      /**
6060       * Gets the `toStringTag` of `value`.
6061       *
6062       * @private
6063       * @param {*} value The value to query.
6064       * @returns {string} Returns the `toStringTag`.
6065       */
6066      var getTag = baseGetTag;
6067  
6068      // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
6069      if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
6070          (Map && getTag(new Map) != mapTag) ||
6071          (Promise && getTag(Promise.resolve()) != promiseTag) ||
6072          (Set && getTag(new Set) != setTag) ||
6073          (WeakMap && getTag(new WeakMap) != weakMapTag)) {
6074        getTag = function(value) {
6075          var result = baseGetTag(value),
6076              Ctor = result == objectTag ? value.constructor : undefined,
6077              ctorString = Ctor ? toSource(Ctor) : '';
6078  
6079          if (ctorString) {
6080            switch (ctorString) {
6081              case dataViewCtorString: return dataViewTag;
6082              case mapCtorString: return mapTag;
6083              case promiseCtorString: return promiseTag;
6084              case setCtorString: return setTag;
6085              case weakMapCtorString: return weakMapTag;
6086            }
6087          }
6088          return result;
6089        };
6090      }
6091  
6092      /**
6093       * Gets the view, applying any `transforms` to the `start` and `end` positions.
6094       *
6095       * @private
6096       * @param {number} start The start of the view.
6097       * @param {number} end The end of the view.
6098       * @param {Array} transforms The transformations to apply to the view.
6099       * @returns {Object} Returns an object containing the `start` and `end`
6100       *  positions of the view.
6101       */
6102      function getView(start, end, transforms) {
6103        var index = -1,
6104            length = transforms.length;
6105  
6106        while (++index < length) {
6107          var data = transforms[index],
6108              size = data.size;
6109  
6110          switch (data.type) {
6111            case 'drop':      start += size; break;
6112            case 'dropRight': end -= size; break;
6113            case 'take':      end = nativeMin(end, start + size); break;
6114            case 'takeRight': start = nativeMax(start, end - size); break;
6115          }
6116        }
6117        return { 'start': start, 'end': end };
6118      }
6119  
6120      /**
6121       * Extracts wrapper details from the `source` body comment.
6122       *
6123       * @private
6124       * @param {string} source The source to inspect.
6125       * @returns {Array} Returns the wrapper details.
6126       */
6127      function getWrapDetails(source) {
6128        var match = source.match(reWrapDetails);
6129        return match ? match[1].split(reSplitDetails) : [];
6130      }
6131  
6132      /**
6133       * Checks if `path` exists on `object`.
6134       *
6135       * @private
6136       * @param {Object} object The object to query.
6137       * @param {Array|string} path The path to check.
6138       * @param {Function} hasFunc The function to check properties.
6139       * @returns {boolean} Returns `true` if `path` exists, else `false`.
6140       */
6141      function hasPath(object, path, hasFunc) {
6142        path = castPath(path, object);
6143  
6144        var index = -1,
6145            length = path.length,
6146            result = false;
6147  
6148        while (++index < length) {
6149          var key = toKey(path[index]);
6150          if (!(result = object != null && hasFunc(object, key))) {
6151            break;
6152          }
6153          object = object[key];
6154        }
6155        if (result || ++index != length) {
6156          return result;
6157        }
6158        length = object == null ? 0 : object.length;
6159        return !!length && isLength(length) && isIndex(key, length) &&
6160          (isArray(object) || isArguments(object));
6161      }
6162  
6163      /**
6164       * Initializes an array clone.
6165       *
6166       * @private
6167       * @param {Array} array The array to clone.
6168       * @returns {Array} Returns the initialized clone.
6169       */
6170      function initCloneArray(array) {
6171        var length = array.length,
6172            result = new array.constructor(length);
6173  
6174        // Add properties assigned by `RegExp#exec`.
6175        if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
6176          result.index = array.index;
6177          result.input = array.input;
6178        }
6179        return result;
6180      }
6181  
6182      /**
6183       * Initializes an object clone.
6184       *
6185       * @private
6186       * @param {Object} object The object to clone.
6187       * @returns {Object} Returns the initialized clone.
6188       */
6189      function initCloneObject(object) {
6190        return (typeof object.constructor == 'function' && !isPrototype(object))
6191          ? baseCreate(getPrototype(object))
6192          : {};
6193      }
6194  
6195      /**
6196       * Initializes an object clone based on its `toStringTag`.
6197       *
6198       * **Note:** This function only supports cloning values with tags of
6199       * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
6200       *
6201       * @private
6202       * @param {Object} object The object to clone.
6203       * @param {string} tag The `toStringTag` of the object to clone.
6204       * @param {boolean} [isDeep] Specify a deep clone.
6205       * @returns {Object} Returns the initialized clone.
6206       */
6207      function initCloneByTag(object, tag, isDeep) {
6208        var Ctor = object.constructor;
6209        switch (tag) {
6210          case arrayBufferTag:
6211            return cloneArrayBuffer(object);
6212  
6213          case boolTag:
6214          case dateTag:
6215            return new Ctor(+object);
6216  
6217          case dataViewTag:
6218            return cloneDataView(object, isDeep);
6219  
6220          case float32Tag: case float64Tag:
6221          case int8Tag: case int16Tag: case int32Tag:
6222          case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
6223            return cloneTypedArray(object, isDeep);
6224  
6225          case mapTag:
6226            return new Ctor;
6227  
6228          case numberTag:
6229          case stringTag:
6230            return new Ctor(object);
6231  
6232          case regexpTag:
6233            return cloneRegExp(object);
6234  
6235          case setTag:
6236            return new Ctor;
6237  
6238          case symbolTag:
6239            return cloneSymbol(object);
6240        }
6241      }
6242  
6243      /**
6244       * Inserts wrapper `details` in a comment at the top of the `source` body.
6245       *
6246       * @private
6247       * @param {string} source The source to modify.
6248       * @returns {Array} details The details to insert.
6249       * @returns {string} Returns the modified source.
6250       */
6251      function insertWrapDetails(source, details) {
6252        var length = details.length;
6253        if (!length) {
6254          return source;
6255        }
6256        var lastIndex = length - 1;
6257        details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
6258        details = details.join(length > 2 ? ', ' : ' ');
6259        return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
6260      }
6261  
6262      /**
6263       * Checks if `value` is a flattenable `arguments` object or array.
6264       *
6265       * @private
6266       * @param {*} value The value to check.
6267       * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
6268       */
6269      function isFlattenable(value) {
6270        return isArray(value) || isArguments(value) ||
6271          !!(spreadableSymbol && value && value[spreadableSymbol]);
6272      }
6273  
6274      /**
6275       * Checks if `value` is a valid array-like index.
6276       *
6277       * @private
6278       * @param {*} value The value to check.
6279       * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
6280       * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
6281       */
6282      function isIndex(value, length) {
6283        var type = typeof value;
6284        length = length == null ? MAX_SAFE_INTEGER : length;
6285  
6286        return !!length &&
6287          (type == 'number' ||
6288            (type != 'symbol' && reIsUint.test(value))) &&
6289              (value > -1 && value % 1 == 0 && value < length);
6290      }
6291  
6292      /**
6293       * Checks if the given arguments are from an iteratee call.
6294       *
6295       * @private
6296       * @param {*} value The potential iteratee value argument.
6297       * @param {*} index The potential iteratee index or key argument.
6298       * @param {*} object The potential iteratee object argument.
6299       * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
6300       *  else `false`.
6301       */
6302      function isIterateeCall(value, index, object) {
6303        if (!isObject(object)) {
6304          return false;
6305        }
6306        var type = typeof index;
6307        if (type == 'number'
6308              ? (isArrayLike(object) && isIndex(index, object.length))
6309              : (type == 'string' && index in object)
6310            ) {
6311          return eq(object[index], value);
6312        }
6313        return false;
6314      }
6315  
6316      /**
6317       * Checks if `value` is a property name and not a property path.
6318       *
6319       * @private
6320       * @param {*} value The value to check.
6321       * @param {Object} [object] The object to query keys on.
6322       * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
6323       */
6324      function isKey(value, object) {
6325        if (isArray(value)) {
6326          return false;
6327        }
6328        var type = typeof value;
6329        if (type == 'number' || type == 'symbol' || type == 'boolean' ||
6330            value == null || isSymbol(value)) {
6331          return true;
6332        }
6333        return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
6334          (object != null && value in Object(object));
6335      }
6336  
6337      /**
6338       * Checks if `value` is suitable for use as unique object key.
6339       *
6340       * @private
6341       * @param {*} value The value to check.
6342       * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
6343       */
6344      function isKeyable(value) {
6345        var type = typeof value;
6346        return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
6347          ? (value !== '__proto__')
6348          : (value === null);
6349      }
6350  
6351      /**
6352       * Checks if `func` has a lazy counterpart.
6353       *
6354       * @private
6355       * @param {Function} func The function to check.
6356       * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
6357       *  else `false`.
6358       */
6359      function isLaziable(func) {
6360        var funcName = getFuncName(func),
6361            other = lodash[funcName];
6362  
6363        if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
6364          return false;
6365        }
6366        if (func === other) {
6367          return true;
6368        }
6369        var data = getData(other);
6370        return !!data && func === data[0];
6371      }
6372  
6373      /**
6374       * Checks if `func` has its source masked.
6375       *
6376       * @private
6377       * @param {Function} func The function to check.
6378       * @returns {boolean} Returns `true` if `func` is masked, else `false`.
6379       */
6380      function isMasked(func) {
6381        return !!maskSrcKey && (maskSrcKey in func);
6382      }
6383  
6384      /**
6385       * Checks if `func` is capable of being masked.
6386       *
6387       * @private
6388       * @param {*} value The value to check.
6389       * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
6390       */
6391      var isMaskable = coreJsData ? isFunction : stubFalse;
6392  
6393      /**
6394       * Checks if `value` is likely a prototype object.
6395       *
6396       * @private
6397       * @param {*} value The value to check.
6398       * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
6399       */
6400      function isPrototype(value) {
6401        var Ctor = value && value.constructor,
6402            proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
6403  
6404        return value === proto;
6405      }
6406  
6407      /**
6408       * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
6409       *
6410       * @private
6411       * @param {*} value The value to check.
6412       * @returns {boolean} Returns `true` if `value` if suitable for strict
6413       *  equality comparisons, else `false`.
6414       */
6415      function isStrictComparable(value) {
6416        return value === value && !isObject(value);
6417      }
6418  
6419      /**
6420       * A specialized version of `matchesProperty` for source values suitable
6421       * for strict equality comparisons, i.e. `===`.
6422       *
6423       * @private
6424       * @param {string} key The key of the property to get.
6425       * @param {*} srcValue The value to match.
6426       * @returns {Function} Returns the new spec function.
6427       */
6428      function matchesStrictComparable(key, srcValue) {
6429        return function(object) {
6430          if (object == null) {
6431            return false;
6432          }
6433          return object[key] === srcValue &&
6434            (srcValue !== undefined || (key in Object(object)));
6435        };
6436      }
6437  
6438      /**
6439       * A specialized version of `_.memoize` which clears the memoized function's
6440       * cache when it exceeds `MAX_MEMOIZE_SIZE`.
6441       *
6442       * @private
6443       * @param {Function} func The function to have its output memoized.
6444       * @returns {Function} Returns the new memoized function.
6445       */
6446      function memoizeCapped(func) {
6447        var result = memoize(func, function(key) {
6448          if (cache.size === MAX_MEMOIZE_SIZE) {
6449            cache.clear();
6450          }
6451          return key;
6452        });
6453  
6454        var cache = result.cache;
6455        return result;
6456      }
6457  
6458      /**
6459       * Merges the function metadata of `source` into `data`.
6460       *
6461       * Merging metadata reduces the number of wrappers used to invoke a function.
6462       * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
6463       * may be applied regardless of execution order. Methods like `_.ary` and
6464       * `_.rearg` modify function arguments, making the order in which they are
6465       * executed important, preventing the merging of metadata. However, we make
6466       * an exception for a safe combined case where curried functions have `_.ary`
6467       * and or `_.rearg` applied.
6468       *
6469       * @private
6470       * @param {Array} data The destination metadata.
6471       * @param {Array} source The source metadata.
6472       * @returns {Array} Returns `data`.
6473       */
6474      function mergeData(data, source) {
6475        var bitmask = data[1],
6476            srcBitmask = source[1],
6477            newBitmask = bitmask | srcBitmask,
6478            isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
6479  
6480        var isCombo =
6481          ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
6482          ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
6483          ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
6484  
6485        // Exit early if metadata can't be merged.
6486        if (!(isCommon || isCombo)) {
6487          return data;
6488        }
6489        // Use source `thisArg` if available.
6490        if (srcBitmask & WRAP_BIND_FLAG) {
6491          data[2] = source[2];
6492          // Set when currying a bound function.
6493          newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
6494        }
6495        // Compose partial arguments.
6496        var value = source[3];
6497        if (value) {
6498          var partials = data[3];
6499          data[3] = partials ? composeArgs(partials, value, source[4]) : value;
6500          data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
6501        }
6502        // Compose partial right arguments.
6503        value = source[5];
6504        if (value) {
6505          partials = data[5];
6506          data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
6507          data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
6508        }
6509        // Use source `argPos` if available.
6510        value = source[7];
6511        if (value) {
6512          data[7] = value;
6513        }
6514        // Use source `ary` if it's smaller.
6515        if (srcBitmask & WRAP_ARY_FLAG) {
6516          data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
6517        }
6518        // Use source `arity` if one is not provided.
6519        if (data[9] == null) {
6520          data[9] = source[9];
6521        }
6522        // Use source `func` and merge bitmasks.
6523        data[0] = source[0];
6524        data[1] = newBitmask;
6525  
6526        return data;
6527      }
6528  
6529      /**
6530       * This function is like
6531       * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
6532       * except that it includes inherited enumerable properties.
6533       *
6534       * @private
6535       * @param {Object} object The object to query.
6536       * @returns {Array} Returns the array of property names.
6537       */
6538      function nativeKeysIn(object) {
6539        var result = [];
6540        if (object != null) {
6541          for (var key in Object(object)) {
6542            result.push(key);
6543          }
6544        }
6545        return result;
6546      }
6547  
6548      /**
6549       * Converts `value` to a string using `Object.prototype.toString`.
6550       *
6551       * @private
6552       * @param {*} value The value to convert.
6553       * @returns {string} Returns the converted string.
6554       */
6555      function objectToString(value) {
6556        return nativeObjectToString.call(value);
6557      }
6558  
6559      /**
6560       * A specialized version of `baseRest` which transforms the rest array.
6561       *
6562       * @private
6563       * @param {Function} func The function to apply a rest parameter to.
6564       * @param {number} [start=func.length-1] The start position of the rest parameter.
6565       * @param {Function} transform The rest array transform.
6566       * @returns {Function} Returns the new function.
6567       */
6568      function overRest(func, start, transform) {
6569        start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
6570        return function() {
6571          var args = arguments,
6572              index = -1,
6573              length = nativeMax(args.length - start, 0),
6574              array = Array(length);
6575  
6576          while (++index < length) {
6577            array[index] = args[start + index];
6578          }
6579          index = -1;
6580          var otherArgs = Array(start + 1);
6581          while (++index < start) {
6582            otherArgs[index] = args[index];
6583          }
6584          otherArgs[start] = transform(array);
6585          return apply(func, this, otherArgs);
6586        };
6587      }
6588  
6589      /**
6590       * Gets the parent value at `path` of `object`.
6591       *
6592       * @private
6593       * @param {Object} object The object to query.
6594       * @param {Array} path The path to get the parent value of.
6595       * @returns {*} Returns the parent value.
6596       */
6597      function parent(object, path) {
6598        return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
6599      }
6600  
6601      /**
6602       * Reorder `array` according to the specified indexes where the element at
6603       * the first index is assigned as the first element, the element at
6604       * the second index is assigned as the second element, and so on.
6605       *
6606       * @private
6607       * @param {Array} array The array to reorder.
6608       * @param {Array} indexes The arranged array indexes.
6609       * @returns {Array} Returns `array`.
6610       */
6611      function reorder(array, indexes) {
6612        var arrLength = array.length,
6613            length = nativeMin(indexes.length, arrLength),
6614            oldArray = copyArray(array);
6615  
6616        while (length--) {
6617          var index = indexes[length];
6618          array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
6619        }
6620        return array;
6621      }
6622  
6623      /**
6624       * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
6625       *
6626       * @private
6627       * @param {Object} object The object to query.
6628       * @param {string} key The key of the property to get.
6629       * @returns {*} Returns the property value.
6630       */
6631      function safeGet(object, key) {
6632        if (key === 'constructor' && typeof object[key] === 'function') {
6633          return;
6634        }
6635  
6636        if (key == '__proto__') {
6637          return;
6638        }
6639  
6640        return object[key];
6641      }
6642  
6643      /**
6644       * Sets metadata for `func`.
6645       *
6646       * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
6647       * period of time, it will trip its breaker and transition to an identity
6648       * function to avoid garbage collection pauses in V8. See
6649       * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
6650       * for more details.
6651       *
6652       * @private
6653       * @param {Function} func The function to associate metadata with.
6654       * @param {*} data The metadata.
6655       * @returns {Function} Returns `func`.
6656       */
6657      var setData = shortOut(baseSetData);
6658  
6659      /**
6660       * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
6661       *
6662       * @private
6663       * @param {Function} func The function to delay.
6664       * @param {number} wait The number of milliseconds to delay invocation.
6665       * @returns {number|Object} Returns the timer id or timeout object.
6666       */
6667      var setTimeout = ctxSetTimeout || function(func, wait) {
6668        return root.setTimeout(func, wait);
6669      };
6670  
6671      /**
6672       * Sets the `toString` method of `func` to return `string`.
6673       *
6674       * @private
6675       * @param {Function} func The function to modify.
6676       * @param {Function} string The `toString` result.
6677       * @returns {Function} Returns `func`.
6678       */
6679      var setToString = shortOut(baseSetToString);
6680  
6681      /**
6682       * Sets the `toString` method of `wrapper` to mimic the source of `reference`
6683       * with wrapper details in a comment at the top of the source body.
6684       *
6685       * @private
6686       * @param {Function} wrapper The function to modify.
6687       * @param {Function} reference The reference function.
6688       * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6689       * @returns {Function} Returns `wrapper`.
6690       */
6691      function setWrapToString(wrapper, reference, bitmask) {
6692        var source = (reference + '');
6693        return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
6694      }
6695  
6696      /**
6697       * Creates a function that'll short out and invoke `identity` instead
6698       * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
6699       * milliseconds.
6700       *
6701       * @private
6702       * @param {Function} func The function to restrict.
6703       * @returns {Function} Returns the new shortable function.
6704       */
6705      function shortOut(func) {
6706        var count = 0,
6707            lastCalled = 0;
6708  
6709        return function() {
6710          var stamp = nativeNow(),
6711              remaining = HOT_SPAN - (stamp - lastCalled);
6712  
6713          lastCalled = stamp;
6714          if (remaining > 0) {
6715            if (++count >= HOT_COUNT) {
6716              return arguments[0];
6717            }
6718          } else {
6719            count = 0;
6720          }
6721          return func.apply(undefined, arguments);
6722        };
6723      }
6724  
6725      /**
6726       * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
6727       *
6728       * @private
6729       * @param {Array} array The array to shuffle.
6730       * @param {number} [size=array.length] The size of `array`.
6731       * @returns {Array} Returns `array`.
6732       */
6733      function shuffleSelf(array, size) {
6734        var index = -1,
6735            length = array.length,
6736            lastIndex = length - 1;
6737  
6738        size = size === undefined ? length : size;
6739        while (++index < size) {
6740          var rand = baseRandom(index, lastIndex),
6741              value = array[rand];
6742  
6743          array[rand] = array[index];
6744          array[index] = value;
6745        }
6746        array.length = size;
6747        return array;
6748      }
6749  
6750      /**
6751       * Converts `string` to a property path array.
6752       *
6753       * @private
6754       * @param {string} string The string to convert.
6755       * @returns {Array} Returns the property path array.
6756       */
6757      var stringToPath = memoizeCapped(function(string) {
6758        var result = [];
6759        if (string.charCodeAt(0) === 46 /* . */) {
6760          result.push('');
6761        }
6762        string.replace(rePropName, function(match, number, quote, subString) {
6763          result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
6764        });
6765        return result;
6766      });
6767  
6768      /**
6769       * Converts `value` to a string key if it's not a string or symbol.
6770       *
6771       * @private
6772       * @param {*} value The value to inspect.
6773       * @returns {string|symbol} Returns the key.
6774       */
6775      function toKey(value) {
6776        if (typeof value == 'string' || isSymbol(value)) {
6777          return value;
6778        }
6779        var result = (value + '');
6780        return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
6781      }
6782  
6783      /**
6784       * Converts `func` to its source code.
6785       *
6786       * @private
6787       * @param {Function} func The function to convert.
6788       * @returns {string} Returns the source code.
6789       */
6790      function toSource(func) {
6791        if (func != null) {
6792          try {
6793            return funcToString.call(func);
6794          } catch (e) {}
6795          try {
6796            return (func + '');
6797          } catch (e) {}
6798        }
6799        return '';
6800      }
6801  
6802      /**
6803       * Updates wrapper `details` based on `bitmask` flags.
6804       *
6805       * @private
6806       * @returns {Array} details The details to modify.
6807       * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6808       * @returns {Array} Returns `details`.
6809       */
6810      function updateWrapDetails(details, bitmask) {
6811        arrayEach(wrapFlags, function(pair) {
6812          var value = '_.' + pair[0];
6813          if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
6814            details.push(value);
6815          }
6816        });
6817        return details.sort();
6818      }
6819  
6820      /**
6821       * Creates a clone of `wrapper`.
6822       *
6823       * @private
6824       * @param {Object} wrapper The wrapper to clone.
6825       * @returns {Object} Returns the cloned wrapper.
6826       */
6827      function wrapperClone(wrapper) {
6828        if (wrapper instanceof LazyWrapper) {
6829          return wrapper.clone();
6830        }
6831        var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
6832        result.__actions__ = copyArray(wrapper.__actions__);
6833        result.__index__  = wrapper.__index__;
6834        result.__values__ = wrapper.__values__;
6835        return result;
6836      }
6837  
6838      /*------------------------------------------------------------------------*/
6839  
6840      /**
6841       * Creates an array of elements split into groups the length of `size`.
6842       * If `array` can't be split evenly, the final chunk will be the remaining
6843       * elements.
6844       *
6845       * @static
6846       * @memberOf _
6847       * @since 3.0.0
6848       * @category Array
6849       * @param {Array} array The array to process.
6850       * @param {number} [size=1] The length of each chunk
6851       * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6852       * @returns {Array} Returns the new array of chunks.
6853       * @example
6854       *
6855       * _.chunk(['a', 'b', 'c', 'd'], 2);
6856       * // => [['a', 'b'], ['c', 'd']]
6857       *
6858       * _.chunk(['a', 'b', 'c', 'd'], 3);
6859       * // => [['a', 'b', 'c'], ['d']]
6860       */
6861      function chunk(array, size, guard) {
6862        if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
6863          size = 1;
6864        } else {
6865          size = nativeMax(toInteger(size), 0);
6866        }
6867        var length = array == null ? 0 : array.length;
6868        if (!length || size < 1) {
6869          return [];
6870        }
6871        var index = 0,
6872            resIndex = 0,
6873            result = Array(nativeCeil(length / size));
6874  
6875        while (index < length) {
6876          result[resIndex++] = baseSlice(array, index, (index += size));
6877        }
6878        return result;
6879      }
6880  
6881      /**
6882       * Creates an array with all falsey values removed. The values `false`, `null`,
6883       * `0`, `""`, `undefined`, and `NaN` are falsey.
6884       *
6885       * @static
6886       * @memberOf _
6887       * @since 0.1.0
6888       * @category Array
6889       * @param {Array} array The array to compact.
6890       * @returns {Array} Returns the new array of filtered values.
6891       * @example
6892       *
6893       * _.compact([0, 1, false, 2, '', 3]);
6894       * // => [1, 2, 3]
6895       */
6896      function compact(array) {
6897        var index = -1,
6898            length = array == null ? 0 : array.length,
6899            resIndex = 0,
6900            result = [];
6901  
6902        while (++index < length) {
6903          var value = array[index];
6904          if (value) {
6905            result[resIndex++] = value;
6906          }
6907        }
6908        return result;
6909      }
6910  
6911      /**
6912       * Creates a new array concatenating `array` with any additional arrays
6913       * and/or values.
6914       *
6915       * @static
6916       * @memberOf _
6917       * @since 4.0.0
6918       * @category Array
6919       * @param {Array} array The array to concatenate.
6920       * @param {...*} [values] The values to concatenate.
6921       * @returns {Array} Returns the new concatenated array.
6922       * @example
6923       *
6924       * var array = [1];
6925       * var other = _.concat(array, 2, [3], [[4]]);
6926       *
6927       * console.log(other);
6928       * // => [1, 2, 3, [4]]
6929       *
6930       * console.log(array);
6931       * // => [1]
6932       */
6933      function concat() {
6934        var length = arguments.length;
6935        if (!length) {
6936          return [];
6937        }
6938        var args = Array(length - 1),
6939            array = arguments[0],
6940            index = length;
6941  
6942        while (index--) {
6943          args[index - 1] = arguments[index];
6944        }
6945        return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
6946      }
6947  
6948      /**
6949       * Creates an array of `array` values not included in the other given arrays
6950       * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
6951       * for equality comparisons. The order and references of result values are
6952       * determined by the first array.
6953       *
6954       * **Note:** Unlike `_.pullAll`, this method returns a new array.
6955       *
6956       * @static
6957       * @memberOf _
6958       * @since 0.1.0
6959       * @category Array
6960       * @param {Array} array The array to inspect.
6961       * @param {...Array} [values] The values to exclude.
6962       * @returns {Array} Returns the new array of filtered values.
6963       * @see _.without, _.xor
6964       * @example
6965       *
6966       * _.difference([2, 1], [2, 3]);
6967       * // => [1]
6968       */
6969      var difference = baseRest(function(array, values) {
6970        return isArrayLikeObject(array)
6971          ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
6972          : [];
6973      });
6974  
6975      /**
6976       * This method is like `_.difference` except that it accepts `iteratee` which
6977       * is invoked for each element of `array` and `values` to generate the criterion
6978       * by which they're compared. The order and references of result values are
6979       * determined by the first array. The iteratee is invoked with one argument:
6980       * (value).
6981       *
6982       * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
6983       *
6984       * @static
6985       * @memberOf _
6986       * @since 4.0.0
6987       * @category Array
6988       * @param {Array} array The array to inspect.
6989       * @param {...Array} [values] The values to exclude.
6990       * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
6991       * @returns {Array} Returns the new array of filtered values.
6992       * @example
6993       *
6994       * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
6995       * // => [1.2]
6996       *
6997       * // The `_.property` iteratee shorthand.
6998       * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
6999       * // => [{ 'x': 2 }]
7000       */
7001      var differenceBy = baseRest(function(array, values) {
7002        var iteratee = last(values);
7003        if (isArrayLikeObject(iteratee)) {
7004          iteratee = undefined;
7005        }
7006        return isArrayLikeObject(array)
7007          ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
7008          : [];
7009      });
7010  
7011      /**
7012       * This method is like `_.difference` except that it accepts `comparator`
7013       * which is invoked to compare elements of `array` to `values`. The order and
7014       * references of result values are determined by the first array. The comparator
7015       * is invoked with two arguments: (arrVal, othVal).
7016       *
7017       * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
7018       *
7019       * @static
7020       * @memberOf _
7021       * @since 4.0.0
7022       * @category Array
7023       * @param {Array} array The array to inspect.
7024       * @param {...Array} [values] The values to exclude.
7025       * @param {Function} [comparator] The comparator invoked per element.
7026       * @returns {Array} Returns the new array of filtered values.
7027       * @example
7028       *
7029       * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7030       *
7031       * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
7032       * // => [{ 'x': 2, 'y': 1 }]
7033       */
7034      var differenceWith = baseRest(function(array, values) {
7035        var comparator = last(values);
7036        if (isArrayLikeObject(comparator)) {
7037          comparator = undefined;
7038        }
7039        return isArrayLikeObject(array)
7040          ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
7041          : [];
7042      });
7043  
7044      /**
7045       * Creates a slice of `array` with `n` elements dropped from the beginning.
7046       *
7047       * @static
7048       * @memberOf _
7049       * @since 0.5.0
7050       * @category Array
7051       * @param {Array} array The array to query.
7052       * @param {number} [n=1] The number of elements to drop.
7053       * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7054       * @returns {Array} Returns the slice of `array`.
7055       * @example
7056       *
7057       * _.drop([1, 2, 3]);
7058       * // => [2, 3]
7059       *
7060       * _.drop([1, 2, 3], 2);
7061       * // => [3]
7062       *
7063       * _.drop([1, 2, 3], 5);
7064       * // => []
7065       *
7066       * _.drop([1, 2, 3], 0);
7067       * // => [1, 2, 3]
7068       */
7069      function drop(array, n, guard) {
7070        var length = array == null ? 0 : array.length;
7071        if (!length) {
7072          return [];
7073        }
7074        n = (guard || n === undefined) ? 1 : toInteger(n);
7075        return baseSlice(array, n < 0 ? 0 : n, length);
7076      }
7077  
7078      /**
7079       * Creates a slice of `array` with `n` elements dropped from the end.
7080       *
7081       * @static
7082       * @memberOf _
7083       * @since 3.0.0
7084       * @category Array
7085       * @param {Array} array The array to query.
7086       * @param {number} [n=1] The number of elements to drop.
7087       * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7088       * @returns {Array} Returns the slice of `array`.
7089       * @example
7090       *
7091       * _.dropRight([1, 2, 3]);
7092       * // => [1, 2]
7093       *
7094       * _.dropRight([1, 2, 3], 2);
7095       * // => [1]
7096       *
7097       * _.dropRight([1, 2, 3], 5);
7098       * // => []
7099       *
7100       * _.dropRight([1, 2, 3], 0);
7101       * // => [1, 2, 3]
7102       */
7103      function dropRight(array, n, guard) {
7104        var length = array == null ? 0 : array.length;
7105        if (!length) {
7106          return [];
7107        }
7108        n = (guard || n === undefined) ? 1 : toInteger(n);
7109        n = length - n;
7110        return baseSlice(array, 0, n < 0 ? 0 : n);
7111      }
7112  
7113      /**
7114       * Creates a slice of `array` excluding elements dropped from the end.
7115       * Elements are dropped until `predicate` returns falsey. The predicate is
7116       * invoked with three arguments: (value, index, array).
7117       *
7118       * @static
7119       * @memberOf _
7120       * @since 3.0.0
7121       * @category Array
7122       * @param {Array} array The array to query.
7123       * @param {Function} [predicate=_.identity] The function invoked per iteration.
7124       * @returns {Array} Returns the slice of `array`.
7125       * @example
7126       *
7127       * var users = [
7128       *   { 'user': 'barney',  'active': true },
7129       *   { 'user': 'fred',    'active': false },
7130       *   { 'user': 'pebbles', 'active': false }
7131       * ];
7132       *
7133       * _.dropRightWhile(users, function(o) { return !o.active; });
7134       * // => objects for ['barney']
7135       *
7136       * // The `_.matches` iteratee shorthand.
7137       * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
7138       * // => objects for ['barney', 'fred']
7139       *
7140       * // The `_.matchesProperty` iteratee shorthand.
7141       * _.dropRightWhile(users, ['active', false]);
7142       * // => objects for ['barney']
7143       *
7144       * // The `_.property` iteratee shorthand.
7145       * _.dropRightWhile(users, 'active');
7146       * // => objects for ['barney', 'fred', 'pebbles']
7147       */
7148      function dropRightWhile(array, predicate) {
7149        return (array && array.length)
7150          ? baseWhile(array, getIteratee(predicate, 3), true, true)
7151          : [];
7152      }
7153  
7154      /**
7155       * Creates a slice of `array` excluding elements dropped from the beginning.
7156       * Elements are dropped until `predicate` returns falsey. The predicate is
7157       * invoked with three arguments: (value, index, array).
7158       *
7159       * @static
7160       * @memberOf _
7161       * @since 3.0.0
7162       * @category Array
7163       * @param {Array} array The array to query.
7164       * @param {Function} [predicate=_.identity] The function invoked per iteration.
7165       * @returns {Array} Returns the slice of `array`.
7166       * @example
7167       *
7168       * var users = [
7169       *   { 'user': 'barney',  'active': false },
7170       *   { 'user': 'fred',    'active': false },
7171       *   { 'user': 'pebbles', 'active': true }
7172       * ];
7173       *
7174       * _.dropWhile(users, function(o) { return !o.active; });
7175       * // => objects for ['pebbles']
7176       *
7177       * // The `_.matches` iteratee shorthand.
7178       * _.dropWhile(users, { 'user': 'barney', 'active': false });
7179       * // => objects for ['fred', 'pebbles']
7180       *
7181       * // The `_.matchesProperty` iteratee shorthand.
7182       * _.dropWhile(users, ['active', false]);
7183       * // => objects for ['pebbles']
7184       *
7185       * // The `_.property` iteratee shorthand.
7186       * _.dropWhile(users, 'active');
7187       * // => objects for ['barney', 'fred', 'pebbles']
7188       */
7189      function dropWhile(array, predicate) {
7190        return (array && array.length)
7191          ? baseWhile(array, getIteratee(predicate, 3), true)
7192          : [];
7193      }
7194  
7195      /**
7196       * Fills elements of `array` with `value` from `start` up to, but not
7197       * including, `end`.
7198       *
7199       * **Note:** This method mutates `array`.
7200       *
7201       * @static
7202       * @memberOf _
7203       * @since 3.2.0
7204       * @category Array
7205       * @param {Array} array The array to fill.
7206       * @param {*} value The value to fill `array` with.
7207       * @param {number} [start=0] The start position.
7208       * @param {number} [end=array.length] The end position.
7209       * @returns {Array} Returns `array`.
7210       * @example
7211       *
7212       * var array = [1, 2, 3];
7213       *
7214       * _.fill(array, 'a');
7215       * console.log(array);
7216       * // => ['a', 'a', 'a']
7217       *
7218       * _.fill(Array(3), 2);
7219       * // => [2, 2, 2]
7220       *
7221       * _.fill([4, 6, 8, 10], '*', 1, 3);
7222       * // => [4, '*', '*', 10]
7223       */
7224      function fill(array, value, start, end) {
7225        var length = array == null ? 0 : array.length;
7226        if (!length) {
7227          return [];
7228        }
7229        if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
7230          start = 0;
7231          end = length;
7232        }
7233        return baseFill(array, value, start, end);
7234      }
7235  
7236      /**
7237       * This method is like `_.find` except that it returns the index of the first
7238       * element `predicate` returns truthy for instead of the element itself.
7239       *
7240       * @static
7241       * @memberOf _
7242       * @since 1.1.0
7243       * @category Array
7244       * @param {Array} array The array to inspect.
7245       * @param {Function} [predicate=_.identity] The function invoked per iteration.
7246       * @param {number} [fromIndex=0] The index to search from.
7247       * @returns {number} Returns the index of the found element, else `-1`.
7248       * @example
7249       *
7250       * var users = [
7251       *   { 'user': 'barney',  'active': false },
7252       *   { 'user': 'fred',    'active': false },
7253       *   { 'user': 'pebbles', 'active': true }
7254       * ];
7255       *
7256       * _.findIndex(users, function(o) { return o.user == 'barney'; });
7257       * // => 0
7258       *
7259       * // The `_.matches` iteratee shorthand.
7260       * _.findIndex(users, { 'user': 'fred', 'active': false });
7261       * // => 1
7262       *
7263       * // The `_.matchesProperty` iteratee shorthand.
7264       * _.findIndex(users, ['active', false]);
7265       * // => 0
7266       *
7267       * // The `_.property` iteratee shorthand.
7268       * _.findIndex(users, 'active');
7269       * // => 2
7270       */
7271      function findIndex(array, predicate, fromIndex) {
7272        var length = array == null ? 0 : array.length;
7273        if (!length) {
7274          return -1;
7275        }
7276        var index = fromIndex == null ? 0 : toInteger(fromIndex);
7277        if (index < 0) {
7278          index = nativeMax(length + index, 0);
7279        }
7280        return baseFindIndex(array, getIteratee(predicate, 3), index);
7281      }
7282  
7283      /**
7284       * This method is like `_.findIndex` except that it iterates over elements
7285       * of `collection` from right to left.
7286       *
7287       * @static
7288       * @memberOf _
7289       * @since 2.0.0
7290       * @category Array
7291       * @param {Array} array The array to inspect.
7292       * @param {Function} [predicate=_.identity] The function invoked per iteration.
7293       * @param {number} [fromIndex=array.length-1] The index to search from.
7294       * @returns {number} Returns the index of the found element, else `-1`.
7295       * @example
7296       *
7297       * var users = [
7298       *   { 'user': 'barney',  'active': true },
7299       *   { 'user': 'fred',    'active': false },
7300       *   { 'user': 'pebbles', 'active': false }
7301       * ];
7302       *
7303       * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
7304       * // => 2
7305       *
7306       * // The `_.matches` iteratee shorthand.
7307       * _.findLastIndex(users, { 'user': 'barney', 'active': true });
7308       * // => 0
7309       *
7310       * // The `_.matchesProperty` iteratee shorthand.
7311       * _.findLastIndex(users, ['active', false]);
7312       * // => 2
7313       *
7314       * // The `_.property` iteratee shorthand.
7315       * _.findLastIndex(users, 'active');
7316       * // => 0
7317       */
7318      function findLastIndex(array, predicate, fromIndex) {
7319        var length = array == null ? 0 : array.length;
7320        if (!length) {
7321          return -1;
7322        }
7323        var index = length - 1;
7324        if (fromIndex !== undefined) {
7325          index = toInteger(fromIndex);
7326          index = fromIndex < 0
7327            ? nativeMax(length + index, 0)
7328            : nativeMin(index, length - 1);
7329        }
7330        return baseFindIndex(array, getIteratee(predicate, 3), index, true);
7331      }
7332  
7333      /**
7334       * Flattens `array` a single level deep.
7335       *
7336       * @static
7337       * @memberOf _
7338       * @since 0.1.0
7339       * @category Array
7340       * @param {Array} array The array to flatten.
7341       * @returns {Array} Returns the new flattened array.
7342       * @example
7343       *
7344       * _.flatten([1, [2, [3, [4]], 5]]);
7345       * // => [1, 2, [3, [4]], 5]
7346       */
7347      function flatten(array) {
7348        var length = array == null ? 0 : array.length;
7349        return length ? baseFlatten(array, 1) : [];
7350      }
7351  
7352      /**
7353       * Recursively flattens `array`.
7354       *
7355       * @static
7356       * @memberOf _
7357       * @since 3.0.0
7358       * @category Array
7359       * @param {Array} array The array to flatten.
7360       * @returns {Array} Returns the new flattened array.
7361       * @example
7362       *
7363       * _.flattenDeep([1, [2, [3, [4]], 5]]);
7364       * // => [1, 2, 3, 4, 5]
7365       */
7366      function flattenDeep(array) {
7367        var length = array == null ? 0 : array.length;
7368        return length ? baseFlatten(array, INFINITY) : [];
7369      }
7370  
7371      /**
7372       * Recursively flatten `array` up to `depth` times.
7373       *
7374       * @static
7375       * @memberOf _
7376       * @since 4.4.0
7377       * @category Array
7378       * @param {Array} array The array to flatten.
7379       * @param {number} [depth=1] The maximum recursion depth.
7380       * @returns {Array} Returns the new flattened array.
7381       * @example
7382       *
7383       * var array = [1, [2, [3, [4]], 5]];
7384       *
7385       * _.flattenDepth(array, 1);
7386       * // => [1, 2, [3, [4]], 5]
7387       *
7388       * _.flattenDepth(array, 2);
7389       * // => [1, 2, 3, [4], 5]
7390       */
7391      function flattenDepth(array, depth) {
7392        var length = array == null ? 0 : array.length;
7393        if (!length) {
7394          return [];
7395        }
7396        depth = depth === undefined ? 1 : toInteger(depth);
7397        return baseFlatten(array, depth);
7398      }
7399  
7400      /**
7401       * The inverse of `_.toPairs`; this method returns an object composed
7402       * from key-value `pairs`.
7403       *
7404       * @static
7405       * @memberOf _
7406       * @since 4.0.0
7407       * @category Array
7408       * @param {Array} pairs The key-value pairs.
7409       * @returns {Object} Returns the new object.
7410       * @example
7411       *
7412       * _.fromPairs([['a', 1], ['b', 2]]);
7413       * // => { 'a': 1, 'b': 2 }
7414       */
7415      function fromPairs(pairs) {
7416        var index = -1,
7417            length = pairs == null ? 0 : pairs.length,
7418            result = {};
7419  
7420        while (++index < length) {
7421          var pair = pairs[index];
7422          result[pair[0]] = pair[1];
7423        }
7424        return result;
7425      }
7426  
7427      /**
7428       * Gets the first element of `array`.
7429       *
7430       * @static
7431       * @memberOf _
7432       * @since 0.1.0
7433       * @alias first
7434       * @category Array
7435       * @param {Array} array The array to query.
7436       * @returns {*} Returns the first element of `array`.
7437       * @example
7438       *
7439       * _.head([1, 2, 3]);
7440       * // => 1
7441       *
7442       * _.head([]);
7443       * // => undefined
7444       */
7445      function head(array) {
7446        return (array && array.length) ? array[0] : undefined;
7447      }
7448  
7449      /**
7450       * Gets the index at which the first occurrence of `value` is found in `array`
7451       * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7452       * for equality comparisons. If `fromIndex` is negative, it's used as the
7453       * offset from the end of `array`.
7454       *
7455       * @static
7456       * @memberOf _
7457       * @since 0.1.0
7458       * @category Array
7459       * @param {Array} array The array to inspect.
7460       * @param {*} value The value to search for.
7461       * @param {number} [fromIndex=0] The index to search from.
7462       * @returns {number} Returns the index of the matched value, else `-1`.
7463       * @example
7464       *
7465       * _.indexOf([1, 2, 1, 2], 2);
7466       * // => 1
7467       *
7468       * // Search from the `fromIndex`.
7469       * _.indexOf([1, 2, 1, 2], 2, 2);
7470       * // => 3
7471       */
7472      function indexOf(array, value, fromIndex) {
7473        var length = array == null ? 0 : array.length;
7474        if (!length) {
7475          return -1;
7476        }
7477        var index = fromIndex == null ? 0 : toInteger(fromIndex);
7478        if (index < 0) {
7479          index = nativeMax(length + index, 0);
7480        }
7481        return baseIndexOf(array, value, index);
7482      }
7483  
7484      /**
7485       * Gets all but the last element of `array`.
7486       *
7487       * @static
7488       * @memberOf _
7489       * @since 0.1.0
7490       * @category Array
7491       * @param {Array} array The array to query.
7492       * @returns {Array} Returns the slice of `array`.
7493       * @example
7494       *
7495       * _.initial([1, 2, 3]);
7496       * // => [1, 2]
7497       */
7498      function initial(array) {
7499        var length = array == null ? 0 : array.length;
7500        return length ? baseSlice(array, 0, -1) : [];
7501      }
7502  
7503      /**
7504       * Creates an array of unique values that are included in all given arrays
7505       * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7506       * for equality comparisons. The order and references of result values are
7507       * determined by the first array.
7508       *
7509       * @static
7510       * @memberOf _
7511       * @since 0.1.0
7512       * @category Array
7513       * @param {...Array} [arrays] The arrays to inspect.
7514       * @returns {Array} Returns the new array of intersecting values.
7515       * @example
7516       *
7517       * _.intersection([2, 1], [2, 3]);
7518       * // => [2]
7519       */
7520      var intersection = baseRest(function(arrays) {
7521        var mapped = arrayMap(arrays, castArrayLikeObject);
7522        return (mapped.length && mapped[0] === arrays[0])
7523          ? baseIntersection(mapped)
7524          : [];
7525      });
7526  
7527      /**
7528       * This method is like `_.intersection` except that it accepts `iteratee`
7529       * which is invoked for each element of each `arrays` to generate the criterion
7530       * by which they're compared. The order and references of result values are
7531       * determined by the first array. The iteratee is invoked with one argument:
7532       * (value).
7533       *
7534       * @static
7535       * @memberOf _
7536       * @since 4.0.0
7537       * @category Array
7538       * @param {...Array} [arrays] The arrays to inspect.
7539       * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7540       * @returns {Array} Returns the new array of intersecting values.
7541       * @example
7542       *
7543       * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7544       * // => [2.1]
7545       *
7546       * // The `_.property` iteratee shorthand.
7547       * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7548       * // => [{ 'x': 1 }]
7549       */
7550      var intersectionBy = baseRest(function(arrays) {
7551        var iteratee = last(arrays),
7552            mapped = arrayMap(arrays, castArrayLikeObject);
7553  
7554        if (iteratee === last(mapped)) {
7555          iteratee = undefined;
7556        } else {
7557          mapped.pop();
7558        }
7559        return (mapped.length && mapped[0] === arrays[0])
7560          ? baseIntersection(mapped, getIteratee(iteratee, 2))
7561          : [];
7562      });
7563  
7564      /**
7565       * This method is like `_.intersection` except that it accepts `comparator`
7566       * which is invoked to compare elements of `arrays`. The order and references
7567       * of result values are determined by the first array. The comparator is
7568       * invoked with two arguments: (arrVal, othVal).
7569       *
7570       * @static
7571       * @memberOf _
7572       * @since 4.0.0
7573       * @category Array
7574       * @param {...Array} [arrays] The arrays to inspect.
7575       * @param {Function} [comparator] The comparator invoked per element.
7576       * @returns {Array} Returns the new array of intersecting values.
7577       * @example
7578       *
7579       * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7580       * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7581       *
7582       * _.intersectionWith(objects, others, _.isEqual);
7583       * // => [{ 'x': 1, 'y': 2 }]
7584       */
7585      var intersectionWith = baseRest(function(arrays) {
7586        var comparator = last(arrays),
7587            mapped = arrayMap(arrays, castArrayLikeObject);
7588  
7589        comparator = typeof comparator == 'function' ? comparator : undefined;
7590        if (comparator) {
7591          mapped.pop();
7592        }
7593        return (mapped.length && mapped[0] === arrays[0])
7594          ? baseIntersection(mapped, undefined, comparator)
7595          : [];
7596      });
7597  
7598      /**
7599       * Converts all elements in `array` into a string separated by `separator`.
7600       *
7601       * @static
7602       * @memberOf _
7603       * @since 4.0.0
7604       * @category Array
7605       * @param {Array} array The array to convert.
7606       * @param {string} [separator=','] The element separator.
7607       * @returns {string} Returns the joined string.
7608       * @example
7609       *
7610       * _.join(['a', 'b', 'c'], '~');
7611       * // => 'a~b~c'
7612       */
7613      function join(array, separator) {
7614        return array == null ? '' : nativeJoin.call(array, separator);
7615      }
7616  
7617      /**
7618       * Gets the last element of `array`.
7619       *
7620       * @static
7621       * @memberOf _
7622       * @since 0.1.0
7623       * @category Array
7624       * @param {Array} array The array to query.
7625       * @returns {*} Returns the last element of `array`.
7626       * @example
7627       *
7628       * _.last([1, 2, 3]);
7629       * // => 3
7630       */
7631      function last(array) {
7632        var length = array == null ? 0 : array.length;
7633        return length ? array[length - 1] : undefined;
7634      }
7635  
7636      /**
7637       * This method is like `_.indexOf` except that it iterates over elements of
7638       * `array` from right to left.
7639       *
7640       * @static
7641       * @memberOf _
7642       * @since 0.1.0
7643       * @category Array
7644       * @param {Array} array The array to inspect.
7645       * @param {*} value The value to search for.
7646       * @param {number} [fromIndex=array.length-1] The index to search from.
7647       * @returns {number} Returns the index of the matched value, else `-1`.
7648       * @example
7649       *
7650       * _.lastIndexOf([1, 2, 1, 2], 2);
7651       * // => 3
7652       *
7653       * // Search from the `fromIndex`.
7654       * _.lastIndexOf([1, 2, 1, 2], 2, 2);
7655       * // => 1
7656       */
7657      function lastIndexOf(array, value, fromIndex) {
7658        var length = array == null ? 0 : array.length;
7659        if (!length) {
7660          return -1;
7661        }
7662        var index = length;
7663        if (fromIndex !== undefined) {
7664          index = toInteger(fromIndex);
7665          index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
7666        }
7667        return value === value
7668          ? strictLastIndexOf(array, value, index)
7669          : baseFindIndex(array, baseIsNaN, index, true);
7670      }
7671  
7672      /**
7673       * Gets the element at index `n` of `array`. If `n` is negative, the nth
7674       * element from the end is returned.
7675       *
7676       * @static
7677       * @memberOf _
7678       * @since 4.11.0
7679       * @category Array
7680       * @param {Array} array The array to query.
7681       * @param {number} [n=0] The index of the element to return.
7682       * @returns {*} Returns the nth element of `array`.
7683       * @example
7684       *
7685       * var array = ['a', 'b', 'c', 'd'];
7686       *
7687       * _.nth(array, 1);
7688       * // => 'b'
7689       *
7690       * _.nth(array, -2);
7691       * // => 'c';
7692       */
7693      function nth(array, n) {
7694        return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
7695      }
7696  
7697      /**
7698       * Removes all given values from `array` using
7699       * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7700       * for equality comparisons.
7701       *
7702       * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
7703       * to remove elements from an array by predicate.
7704       *
7705       * @static
7706       * @memberOf _
7707       * @since 2.0.0
7708       * @category Array
7709       * @param {Array} array The array to modify.
7710       * @param {...*} [values] The values to remove.
7711       * @returns {Array} Returns `array`.
7712       * @example
7713       *
7714       * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7715       *
7716       * _.pull(array, 'a', 'c');
7717       * console.log(array);
7718       * // => ['b', 'b']
7719       */
7720      var pull = baseRest(pullAll);
7721  
7722      /**
7723       * This method is like `_.pull` except that it accepts an array of values to remove.
7724       *
7725       * **Note:** Unlike `_.difference`, this method mutates `array`.
7726       *
7727       * @static
7728       * @memberOf _
7729       * @since 4.0.0
7730       * @category Array
7731       * @param {Array} array The array to modify.
7732       * @param {Array} values The values to remove.
7733       * @returns {Array} Returns `array`.
7734       * @example
7735       *
7736       * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7737       *
7738       * _.pullAll(array, ['a', 'c']);
7739       * console.log(array);
7740       * // => ['b', 'b']
7741       */
7742      function pullAll(array, values) {
7743        return (array && array.length && values && values.length)
7744          ? basePullAll(array, values)
7745          : array;
7746      }
7747  
7748      /**
7749       * This method is like `_.pullAll` except that it accepts `iteratee` which is
7750       * invoked for each element of `array` and `values` to generate the criterion
7751       * by which they're compared. The iteratee is invoked with one argument: (value).
7752       *
7753       * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
7754       *
7755       * @static
7756       * @memberOf _
7757       * @since 4.0.0
7758       * @category Array
7759       * @param {Array} array The array to modify.
7760       * @param {Array} values The values to remove.
7761       * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7762       * @returns {Array} Returns `array`.
7763       * @example
7764       *
7765       * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
7766       *
7767       * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
7768       * console.log(array);
7769       * // => [{ 'x': 2 }]
7770       */
7771      function pullAllBy(array, values, iteratee) {
7772        return (array && array.length && values && values.length)
7773          ? basePullAll(array, values, getIteratee(iteratee, 2))
7774          : array;
7775      }
7776  
7777      /**
7778       * This method is like `_.pullAll` except that it accepts `comparator` which
7779       * is invoked to compare elements of `array` to `values`. The comparator is
7780       * invoked with two arguments: (arrVal, othVal).
7781       *
7782       * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
7783       *
7784       * @static
7785       * @memberOf _
7786       * @since 4.6.0
7787       * @category Array
7788       * @param {Array} array The array to modify.
7789       * @param {Array} values The values to remove.
7790       * @param {Function} [comparator] The comparator invoked per element.
7791       * @returns {Array} Returns `array`.
7792       * @example
7793       *
7794       * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
7795       *
7796       * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
7797       * console.log(array);
7798       * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
7799       */
7800      function pullAllWith(array, values, comparator) {
7801        return (array && array.length && values && values.length)
7802          ? basePullAll(array, values, undefined, comparator)
7803          : array;
7804      }
7805  
7806      /**
7807       * Removes elements from `array` corresponding to `indexes` and returns an
7808       * array of removed elements.
7809       *
7810       * **Note:** Unlike `_.at`, this method mutates `array`.
7811       *
7812       * @static
7813       * @memberOf _
7814       * @since 3.0.0
7815       * @category Array
7816       * @param {Array} array The array to modify.
7817       * @param {...(number|number[])} [indexes] The indexes of elements to remove.
7818       * @returns {Array} Returns the new array of removed elements.
7819       * @example
7820       *
7821       * var array = ['a', 'b', 'c', 'd'];
7822       * var pulled = _.pullAt(array, [1, 3]);
7823       *
7824       * console.log(array);
7825       * // => ['a', 'c']
7826       *
7827       * console.log(pulled);
7828       * // => ['b', 'd']
7829       */
7830      var pullAt = flatRest(function(array, indexes) {
7831        var length = array == null ? 0 : array.length,
7832            result = baseAt(array, indexes);
7833  
7834        basePullAt(array, arrayMap(indexes, function(index) {
7835          return isIndex(index, length) ? +index : index;
7836        }).sort(compareAscending));
7837  
7838        return result;
7839      });
7840  
7841      /**
7842       * Removes all elements from `array` that `predicate` returns truthy for
7843       * and returns an array of the removed elements. The predicate is invoked
7844       * with three arguments: (value, index, array).
7845       *
7846       * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
7847       * to pull elements from an array by value.
7848       *
7849       * @static
7850       * @memberOf _
7851       * @since 2.0.0
7852       * @category Array
7853       * @param {Array} array The array to modify.
7854       * @param {Function} [predicate=_.identity] The function invoked per iteration.
7855       * @returns {Array} Returns the new array of removed elements.
7856       * @example
7857       *
7858       * var array = [1, 2, 3, 4];
7859       * var evens = _.remove(array, function(n) {
7860       *   return n % 2 == 0;
7861       * });
7862       *
7863       * console.log(array);
7864       * // => [1, 3]
7865       *
7866       * console.log(evens);
7867       * // => [2, 4]
7868       */
7869      function remove(array, predicate) {
7870        var result = [];
7871        if (!(array && array.length)) {
7872          return result;
7873        }
7874        var index = -1,
7875            indexes = [],
7876            length = array.length;
7877  
7878        predicate = getIteratee(predicate, 3);
7879        while (++index < length) {
7880          var value = array[index];
7881          if (predicate(value, index, array)) {
7882            result.push(value);
7883            indexes.push(index);
7884          }
7885        }
7886        basePullAt(array, indexes);
7887        return result;
7888      }
7889  
7890      /**
7891       * Reverses `array` so that the first element becomes the last, the second
7892       * element becomes the second to last, and so on.
7893       *
7894       * **Note:** This method mutates `array` and is based on
7895       * [`Array#reverse`](https://mdn.io/Array/reverse).
7896       *
7897       * @static
7898       * @memberOf _
7899       * @since 4.0.0
7900       * @category Array
7901       * @param {Array} array The array to modify.
7902       * @returns {Array} Returns `array`.
7903       * @example
7904       *
7905       * var array = [1, 2, 3];
7906       *
7907       * _.reverse(array);
7908       * // => [3, 2, 1]
7909       *
7910       * console.log(array);
7911       * // => [3, 2, 1]
7912       */
7913      function reverse(array) {
7914        return array == null ? array : nativeReverse.call(array);
7915      }
7916  
7917      /**
7918       * Creates a slice of `array` from `start` up to, but not including, `end`.
7919       *
7920       * **Note:** This method is used instead of
7921       * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
7922       * returned.
7923       *
7924       * @static
7925       * @memberOf _
7926       * @since 3.0.0
7927       * @category Array
7928       * @param {Array} array The array to slice.
7929       * @param {number} [start=0] The start position.
7930       * @param {number} [end=array.length] The end position.
7931       * @returns {Array} Returns the slice of `array`.
7932       */
7933      function slice(array, start, end) {
7934        var length = array == null ? 0 : array.length;
7935        if (!length) {
7936          return [];
7937        }
7938        if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
7939          start = 0;
7940          end = length;
7941        }
7942        else {
7943          start = start == null ? 0 : toInteger(start);
7944          end = end === undefined ? length : toInteger(end);
7945        }
7946        return baseSlice(array, start, end);
7947      }
7948  
7949      /**
7950       * Uses a binary search to determine the lowest index at which `value`
7951       * should be inserted into `array` in order to maintain its sort order.
7952       *
7953       * @static
7954       * @memberOf _
7955       * @since 0.1.0
7956       * @category Array
7957       * @param {Array} array The sorted array to inspect.
7958       * @param {*} value The value to evaluate.
7959       * @returns {number} Returns the index at which `value` should be inserted
7960       *  into `array`.
7961       * @example
7962       *
7963       * _.sortedIndex([30, 50], 40);
7964       * // => 1
7965       */
7966      function sortedIndex(array, value) {
7967        return baseSortedIndex(array, value);
7968      }
7969  
7970      /**
7971       * This method is like `_.sortedIndex` except that it accepts `iteratee`
7972       * which is invoked for `value` and each element of `array` to compute their
7973       * sort ranking. The iteratee is invoked with one argument: (value).
7974       *
7975       * @static
7976       * @memberOf _
7977       * @since 4.0.0
7978       * @category Array
7979       * @param {Array} array The sorted array to inspect.
7980       * @param {*} value The value to evaluate.
7981       * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7982       * @returns {number} Returns the index at which `value` should be inserted
7983       *  into `array`.
7984       * @example
7985       *
7986       * var objects = [{ 'x': 4 }, { 'x': 5 }];
7987       *
7988       * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
7989       * // => 0
7990       *
7991       * // The `_.property` iteratee shorthand.
7992       * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
7993       * // => 0
7994       */
7995      function sortedIndexBy(array, value, iteratee) {
7996        return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
7997      }
7998  
7999      /**
8000       * This method is like `_.indexOf` except that it performs a binary
8001       * search on a sorted `array`.
8002       *
8003       * @static
8004       * @memberOf _
8005       * @since 4.0.0
8006       * @category Array
8007       * @param {Array} array The array to inspect.
8008       * @param {*} value The value to search for.
8009       * @returns {number} Returns the index of the matched value, else `-1`.
8010       * @example
8011       *
8012       * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
8013       * // => 1
8014       */
8015      function sortedIndexOf(array, value) {
8016        var length = array == null ? 0 : array.length;
8017        if (length) {
8018          var index = baseSortedIndex(array, value);
8019          if (index < length && eq(array[index], value)) {
8020            return index;
8021          }
8022        }
8023        return -1;
8024      }
8025  
8026      /**
8027       * This method is like `_.sortedIndex` except that it returns the highest
8028       * index at which `value` should be inserted into `array` in order to
8029       * maintain its sort order.
8030       *
8031       * @static
8032       * @memberOf _
8033       * @since 3.0.0
8034       * @category Array
8035       * @param {Array} array The sorted array to inspect.
8036       * @param {*} value The value to evaluate.
8037       * @returns {number} Returns the index at which `value` should be inserted
8038       *  into `array`.
8039       * @example
8040       *
8041       * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
8042       * // => 4
8043       */
8044      function sortedLastIndex(array, value) {
8045        return baseSortedIndex(array, value, true);
8046      }
8047  
8048      /**
8049       * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
8050       * which is invoked for `value` and each element of `array` to compute their
8051       * sort ranking. The iteratee is invoked with one argument: (value).
8052       *
8053       * @static
8054       * @memberOf _
8055       * @since 4.0.0
8056       * @category Array
8057       * @param {Array} array The sorted array to inspect.
8058       * @param {*} value The value to evaluate.
8059       * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8060       * @returns {number} Returns the index at which `value` should be inserted
8061       *  into `array`.
8062       * @example
8063       *
8064       * var objects = [{ 'x': 4 }, { 'x': 5 }];
8065       *
8066       * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8067       * // => 1
8068       *
8069       * // The `_.property` iteratee shorthand.
8070       * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
8071       * // => 1
8072       */
8073      function sortedLastIndexBy(array, value, iteratee) {
8074        return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
8075      }
8076  
8077      /**
8078       * This method is like `_.lastIndexOf` except that it performs a binary
8079       * search on a sorted `array`.
8080       *
8081       * @static
8082       * @memberOf _
8083       * @since 4.0.0
8084       * @category Array
8085       * @param {Array} array The array to inspect.
8086       * @param {*} value The value to search for.
8087       * @returns {number} Returns the index of the matched value, else `-1`.
8088       * @example
8089       *
8090       * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
8091       * // => 3
8092       */
8093      function sortedLastIndexOf(array, value) {
8094        var length = array == null ? 0 : array.length;
8095        if (length) {
8096          var index = baseSortedIndex(array, value, true) - 1;
8097          if (eq(array[index], value)) {
8098            return index;
8099          }
8100        }
8101        return -1;
8102      }
8103  
8104      /**
8105       * This method is like `_.uniq` except that it's designed and optimized
8106       * for sorted arrays.
8107       *
8108       * @static
8109       * @memberOf _
8110       * @since 4.0.0
8111       * @category Array
8112       * @param {Array} array The array to inspect.
8113       * @returns {Array} Returns the new duplicate free array.
8114       * @example
8115       *
8116       * _.sortedUniq([1, 1, 2]);
8117       * // => [1, 2]
8118       */
8119      function sortedUniq(array) {
8120        return (array && array.length)
8121          ? baseSortedUniq(array)
8122          : [];
8123      }
8124  
8125      /**
8126       * This method is like `_.uniqBy` except that it's designed and optimized
8127       * for sorted arrays.
8128       *
8129       * @static
8130       * @memberOf _
8131       * @since 4.0.0
8132       * @category Array
8133       * @param {Array} array The array to inspect.
8134       * @param {Function} [iteratee] The iteratee invoked per element.
8135       * @returns {Array} Returns the new duplicate free array.
8136       * @example
8137       *
8138       * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
8139       * // => [1.1, 2.3]
8140       */
8141      function sortedUniqBy(array, iteratee) {
8142        return (array && array.length)
8143          ? baseSortedUniq(array, getIteratee(iteratee, 2))
8144          : [];
8145      }
8146  
8147      /**
8148       * Gets all but the first element of `array`.
8149       *
8150       * @static
8151       * @memberOf _
8152       * @since 4.0.0
8153       * @category Array
8154       * @param {Array} array The array to query.
8155       * @returns {Array} Returns the slice of `array`.
8156       * @example
8157       *
8158       * _.tail([1, 2, 3]);
8159       * // => [2, 3]
8160       */
8161      function tail(array) {
8162        var length = array == null ? 0 : array.length;
8163        return length ? baseSlice(array, 1, length) : [];
8164      }
8165  
8166      /**
8167       * Creates a slice of `array` with `n` elements taken from the beginning.
8168       *
8169       * @static
8170       * @memberOf _
8171       * @since 0.1.0
8172       * @category Array
8173       * @param {Array} array The array to query.
8174       * @param {number} [n=1] The number of elements to take.
8175       * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8176       * @returns {Array} Returns the slice of `array`.
8177       * @example
8178       *
8179       * _.take([1, 2, 3]);
8180       * // => [1]
8181       *
8182       * _.take([1, 2, 3], 2);
8183       * // => [1, 2]
8184       *
8185       * _.take([1, 2, 3], 5);
8186       * // => [1, 2, 3]
8187       *
8188       * _.take([1, 2, 3], 0);
8189       * // => []
8190       */
8191      function take(array, n, guard) {
8192        if (!(array && array.length)) {
8193          return [];
8194        }
8195        n = (guard || n === undefined) ? 1 : toInteger(n);
8196        return baseSlice(array, 0, n < 0 ? 0 : n);
8197      }
8198  
8199      /**
8200       * Creates a slice of `array` with `n` elements taken from the end.
8201       *
8202       * @static
8203       * @memberOf _
8204       * @since 3.0.0
8205       * @category Array
8206       * @param {Array} array The array to query.
8207       * @param {number} [n=1] The number of elements to take.
8208       * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8209       * @returns {Array} Returns the slice of `array`.
8210       * @example
8211       *
8212       * _.takeRight([1, 2, 3]);
8213       * // => [3]
8214       *
8215       * _.takeRight([1, 2, 3], 2);
8216       * // => [2, 3]
8217       *
8218       * _.takeRight([1, 2, 3], 5);
8219       * // => [1, 2, 3]
8220       *
8221       * _.takeRight([1, 2, 3], 0);
8222       * // => []
8223       */
8224      function takeRight(array, n, guard) {
8225        var length = array == null ? 0 : array.length;
8226        if (!length) {
8227          return [];
8228        }
8229        n = (guard || n === undefined) ? 1 : toInteger(n);
8230        n = length - n;
8231        return baseSlice(array, n < 0 ? 0 : n, length);
8232      }
8233  
8234      /**
8235       * Creates a slice of `array` with elements taken from the end. Elements are
8236       * taken until `predicate` returns falsey. The predicate is invoked with
8237       * three arguments: (value, index, array).
8238       *
8239       * @static
8240       * @memberOf _
8241       * @since 3.0.0
8242       * @category Array
8243       * @param {Array} array The array to query.
8244       * @param {Function} [predicate=_.identity] The function invoked per iteration.
8245       * @returns {Array} Returns the slice of `array`.
8246       * @example
8247       *
8248       * var users = [
8249       *   { 'user': 'barney',  'active': true },
8250       *   { 'user': 'fred',    'active': false },
8251       *   { 'user': 'pebbles', 'active': false }
8252       * ];
8253       *
8254       * _.takeRightWhile(users, function(o) { return !o.active; });
8255       * // => objects for ['fred', 'pebbles']
8256       *
8257       * // The `_.matches` iteratee shorthand.
8258       * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
8259       * // => objects for ['pebbles']
8260       *
8261       * // The `_.matchesProperty` iteratee shorthand.
8262       * _.takeRightWhile(users, ['active', false]);
8263       * // => objects for ['fred', 'pebbles']
8264       *
8265       * // The `_.property` iteratee shorthand.
8266       * _.takeRightWhile(users, 'active');
8267       * // => []
8268       */
8269      function takeRightWhile(array, predicate) {
8270        return (array && array.length)
8271          ? baseWhile(array, getIteratee(predicate, 3), false, true)
8272          : [];
8273      }
8274  
8275      /**
8276       * Creates a slice of `array` with elements taken from the beginning. Elements
8277       * are taken until `predicate` returns falsey. The predicate is invoked with
8278       * three arguments: (value, index, array).
8279       *
8280       * @static
8281       * @memberOf _
8282       * @since 3.0.0
8283       * @category Array
8284       * @param {Array} array The array to query.
8285       * @param {Function} [predicate=_.identity] The function invoked per iteration.
8286       * @returns {Array} Returns the slice of `array`.
8287       * @example
8288       *
8289       * var users = [
8290       *   { 'user': 'barney',  'active': false },
8291       *   { 'user': 'fred',    'active': false },
8292       *   { 'user': 'pebbles', 'active': true }
8293       * ];
8294       *
8295       * _.takeWhile(users, function(o) { return !o.active; });
8296       * // => objects for ['barney', 'fred']
8297       *
8298       * // The `_.matches` iteratee shorthand.
8299       * _.takeWhile(users, { 'user': 'barney', 'active': false });
8300       * // => objects for ['barney']
8301       *
8302       * // The `_.matchesProperty` iteratee shorthand.
8303       * _.takeWhile(users, ['active', false]);
8304       * // => objects for ['barney', 'fred']
8305       *
8306       * // The `_.property` iteratee shorthand.
8307       * _.takeWhile(users, 'active');
8308       * // => []
8309       */
8310      function takeWhile(array, predicate) {
8311        return (array && array.length)
8312          ? baseWhile(array, getIteratee(predicate, 3))
8313          : [];
8314      }
8315  
8316      /**
8317       * Creates an array of unique values, in order, from all given arrays using
8318       * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8319       * for equality comparisons.
8320       *
8321       * @static
8322       * @memberOf _
8323       * @since 0.1.0
8324       * @category Array
8325       * @param {...Array} [arrays] The arrays to inspect.
8326       * @returns {Array} Returns the new array of combined values.
8327       * @example
8328       *
8329       * _.union([2], [1, 2]);
8330       * // => [2, 1]
8331       */
8332      var union = baseRest(function(arrays) {
8333        return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
8334      });
8335  
8336      /**
8337       * This method is like `_.union` except that it accepts `iteratee` which is
8338       * invoked for each element of each `arrays` to generate the criterion by
8339       * which uniqueness is computed. Result values are chosen from the first
8340       * array in which the value occurs. The iteratee is invoked with one argument:
8341       * (value).
8342       *
8343       * @static
8344       * @memberOf _
8345       * @since 4.0.0
8346       * @category Array
8347       * @param {...Array} [arrays] The arrays to inspect.
8348       * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8349       * @returns {Array} Returns the new array of combined values.
8350       * @example
8351       *
8352       * _.unionBy([2.1], [1.2, 2.3], Math.floor);
8353       * // => [2.1, 1.2]
8354       *
8355       * // The `_.property` iteratee shorthand.
8356       * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8357       * // => [{ 'x': 1 }, { 'x': 2 }]
8358       */
8359      var unionBy = baseRest(function(arrays) {
8360        var iteratee = last(arrays);
8361        if (isArrayLikeObject(iteratee)) {
8362          iteratee = undefined;
8363        }
8364        return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
8365      });
8366  
8367      /**
8368       * This method is like `_.union` except that it accepts `comparator` which
8369       * is invoked to compare elements of `arrays`. Result values are chosen from
8370       * the first array in which the value occurs. The comparator is invoked
8371       * with two arguments: (arrVal, othVal).
8372       *
8373       * @static
8374       * @memberOf _
8375       * @since 4.0.0
8376       * @category Array
8377       * @param {...Array} [arrays] The arrays to inspect.
8378       * @param {Function} [comparator] The comparator invoked per element.
8379       * @returns {Array} Returns the new array of combined values.
8380       * @example
8381       *
8382       * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8383       * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8384       *
8385       * _.unionWith(objects, others, _.isEqual);
8386       * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8387       */
8388      var unionWith = baseRest(function(arrays) {
8389        var comparator = last(arrays);
8390        comparator = typeof comparator == 'function' ? comparator : undefined;
8391        return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
8392      });
8393  
8394      /**
8395       * Creates a duplicate-free version of an array, using
8396       * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8397       * for equality comparisons, in which only the first occurrence of each element
8398       * is kept. The order of result values is determined by the order they occur
8399       * in the array.
8400       *
8401       * @static
8402       * @memberOf _
8403       * @since 0.1.0
8404       * @category Array
8405       * @param {Array} array The array to inspect.
8406       * @returns {Array} Returns the new duplicate free array.
8407       * @example
8408       *
8409       * _.uniq([2, 1, 2]);
8410       * // => [2, 1]
8411       */
8412      function uniq(array) {
8413        return (array && array.length) ? baseUniq(array) : [];
8414      }
8415  
8416      /**
8417       * This method is like `_.uniq` except that it accepts `iteratee` which is
8418       * invoked for each element in `array` to generate the criterion by which
8419       * uniqueness is computed. The order of result values is determined by the
8420       * order they occur in the array. The iteratee is invoked with one argument:
8421       * (value).
8422       *
8423       * @static
8424       * @memberOf _
8425       * @since 4.0.0
8426       * @category Array
8427       * @param {Array} array The array to inspect.
8428       * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8429       * @returns {Array} Returns the new duplicate free array.
8430       * @example
8431       *
8432       * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
8433       * // => [2.1, 1.2]
8434       *
8435       * // The `_.property` iteratee shorthand.
8436       * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
8437       * // => [{ 'x': 1 }, { 'x': 2 }]
8438       */
8439      function uniqBy(array, iteratee) {
8440        return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
8441      }
8442  
8443      /**
8444       * This method is like `_.uniq` except that it accepts `comparator` which
8445       * is invoked to compare elements of `array`. The order of result values is
8446       * determined by the order they occur in the array.The comparator is invoked
8447       * with two arguments: (arrVal, othVal).
8448       *
8449       * @static
8450       * @memberOf _
8451       * @since 4.0.0
8452       * @category Array
8453       * @param {Array} array The array to inspect.
8454       * @param {Function} [comparator] The comparator invoked per element.
8455       * @returns {Array} Returns the new duplicate free array.
8456       * @example
8457       *
8458       * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
8459       *
8460       * _.uniqWith(objects, _.isEqual);
8461       * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
8462       */
8463      function uniqWith(array, comparator) {
8464        comparator = typeof comparator == 'function' ? comparator : undefined;
8465        return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
8466      }
8467  
8468      /**
8469       * This method is like `_.zip` except that it accepts an array of grouped
8470       * elements and creates an array regrouping the elements to their pre-zip
8471       * configuration.
8472       *
8473       * @static
8474       * @memberOf _
8475       * @since 1.2.0
8476       * @category Array
8477       * @param {Array} array The array of grouped elements to process.
8478       * @returns {Array} Returns the new array of regrouped elements.
8479       * @example
8480       *
8481       * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
8482       * // => [['a', 1, true], ['b', 2, false]]
8483       *
8484       * _.unzip(zipped);
8485       * // => [['a', 'b'], [1, 2], [true, false]]
8486       */
8487      function unzip(array) {
8488        if (!(array && array.length)) {
8489          return [];
8490        }
8491        var length = 0;
8492        array = arrayFilter(array, function(group) {
8493          if (isArrayLikeObject(group)) {
8494            length = nativeMax(group.length, length);
8495            return true;
8496          }
8497        });
8498        return baseTimes(length, function(index) {
8499          return arrayMap(array, baseProperty(index));
8500        });
8501      }
8502  
8503      /**
8504       * This method is like `_.unzip` except that it accepts `iteratee` to specify
8505       * how regrouped values should be combined. The iteratee is invoked with the
8506       * elements of each group: (...group).
8507       *
8508       * @static
8509       * @memberOf _
8510       * @since 3.8.0
8511       * @category Array
8512       * @param {Array} array The array of grouped elements to process.
8513       * @param {Function} [iteratee=_.identity] The function to combine
8514       *  regrouped values.
8515       * @returns {Array} Returns the new array of regrouped elements.
8516       * @example
8517       *
8518       * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
8519       * // => [[1, 10, 100], [2, 20, 200]]
8520       *
8521       * _.unzipWith(zipped, _.add);
8522       * // => [3, 30, 300]
8523       */
8524      function unzipWith(array, iteratee) {
8525        if (!(array && array.length)) {
8526          return [];
8527        }
8528        var result = unzip(array);
8529        if (iteratee == null) {
8530          return result;
8531        }
8532        return arrayMap(result, function(group) {
8533          return apply(iteratee, undefined, group);
8534        });
8535      }
8536  
8537      /**
8538       * Creates an array excluding all given values using
8539       * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8540       * for equality comparisons.
8541       *
8542       * **Note:** Unlike `_.pull`, this method returns a new array.
8543       *
8544       * @static
8545       * @memberOf _
8546       * @since 0.1.0
8547       * @category Array
8548       * @param {Array} array The array to inspect.
8549       * @param {...*} [values] The values to exclude.
8550       * @returns {Array} Returns the new array of filtered values.
8551       * @see _.difference, _.xor
8552       * @example
8553       *
8554       * _.without([2, 1, 2, 3], 1, 2);
8555       * // => [3]
8556       */
8557      var without = baseRest(function(array, values) {
8558        return isArrayLikeObject(array)
8559          ? baseDifference(array, values)
8560          : [];
8561      });
8562  
8563      /**
8564       * Creates an array of unique values that is the
8565       * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
8566       * of the given arrays. The order of result values is determined by the order
8567       * they occur in the arrays.
8568       *
8569       * @static
8570       * @memberOf _
8571       * @since 2.4.0
8572       * @category Array
8573       * @param {...Array} [arrays] The arrays to inspect.
8574       * @returns {Array} Returns the new array of filtered values.
8575       * @see _.difference, _.without
8576       * @example
8577       *
8578       * _.xor([2, 1], [2, 3]);
8579       * // => [1, 3]
8580       */
8581      var xor = baseRest(function(arrays) {
8582        return baseXor(arrayFilter(arrays, isArrayLikeObject));
8583      });
8584  
8585      /**
8586       * This method is like `_.xor` except that it accepts `iteratee` which is
8587       * invoked for each element of each `arrays` to generate the criterion by
8588       * which by which they're compared. The order of result values is determined
8589       * by the order they occur in the arrays. The iteratee is invoked with one
8590       * argument: (value).
8591       *
8592       * @static
8593       * @memberOf _
8594       * @since 4.0.0
8595       * @category Array
8596       * @param {...Array} [arrays] The arrays to inspect.
8597       * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8598       * @returns {Array} Returns the new array of filtered values.
8599       * @example
8600       *
8601       * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8602       * // => [1.2, 3.4]
8603       *
8604       * // The `_.property` iteratee shorthand.
8605       * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8606       * // => [{ 'x': 2 }]
8607       */
8608      var xorBy = baseRest(function(arrays) {
8609        var iteratee = last(arrays);
8610        if (isArrayLikeObject(iteratee)) {
8611          iteratee = undefined;
8612        }
8613        return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
8614      });
8615  
8616      /**
8617       * This method is like `_.xor` except that it accepts `comparator` which is
8618       * invoked to compare elements of `arrays`. The order of result values is
8619       * determined by the order they occur in the arrays. The comparator is invoked
8620       * with two arguments: (arrVal, othVal).
8621       *
8622       * @static
8623       * @memberOf _
8624       * @since 4.0.0
8625       * @category Array
8626       * @param {...Array} [arrays] The arrays to inspect.
8627       * @param {Function} [comparator] The comparator invoked per element.
8628       * @returns {Array} Returns the new array of filtered values.
8629       * @example
8630       *
8631       * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8632       * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8633       *
8634       * _.xorWith(objects, others, _.isEqual);
8635       * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8636       */
8637      var xorWith = baseRest(function(arrays) {
8638        var comparator = last(arrays);
8639        comparator = typeof comparator == 'function' ? comparator : undefined;
8640        return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
8641      });
8642  
8643      /**
8644       * Creates an array of grouped elements, the first of which contains the
8645       * first elements of the given arrays, the second of which contains the
8646       * second elements of the given arrays, and so on.
8647       *
8648       * @static
8649       * @memberOf _
8650       * @since 0.1.0
8651       * @category Array
8652       * @param {...Array} [arrays] The arrays to process.
8653       * @returns {Array} Returns the new array of grouped elements.