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