diff --git a/dist/lodash.compat.js b/dist/lodash.compat.js index 4ea957a48..36a0f4b03 100644 --- a/dist/lodash.compat.js +++ b/dist/lodash.compat.js @@ -31,8 +31,9 @@ /** Used as the TypeError message for "Functions" methods */ var FUNC_ERROR_TEXT = 'Expected a function'; - /** Used as a reference for the max length of an array */ - var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1; + /** Used as references for the max length and index of an array */ + var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; /** * Used as the maximum length of an array-like value. @@ -47,9 +48,6 @@ /** Used to generate unique IDs */ var idCounter = 0; - /** Used to detect words composed of all capital letters */ - var reAllCaps = /^[A-Z]+$/; - /** Used to match empty string literals in compiled template source */ var reEmptyStringLeading = /\b__p \+= '';/g, reEmptyStringMiddle = /\b(__p \+=) '' \+/g, @@ -103,7 +101,13 @@ var reUnescapedString = /['\n\r\u2028\u2029\\]/g; /** Used to match words to create compound words */ - var reWords = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g; + var reWords = (function() { + var nums = '[0-9]', + upper = '[A-Z\\xC0-\\xD6\\xD8-\\xDE]', + lower = '[a-z\\xDF-\\xF6\\xF8-\\xFF]+' + nums + '*'; + + return RegExp(upper + '{2,}(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|' + nums + '+', 'g'); + }()); /** Used to detect and test whitespace */ var whitespace = ( @@ -200,7 +204,7 @@ }; /** - * Used to convert characters to HTML entities. + * Used to map characters to HTML entities. * * **Note:** Though the ">" character is escaped for symmetry, characters like * ">" and "/" don't require escaping in HTML and have no special meaning @@ -222,7 +226,7 @@ '`': '`' }; - /** Used to convert HTML entities to characters */ + /** Used to map HTML entities to characters */ var htmlUnescapes = { '&': '&', '<': '<', @@ -232,11 +236,7 @@ '`': '`' }; - /** - * Used to convert latin-1 supplement letters to basic latin (ASCII) letters. - * See [Wikipedia](http://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * for more details. - */ + /** Used to map latin-1 supplementary letters to basic latin letters */ var deburredLetters = { '\xC0': 'A', '\xC1': 'A', '\xC2': 'A', '\xC3': 'A', '\xC4': 'A', '\xC5': 'A', '\xE0': 'a', '\xE1': 'a', '\xE2': 'a', '\xE3': 'a', '\xE4': 'a', '\xE5': 'a', @@ -252,7 +252,7 @@ '\xD9': 'U', '\xDA': 'U', '\xDB': 'U', '\xDC': 'U', '\xF9': 'u', '\xFA': 'u', '\xFB': 'u', '\xFC': 'u', '\xDD': 'Y', '\xFD': 'y', '\xFF': 'y', - '\xC6': 'AE', '\xE6': 'ae', + '\xC6': 'Ae', '\xE6': 'ae', '\xDE': 'Th', '\xFE': 'th', '\xDF': 'ss', '\xD7': ' ', '\xF7': ' ' }; @@ -293,6 +293,184 @@ /*--------------------------------------------------------------------------*/ + /** + * A specialized version of `_.forEach` for arrays without support for + * callback shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns `true` if all elements passed the predicate check, + * else `false` + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray=false] Specify using the first element of + * `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; + + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray=false] Specify using the last element of + * `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passed the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + /** * The base implementation of `_.at` without support for strings and individual * key arguments. @@ -324,10 +502,13 @@ */ function baseCompareAscending(value, other) { if (value !== other) { - if (value > other || typeof value == 'undefined') { + var valIsReflexive = value === value, + othIsReflexive = other === other; + + if (value > other || !valIsReflexive || (typeof value == 'undefined' && othIsReflexive)) { return 1; } - if (value < other || typeof other == 'undefined') { + if (value < other || !othIsReflexive || (typeof other == 'undefined' && valIsReflexive)) { return -1; } } @@ -478,30 +659,7 @@ } /** - * Creates a function that produces compound words out of the words in a - * given string. - * - * @private - * @param {Function} callback The function invoked to combine each word. - * @returns {Function} Returns the new compounder function. - */ - function createCompounder(callback) { - return function(string) { - var index = -1, - words = string != null && String(string).replace(reLatin1, deburrLetter).match(reWords), - length = words ? words.length : 0, - result = ''; - - while (++index < length) { - result = callback(result, words[index], index, words); - } - return result; - }; - } - - /** - * Used by `createCompounder` to convert latin-1 supplement letters to basic - * latin (ASCII) letters. + * Used by `deburr` to convert latin-1 to basic latin letters. * * @private * @param {string} letter The matched letter to deburr. @@ -567,6 +725,58 @@ (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); } + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } + + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } + /** * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace * character of `string`. @@ -697,6 +907,7 @@ setTimeout = context.setTimeout, splice = arrayProto.splice, Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array, + unshift = arrayProto.unshift, WeakMap = isNative(WeakMap = context.WeakMap) && WeakMap; /** Used to clone array buffers */ @@ -782,15 +993,15 @@ * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `pluck`, `property`, * `pull`, `pullAt`, `push`, `range`, `reject`, `remove`, `rest`, `reverse`, * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `take`, `takeRight`, - * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `times`, `toArray`, - * `transform`, `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, - * `where`, `without`, `wrap`, `xor`, `zip`, and `zipObject` + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `times`, + * `toArray`, `transform`, `union`, `uniq`, `unshift`, `unzip`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, and `zipObject` * * The non-chainable wrapper functions are: * `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `contains`, - * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, - * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, - * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, isDate`, + * `deburr`, endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `has`, `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, isDate`, * `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`, `isFunction`, * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, * `isRegExp`, `isString`, `isUndefined`, `join`, `kebabCase`, `last`, @@ -798,7 +1009,7 @@ * `padRight`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, * `result`, `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, * `sortedLastIndex`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, - * `trunc`, `unescape`, `uniqueId`, and `value` + * `trunc`, `unescape`, `uniqueId`, `value`, and `words` * * The wrapper function `sample` will return a wrapped value when `n` is * provided, otherwise it will return an unwrapped value. @@ -833,7 +1044,7 @@ return value; } if (!isArray(value) && hasOwnProperty.call(value, '__wrapped__')) { - value = value.__wrapped__; + return new lodashWrapper(value.__wrapped__, value.__chain__, baseSlice(value.__queue__)); } } return new lodashWrapper(value); @@ -845,10 +1056,12 @@ * @private * @param {*} value The value to wrap in a `lodash` instance. * @param {boolean} [chainAll=false] Enable chaining for all methods. + * @param {Array} [queue=[]] Actions to peform to resolve the unwrapped value. * @returns {Object} Returns a `lodash` instance. */ - function lodashWrapper(value, chainAll) { + function lodashWrapper(value, chainAll, queue) { this.__chain__ = !!chainAll; + this.__queue__ = queue || []; this.__wrapped__ = value; } @@ -1078,184 +1291,6 @@ /*------------------------------------------------------------------------*/ - /** - * A specialized version of `_.forEach` for arrays without support for - * callback shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array.length; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.forEachRight` for arrays without support for - * callback shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEachRight(array, iteratee) { - var length = array.length; - - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.every` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns `true` if all elements passed the predicate check, - * else `false` - */ - function arrayEvery(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; - } - - /** - * A specialized version of `_.map` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * A specialized version of `_.filter` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[++resIndex] = value; - } - } - return result; - } - - /** - * A specialized version of `_.reduce` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray=false] Specify using the first element of - * `array` as the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduce(array, iteratee, accumulator, initFromArray) { - var index = -1, - length = array.length; - - if (initFromArray && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; - } - - /** - * A specialized version of `_.reduceRight` for arrays without support for - * callback shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray=false] Specify using the last element of - * `array` as the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduceRight(array, iteratee, accumulator, initFromArray) { - var length = array.length; - - if (initFromArray && length) { - accumulator = array[--length]; - } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); - } - return accumulator; - } - - /** - * A specialized version of `_.some` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passed the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - /** * Used by `_.defaults` to customize its `_.assign` use. * @@ -1447,7 +1482,6 @@ ? baseClone(valValue, isDeep, null, stackA, stackB) : valClone; }); - return result; } @@ -1500,7 +1534,7 @@ * * @private * @param {Array} array The array to inspect. - * @param {Array} [values] The array of values to exclude. + * @param {Array} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. */ function baseDifference(array, values) { @@ -1555,7 +1589,7 @@ return baseForOwn(collection, iteratee); } var index = -1, - iterable = toIterable(collection); + iterable = toObject(collection); while (++index < length) { if (iteratee(iterable[index], index, iterable) === false) { @@ -1579,7 +1613,7 @@ if (!(typeof length == 'number' && length > -1 && length <= MAX_SAFE_INTEGER)) { return baseForOwnRight(collection, iteratee); } - var iterable = toIterable(collection); + var iterable = toObject(collection); while (length--) { if (iteratee(iterable[length], length, iterable) === false) { break; @@ -1707,12 +1741,13 @@ */ function baseFor(object, iteratee, keysFunc) { var index = -1, + iterable = toObject(object), props = keysFunc(object), length = props.length; while (++index < length) { var key = props[index]; - if (iteratee(object[key], key, object) === false) { + if (iteratee(iterable[key], key, iterable) === false) { break; } } @@ -1730,12 +1765,13 @@ * @returns {Object} Returns `object`. */ function baseForRight(object, iteratee, keysFunc) { - var props = keysFunc(object), + var iterable = toObject(object), + props = keysFunc(object), length = props.length; while (length--) { var key = props[length]; - if (iteratee(object[key], key, object) === false) { + if (iteratee(iterable[key], key, iterable) === false) { break; } } @@ -1867,7 +1903,7 @@ othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); if (valWrapped || othWrapped) { - return baseIsEqual(valWrapped ? value.__wrapped__ : value, othWrapped ? other.__wrapped__ : other, customizer, isWhere, stackA, stackB); + return baseIsEqual(valWrapped ? value.value() : value, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB); } if (!isSameClass) { return false; @@ -1896,10 +1932,9 @@ } if (!valHasCtor) { // non `Object` object instances with different constructors are not equal - if (valCtor != othCtor && - !(isFunction(valCtor) && valCtor instanceof valCtor && isFunction(othCtor) && othCtor instanceof othCtor) && - ('constructor' in value && 'constructor' in other) - ) { + if (valCtor != othCtor && ('constructor' in value && 'constructor' in other) && + !(typeof valCtor == 'function' && valCtor instanceof valCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { return false; } } @@ -2108,7 +2143,6 @@ } object[key] = result; }); - return object; } @@ -2120,7 +2154,7 @@ * @private * @param {Function} func The function to partially apply arguments to. * @param {number} bitmask The bitmask of flags to compose. - * @param {Array} args The array of arguments to be partially applied. + * @param {Array} args The arguments to be partially applied. * @param {*} [thisArg] The `this` binding of `func`. * @returns {Function} Returns the new partially applied function. */ @@ -2247,17 +2281,21 @@ high = array ? array.length : low; value = iteratee(value); - var hintNum = typeof value == 'number' || - (value != null && isFunction(value.valueOf) && typeof value.valueOf() == 'number'); + + var valIsNaN = value !== value, + valIsUndef = typeof value == 'undefined'; while (low < high) { - var mid = (low + high) >>> 1, + var mid = floor((low + high) / 2), computed = iteratee(array[mid]), - setLow = retHighest ? (computed <= value) : (computed < value); + isReflexive = computed === computed; - if (hintNum && typeof computed != 'undefined') { - computed = +computed; - setLow = computed != computed || setLow; + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || typeof computed != 'undefined'); + } else { + setLow = retHighest ? (computed <= value) : (computed < value); } if (setLow) { low = mid + 1; @@ -2265,7 +2303,7 @@ high = mid; } } - return high; + return nativeMin(high, MAX_ARRAY_INDEX); } /** @@ -2376,8 +2414,8 @@ * placeholders, and provided arguments into a single array of arguments. * * @private - * @param {Array} partialArgs An array of arguments to prepend to those provided. - * @param {Array} partialHolders An array of `partialArgs` placeholder indexes. + * @param {Array} partialArgs The arguments to prepend to those provided. + * @param {Array} partialHolders The `partialArgs` placeholder indexes. * @param {Array|Object} args The provided arguments. * @returns {Array} Returns the new array of composed arguments. */ @@ -2406,8 +2444,8 @@ * is tailored for `_.partialRight`. * * @private - * @param {Array} partialRightArgs An array of arguments to append to those provided. - * @param {Array} partialHolders An array of `partialRightArgs` placeholder indexes. + * @param {Array} partialRightArgs The arguments to append to those provided. + * @param {Array} partialHolders The `partialRightArgs` placeholder indexes. * @param {Array|Object} args The provided arguments. * @returns {Array} Returns the new array of composed arguments. */ @@ -2447,9 +2485,9 @@ */ function createAggregator(setter, initializer) { return function(collection, iteratee, thisArg) { - var result = initializer ? initializer() : {}; iteratee = getCallback(iteratee, thisArg, 3); + var result = initializer ? initializer() : {}; if (isArray(collection)) { var index = -1, length = collection.length; @@ -2538,6 +2576,28 @@ return cache; }; + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function invoked to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; + + while (++index < length) { + result = callback(result, array[index], index, words); + } + return result; + }; + } + /** * Creates a function that produces an instance of `Ctor` regardless of * whether it was invoked as part of a `new` expression or by `call` or `apply`. @@ -2566,10 +2626,10 @@ * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. * @param {number} arity The arity of `func`. * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partialArgs] An array of arguments to prepend to those provided to the new function. - * @param {Array} [partialHolders] An array of `partialArgs` placeholder indexes. - * @param {Array} [partialRightArgs] An array of arguments to append to those provided to the new function. - * @param {Array} [partialRightHolders] An array of `partialRightArgs` placeholder indexes. + * @param {Array} [partialArgs] The arguments to prepend to those provided to the new function. + * @param {Array} [partialHolders] The `partialArgs` placeholder indexes. + * @param {Array} [partialRightArgs] The arguments to append to those provided to the new function. + * @param {Array} [partialRightHolders] The `partialRightArgs` placeholder indexes. * @returns {Function} Returns the new function. */ function createHybridWrapper(func, bitmask, arity, thisArg, partialArgs, partialHolders, partialRightArgs, partialRightHolders) { @@ -2659,7 +2719,7 @@ * @private * @param {Function} func The function to partially apply arguments to. * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. - * @param {Array} partialArgs An array of arguments to prepend to those provided to the new function. + * @param {Array} partialArgs The arguments to prepend to those provided to the new function. * @param {*} [thisArg] The `this` binding of `func`. * @returns {Function} Returns the new bound function. */ @@ -2704,10 +2764,10 @@ * 64 - `_.partialRight` * @param {number} arity The arity of `func`. * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partialArgs] An array of arguments to prepend to those provided to the new function. - * @param {Array} [partialHolders] An array of `partialArgs` placeholder indexes. - * @param {Array} [partialRightArgs] An array of arguments to append to those provided to the new function. - * @param {Array} [partialRightHolders] An array of `partialRightArgs` placeholder indexes. + * @param {Array} [partialArgs] The arguments to prepend to those provided to the new function. + * @param {Array} [partialHolders] The `partialArgs` placeholder indexes. + * @param {Array} [partialRightArgs] The arguments to append to those provided to the new function. + * @param {Array} [partialRightHolders] The `partialRightArgs` placeholder indexes. * @returns {Function} Returns the new function. */ function createWrapper(func, bitmask, arity, thisArg, partialArgs, partialHolders, partialRightArgs, partialRightHolders) { @@ -2862,7 +2922,7 @@ isArgs = className == argsClass || (!support.argsClass && isArguments(object)), isObj = className == objectClass; - if (isObj && !(isFunction(Ctor) && (Ctor instanceof Ctor))) { + if (isObj && !(typeof Ctor == 'function' && Ctor instanceof Ctor)) { Ctor = Object; } if (isArgs || isObj) { @@ -2935,6 +2995,8 @@ * @returns {Object} Returns the new object. */ function pickByArray(object, props) { + object = toObject(object); + var index = -1, length = props.length, result = {}; @@ -2968,30 +3030,6 @@ return result; } - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - if (array[index] === placeholder) { - array[index] = PLACEHOLDER; - result[++resIndex] = index; - } - } - return result; - } - /** * Sets metadata for `func`. * @@ -3041,7 +3079,7 @@ if (!(value && typeof value == 'object' && toString.call(value) == objectClass && !isHostObject(value)) || (!hasOwnProperty.call(value, 'constructor') && - (Ctor = value.constructor, isFunction(Ctor) && !(Ctor instanceof Ctor))) || + (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor))) || (!support.argsClass && isArguments(value))) { return false; } @@ -3082,8 +3120,8 @@ result = []; var allowIndexes = typeof objLength == 'number' && objLength > 0 && - (isArray(object) || (support.nonEnumArgs && isArguments(object)) || - (support.nonEnumStrings && isString(object))); + (isArray(object) || (support.nonEnumStrings && isString(object)) || + (support.nonEnumArgs && isArguments(object))); while (++index < length) { var key = props[index]; @@ -3095,34 +3133,6 @@ return result; } - /** - * An implementation of `_.uniq` optimized for sorted arrays without support - * for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. - */ - function sortedUniq(array, iteratee) { - var seen, - index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; - - if (!index || seen !== computed) { - seen = computed; - result[++resIndex] = value; - } - } - return result; - } - /** * Converts `value` to an array-like object if it is not one. * @@ -3138,14 +3148,10 @@ if (!(typeof length == 'number' && length > -1 && length <= MAX_SAFE_INTEGER)) { return values(value); } - value = toObject(value); if (support.unindexedChars && isString(value)) { - var index = -1; - while (++index < length) { - value[index] = value.charAt(index); - } + return value.split(''); } - return value; + return isObject(value) ? value : Object(value); } /** @@ -3156,6 +3162,16 @@ * @returns {Object} Returns the object. */ function toObject(value) { + if (support.unindexedChars && isString(value)) { + var index = -1, + length = value.length, + result = Object(value); + + while (++index < length) { + result[index] = value.charAt(index); + } + return result; + } return isObject(value) ? value : Object(value); } @@ -3342,18 +3358,18 @@ * _.dropRightWhile([1, 2, 3], function(n) { return n > 1; }); * // => [1] * - * var characters = [ - * { 'name': 'barney', 'employer': 'slate' }, - * { 'name': 'fred', 'employer': 'slate', 'blocked': true }, - * { 'name': 'pebbles', 'employer': 'na', 'blocked': true } + * var users = [ + * { 'user': 'barney', 'employer': 'slate' }, + * { 'user': 'fred', 'employer': 'slate', 'blocked': true }, + * { 'user': 'pebbles', 'employer': 'na', 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.pluck(_.dropRightWhile(characters, 'blocked'), 'name'); + * _.pluck(_.dropRightWhile(users, 'blocked'), 'user'); * // => ['barney'] * * // using "_.where" callback shorthand - * _.pluck(_.dropRightWhile(characters, { 'employer': 'na' }), 'name'); + * _.pluck(_.dropRightWhile(users, { 'employer': 'na' }), 'user'); * // => ['barney', 'fred'] */ function dropRightWhile(array, predicate, thisArg) { @@ -3391,18 +3407,18 @@ * _.dropWhile([1, 2, 3], function(n) { return n < 3; }); * // => [3] * - * var characters = [ - * { 'name': 'barney', 'employer': 'slate', 'blocked': true }, - * { 'name': 'fred', 'employer': 'slate' }, - * { 'name': 'pebbles', 'employer': 'na', 'blocked': true } + * var users = [ + * { 'user': 'barney', 'employer': 'slate', 'blocked': true }, + * { 'user': 'fred', 'employer': 'slate' }, + * { 'user': 'pebbles', 'employer': 'na', 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.pluck(_.dropWhile(characters, 'blocked'), 'name'); + * _.pluck(_.dropWhile(users, 'blocked'), 'user'); * // => ['fred', 'pebbles'] * * // using "_.where" callback shorthand - * _.pluck(_.dropWhile(characters, { 'employer': 'slate' }), 'name'); + * _.pluck(_.dropWhile(users, { 'employer': 'slate' }), 'user'); * // => ['pebbles'] */ function dropWhile(array, predicate, thisArg) { @@ -3436,23 +3452,23 @@ * @returns {number} Returns the index of the found element, else `-1`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true }, + * { 'user': 'pebbles', 'age': 1 } * ]; * - * _.findIndex(characters, function(chr) { + * _.findIndex(users, function(chr) { * return chr.age < 20; * }); * // => 2 * * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); + * _.findIndex(users, { 'age': 36 }); * // => 0 * * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); + * _.findIndex(users, 'blocked'); * // => 1 */ function findIndex(array, predicate, thisArg) { @@ -3490,23 +3506,23 @@ * @returns {number} Returns the index of the found element, else `-1`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': true }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36, 'blocked': true }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1, 'blocked': true } * ]; * - * _.findLastIndex(characters, function(chr) { + * _.findLastIndex(users, function(chr) { * return chr.age > 30; * }); * // => 1 * * // using "_.where" callback shorthand - * _.findLastIndex(characters, { 'age': 36 }); + * _.findLastIndex(users, { 'age': 36 }); * // => 0 * * // using "_.pluck" callback shorthand - * _.findLastIndex(characters, 'blocked'); + * _.findLastIndex(users, 'blocked'); * // => 2 */ function findLastIndex(array, predicate, thisArg) { @@ -4118,18 +4134,18 @@ * _.takeRightWhile([1, 2, 3], function(n) { return n > 1; }); * // => [2, 3] * - * var characters = [ - * { 'name': 'barney', 'employer': 'slate' }, - * { 'name': 'fred', 'employer': 'slate', 'blocked': true }, - * { 'name': 'pebbles', 'employer': 'na', 'blocked': true } + * var users = [ + * { 'user': 'barney', 'employer': 'slate' }, + * { 'user': 'fred', 'employer': 'slate', 'blocked': true }, + * { 'user': 'pebbles', 'employer': 'na', 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.pluck(_.takeRightWhile(characters, 'blocked'), 'name'); + * _.pluck(_.takeRightWhile(users, 'blocked'), 'user'); * // => ['fred', 'pebbles'] * * // using "_.where" callback shorthand - * _.pluck(_.takeRightWhile(characters, { 'employer': 'na' }), 'name'); + * _.pluck(_.takeRightWhile(users, { 'employer': 'na' }), 'user'); * // => ['pebbles'] */ function takeRightWhile(array, predicate, thisArg) { @@ -4167,18 +4183,18 @@ * _.takeWhile([1, 2, 3], function(n) { return n < 3; }); * // => [1, 2] * - * var characters = [ - * { 'name': 'barney', 'employer': 'slate', 'blocked': true }, - * { 'name': 'fred', 'employer': 'slate' }, - * { 'name': 'pebbles', 'employer': 'na', 'blocked': true } + * var users = [ + * { 'user': 'barney', 'employer': 'slate', 'blocked': true }, + * { 'user': 'fred', 'employer': 'slate' }, + * { 'user': 'pebbles', 'employer': 'na', 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.pluck(_.takeWhile(characters, 'blocked'), 'name'); + * _.pluck(_.takeWhile(users, 'blocked'), 'user'); * // => ['barney'] * * // using "_.where" callback shorthand - * _.pluck(_.takeWhile(characters, { 'employer': 'slate' }), 'name'); + * _.pluck(_.takeWhile(users, { 'employer': 'slate' }), 'user'); * // => ['barney', 'fred'] */ function takeWhile(array, predicate, thisArg) { @@ -4403,8 +4419,8 @@ * @memberOf _ * @alias object * @category Array - * @param {Array} props The array of property names. - * @param {Array} [vals=[]] The array of property values. + * @param {Array} props The property names. + * @param {Array} [vals=[]] The property values. * @returns {Object} Returns the new object. * @example * @@ -4443,15 +4459,15 @@ * @returns {Object} Returns the new wrapper object. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } * ]; * - * var youngest = _.chain(characters) + * var youngest = _.chain(users) * .sortBy('age') - * .map(function(chr) { return chr.name + ' is ' + chr.age; }) + * .map(function(chr) { return chr.user + ' is ' + chr.age; }) * .first() * .value(); * // => 'pebbles is 1' @@ -4477,17 +4493,39 @@ * @returns {*} Returns `value`. * @example * - * _([1, 2, 3, 4]) + * _([1, 2, 3]) * .tap(function(array) { array.pop(); }) * .reverse() * .value(); - * // => [3, 2, 1] + * // => [2, 1] */ function tap(value, interceptor, thisArg) { interceptor.call(thisArg, value); return value; } + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _([1, 2, 3]) + * .last() + * .thru(function(value) { return [value]; }) + * .value(); + * // => [3] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); + } + /** * Enables explicit method chaining on the wrapper object. * @@ -4497,29 +4535,28 @@ * @returns {*} Returns the wrapper object. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // without explicit chaining - * _(characters).first(); - * // => { 'name': 'barney', 'age': 36 } + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } * * // with explicit chaining - * _(characters).chain() + * _(users).chain() * .first() * .pick('age') * .value(); * // => { 'age': 36 } */ function wrapperChain() { - this.__chain__ = true; - return this; + return chain(this); } /** - * Produces the result of coercing the wrapped value to a string. + * Produces the result of coercing the unwrapped value to a string. * * @name toString * @memberOf _ @@ -4531,24 +4568,37 @@ * // => '1,2,3' */ function wrapperToString() { - return String(this.__wrapped__); + return String(this.value()); } /** - * Extracts the wrapped value. + * Extracts the unwrapped value from its wrapper. * * @name valueOf * @memberOf _ * @alias toJSON, value * @category Chain - * @returns {*} Returns the wrapped value. + * @returns {*} Returns the unwrapped value. * @example * * _([1, 2, 3]).valueOf(); * // => [1, 2, 3] */ function wrapperValueOf() { - return this.__wrapped__; + var index = -1, + queue = this.__queue__, + length = queue.length, + result = this.__wrapped__; + + while (++index < length) { + var args = [result], + data = queue[index], + object = data[1]; + + push.apply(args, data[2]); + result = object[data[0]].apply(object, args); + } + return result; } /*------------------------------------------------------------------------*/ @@ -4607,7 +4657,7 @@ * _.contains([1, 2, 3], 1, 2); * // => false * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * _.contains({ 'user': 'fred', 'age': 40 }, 'fred'); * // => true * * _.contains('pebbles', 'eb'); @@ -4696,17 +4746,17 @@ * _.every([true, 1, null, 'yes']); * // => false * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); + * _.every(users, 'age'); * // => true * * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); + * _.every(users, { 'age': 36 }); * // => false */ function every(collection, predicate, thisArg) { @@ -4744,18 +4794,18 @@ * var evens = _.filter([1, 2, 3, 4], function(n) { return n % 2 == 0; }); * // => [2, 4] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * _.filter(users, 'blocked'); + * // => [{ 'user': 'fred', 'age': 40, 'blocked': true }] * * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36 }] + * _.filter(users, { 'age': 36 }); + * // => [{ 'user': 'barney', 'age': 36 }] */ function filter(collection, predicate, thisArg) { var func = isArray(collection) ? arrayFilter : baseFilter; @@ -4788,24 +4838,24 @@ * @returns {*} Returns the matched element, else `undefined`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true }, + * { 'user': 'pebbles', 'age': 1 } * ]; * - * _.find(characters, function(chr) { + * _.find(users, function(chr) { * return chr.age < 40; * }); - * // => { 'name': 'barney', 'age': 36 } + * // => { 'user': 'barney', 'age': 36 } * * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1 } + * _.find(users, { 'age': 1 }); + * // => { 'user': 'pebbles', 'age': 1 } * * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } + * _.find(users, 'blocked'); + * // => { 'user': 'fred', 'age': 40, 'blocked': true } */ function find(collection, predicate, thisArg) { if (isArray(collection)) { @@ -4852,16 +4902,16 @@ * @returns {*} Returns the matched element, else `undefined`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'employer': 'slate' }, - * { 'name': 'fred', 'age': 40, 'employer': 'slate' } + * var users = [ + * { 'user': 'barney', 'age': 36, 'employer': 'slate' }, + * { 'user': 'fred', 'age': 40, 'employer': 'slate' } * ]; * - * _.findWhere(characters, { 'employer': 'slate' }); - * // => { 'name': 'barney', 'age': 36, 'employer': 'slate' } + * _.findWhere(users, { 'employer': 'slate' }); + * // => { 'user': 'barney', 'age': 36, 'employer': 'slate' } * - * _.findWhere(characters, { 'age': 40 }); - * // => { 'name': 'fred', 'age': 40, 'employer': 'slate' } + * _.findWhere(users, { 'age': 40 }); + * // => { 'user': 'fred', 'age': 40, 'employer': 'slate' } */ function findWhere(collection, source) { return find(collection, matches(source)); @@ -4888,10 +4938,10 @@ * @example * * _([1, 2, 3]).forEach(function(n) { console.log(n); }); - * // => logs each value and returns the array + * // => logs each value from left to right and returns the array * * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(n, key) { console.log(n, key); }); - * // => logs each value-key pair and returns the object (property order is not guaranteed) + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) */ function forEach(collection, iteratee, thisArg) { return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) @@ -5062,15 +5112,15 @@ * // => [3, 6, 9] * * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(n) { return n * 3; }); - * // => [3, 6, 9] (property order is not guaranteed) + * // => [3, 6, 9] (iteration order is not guaranteed) * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); + * _.map(users, 'user'); * // => ['barney', 'fred'] */ function map(collection, iteratee, thisArg) { @@ -5111,17 +5161,17 @@ * _.max([]); * // => -Infinity * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; + * _.max(users, function(chr) { return chr.age; }); + * // => { 'user': 'fred', 'age': 40 }; * * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; + * _.max(users, 'age'); + * // => { 'user': 'fred', 'age': 40 }; */ function max(collection, iteratee, thisArg) { var computed = -Infinity, @@ -5194,17 +5244,17 @@ * _.min([]); * // => Infinity * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; + * _.min(users, function(chr) { return chr.age; }); + * // => { 'user': 'barney', 'age': 36 }; * * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; + * _.min(users, 'age'); + * // => { 'user': 'barney', 'age': 36 }; */ function min(collection, iteratee, thisArg) { var computed = Infinity, @@ -5276,18 +5326,18 @@ * _.partition([1.2, 2.3, 3.4], function(n) { return this.floor(n) % 2; }, Math); * // => [[1, 3], [2]] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true }, + * { 'user': 'pebbles', 'age': 1 } * ]; * * // using "_.where" callback shorthand - * _.map(_.partition(characters, { 'age': 1 }), function(array) { return _.pluck(array, 'name'); }); + * _.map(_.partition(users, { 'age': 1 }), function(array) { return _.pluck(array, 'user'); }); * // => [['pebbles'], ['barney', 'fred']] * * // using "_.pluck" callback shorthand - * _.map(_.partition(characters, 'blocked'), function(array) { return _.pluck(array, 'name'); }); + * _.map(_.partition(users, 'blocked'), function(array) { return _.pluck(array, 'user'); }); * // => [['fred'], ['barney', 'pebbles']] */ var partition = createAggregator(function(result, value, key) { @@ -5305,13 +5355,17 @@ * @returns {Array} Returns the property values. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * _.pluck(characters, 'name'); + * _.pluck(users, 'user'); * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) */ function pluck(collection, key) { return map(collection, property(key)); @@ -5343,7 +5397,7 @@ * result[key] = n * 3; * return result; * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } (property order is not guaranteed) + * // => { 'a': 3, 'b': 6, 'c': 9 } (iteration order is not guaranteed) */ function reduce(collection, iteratee, accumulator, thisArg) { var func = isArray(collection) ? arrayReduce : baseReduce; @@ -5399,18 +5453,18 @@ * var odds = _.reject([1, 2, 3, 4], function(n) { return n % 2 == 0; }); * // => [1, 3] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36 }] + * _.reject(users, 'blocked'); + * // => [{ 'user': 'barney', 'age': 36 }] * * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * _.reject(users, { 'age': 36 }); + * // => [{ 'user': 'fred', 'age': 40, 'blocked': true }] */ function reject(collection, predicate, thisArg) { var func = isArray(collection) ? arrayFilter : baseFilter; @@ -5538,17 +5592,17 @@ * _.some([null, 0, 'yes', false], Boolean); * // => true * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); + * _.some(users, 'blocked'); * // => true * * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); + * _.some(users, { 'age': 1 }); * // => false */ function some(collection, predicate, thisArg) { @@ -5593,19 +5647,19 @@ * _.sortBy([1, 2, 3], function(n) { return this.sin(n); }, Math); * // => [3, 1, 2] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 26 }, + * { 'user': 'fred', 'age': 30 } * ]; * * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); + * _.map(_.sortBy(users, 'age'), _.values); * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] * * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * _.map(_.sortBy(users, ['user', 'age']), _.values); * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] */ function sortBy(collection, iteratee, thisArg) { @@ -5678,18 +5732,18 @@ * @returns {Array} Returns the new filtered array. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'employer': 'slate', 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'employer': 'slate', 'pets': ['baby puss', 'dino'] } + * var users = [ + * { 'user': 'barney', 'age': 36, 'employer': 'slate', 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'employer': 'slate', 'pets': ['baby puss', 'dino'] } * ]; * - * _.pluck(_.where(characters, { 'age': 36 }), 'name'); + * _.pluck(_.where(users, { 'age': 36 }), 'user'); * // => ['barney'] * - * _.pluck(_.where(characters, { 'pets': ['dino'] }), 'name'); + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); * // => ['fred'] * - * _.pluck(_.where(characters, { 'employer': 'slate' }), 'name'); + * _.pluck(_.where(users, { 'employer': 'slate' }), 'user'); * // => ['barney', 'fred'] */ function where(collection, source) { @@ -5719,7 +5773,7 @@ * _.forEach(saves, function(type) { * asyncSave({ 'type': type, 'complete': done }); * }); - * // => logs 'done saving!' after all saves have completed + * // => logs 'done saving!' after the two async saves have completed */ function after(n, func) { if (!isFunction(func)) { @@ -5740,19 +5794,20 @@ } /** - * Creates a function that invokes `func`, with the `this` binding and - * arguments of the created function, until it is called `n` times. + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. * * @static * @memberOf _ * @category Function - * @param {number} n The number of times `func` may be called. + * @param {number} n The number of calls at which `func` is no longer invoked. * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * jQuery('#add').on('click', _.before(5, addContactToList)); - * // => allows adding up to 5 contacts to the list + * // => allows adding up to 4 contacts to the list */ function before(n, func) { var result; @@ -5793,10 +5848,10 @@ * @example * * var func = function(greeting) { - * return greeting + ' ' + this.name; + * return greeting + ' ' + this.user; * }; * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func = _.bind(func, { 'user': 'fred' }, 'hi'); * func(); * // => 'hi fred' */ @@ -5862,9 +5917,9 @@ * @example * * var object = { - * 'name': 'fred', + * 'user': 'fred', * 'greet': function(greeting) { - * return greeting + ' ' + this.name; + * return greeting + ' ' + this.user; * } * }; * @@ -5873,7 +5928,7 @@ * // => 'hi fred' * * object.greet = function(greeting) { - * return greeting + 'ya ' + this.name + '!'; + * return greeting + 'ya ' + this.user + '!'; * }; * * func(); @@ -5960,15 +6015,15 @@ } /** - * Creates a function that delays the invocation of `func` until after `wait` - * milliseconds have elapsed since the last time it was invoked. The created - * function comes with a `cancel` method to cancel delayed invokes. Provide an - * options object to indicate that `func` should be invoked on the leading - * and/or trailing edge of the `wait` timeout. Subsequent calls to the - * debounced function return the result of the last `func` invocation. + * Creates a function that delays invoking `func` until after `wait` milliseconds + * have elapsed since the last time it was invoked. The created function comes + * with a `cancel` method to cancel delayed invocations. Provide an options + * object to indicate that `func` should be invoked on the leading and/or + * trailing edge of the `wait` timeout. Subsequent calls to the debounced + * function return the result of the last `func` invocation. * - * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked on - * the trailing edge of the timeout only if the the debounced function is + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is * invoked more than once during the `wait` timeout. * * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) @@ -6009,7 +6064,7 @@ * Object.observe(models.todo, todoChanges); * * Object.observe(models, function(changes) { - * if (_.find(changes, { 'name': 'todo', 'type': 'delete'})) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { * todoChanges.cancel(); * } * }, ['delete']); @@ -6442,8 +6497,8 @@ /** * Creates a function that only invokes `func` at most once per every `wait` * milliseconds. The created function comes with a `cancel` method to cancel - * delayed invokes. Provide an options object to indicate that `func` should - * be invoked on the leading and/or trailing edge of the `wait` timeout. + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. * Subsequent calls to the throttled function return the result of the last * `func` call. * @@ -6546,17 +6601,17 @@ * @returns {*} Returns the cloned value. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; + * var shallow = _.clone(users); + * shallow[0] === users[0]; * // => true * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; + * var deep = _.clone(users, true); + * deep[0] === users[0]; * // => false * * _.mixin({ @@ -6608,13 +6663,13 @@ * @returns {*} Returns the deep cloned value. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * var deep = _.cloneDeep(characters); - * deep[0] === characters[0]; + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; * // => false * * var view = { @@ -6816,8 +6871,8 @@ * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * - * var object = { 'name': 'fred' }; - * var other = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; * * object == other; * // => false @@ -7179,15 +7234,15 @@ * @returns {Object} Returns the destination object. * @example * - * _.assign({ 'name': 'fred' }, { 'age': 40 }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'age': 40, 'employer': 'slate' } + * _.assign({ 'user': 'fred' }, { 'age': 40 }, { 'employer': 'slate' }); + * // => { 'user': 'fred', 'age': 40, 'employer': 'slate' } * * var defaults = _.partialRight(_.assign, function(value, other) { * return typeof value == 'undefined' ? other : value; * }); * - * defaults({ 'name': 'barney' }, { 'age': 36 }, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'age': 36, 'employer': 'slate' } + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred', 'employer': 'slate' }); + * // => { 'user': 'barney', 'age': 36, 'employer': 'slate' } */ var assign = createAssigner(baseAssign); @@ -7243,8 +7298,8 @@ * @returns {Object} Returns the destination object. * @example * - * _.defaults({ 'name': 'barney' }, { 'age': 36 }, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'age': 36, 'employer': 'slate' } + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred', 'employer': 'slate' }); + * // => { 'user': 'barney', 'age': 36, 'employer': 'slate' } */ function defaults(object) { if (object == null) { @@ -7277,23 +7332,23 @@ * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * var characters = { + * var users = { * 'barney': { 'age': 36 }, * 'fred': { 'age': 40, 'blocked': true }, * 'pebbles': { 'age': 1 } * }; * - * _.findKey(characters, function(chr) { + * _.findKey(users, function(chr) { * return chr.age < 40; * }); - * // => 'barney' (property order is not guaranteed) + * // => 'barney' (iteration order is not guaranteed) * * // using "_.where" callback shorthand - * _.findKey(characters, { 'age': 1 }); + * _.findKey(users, { 'age': 1 }); * // => 'pebbles' * * // using "_.pluck" callback shorthand - * _.findKey(characters, 'blocked'); + * _.findKey(users, 'blocked'); * // => 'fred' */ function findKey(object, predicate, thisArg) { @@ -7323,23 +7378,23 @@ * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * var characters = { + * var users = { * 'barney': { 'age': 36, 'blocked': true }, * 'fred': { 'age': 40 }, * 'pebbles': { 'age': 1, 'blocked': true } * }; * - * _.findLastKey(characters, function(chr) { + * _.findLastKey(users, function(chr) { * return chr.age < 40; * }); * // => returns `pebbles`, assuming `_.findKey` returns `barney` * * // using "_.where" callback shorthand - * _.findLastKey(characters, { 'age': 40 }); + * _.findLastKey(users, { 'age': 40 }); * // => 'fred' * * // using "_.pluck" callback shorthand - * _.findLastKey(characters, 'blocked'); + * _.findLastKey(users, 'blocked'); * // => 'pebbles' */ function findLastKey(object, predicate, thisArg) { @@ -7372,7 +7427,7 @@ * _.forIn(new Shape, function(value, key) { * console.log(key); * }); - * // => logs 'x', 'y', and 'z' (property order is not guaranteed) + * // => logs 'x', 'y', and 'z' (iteration order is not guaranteed) */ function forIn(object, iteratee, thisArg) { if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { @@ -7429,7 +7484,7 @@ * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(n, key) { * console.log(key); * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed) + * // => logs '0', '1', and 'length' (iteration order is not guaranteed) */ function forOwn(object, iteratee, thisArg) { if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { @@ -7566,20 +7621,19 @@ * Shape.prototype.z = 0; * * _.keys(new Shape); - * // => ['x', 'y'] (property order is not guaranteed) + * // => ['x', 'y'] (iteration order is not guaranteed) */ var keys = !nativeKeys ? shimKeys : function(object) { - object = toObject(object); - - var Ctor = object.constructor, - length = object.length; - - if ((Ctor && object === Ctor.prototype) || + if (object) { + var Ctor = object.constructor, + length = object.length; + } + if ((typeof Ctor == 'function' && Ctor.prototype === object) || (typeof length == 'number' && length > 0) || (support.enumPrototypes && typeof object == 'function')) { return shimKeys(object); } - return nativeKeys(object); + return isObject(object) ? nativeKeys(object) : []; }; /** @@ -7600,14 +7654,15 @@ * Shape.prototype.z = 0; * * _.keysIn(new Shape); - * // => ['x', 'y', 'z'] (property order is not guaranteed) + * // => ['x', 'y', 'z'] (iteration order is not guaranteed) */ function keysIn(object) { if (object == null) { return []; } - object = toObject(object); - + if (!isObject(object)) { + object = Object(object); + } var length = object.length; length = (typeof length == 'number' && length > 0 && (isArray(object) || (support.nonEnumStrings && isString(object)) || @@ -7616,7 +7671,7 @@ var keyIndex, Ctor = object.constructor, index = -1, - isProto = Ctor && object === Ctor.prototype, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, maxIndex = length - 1, result = Array(length), skipIndexes = length > 0, @@ -7683,19 +7738,19 @@ * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(n) { return n * 3; }); * // => { 'a': 3, 'b': 6, 'c': 9 } * - * var characters = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } * }; * * // using "_.pluck" callback shorthand - * _.mapValues(characters, 'age'); + * _.mapValues(users, 'age'); * // => { 'fred': 40, 'pebbles': 1 } */ function mapValues(object, iteratee, thisArg) { - var result = {}; iteratee = getCallback(iteratee, thisArg, 3); + var result = {} baseForOwn(object, function(value, key, object) { result[key] = iteratee(value, key, object); }); @@ -7721,22 +7776,16 @@ * @returns {Object} Returns the destination object. * @example * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] * }; * * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] + * 'data': [{ 'age': 36 }, { 'age': 40 }] * }; * - * _.merge(names, ages); - * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } * * var food = { * 'fruits': ['apple'], @@ -7774,25 +7823,24 @@ * @returns {Object} Returns the new object. * @example * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } + * _.omit({ 'user': 'fred', 'age': 40 }, 'age'); + * // => { 'user': 'fred' } * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * _.omit({ 'user': 'fred', 'age': 40 }, function(value) { * return typeof value == 'number'; * }); - * // => { 'name': 'fred' } + * // => { 'user': 'fred' } */ function omit(object, predicate, thisArg) { if (object == null) { return {}; } - var iterable = toObject(object); if (typeof predicate != 'function') { var props = arrayMap(baseFlatten(arguments, false, false, 1), String); - return pickByArray(iterable, baseDifference(keysIn(iterable), props)); + return pickByArray(object, baseDifference(keysIn(object), props)); } predicate = getCallback(predicate, thisArg, 3); - return pickByCallback(iterable, function(value, key, object) { + return pickByCallback(object, function(value, key, object) { return !predicate(value, key, object); }); } @@ -7809,7 +7857,7 @@ * @example * * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed) + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) */ function pairs(object) { var index = -1, @@ -7843,22 +7891,21 @@ * @returns {Object} Returns the new object. * @example * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } + * _.pick({ 'user': 'fred', '_userid': 'fred1' }, 'user'); + * // => { 'user': 'fred' } * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * _.pick({ 'user': 'fred', '_userid': 'fred1' }, function(value, key) { * return key.charAt(0) != '_'; * }); - * // => { 'name': 'fred' } + * // => { 'user': 'fred' } */ function pick(object, predicate, thisArg) { if (object == null) { return {}; } - var iterable = toObject(object); return typeof predicate == 'function' - ? pickByCallback(iterable, getCallback(predicate, thisArg, 3)) - : pickByArray(iterable, baseFlatten(arguments, false, false, 1)); + ? pickByCallback(object, getCallback(predicate, thisArg, 3)) + : pickByArray(object, baseFlatten(arguments, false, false, 1)); } /** @@ -7893,25 +7940,22 @@ * // => { 'a': 3, 'b': 6, 'c': 9 } */ function transform(object, iteratee, accumulator, thisArg) { - var isArr = isArrayLike(object); + iteratee = getCallback(iteratee, thisArg, 4); + var isArr = isArrayLike(object); if (accumulator == null) { if (isArr) { accumulator = []; + } else if (isObject(object)) { + var Ctor = object.constructor; + accumulator = baseCreate(typeof Ctor == 'function' && Ctor.prototype); } else { - if (isObject(object)) { - var Ctor = object.constructor, - proto = Ctor && Ctor.prototype; - } - accumulator = baseCreate(proto); + accumulator = {}; } } - if (iteratee) { - iteratee = getCallback(iteratee, thisArg, 4); - (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); return accumulator; } @@ -7933,7 +7977,7 @@ * Shape.prototype.z = 0; * * _.values(new Shape(2, 1)); - * // => [2, 1] (property order is not guaranteed) + * // => [2, 1] (iteration order is not guaranteed) */ function values(object) { return baseValues(object, keys); @@ -7958,7 +8002,7 @@ * Shape.prototype.z = 0; * * _.valuesIn(new Shape(2, 1)); - * // => [2, 1, 0] (property order is not guaranteed) + * // => [2, 1, 0] (iteration order is not guaranteed) */ function valuesIn(object) { return baseValues(object, keysIn); @@ -7987,10 +8031,8 @@ * // => 'helloWorld' */ var camelCase = createCompounder(function(result, word, index) { - if (!index && reAllCaps.test(word)) { - return result + word.toLowerCase(); - } - return result + (word.charAt(0)[index ? 'toUpperCase' : 'toLowerCase']() + word.slice(1)); + word = word.toLowerCase(); + return index ? (result + word.charAt(0).toUpperCase() + word.slice(1)) : word; }); /** @@ -8007,11 +8049,28 @@ * // => 'Fred' */ function capitalize(string) { - if (string == null) { - return ''; - } - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); + string = string == null ? '' : String(string); + return string ? (string.charAt(0).toUpperCase() + string.slice(1)) : string; + } + + /** + * Deburrs `string` by converting latin-1 supplementary letters to basic latin letters. + * See [Wikipedia](http://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the beburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = string == null ? '' : String(string); + return string ? string.replace(reLatin1, deburrLetter) : string; } /** @@ -8069,7 +8128,7 @@ function escape(string) { // reset `lastIndex` because in IE < 9 `String#replace` does not string = string == null ? '' : String(string); - return (reUnescapedHtml.lastIndex = 0, reUnescapedHtml.test(string)) + return string && (reUnescapedHtml.lastIndex = 0, reUnescapedHtml.test(string)) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string; } @@ -8085,12 +8144,12 @@ * @returns {string} Returns the escaped string. * @example * - * _.escapeRegExp('[lodash](http://lodash.com)'); - * // => '\[lodash\]\(http://lodash\.com\)' + * _.escapeRegExp('[lodash](http://lodash.com/)'); + * // => '\[lodash\]\(http://lodash\.com/\)' */ function escapeRegExp(string) { string = string == null ? '' : String(string); - return (reRegExpChars.lastIndex = 0, reRegExpChars.test(string)) + return string && (reRegExpChars.lastIndex = 0, reRegExpChars.test(string)) ? string.replace(reRegExpChars, '\\$&') : string; } @@ -8184,7 +8243,7 @@ */ function padLeft(string, length, chars) { string = string == null ? '' : String(string); - return createPad(string, length, chars) + string; + return string ? (createPad(string, length, chars) + string) : string; } /** @@ -8212,7 +8271,7 @@ */ function padRight(string, length, chars) { string = string == null ? '' : String(string); - return string + createPad(string, length, chars); + return string ? (string + createPad(string, length, chars)) : string; } /** @@ -8342,9 +8401,9 @@ * @example * * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'fred' }); - * // => 'hello fred' + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' * * // using the HTML "escape" delimiter to escape data property values * var compiled = _.template('<%- value %>'); @@ -8352,24 +8411,24 @@ * // => '<script>' * * // using the "evaluate" delimiter to execute JavaScript and generate HTML - * var compiled = _.template('<% _.forEach(people, function(name) { %>
  • <%- name %>
  • <% }); %>'); - * compiled({ 'people': ['fred', 'barney'] }); + * var compiled = _.template('<% _.forEach(users, function(user) { %>
  • <%- user %>
  • <% }); %>'); + * compiled({ 'users': ['fred', 'barney'] }); * // => '
  • fred
  • barney
  • ' * * // using the internal `print` function in "evaluate" delimiters - * var compiled = _.template('<% print("hello " + name); %>!'); - * compiled({ 'name': 'barney' }); + * var compiled = _.template('<% print("hello " + user); %>!'); + * compiled({ 'user': 'barney' }); * // => 'hello barney!' * * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter - * var compiled = _.template('hello ${ name }'); - * compiled({ 'name': 'pebbles' }); - * // => 'hello pebbles' + * var compiled = _.template('hello ${ user }!'); + * compiled({ 'user': 'pebbles' }); + * // => 'hello pebbles!' * * // using custom template delimiters * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; - * var compiled = _.template('hello {{ name }}!'); - * compiled({ 'name': 'mustache' }); + * var compiled = _.template('hello {{ user }}!'); + * compiled({ 'user': 'mustache' }); * // => 'hello mustache!' * * // using backslashes to treat delimiters as plain text @@ -8378,22 +8437,22 @@ * // => '<%- value %>' * * // using the `imports` option to import `jQuery` as `jq` - * var text = '<% jq.each(people, function(name) { %>
  • <%- name %>
  • <% }); %>'; + * var text = '<% jq.each(users, function(user) { %>
  • <%- user %>
  • <% }); %>'; * var compiled = _.template(text, { 'imports': { 'jq': jQuery } }); - * compiled({ 'people': ['fred', 'barney'] }); + * compiled({ 'users': ['fred', 'barney'] }); * // => '
  • fred
  • barney
  • ' * * // using the `sourceURL` option to specify a custom sourceURL for the template - * var compiled = _.template('hello <%= name %>', { 'sourceURL': '/basic/greeting.jst' }); + * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' }); * compiled(data); * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector * * // using the `variable` option to ensure a with-statement isn't used in the compiled template - * var compiled = _.template('hi <%= data.name %>!', { 'variable': 'data' }); + * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' }); * compiled.source; * // => function(data) { - * var __t, __p = '', __e = _.escape; - * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!'; + * var __t, __p = ''; + * __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; * return __p; * } * @@ -8688,16 +8747,38 @@ * @returns {string} Returns the unescaped string. * @example * - * _.unescape('fred, barney & pebbles'); - * // => 'fred, barney & pebbles' + * _.unescape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' */ function unescape(string) { string = string == null ? '' : String(string); - return (reEscapedHtml.lastIndex = 0, reEscapedHtml.test(string)) + return string && (reEscapedHtml.lastIndex = 0, reEscapedHtml.test(string)) ? string.replace(reEscapedHtml, unescapeHtmlChar) : string; } + /** + * Splits `string` into an array of its words. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to inspect. + * @param {RegExp|string} [pattern] The pattern to match words. + * @returns {Array} Returns the words of `string`. + * @example + * + * _.words('fred, barney, & pebbles'); + * // => ['fred', 'barney', 'pebbles'] + * + * _.words('fred, barney, & pebbles', /[^, ]+/g); + * // => ['fred', 'barney', '&', 'pebbles'] + */ + function words(string, pattern) { + string = string != null && String(string); + return (string && string.match(pattern || reWords)) || []; + } + /*------------------------------------------------------------------------*/ /** @@ -8743,9 +8824,9 @@ * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // wrap to create custom callback shorthands @@ -8759,8 +8840,8 @@ * }; * }); * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] + * _.filter(users, 'age__gt38'); + * // => [{ 'user': 'fred', 'age': 40 }] */ function callback(func, thisArg) { return baseCallback(func, thisArg); @@ -8776,7 +8857,7 @@ * @returns {Function} Returns the new function. * @example * - * var object = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; * var getter = _.constant(object); * getter() === object; * // => true @@ -8797,7 +8878,7 @@ * @returns {*} Returns `value`. * @example * - * var object = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; * _.identity(object) === object; * // => true */ @@ -8817,18 +8898,18 @@ * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } + * var users = [ + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } * ]; * * var matchesAge = _.matches({ 'age': 36 }); * - * _.filter(characters, matchesAge); - * // => [{ 'name': 'barney', 'age': 36 }] + * _.filter(users, matchesAge); + * // => [{ 'user': 'barney', 'age': 36 }] * - * _.find(characters, matchesAge); - * // => { 'name': 'barney', 'age': 36 } + * _.find(users, matchesAge); + * // => { 'user': 'barney', 'age': 36 } */ function matches(source) { var props = keys(source), @@ -8934,28 +9015,22 @@ length = methodNames.length; while (++index < length) { - var methodName = methodNames[index], - func = object[methodName] = source[methodName]; - + var methodName = methodNames[index]; + object[methodName] = source[methodName]; if (isFunc) { - object.prototype[methodName] = (function(func) { + object.prototype[methodName] = (function(methodName) { return function() { - var chainAll = this.__chain__, - value = this.__wrapped__, - args = [value]; - - push.apply(args, arguments); - var result = func.apply(object, args); - if (chain || chainAll) { - if (value === result && isObject(result)) { - return this; - } - result = new object(result); - result.__chain__ = chainAll; + if (chain || this.__chain__) { + var result = object(this.__wrapped__); + result.__chain__ = this.__chain__; + (result.__queue__ = baseSlice(this.__queue__)).push([methodName, object, arguments]); + return result; } - return result; + var args = [this.value()]; + push.apply(args, arguments); + return object[methodName].apply(object, args); }; - }(func)); + }(methodName)); } } return object; @@ -8986,7 +9061,7 @@ * @category Utility * @example * - * var object = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; * _.noop(object) === undefined; * // => true */ @@ -9016,8 +9091,7 @@ * in which case a `radix` of `16` is used. * * **Note:** This method avoids differences in native ES3 and ES5 `parseInt` - * implementations. See the [ES5 spec](http://es5.github.io/#E) - * for more details. + * implementations. See the [ES5 spec](http://es5.github.io/#E) for more details. * * @static * @memberOf _ @@ -9057,18 +9131,18 @@ * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } + * var users = [ + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } * ]; * - * var getName = _.property('name'); + * var getName = _.property('user'); * - * _.map(characters, getName); + * _.map(users, getName); * // => ['barney', 'fred'] * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + * _.sortBy(users, getName); + * // => [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] */ function property(key) { return function(object) { @@ -9219,13 +9293,13 @@ * @example * * var object = { - * 'name': 'fred', + * 'user': 'fred', * 'age': function() { * return 40; * } * }; * - * _.result(object, 'name'); + * _.result(object, 'user'); * // => 'fred' * * _.result(object, 'age'); @@ -9382,6 +9456,7 @@ lodash.takeWhile = takeWhile; lodash.tap = tap; lodash.throttle = throttle; + lodash.thru = thru; lodash.times = times; lodash.toArray = toArray; lodash.transform = transform; @@ -9412,7 +9487,7 @@ lodash.unique = uniq; // add functions to `lodash.prototype` - mixin(lodash, baseAssign({}, lodash)); + mixin(lodash, lodash); /*------------------------------------------------------------------------*/ @@ -9423,6 +9498,7 @@ lodash.clone = clone; lodash.cloneDeep = cloneDeep; lodash.contains = contains; + lodash.deburr = deburr; lodash.endsWith = endsWith; lodash.escape = escape; lodash.escapeRegExp = escapeRegExp; @@ -9488,6 +9564,7 @@ lodash.trunc = trunc; lodash.unescape = unescape; lodash.uniqueId = uniqueId; + lodash.words = words; // add aliases lodash.all = every; @@ -9514,19 +9591,15 @@ // add functions capable of returning wrapped and unwrapped values when chaining lodash.sample = sample; - baseForOwn(lodash, function(func, methodName) { - var callbackable = methodName != 'sample'; - if (!lodash.prototype[methodName]) { - lodash.prototype[methodName] = function(n, guard) { - var chainAll = this.__chain__, - result = func(this.__wrapped__, n, guard); - - return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function'))) - ? result - : new lodashWrapper(result, chainAll); - }; + lodash.prototype.sample = function(n, guard) { + n = guard ? null : n; + if (!this.__chain__ && n == null) { + return lodash.sample(this.value()); } - }); + return this.thru(function(value) { + return lodash.sample(value, n); + }); + }; /*------------------------------------------------------------------------*/ @@ -9552,57 +9625,34 @@ lodash[methodName].placeholder = lodash; }); - // add `Array` functions that return unwrapped values - arrayEach(['join', 'pop', 'shift'], function(methodName) { - var func = arrayProto[methodName]; - lodash.prototype[methodName] = function() { - var chainAll = this.__chain__, - result = func.apply(this.__wrapped__, arguments); + // add `Array.prototype` functions + arrayEach(['concat', 'join', 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { + var arrayFunc = arrayProto[methodName], + retUnwrapped = /^(?:join|pop|shift)$/.test(methodName), + chainName = /^(?:push|reverse|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', + fixObjects = !support.spliceObjects && /^(?:pop|shift|splice)$/.test(methodName); - return chainAll - ? new lodashWrapper(result, chainAll) - : result; + // avoid array-like object bugs with `Array#shift` and `Array#splice` in + // IE < 9, Firefox < 10, Narwhal, and RingoJS + var func = !fixObjects ? arrayFunc : function() { + var result = arrayFunc.apply(this, arguments); + if (this.length === 0) { + delete this[0]; + } + return result; + }; + + lodash.prototype[methodName] = function() { + var args = arguments; + if (retUnwrapped && !this.__chain__) { + return func.apply(this.value(), args); + } + return this[chainName](function(value) { + return func.apply(value, args); + }); }; }); - // add `Array` functions that return the existing wrapped value - arrayEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) { - var func = arrayProto[methodName]; - lodash.prototype[methodName] = function() { - func.apply(this.__wrapped__, arguments); - return this; - }; - }); - - // add `Array` functions that return new wrapped values - arrayEach(['concat', 'splice'], function(methodName) { - var func = arrayProto[methodName]; - lodash.prototype[methodName] = function() { - return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__); - }; - }); - - // avoid array-like object bugs with `Array#shift` and `Array#splice` - // in IE < 9, Firefox < 10, Narwhal, and RingoJS - if (!support.spliceObjects) { - arrayEach(['pop', 'shift', 'splice'], function(methodName) { - var func = arrayProto[methodName], - isSplice = methodName == 'splice'; - - lodash.prototype[methodName] = function() { - var chainAll = this.__chain__, - value = this.__wrapped__, - result = func.apply(value, arguments); - - if (value.length === 0) { - delete value[0]; - } - return (chainAll || isSplice) - ? new lodashWrapper(result, chainAll) - : result; - }; - }); - } return lodash; } diff --git a/dist/lodash.compat.min.js b/dist/lodash.compat.min.js index f52700419..9b4ab3224 100644 --- a/dist/lodash.compat.min.js +++ b/dist/lodash.compat.min.js @@ -3,74 +3,75 @@ * Lo-Dash 3.0.0-pre (Custom Build) lodash.com/license | Underscore.js 1.7.0 underscorejs.org/LICENSE * Build: `lodash -o ./dist/lodash.compat.js` */ -;(function(){function n(n,t){for(var r=-1,e=t.length,u=Array(e);++rt||typeof n=="undefined")return 1;if(n=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n) -}function v(n){for(var t=-1,r=n.length;++ti(t,f)&&c.push(f);return c}function qt(n,t){var r=n?n.length:0;if(typeof r!="number"||-1>=r||r>F)return Qt(n,t); -for(var e=-1,u=Lr(n);++e=r||r>F)return nr(n,t);for(var e=Lr(n);r--&&false!==t(e[r],r,e););return n}function Kt(n,t){var r=true;return qt(n,function(n,e,u){return r=!!t(n,e,u)}),r}function Vt(n,t){var r=[];return qt(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function Yt(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function Jt(n,t,r,e){e=(e||0)-1;for(var u=n.length,o=-1,i=[];++el))return false}else{var g=p&&nu.call(n,"__wrapped__"),h=h&&nu.call(t,"__wrapped__"); -if(g||h)return rr(g?n.__wrapped__:n,h?t.__wrapped__:t,r,e,u,o);if(!s)return false;if(!a&&!p){switch(c){case it:case at:return+n==+t;case lt:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case pt:case ht:return n==Ke(t)}return false}if(Fu.argsClass||(l=ve(n),i=ve(t)),g=l?qe:n.constructor,c=i?qe:t.constructor,a){if(g.prototype.name!=c.prototype.name)return false}else if(p=!l&&nu.call(n,"constructor"),h=!i&&nu.call(t,"constructor"),p!=h||!(p||g==c||de(g)&&g instanceof g&&de(c)&&c instanceof c)&&"constructor"in n&&"constructor"in t)return false; -if(g=a?["message","name"]:Ku(n),c=a?g:Ku(t),l&&g.push("length"),i&&c.push("length"),l=g.length,p=c.length,l!=p&&!e)return false}for(u||(u=[]),o||(o=[]),c=u.length;c--;)if(u[c]==n)return o[c]==t;if(u.push(n),o.push(t),i=true,f)for(;i&&++c>>1,f=r(n[a]),c=e?f<=t:fo(l,p)&&((t||f)&&l.push(p),c.push(s))}return c}function pr(n,t){for(var r=-1,e=t(n),u=e.length,o=$e(u);++rt)return r; -var e=typeof arguments[2];if("number"!=e&&"string"!=e||!arguments[3]||arguments[3][arguments[2]]!==arguments[1]||(t=2),3=t||t>F)return Ee(n);if(n=Wr(n),Fu.unindexedChars&&Ae(n))for(var r=-1;++re?ju(u+e,0):e||0;else if(e)return e=Mr(n,t),u&&n[e]===t?e:-1;return r(n,t,e)}function Br(n){return Dr(n,1)}function Dr(n,t,r){var u=-1,o=n?n.length:0;if(t=null==t?0:+t||0,0>t&&(t=-t>o?0:o+t),r=typeof r=="undefined"||r>o?o:+r||0,0>r&&(r+=o),r&&r==o&&!t)return e(n);for(o=t>r?0:r-t,r=$e(o);++ur?ju(e+r,0):r||0:0,typeof n=="string"||!Mu(n)&&Ae(n)?ru&&(u=a);else t=i&&a?o:xr(t,r,3),qt(n,function(n,r,o){r=t(n,r,o),(r>e||-1/0===r&&r===u)&&(e=r,u=n)});return u}function te(n,t){return Qr(n,Ne(t))}function re(n,t,r,e){return(Mu(n)?Rt:fr)(n,xr(t,e,4),r,3>arguments.length,qt)}function ee(n,t,r,e){return(Mu(n)?kt:fr)(n,xr(t,e,4),r,3>arguments.length,Zt)}function ue(n){n=Lr(n);for(var t=-1,r=n.length,e=$e(r);++targuments.length)return Ar(n,w,null,t);var r=Dr(arguments,2),e=Fr(r,ae.placeholder);return ir(n,w|E,r,e,t)}function fe(n,t){var r=w|j;if(2=r||r>t?(a&&au(a),r=p,a=s=p=_,r&&(h=Gu(),f=n.apply(l,i),s||a||(i=l=null))):s=hu(e,r)}function u(){s&&au(s),a=s=p=_,(v||g!==t)&&(h=Gu(),f=n.apply(l,i),s||a||(i=l=null))}function o(){if(i=arguments,c=Gu(),l=this,p=v&&(s||!y),false===g)var r=y&&!s;else{a||y||(h=c);var o=g-(c-h),m=0>=o||o>g;m?(a&&(a=au(a)),h=c,f=n.apply(l,i)):a||(a=hu(u,o))}return m&&s?s=au(s):s||t===g||(s=hu(e,t)),r&&(m=true,f=n.apply(l,i)),!m||s||a||(i=l=null),f -}var i,a,f,c,l,s,p,h=0,g=false,v=true;if(!de(n))throw new Ve(R);if(t=0>t?0:t,true===r)var y=true,v=false;else _e(r)&&(y=r.leading,g="maxWait"in r&&ju(+r.maxWait||0,t),v="trailing"in r?r.trailing:v);return o.cancel=function(){s&&au(s),a&&au(a),a=s=p=_},o}function pe(){var n=arguments,t=n.length-1;if(0>t)return function(){};if(!It(n,de))throw new Ve(R);return function(){for(var r=t,e=n[r].apply(this,arguments);r--;)e=n[r].call(this,e);return e}}function he(n){var t=Dr(arguments,1),r=Fr(t,he.placeholder);return ir(n,E,t,r) -}function ge(n){var t=Dr(arguments,1),r=Fr(t,ge.placeholder);return ir(n,I,t,r)}function ve(n){var t=n&&typeof n=="object"?n.length:_;return typeof t=="number"&&-1t||null==n||!bu(t))return r;n=Ke(n);do t%2&&(r+=n),t=fu(t/2),n+=n; -while(t);return r}function Ce(n,t){return(n=null==n?"":Ke(n))?null==t?n.slice(v(n),y(n)+1):(t=Ke(t),n.slice(i(n,t),a(n,t)+1)):n}function Re(n){try{return n()}catch(t){return me(t)?t:Be(t)}}function ke(n,t){return Pt(n,t)}function Fe(n){return n}function Ue(n){var t=Ku(n),r=t.length;if(1==r){var e=t[0],u=n[e];if(Cr(u))return function(n){return null!=n&&u===n[e]&&nu.call(n,e)}}for(var o=r,i=$e(r),a=$e(r);o--;){var u=n[t[o]],f=Cr(u);i[o]=f,a[o]=f?u:Bt(u)}return function(n){if(o=r,null==n)return!o;for(;o--;)if(i[o]?a[o]!==n[t[o]]:!nu.call(n,t[o]))return false; -for(o=r;o--;)if(i[o]?!nu.call(n,t[o]):!rr(a[o],n[t[o]],null,true))return false;return true}}function Te(n,t,r){var e=true,u=_e(t),o=null==r,i=o&&u&&Ku(t),a=i&&tr(t,i);(i&&i.length&&!a.length||o&&!u)&&(o&&(r=t),a=false,t=n,n=this),a||(a=tr(t,Ku(t))),false===r?e=false:_e(r)&&"chain"in r&&(e=r.chain),r=-1,u=de(n);for(o=a.length;++r=S)return r}else n=0;return Uu(r,e)}}(),Nu=yr(function(n,t,r){nu.call(n,r)?++n[r]:n[r]=1}),$u=yr(function(n,t,r){nu.call(n,r)?n[r].push(t):n[r]=[t]}),Pu=yr(function(n,t,r){n[r]=t}),Bu=yr(function(n,t,r){n[r?0:1].push(t) -},function(){return[[],[]]}),Du=he(ie,2);Fu.argsClass||(ve=function(n){var t=n&&typeof n=="object"?n.length:_;return typeof t=="number"&&-1--n?t.apply(this,arguments):void 0}},g.assign=Zu,g.at=function(t){var r=t?t.length:0;return typeof r=="number"&&-1t?0:t)},g.dropRight=function(n,t,r){var e=n?n.length:0; -return t=e-((null==t||r?1:t)||0),Dr(n,0,0>t?0:t)},g.dropRightWhile=function(n,t,r){var e=n?n.length:0;for(t=xr(t,r,3);e--&&t(n[e],e,n););return Dr(n,0,e+1)},g.dropWhile=function(n,t,r){var e=-1,u=n?n.length:0;for(t=xr(t,r,3);++e(p?u(p,f):i(s,f))){for(t=e;--t;){var h=o[t];if(0>(h?u(h,f):i(n[t],f)))continue n}p&&p.push(f),s.push(f)}return s},g.invert=function(n,t){for(var r=-1,e=Ku(n),u=e.length,o={};++rt?0:t)},g.takeRight=function(n,t,r){var e=n?n.length:0;return t=e-((null==t||r?1:t)||0),Dr(n,0>t?0:t)},g.takeRightWhile=function(n,t,r){var e=n?n.length:0;for(t=xr(t,r,3);e--&&t(n[e],e,n););return Dr(n,e+1)},g.takeWhile=function(n,t,r){var e=-1,u=n?n.length:0;for(t=xr(t,r,3);++er?0:+r||0,e))-t.length,0<=r&&n.indexOf(t,r)==r},g.escape=function(n){return n=null==n?"":Ke(n),B.lastIndex=0,B.test(n)?n.replace(B,p):n},g.escapeRegExp=Ie,g.every=Yr,g.find=Xr,g.findIndex=Nr,g.findKey=function(n,t,r){return t=xr(t,r,3),Yt(n,t,Qt,true)},g.findLast=function(n,t,r){return t=xr(t,r,3),Yt(n,t,Zt) -},g.findLastIndex=function(n,t,r){var e=n?n.length:0;for(t=xr(t,r,3);e--;)if(t(n[e],e,n))return e;return-1},g.findLastKey=function(n,t,r){return t=xr(t,r,3),Yt(n,t,nr,true)},g.findWhere=function(n,t){return Xr(n,Ue(t))},g.first=$r,g.has=function(n,t){return n?nu.call(n,t):false},g.identity=Fe,g.indexOf=Pr,g.isArguments=ve,g.isArray=Mu,g.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&ru.call(n)==it||false},g.isDate=function(n){return n&&typeof n=="object"&&ru.call(n)==at||false},g.isElement=ye,g.isEmpty=function(n){if(null==n)return true; -var t=n.length;return typeof t=="number"&&-1r?ju(u+r,0):Au(r||0,u-1))+1;else if(r)return u=zr(n,t)-1,e&&n[u]===t?u:-1;for(r=t===t;u--;)if(e=n[u],r?e===t:e!==e)return u;return-1},g.max=ne,g.min=function(n,t,r){var e=1/0,u=e,i=typeof t;"number"!=i&&"string"!=i||!r||r[t]!==n||(t=null);var i=null==t,a=!(i&&Mu(n))&&Ae(n);if(i&&!a)for(r=-1,n=Lr(n),i=n.length;++rr?0:+r||0,n.length),n.lastIndexOf(t,r)==r},g.template=function(n,t,r){var e=g.templateSettings;t=Zu({},r||t,e,Nt),n=Ke(null==n?"":n),r=Zu({},t.imports,e.imports,Nt); -var u,o,i=Ku(r),a=Ee(r),f=0;r=t.interpolate||X;var c="__p+='";if(r=Ze((t.escape||X).source+"|"+r.source+"|"+(r===z?q:X).source+"|"+(t.evaluate||X).source+"|$","g"),n.replace(r,function(t,r,e,i,a,l){return e||(e=i),c+=n.slice(f,l).replace(Q,h),r&&(u=true,c+="'+__e("+r+")+'"),a&&(o=true,c+="';"+a+";\n__p+='"),e&&(c+="'+((__t=("+e+"))==null?'':__t)+'"),f=l+t.length,t}),c+="';",(t=t.variable)||(c="with(obj){"+c+"}"),c=(o?c.replace(W,""):c).replace(N,"$1").replace($,"$1;"),c="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+c+"return __p}",t=Re(function(){return De(i,"return "+c).apply(_,a) -}),t.source=c,me(t))throw t;return t},g.trim=Ce,g.trimLeft=function(n,t){return(n=null==n?"":Ke(n))?null==t?n.slice(v(n)):(t=Ke(t),n.slice(i(n,t))):n},g.trimRight=function(n,t){return(n=null==n?"":Ke(n))?null==t?n.slice(0,y(n)+1):(t=Ke(t),n.slice(0,a(n,t)+1)):n},g.trunc=function(n,t){var r=30,e="...";if(_e(t))var u="separator"in t?t.separator:u,r="length"in t?+t.length||0:r,e="omission"in t?Ke(t.omission):e;else null!=t&&(r=+t||0);if(n=null==n?"":Ke(n),r>=n.length)return n;var o=r-e.length;if(1>o)return e; -if(r=n.slice(0,o),null==u)return r+e;if(je(u)){if(n.slice(o).search(u)){var i,a,f=n.slice(0,o);for(u.global||(u=Ze(u.source,(Z.exec(u)||"")+"g")),u.lastIndex=0;i=u.exec(f);)a=i.index;r=r.slice(0,null==a?o:a)}}else n.indexOf(u,o)!=o&&(u=r.lastIndexOf(u),-1t?0:+t||0,n.length),n)},Qt(g,function(n,t){var r="sample"!=t;g.prototype[t]||(g.prototype[t]=function(t,e){var u=this.__chain__,o=n(this.__wrapped__,t,e);return u||null!=t&&(!e||r&&typeof t=="function")?new J(o,u):o})}),g.VERSION=b,J.prototype=g.prototype,g.prototype.chain=function(){return this.__chain__=true,this},g.prototype.toString=function(){return Ke(this.__wrapped__) -},g.prototype.toJSON=g.prototype.value=g.prototype.valueOf=function(){return this.__wrapped__},nt("bind bindKey curry curryRight partial partialRight".split(" "),function(n){g[n].placeholder=g}),nt(["join","pop","shift"],function(n){var t=Ye[n];g.prototype[n]=function(){var n=this.__chain__,r=t.apply(this.__wrapped__,arguments);return n?new J(r,n):r}}),nt(["push","reverse","sort","unshift"],function(n){var t=Ye[n];g.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),nt(["concat","splice"],function(n){var t=Ye[n]; -g.prototype[n]=function(){return new J(t.apply(this.__wrapped__,arguments),this.__chain__)}}),Fu.spliceObjects||nt(["pop","shift","splice"],function(n){var t=Ye[n],r="splice"==n;g.prototype[n]=function(){var n=this.__chain__,e=this.__wrapped__,u=t.apply(e,arguments);return 0===e.length&&delete e[0],n||r?new J(u,n):u}}),g}var _,b="3.0.0-pre",w=1,j=2,A=4,x=8,O=16,E=32,I=64,S=150,C=16,R="Expected a function",k=Math.pow(2,32)-1,F=Math.pow(2,53)-1,U="__lodash_placeholder__",T=0,L=/^[A-Z]+$/,W=/\b__p\+='';/g,N=/\b(__p\+=)''\+/g,$=/(__e\(.*?\)|\b__t\))\+'';/g,P=/&(?:amp|lt|gt|quot|#39|#96);/g,B=/[&<>"'`]/g,D=/<%-([\s\S]+?)%>/g,M=/<%([\s\S]+?)%>/g,z=/<%=([\s\S]+?)%>/g,q=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,Z=/\w*$/,K=/^\s*function[ \n\r\t]+\w/,V=/^0[xX]/,Y=/^\[object .+?Constructor\]$/,J=/[\xC0-\xFF]/g,X=/($^)/,G=/[.*+?^${}()|[\]\/\\]/g,H=/\bthis\b/,Q=/['\n\r\u2028\u2029\\]/g,nt=/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g,tt=" \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",rt="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window WinRTError".split(" "),et="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),ut="[object Arguments]",ot="[object Array]",it="[object Boolean]",at="[object Date]",ft="[object Error]",ct="[object Function]",lt="[object Number]",st="[object Object]",pt="[object RegExp]",ht="[object String]",gt="[object ArrayBuffer]",vt="[object Float32Array]",yt="[object Float64Array]",mt="[object Int8Array]",dt="[object Int16Array]",_t="[object Int32Array]",bt="[object Uint8Array]",wt="[object Uint8ClampedArray]",jt="[object Uint16Array]",At="[object Uint32Array]",xt={}; -xt[ut]=xt[ot]=xt[vt]=xt[yt]=xt[mt]=xt[dt]=xt[_t]=xt[bt]=xt[wt]=xt[jt]=xt[At]=true,xt[gt]=xt[it]=xt[at]=xt[ft]=xt[ct]=xt["[object Map]"]=xt[lt]=xt[st]=xt[pt]=xt["[object Set]"]=xt[ht]=xt["[object WeakMap]"]=false;var Ot={};Ot[ut]=Ot[ot]=Ot[gt]=Ot[it]=Ot[at]=Ot[vt]=Ot[yt]=Ot[mt]=Ot[dt]=Ot[_t]=Ot[lt]=Ot[st]=Ot[pt]=Ot[ht]=Ot[bt]=Ot[wt]=Ot[jt]=Ot[At]=true,Ot[ft]=Ot[ct]=Ot["[object Map]"]=Ot["[object Set]"]=Ot["[object WeakMap]"]=false;var Et={leading:false,maxWait:0,trailing:false},It={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},St={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Ct={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"AE","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\xd7":" ","\xf7":" "},Rt={"function":true,object:true},kt={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Ft=Rt[typeof window]&&window||this,Ut=Rt[typeof exports]&&exports&&!exports.nodeType&&exports,Rt=Rt[typeof module]&&module&&!module.nodeType&&module,Tt=Ut&&Rt&&typeof global=="object"&&global; -!Tt||Tt.global!==Tt&&Tt.window!==Tt&&Tt.self!==Tt||(Ft=Tt);var Tt=Rt&&Rt.exports===Ut&&Ut,Lt=function(){try{({toString:0}+"")}catch(n){return function(){return false}}return function(n){return typeof n.toString!="function"&&typeof(n+"")=="string"}}(),Wt=d();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Ft._=Wt, define(function(){return Wt})):Ut&&Rt?Tt?(Rt.exports=Wt)._=Wt:Ut._=Wt:Ft._=Wt}).call(this); \ No newline at end of file +;(function(){function n(n,t){for(var r=-1,e=n.length;++rt||!r||typeof n=="undefined"&&e)return 1;if(n=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n) +}function x(n,t){for(var r=-1,e=n.length,u=-1,o=[];++ru(t,i)&&f.push(i);return f}function Vt(n,t){var r=n?n.length:0;if(typeof r!="number"||-1>=r||r>q)return rr(n,t);for(var e=-1,u=$r(n);++e=r||r>q)return er(n,t);for(var e=$r(n);r--&&false!==t(e[r],r,e););return n}function Jt(n,t){var r=true;return Vt(n,function(n,e,u){return r=!!t(n,e,u)}),r}function Xt(n,t){var r=[];return Vt(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function Gt(n,t,r,e){var u; +return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function Ht(n,t,r,e){e=(e||0)-1;for(var u=n.length,o=-1,i=[];++ec))return false}else{var g=p&&iu.call(n,"__wrapped__"),h=h&&iu.call(t,"__wrapped__");if(g||h)return or(g?n.value():n,h?t.value():t,r,e,u,o);if(!s)return false;if(!f&&!p){switch(l){case ht:case gt:return+n==+t;case mt:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case bt:case _t:return n==He(t)}return false}if(Nu.argsClass||(c=be(n),i=be(t)),g=c?Xe:n.constructor,l=i?Xe:t.constructor,f){if(g.prototype.name!=l.prototype.name)return false +}else if(p=!c&&iu.call(n,"constructor"),h=!i&&iu.call(t,"constructor"),p!=h||!p&&g!=l&&"constructor"in n&&"constructor"in t&&!(typeof g=="function"&&g instanceof g&&typeof l=="function"&&l instanceof l))return false;if(g=f?["message","name"]:Hu(n),l=f?g:Hu(t),c&&g.push("length"),i&&l.push("length"),c=g.length,p=l.length,c!=p&&!e)return false}for(u||(u=[]),o||(o=[]),l=u.length;l--;)if(u[l]==n)return o[l]==t;if(u.push(n),o.push(t),i=true,a)for(;i&&++le(a,p)&&((t||i)&&a.push(p),f.push(c))}return f}function vr(n,t){for(var r=-1,e=t(n),u=e.length,o=ze(u);++rt)return r;var e=typeof arguments[2];if("number"!=e&&"string"!=e||!arguments[3]||arguments[3][arguments[2]]!==arguments[1]||(t=2),3r?Cu(e+r,0):r||0;else if(r)return r=Kr(n,t),e&&n[r]===t?r:-1;return l(n,t,r)}function Mr(n){return zr(n,1)}function zr(n,t,r){var e=-1,u=n?n.length:0;if(t=null==t?0:+t||0,0>t&&(t=-t>u?0:u+t),r=typeof r=="undefined"||r>u?u:+r||0,0>r&&(r+=u),r&&r==u&&!t)return c(n);for(u=t>r?0:r-t,r=ze(u);++er?Cu(e+r,0):r||0:0,typeof n=="string"||!Yu(n)&&Ie(n)?ru&&(u=i);else t=o&&i?p:Cr(t,r,3),Vt(n,function(n,r,o){r=t(n,r,o),(r>e||-1/0===r&&r===u)&&(e=r,u=n)});return u}function oe(n,t){return ee(n,Me(t))}function ie(n,t,r,e){return(Yu(n)?u:sr)(n,Cr(t,e,4),r,3>arguments.length,Vt)}function fe(n,t,r,e){return(Yu(n)?o:sr)(n,Cr(t,e,4),r,3>arguments.length,Yt)}function ae(n){n=Nr(n);for(var t=-1,r=n.length,e=ze(r);++targuments.length)return Ir(n,C,null,t);var r=zr(arguments,2),e=x(r,se.placeholder);return lr(n,C|k,r,e,t)}function pe(n,t){var r=C|S;if(2=r||r>t?(f&&hu(f),r=p,f=s=p=O,r&&(h=eo(),a=n.apply(c,i),s||f||(i=c=null))):s=bu(e,r)}function u(){s&&hu(s),f=s=p=O,(v||g!==t)&&(h=eo(),a=n.apply(c,i),s||f||(i=c=null))}function o(){if(i=arguments,l=eo(),c=this,p=v&&(s||!y),false===g)var r=y&&!s;else{f||y||(h=l);var o=g-(l-h),m=0>=o||o>g;m?(f&&(f=hu(f)),h=l,a=n.apply(c,i)):f||(f=bu(u,o)) +}return m&&s?s=hu(s):s||t===g||(s=bu(e,t)),r&&(m=true,a=n.apply(c,i)),!m||s||f||(i=c=null),a}var i,f,a,l,c,s,p,h=0,g=false,v=true;if(!we(n))throw new Qe(L);if(t=0>t?0:t,true===r)var y=true,v=false;else je(r)&&(y=r.leading,g="maxWait"in r&&Cu(+r.maxWait||0,t),v="trailing"in r?r.trailing:v);return o.cancel=function(){s&&hu(s),f&&hu(f),f=s=p=O},o}function ye(){var n=arguments,r=n.length-1;if(0>r)return function(){};if(!t(n,we))throw new Qe(L);return function(){for(var t=r,e=n[t].apply(this,arguments);t--;)e=n[t].call(this,e); +return e}}function me(n){var t=zr(arguments,1),r=x(t,me.placeholder);return lr(n,k,t,r)}function de(n){var t=zr(arguments,1),r=x(t,de.placeholder);return lr(n,U,t,r)}function be(n){var t=n&&typeof n=="object"?n.length:O;return typeof t=="number"&&-1t||null==n||!Ou(t))return r; +n=He(n);do t%2&&(r+=n),t=gu(t/2),n+=n;while(t);return r}function Ue(n,t){return(n=null==n?"":He(n))?null==t?n.slice(w(n),j(n)+1):(t=He(t),n.slice(h(n,t),g(n,t)+1)):n}function Te(n,t){return(n=null!=n&&He(n))&&n.match(t||ft)||[]}function We(n){try{return n()}catch(t){return xe(t)?t:Ze(t)}}function Le(n,t){return qt(n,t)}function Ne(n){return n}function $e(n){var t=Hu(n),r=t.length;if(1==r){var e=t[0],u=n[e];if(kr(u))return function(n){return null!=n&&u===n[e]&&iu.call(n,e)}}for(var o=r,i=ze(r),f=ze(r);o--;){var u=n[t[o]],a=kr(u); +i[o]=a,f[o]=a?u:Pt(u)}return function(n){if(o=r,null==n)return!o;for(;o--;)if(i[o]?f[o]!==n[t[o]]:!iu.call(n,t[o]))return false;for(o=r;o--;)if(i[o]?!iu.call(n,t[o]):!or(f[o],n[t[o]],null,true))return false;return true}}function qe(n,t,r){var e=true,u=je(t),o=null==r,i=o&&u&&Hu(t),f=i&&ur(t,i);(i&&i.length&&!f.length||o&&!u)&&(o&&(r=t),f=false,t=n,n=this),f||(f=ur(t,Hu(t))),false===r?e=false:je(r)&&"chain"in r&&(e=r.chain),r=-1,u=we(n);for(o=f.length;++r=T)return r}else n=0;return $u(r,e)}}(),Mu=br(function(n,t,r){iu.call(n,r)?++n[r]:n[r]=1}),zu=br(function(n,t,r){iu.call(n,r)?n[r].push(t):n[r]=[t]}),Ku=br(function(n,t,r){n[r]=t}),Zu=br(function(n,t,r){n[r?0:1].push(t) +},function(){return[[],[]]}),Vu=me(ce,2);Nu.argsClass||(be=function(n){var t=n&&typeof n=="object"?n.length:O;return typeof t=="number"&&-1--n?t.apply(this,arguments):void 0}},Ut.assign=Gu,Ut.at=function(n){var t=n?n.length:0;return typeof t=="number"&&-1t?0:t)},Ut.dropRight=function(n,t,r){var e=n?n.length:0; +return t=e-((null==t||r?1:t)||0),zr(n,0,0>t?0:t)},Ut.dropRightWhile=function(n,t,r){var e=n?n.length:0;for(t=Cr(t,r,3);e--&&t(n[e],e,n););return zr(n,0,e+1)},Ut.dropWhile=function(n,t,r){var e=-1,u=n?n.length:0;for(t=Cr(t,r,3);++e(p?s(p,i):u(c,i))){for(t=r;--t;){var h=e[t];if(0>(h?s(h,i):u(n[t],i)))continue n}p&&p.push(i),c.push(i)}return c},Ut.invert=function(n,t){for(var r=-1,e=Hu(n),u=e.length,o={};++rt?0:t)},Ut.takeRight=function(n,t,r){var e=n?n.length:0;return t=e-((null==t||r?1:t)||0),zr(n,0>t?0:t)},Ut.takeRightWhile=function(n,t,r){var e=n?n.length:0;for(t=Cr(t,r,3);e--&&t(n[e],e,n););return zr(n,e+1)},Ut.takeWhile=function(n,t,r){var e=-1,u=n?n.length:0;for(t=Cr(t,r,3);++er?0:+r||0,e))-t.length,0<=r&&n.indexOf(t,r)==r},Ut.escape=function(n){return(n=null==n?"":He(n))&&(V.lastIndex=0,V.test(n))?n.replace(V,d):n},Ut.escapeRegExp=De,Ut.every=Hr,Ut.find=ne,Ut.findIndex=qr,Ut.findKey=function(n,t,r){return t=Cr(t,r,3),Gt(n,t,rr,true) +},Ut.findLast=function(n,t,r){return t=Cr(t,r,3),Gt(n,t,Yt)},Ut.findLastIndex=function(n,t,r){var e=n?n.length:0;for(t=Cr(t,r,3);e--;)if(t(n[e],e,n))return e;return-1},Ut.findLastKey=function(n,t,r){return t=Cr(t,r,3),Gt(n,t,er,true)},Ut.findWhere=function(n,t){return ne(n,$e(t))},Ut.first=Pr,Ut.has=function(n,t){return n?iu.call(n,t):false},Ut.identity=Ne,Ut.indexOf=Br,Ut.isArguments=be,Ut.isArray=Yu,Ut.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&au.call(n)==ht||false},Ut.isDate=function(n){return n&&typeof n=="object"&&au.call(n)==gt||false +},Ut.isElement=_e,Ut.isEmpty=function(n){if(null==n)return true;var t=n.length;return typeof t=="number"&&-1r?Cu(u+r,0):Su(r||0,u-1))+1;else if(r)return u=Zr(n,t)-1,e&&n[u]===t?u:-1;for(r=t===t;u--;)if(e=n[u],r?e===t:e!==e)return u;return-1},Ut.max=ue,Ut.min=function(n,t,r){var e=1/0,u=e,o=typeof t;"number"!=o&&"string"!=o||!r||r[t]!==n||(t=null);var o=null==t,i=!(o&&Yu(n))&&Ie(n);if(o&&!i)for(r=-1,n=Nr(n),o=n.length;++rr?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Ut.template=function(n,t,r){var e=Ut.templateSettings;t=Gu({},r||t,e,Lt),n=He(null==n?"":n),r=Gu({},t.imports,e.imports,Lt); +var u,o,i=Hu(r),f=Fe(r),a=0;r=t.interpolate||et;var l="__p+='";if(r=Ge((t.escape||et).source+"|"+r.source+"|"+(r===X?G:et).source+"|"+(t.evaluate||et).source+"|$","g"),n.replace(r,function(t,r,e,i,f,c){return e||(e=i),l+=n.slice(a,c).replace(it,b),r&&(u=true,l+="'+__e("+r+")+'"),f&&(o=true,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),a=c+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(o?l.replace(M,""):l).replace(z,"$1").replace(K,"$1;"),l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}",t=We(function(){return Ve(i,"return "+l).apply(O,f) +}),t.source=l,xe(t))throw t;return t},Ut.trim=Ue,Ut.trimLeft=function(n,t){return(n=null==n?"":He(n))?null==t?n.slice(w(n)):(t=He(t),n.slice(h(n,t))):n},Ut.trimRight=function(n,t){return(n=null==n?"":He(n))?null==t?n.slice(0,j(n)+1):(t=He(t),n.slice(0,g(n,t)+1)):n},Ut.trunc=function(n,t){var r=30,e="...";if(je(t))var u="separator"in t?t.separator:u,r="length"in t?+t.length||0:r,e="omission"in t?He(t.omission):e;else null!=t&&(r=+t||0);if(n=null==n?"":He(n),r>=n.length)return n;var o=r-e.length;if(1>o)return e; +if(r=n.slice(0,o),null==u)return r+e;if(Oe(u)){if(n.slice(o).search(u)){var i,f,a=n.slice(0,o);for(u.global||(u=Ge(u.source,(H.exec(u)||"")+"g")),u.lastIndex=0;i=u.exec(a);)f=i.index;r=r.slice(0,null==f?o:f)}}else n.indexOf(u,o)!=o&&(u=r.lastIndexOf(u),-1t?0:+t||0,n.length),n)},Ut.prototype.sample=function(n,t){return n=t?null:n,this.__chain__||null!=n?this.thru(function(t){return Ut.sample(t,n)}):Ut.sample(this.value())},Ut.VERSION=I,Tt.prototype=Ut.prototype,Ut.prototype.chain=function(){return Xr(this)},Ut.prototype.toString=function(){return He(this.value())},Ut.prototype.toJSON=Ut.prototype.value=Ut.prototype.valueOf=function(){for(var n=-1,t=this.__queue__,r=t.length,e=this.__wrapped__;++n"'`]/g,Y=/<%-([\s\S]+?)%>/g,J=/<%([\s\S]+?)%>/g,X=/<%=([\s\S]+?)%>/g,G=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,H=/\w*$/,Q=/^\s*function[ \n\r\t]+\w/,nt=/^0[xX]/,tt=/^\[object .+?Constructor\]$/,rt=/[\xC0-\xFF]/g,et=/($^)/,ut=/[.*+?^${}()|[\]\/\\]/g,ot=/\bthis\b/,it=/['\n\r\u2028\u2029\\]/g,ft=RegExp("[A-Z\\xC0-\\xD6\\xD8-\\xDE]{2,}(?=[A-Z\\xC0-\\xD6\\xD8-\\xDE][a-z\\xDF-\\xF6\\xF8-\\xFF]+[0-9]*)|[A-Z\\xC0-\\xD6\\xD8-\\xDE]?[a-z\\xDF-\\xF6\\xF8-\\xFF]+[0-9]*|[A-Z\\xC0-\\xD6\\xD8-\\xDE]+|[0-9]+","g"),at=" \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",lt="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window WinRTError".split(" "),ct="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),st="[object Arguments]",pt="[object Array]",ht="[object Boolean]",gt="[object Date]",vt="[object Error]",yt="[object Function]",mt="[object Number]",dt="[object Object]",bt="[object RegExp]",_t="[object String]",xt="[object ArrayBuffer]",wt="[object Float32Array]",jt="[object Float64Array]",At="[object Int8Array]",Et="[object Int16Array]",Ot="[object Int32Array]",It="[object Uint8Array]",Ct="[object Uint8ClampedArray]",St="[object Uint16Array]",Ft="[object Uint32Array]",Rt={}; +Rt[st]=Rt[pt]=Rt[wt]=Rt[jt]=Rt[At]=Rt[Et]=Rt[Ot]=Rt[It]=Rt[Ct]=Rt[St]=Rt[Ft]=true,Rt[xt]=Rt[ht]=Rt[gt]=Rt[vt]=Rt[yt]=Rt["[object Map]"]=Rt[mt]=Rt[dt]=Rt[bt]=Rt["[object Set]"]=Rt[_t]=Rt["[object WeakMap]"]=false;var Dt={};Dt[st]=Dt[pt]=Dt[xt]=Dt[ht]=Dt[gt]=Dt[wt]=Dt[jt]=Dt[At]=Dt[Et]=Dt[Ot]=Dt[mt]=Dt[dt]=Dt[bt]=Dt[_t]=Dt[It]=Dt[Ct]=Dt[St]=Dt[Ft]=true,Dt[vt]=Dt[yt]=Dt["[object Map]"]=Dt["[object Set]"]=Dt["[object WeakMap]"]=false;var kt={leading:false,maxWait:0,trailing:false},Ut={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Tt={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Wt={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\xd7":" ","\xf7":" "},Lt={"function":true,object:true},Nt={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},$t=Lt[typeof window]&&window||this,qt=Lt[typeof exports]&&exports&&!exports.nodeType&&exports,Lt=Lt[typeof module]&&module&&!module.nodeType&&module,Pt=qt&&Lt&&typeof global=="object"&&global; +!Pt||Pt.global!==Pt&&Pt.window!==Pt&&Pt.self!==Pt||($t=Pt);var Pt=Lt&&Lt.exports===qt&&qt,Bt=function(){try{({toString:0}+"")}catch(n){return function(){return false}}return function(n){return typeof n.toString!="function"&&typeof(n+"")=="string"}}(),Mt=E();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($t._=Mt, define(function(){return Mt})):qt&&Lt?Pt?(Lt.exports=Mt)._=Mt:qt._=Mt:$t._=Mt}).call(this); \ No newline at end of file diff --git a/dist/lodash.js b/dist/lodash.js index 08af34a85..6bae84a0b 100644 --- a/dist/lodash.js +++ b/dist/lodash.js @@ -31,8 +31,9 @@ /** Used as the TypeError message for "Functions" methods */ var FUNC_ERROR_TEXT = 'Expected a function'; - /** Used as a reference for the max length of an array */ - var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1; + /** Used as references for the max length and index of an array */ + var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; /** * Used as the maximum length of an array-like value. @@ -47,9 +48,6 @@ /** Used to generate unique IDs */ var idCounter = 0; - /** Used to detect words composed of all capital letters */ - var reAllCaps = /^[A-Z]+$/; - /** Used to match empty string literals in compiled template source */ var reEmptyStringLeading = /\b__p \+= '';/g, reEmptyStringMiddle = /\b(__p \+=) '' \+/g, @@ -103,7 +101,13 @@ var reUnescapedString = /['\n\r\u2028\u2029\\]/g; /** Used to match words to create compound words */ - var reWords = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g; + var reWords = (function() { + var nums = '[0-9]', + upper = '[A-Z\\xC0-\\xD6\\xD8-\\xDE]', + lower = '[a-z\\xDF-\\xF6\\xF8-\\xFF]+' + nums + '*'; + + return RegExp(upper + '{2,}(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|' + nums + '+', 'g'); + }()); /** Used to detect and test whitespace */ var whitespace = ( @@ -194,7 +198,7 @@ }; /** - * Used to convert characters to HTML entities. + * Used to map characters to HTML entities. * * **Note:** Though the ">" character is escaped for symmetry, characters like * ">" and "/" don't require escaping in HTML and have no special meaning @@ -216,7 +220,7 @@ '`': '`' }; - /** Used to convert HTML entities to characters */ + /** Used to map HTML entities to characters */ var htmlUnescapes = { '&': '&', '<': '<', @@ -226,11 +230,7 @@ '`': '`' }; - /** - * Used to convert latin-1 supplement letters to basic latin (ASCII) letters. - * See [Wikipedia](http://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * for more details. - */ + /** Used to map latin-1 supplementary letters to basic latin letters */ var deburredLetters = { '\xC0': 'A', '\xC1': 'A', '\xC2': 'A', '\xC3': 'A', '\xC4': 'A', '\xC5': 'A', '\xE0': 'a', '\xE1': 'a', '\xE2': 'a', '\xE3': 'a', '\xE4': 'a', '\xE5': 'a', @@ -246,7 +246,7 @@ '\xD9': 'U', '\xDA': 'U', '\xDB': 'U', '\xDC': 'U', '\xF9': 'u', '\xFA': 'u', '\xFB': 'u', '\xFC': 'u', '\xDD': 'Y', '\xFD': 'y', '\xFF': 'y', - '\xC6': 'AE', '\xE6': 'ae', + '\xC6': 'Ae', '\xE6': 'ae', '\xDE': 'Th', '\xFE': 'th', '\xDF': 'ss', '\xD7': ' ', '\xF7': ' ' }; @@ -287,6 +287,184 @@ /*--------------------------------------------------------------------------*/ + /** + * A specialized version of `_.forEach` for arrays without support for + * callback shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns `true` if all elements passed the predicate check, + * else `false` + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray=false] Specify using the first element of + * `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; + + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray=false] Specify using the last element of + * `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passed the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + /** * The base implementation of `_.at` without support for strings and individual * key arguments. @@ -318,10 +496,13 @@ */ function baseCompareAscending(value, other) { if (value !== other) { - if (value > other || typeof value == 'undefined') { + var valIsReflexive = value === value, + othIsReflexive = other === other; + + if (value > other || !valIsReflexive || (typeof value == 'undefined' && othIsReflexive)) { return 1; } - if (value < other || typeof other == 'undefined') { + if (value < other || !othIsReflexive || (typeof other == 'undefined' && valIsReflexive)) { return -1; } } @@ -472,30 +653,7 @@ } /** - * Creates a function that produces compound words out of the words in a - * given string. - * - * @private - * @param {Function} callback The function invoked to combine each word. - * @returns {Function} Returns the new compounder function. - */ - function createCompounder(callback) { - return function(string) { - var index = -1, - words = string != null && String(string).replace(reLatin1, deburrLetter).match(reWords), - length = words ? words.length : 0, - result = ''; - - while (++index < length) { - result = callback(result, words[index], index, words); - } - return result; - }; - } - - /** - * Used by `createCompounder` to convert latin-1 supplement letters to basic - * latin (ASCII) letters. + * Used by `deburr` to convert latin-1 to basic latin letters. * * @private * @param {string} letter The matched letter to deburr. @@ -541,6 +699,58 @@ (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); } + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } + + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } + /** * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace * character of `string`. @@ -669,6 +879,7 @@ setTimeout = context.setTimeout, splice = arrayProto.splice, Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array, + unshift = arrayProto.unshift, WeakMap = isNative(WeakMap = context.WeakMap) && WeakMap; /** Used to clone array buffers */ @@ -726,15 +937,15 @@ * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `pluck`, `property`, * `pull`, `pullAt`, `push`, `range`, `reject`, `remove`, `rest`, `reverse`, * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `take`, `takeRight`, - * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `times`, `toArray`, - * `transform`, `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, - * `where`, `without`, `wrap`, `xor`, `zip`, and `zipObject` + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `times`, + * `toArray`, `transform`, `union`, `uniq`, `unshift`, `unzip`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, and `zipObject` * * The non-chainable wrapper functions are: * `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `contains`, - * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, - * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, - * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, isDate`, + * `deburr`, endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `has`, `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, isDate`, * `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`, `isFunction`, * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, * `isRegExp`, `isString`, `isUndefined`, `join`, `kebabCase`, `last`, @@ -742,7 +953,7 @@ * `padRight`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, * `result`, `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, * `sortedLastIndex`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, - * `trunc`, `unescape`, `uniqueId`, and `value` + * `trunc`, `unescape`, `uniqueId`, `value`, and `words` * * The wrapper function `sample` will return a wrapped value when `n` is * provided, otherwise it will return an unwrapped value. @@ -777,7 +988,7 @@ return value; } if (!isArray(value) && hasOwnProperty.call(value, '__wrapped__')) { - value = value.__wrapped__; + return new lodashWrapper(value.__wrapped__, value.__chain__, baseSlice(value.__queue__)); } } return new lodashWrapper(value); @@ -789,10 +1000,12 @@ * @private * @param {*} value The value to wrap in a `lodash` instance. * @param {boolean} [chainAll=false] Enable chaining for all methods. + * @param {Array} [queue=[]] Actions to peform to resolve the unwrapped value. * @returns {Object} Returns a `lodash` instance. */ - function lodashWrapper(value, chainAll) { + function lodashWrapper(value, chainAll, queue) { this.__chain__ = !!chainAll; + this.__queue__ = queue || []; this.__wrapped__ = value; } @@ -919,184 +1132,6 @@ /*------------------------------------------------------------------------*/ - /** - * A specialized version of `_.forEach` for arrays without support for - * callback shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array.length; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.forEachRight` for arrays without support for - * callback shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEachRight(array, iteratee) { - var length = array.length; - - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.every` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns `true` if all elements passed the predicate check, - * else `false` - */ - function arrayEvery(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; - } - - /** - * A specialized version of `_.map` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * A specialized version of `_.filter` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[++resIndex] = value; - } - } - return result; - } - - /** - * A specialized version of `_.reduce` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray=false] Specify using the first element of - * `array` as the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduce(array, iteratee, accumulator, initFromArray) { - var index = -1, - length = array.length; - - if (initFromArray && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; - } - - /** - * A specialized version of `_.reduceRight` for arrays without support for - * callback shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray=false] Specify using the last element of - * `array` as the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduceRight(array, iteratee, accumulator, initFromArray) { - var length = array.length; - - if (initFromArray && length) { - accumulator = array[--length]; - } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); - } - return accumulator; - } - - /** - * A specialized version of `_.some` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passed the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - /** * Used by `_.defaults` to customize its `_.assign` use. * @@ -1288,7 +1323,6 @@ ? baseClone(valValue, isDeep, null, stackA, stackB) : valClone; }); - return result; } @@ -1341,7 +1375,7 @@ * * @private * @param {Array} array The array to inspect. - * @param {Array} [values] The array of values to exclude. + * @param {Array} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. */ function baseDifference(array, values) { @@ -1396,7 +1430,7 @@ return baseForOwn(collection, iteratee); } var index = -1, - iterable = toIterable(collection); + iterable = toObject(collection); while (++index < length) { if (iteratee(iterable[index], index, iterable) === false) { @@ -1420,7 +1454,7 @@ if (!(typeof length == 'number' && length > -1 && length <= MAX_SAFE_INTEGER)) { return baseForOwnRight(collection, iteratee); } - var iterable = toIterable(collection); + var iterable = toObject(collection); while (length--) { if (iteratee(iterable[length], length, iterable) === false) { break; @@ -1548,12 +1582,13 @@ */ function baseFor(object, iteratee, keysFunc) { var index = -1, + iterable = toObject(object), props = keysFunc(object), length = props.length; while (++index < length) { var key = props[index]; - if (iteratee(object[key], key, object) === false) { + if (iteratee(iterable[key], key, iterable) === false) { break; } } @@ -1571,12 +1606,13 @@ * @returns {Object} Returns `object`. */ function baseForRight(object, iteratee, keysFunc) { - var props = keysFunc(object), + var iterable = toObject(object), + props = keysFunc(object), length = props.length; while (length--) { var key = props[length]; - if (iteratee(object[key], key, object) === false) { + if (iteratee(iterable[key], key, iterable) === false) { break; } } @@ -1708,7 +1744,7 @@ othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); if (valWrapped || othWrapped) { - return baseIsEqual(valWrapped ? value.__wrapped__ : value, othWrapped ? other.__wrapped__ : other, customizer, isWhere, stackA, stackB); + return baseIsEqual(valWrapped ? value.value() : value, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB); } if (!isSameClass) { return false; @@ -1733,10 +1769,9 @@ } if (!valHasCtor) { // non `Object` object instances with different constructors are not equal - if (valCtor != othCtor && - !(isFunction(valCtor) && valCtor instanceof valCtor && isFunction(othCtor) && othCtor instanceof othCtor) && - ('constructor' in value && 'constructor' in other) - ) { + if (valCtor != othCtor && ('constructor' in value && 'constructor' in other) && + !(typeof valCtor == 'function' && valCtor instanceof valCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { return false; } } @@ -1945,7 +1980,6 @@ } object[key] = result; }); - return object; } @@ -1957,7 +1991,7 @@ * @private * @param {Function} func The function to partially apply arguments to. * @param {number} bitmask The bitmask of flags to compose. - * @param {Array} args The array of arguments to be partially applied. + * @param {Array} args The arguments to be partially applied. * @param {*} [thisArg] The `this` binding of `func`. * @returns {Function} Returns the new partially applied function. */ @@ -2084,17 +2118,21 @@ high = array ? array.length : low; value = iteratee(value); - var hintNum = typeof value == 'number' || - (value != null && isFunction(value.valueOf) && typeof value.valueOf() == 'number'); + + var valIsNaN = value !== value, + valIsUndef = typeof value == 'undefined'; while (low < high) { - var mid = (low + high) >>> 1, + var mid = floor((low + high) / 2), computed = iteratee(array[mid]), - setLow = retHighest ? (computed <= value) : (computed < value); + isReflexive = computed === computed; - if (hintNum && typeof computed != 'undefined') { - computed = +computed; - setLow = computed != computed || setLow; + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || typeof computed != 'undefined'); + } else { + setLow = retHighest ? (computed <= value) : (computed < value); } if (setLow) { low = mid + 1; @@ -2102,7 +2140,7 @@ high = mid; } } - return high; + return nativeMin(high, MAX_ARRAY_INDEX); } /** @@ -2213,8 +2251,8 @@ * placeholders, and provided arguments into a single array of arguments. * * @private - * @param {Array} partialArgs An array of arguments to prepend to those provided. - * @param {Array} partialHolders An array of `partialArgs` placeholder indexes. + * @param {Array} partialArgs The arguments to prepend to those provided. + * @param {Array} partialHolders The `partialArgs` placeholder indexes. * @param {Array|Object} args The provided arguments. * @returns {Array} Returns the new array of composed arguments. */ @@ -2243,8 +2281,8 @@ * is tailored for `_.partialRight`. * * @private - * @param {Array} partialRightArgs An array of arguments to append to those provided. - * @param {Array} partialHolders An array of `partialRightArgs` placeholder indexes. + * @param {Array} partialRightArgs The arguments to append to those provided. + * @param {Array} partialHolders The `partialRightArgs` placeholder indexes. * @param {Array|Object} args The provided arguments. * @returns {Array} Returns the new array of composed arguments. */ @@ -2284,9 +2322,9 @@ */ function createAggregator(setter, initializer) { return function(collection, iteratee, thisArg) { - var result = initializer ? initializer() : {}; iteratee = getCallback(iteratee, thisArg, 3); + var result = initializer ? initializer() : {}; if (isArray(collection)) { var index = -1, length = collection.length; @@ -2375,6 +2413,28 @@ return cache; }; + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function invoked to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; + + while (++index < length) { + result = callback(result, array[index], index, words); + } + return result; + }; + } + /** * Creates a function that produces an instance of `Ctor` regardless of * whether it was invoked as part of a `new` expression or by `call` or `apply`. @@ -2403,10 +2463,10 @@ * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. * @param {number} arity The arity of `func`. * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partialArgs] An array of arguments to prepend to those provided to the new function. - * @param {Array} [partialHolders] An array of `partialArgs` placeholder indexes. - * @param {Array} [partialRightArgs] An array of arguments to append to those provided to the new function. - * @param {Array} [partialRightHolders] An array of `partialRightArgs` placeholder indexes. + * @param {Array} [partialArgs] The arguments to prepend to those provided to the new function. + * @param {Array} [partialHolders] The `partialArgs` placeholder indexes. + * @param {Array} [partialRightArgs] The arguments to append to those provided to the new function. + * @param {Array} [partialRightHolders] The `partialRightArgs` placeholder indexes. * @returns {Function} Returns the new function. */ function createHybridWrapper(func, bitmask, arity, thisArg, partialArgs, partialHolders, partialRightArgs, partialRightHolders) { @@ -2496,7 +2556,7 @@ * @private * @param {Function} func The function to partially apply arguments to. * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. - * @param {Array} partialArgs An array of arguments to prepend to those provided to the new function. + * @param {Array} partialArgs The arguments to prepend to those provided to the new function. * @param {*} [thisArg] The `this` binding of `func`. * @returns {Function} Returns the new bound function. */ @@ -2541,10 +2601,10 @@ * 64 - `_.partialRight` * @param {number} arity The arity of `func`. * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partialArgs] An array of arguments to prepend to those provided to the new function. - * @param {Array} [partialHolders] An array of `partialArgs` placeholder indexes. - * @param {Array} [partialRightArgs] An array of arguments to append to those provided to the new function. - * @param {Array} [partialRightHolders] An array of `partialRightArgs` placeholder indexes. + * @param {Array} [partialArgs] The arguments to prepend to those provided to the new function. + * @param {Array} [partialHolders] The `partialArgs` placeholder indexes. + * @param {Array} [partialRightArgs] The arguments to append to those provided to the new function. + * @param {Array} [partialRightHolders] The `partialRightArgs` placeholder indexes. * @returns {Function} Returns the new function. */ function createWrapper(func, bitmask, arity, thisArg, partialArgs, partialHolders, partialRightArgs, partialRightHolders) { @@ -2699,7 +2759,7 @@ isArgs = className == argsClass, isObj = className == objectClass; - if (isObj && !(isFunction(Ctor) && (Ctor instanceof Ctor))) { + if (isObj && !(typeof Ctor == 'function' && Ctor instanceof Ctor)) { Ctor = Object; } if (isArgs || isObj) { @@ -2768,6 +2828,8 @@ * @returns {Object} Returns the new object. */ function pickByArray(object, props) { + object = toObject(object); + var index = -1, length = props.length, result = {}; @@ -2801,30 +2863,6 @@ return result; } - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - if (array[index] === placeholder) { - array[index] = PLACEHOLDER; - result[++resIndex] = index; - } - } - return result; - } - /** * Sets metadata for `func`. * @@ -2874,7 +2912,7 @@ if (!(value && typeof value == 'object' && toString.call(value) == objectClass) || (!hasOwnProperty.call(value, 'constructor') && - (Ctor = value.constructor, isFunction(Ctor) && !(Ctor instanceof Ctor)))) { + (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { return false; } // In most environments an object's own properties are iterated before @@ -2916,34 +2954,6 @@ return result; } - /** - * An implementation of `_.uniq` optimized for sorted arrays without support - * for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. - */ - function sortedUniq(array, iteratee) { - var seen, - index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; - - if (!index || seen !== computed) { - seen = computed; - result[++resIndex] = value; - } - } - return result; - } - /** * Converts `value` to an array-like object if it is not one. * @@ -2959,8 +2969,7 @@ if (!(typeof length == 'number' && length > -1 && length <= MAX_SAFE_INTEGER)) { return values(value); } - value = toObject(value); - return value; + return isObject(value) ? value : Object(value); } /** @@ -3157,18 +3166,18 @@ * _.dropRightWhile([1, 2, 3], function(n) { return n > 1; }); * // => [1] * - * var characters = [ - * { 'name': 'barney', 'employer': 'slate' }, - * { 'name': 'fred', 'employer': 'slate', 'blocked': true }, - * { 'name': 'pebbles', 'employer': 'na', 'blocked': true } + * var users = [ + * { 'user': 'barney', 'employer': 'slate' }, + * { 'user': 'fred', 'employer': 'slate', 'blocked': true }, + * { 'user': 'pebbles', 'employer': 'na', 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.pluck(_.dropRightWhile(characters, 'blocked'), 'name'); + * _.pluck(_.dropRightWhile(users, 'blocked'), 'user'); * // => ['barney'] * * // using "_.where" callback shorthand - * _.pluck(_.dropRightWhile(characters, { 'employer': 'na' }), 'name'); + * _.pluck(_.dropRightWhile(users, { 'employer': 'na' }), 'user'); * // => ['barney', 'fred'] */ function dropRightWhile(array, predicate, thisArg) { @@ -3206,18 +3215,18 @@ * _.dropWhile([1, 2, 3], function(n) { return n < 3; }); * // => [3] * - * var characters = [ - * { 'name': 'barney', 'employer': 'slate', 'blocked': true }, - * { 'name': 'fred', 'employer': 'slate' }, - * { 'name': 'pebbles', 'employer': 'na', 'blocked': true } + * var users = [ + * { 'user': 'barney', 'employer': 'slate', 'blocked': true }, + * { 'user': 'fred', 'employer': 'slate' }, + * { 'user': 'pebbles', 'employer': 'na', 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.pluck(_.dropWhile(characters, 'blocked'), 'name'); + * _.pluck(_.dropWhile(users, 'blocked'), 'user'); * // => ['fred', 'pebbles'] * * // using "_.where" callback shorthand - * _.pluck(_.dropWhile(characters, { 'employer': 'slate' }), 'name'); + * _.pluck(_.dropWhile(users, { 'employer': 'slate' }), 'user'); * // => ['pebbles'] */ function dropWhile(array, predicate, thisArg) { @@ -3251,23 +3260,23 @@ * @returns {number} Returns the index of the found element, else `-1`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true }, + * { 'user': 'pebbles', 'age': 1 } * ]; * - * _.findIndex(characters, function(chr) { + * _.findIndex(users, function(chr) { * return chr.age < 20; * }); * // => 2 * * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); + * _.findIndex(users, { 'age': 36 }); * // => 0 * * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); + * _.findIndex(users, 'blocked'); * // => 1 */ function findIndex(array, predicate, thisArg) { @@ -3305,23 +3314,23 @@ * @returns {number} Returns the index of the found element, else `-1`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': true }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36, 'blocked': true }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1, 'blocked': true } * ]; * - * _.findLastIndex(characters, function(chr) { + * _.findLastIndex(users, function(chr) { * return chr.age > 30; * }); * // => 1 * * // using "_.where" callback shorthand - * _.findLastIndex(characters, { 'age': 36 }); + * _.findLastIndex(users, { 'age': 36 }); * // => 0 * * // using "_.pluck" callback shorthand - * _.findLastIndex(characters, 'blocked'); + * _.findLastIndex(users, 'blocked'); * // => 2 */ function findLastIndex(array, predicate, thisArg) { @@ -3933,18 +3942,18 @@ * _.takeRightWhile([1, 2, 3], function(n) { return n > 1; }); * // => [2, 3] * - * var characters = [ - * { 'name': 'barney', 'employer': 'slate' }, - * { 'name': 'fred', 'employer': 'slate', 'blocked': true }, - * { 'name': 'pebbles', 'employer': 'na', 'blocked': true } + * var users = [ + * { 'user': 'barney', 'employer': 'slate' }, + * { 'user': 'fred', 'employer': 'slate', 'blocked': true }, + * { 'user': 'pebbles', 'employer': 'na', 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.pluck(_.takeRightWhile(characters, 'blocked'), 'name'); + * _.pluck(_.takeRightWhile(users, 'blocked'), 'user'); * // => ['fred', 'pebbles'] * * // using "_.where" callback shorthand - * _.pluck(_.takeRightWhile(characters, { 'employer': 'na' }), 'name'); + * _.pluck(_.takeRightWhile(users, { 'employer': 'na' }), 'user'); * // => ['pebbles'] */ function takeRightWhile(array, predicate, thisArg) { @@ -3982,18 +3991,18 @@ * _.takeWhile([1, 2, 3], function(n) { return n < 3; }); * // => [1, 2] * - * var characters = [ - * { 'name': 'barney', 'employer': 'slate', 'blocked': true }, - * { 'name': 'fred', 'employer': 'slate' }, - * { 'name': 'pebbles', 'employer': 'na', 'blocked': true } + * var users = [ + * { 'user': 'barney', 'employer': 'slate', 'blocked': true }, + * { 'user': 'fred', 'employer': 'slate' }, + * { 'user': 'pebbles', 'employer': 'na', 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.pluck(_.takeWhile(characters, 'blocked'), 'name'); + * _.pluck(_.takeWhile(users, 'blocked'), 'user'); * // => ['barney'] * * // using "_.where" callback shorthand - * _.pluck(_.takeWhile(characters, { 'employer': 'slate' }), 'name'); + * _.pluck(_.takeWhile(users, { 'employer': 'slate' }), 'user'); * // => ['barney', 'fred'] */ function takeWhile(array, predicate, thisArg) { @@ -4218,8 +4227,8 @@ * @memberOf _ * @alias object * @category Array - * @param {Array} props The array of property names. - * @param {Array} [vals=[]] The array of property values. + * @param {Array} props The property names. + * @param {Array} [vals=[]] The property values. * @returns {Object} Returns the new object. * @example * @@ -4258,15 +4267,15 @@ * @returns {Object} Returns the new wrapper object. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } * ]; * - * var youngest = _.chain(characters) + * var youngest = _.chain(users) * .sortBy('age') - * .map(function(chr) { return chr.name + ' is ' + chr.age; }) + * .map(function(chr) { return chr.user + ' is ' + chr.age; }) * .first() * .value(); * // => 'pebbles is 1' @@ -4292,17 +4301,39 @@ * @returns {*} Returns `value`. * @example * - * _([1, 2, 3, 4]) + * _([1, 2, 3]) * .tap(function(array) { array.pop(); }) * .reverse() * .value(); - * // => [3, 2, 1] + * // => [2, 1] */ function tap(value, interceptor, thisArg) { interceptor.call(thisArg, value); return value; } + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _([1, 2, 3]) + * .last() + * .thru(function(value) { return [value]; }) + * .value(); + * // => [3] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); + } + /** * Enables explicit method chaining on the wrapper object. * @@ -4312,29 +4343,28 @@ * @returns {*} Returns the wrapper object. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // without explicit chaining - * _(characters).first(); - * // => { 'name': 'barney', 'age': 36 } + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } * * // with explicit chaining - * _(characters).chain() + * _(users).chain() * .first() * .pick('age') * .value(); * // => { 'age': 36 } */ function wrapperChain() { - this.__chain__ = true; - return this; + return chain(this); } /** - * Produces the result of coercing the wrapped value to a string. + * Produces the result of coercing the unwrapped value to a string. * * @name toString * @memberOf _ @@ -4346,24 +4376,37 @@ * // => '1,2,3' */ function wrapperToString() { - return String(this.__wrapped__); + return String(this.value()); } /** - * Extracts the wrapped value. + * Extracts the unwrapped value from its wrapper. * * @name valueOf * @memberOf _ * @alias toJSON, value * @category Chain - * @returns {*} Returns the wrapped value. + * @returns {*} Returns the unwrapped value. * @example * * _([1, 2, 3]).valueOf(); * // => [1, 2, 3] */ function wrapperValueOf() { - return this.__wrapped__; + var index = -1, + queue = this.__queue__, + length = queue.length, + result = this.__wrapped__; + + while (++index < length) { + var args = [result], + data = queue[index], + object = data[1]; + + push.apply(args, data[2]); + result = object[data[0]].apply(object, args); + } + return result; } /*------------------------------------------------------------------------*/ @@ -4422,7 +4465,7 @@ * _.contains([1, 2, 3], 1, 2); * // => false * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * _.contains({ 'user': 'fred', 'age': 40 }, 'fred'); * // => true * * _.contains('pebbles', 'eb'); @@ -4511,17 +4554,17 @@ * _.every([true, 1, null, 'yes']); * // => false * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); + * _.every(users, 'age'); * // => true * * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); + * _.every(users, { 'age': 36 }); * // => false */ function every(collection, predicate, thisArg) { @@ -4559,18 +4602,18 @@ * var evens = _.filter([1, 2, 3, 4], function(n) { return n % 2 == 0; }); * // => [2, 4] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * _.filter(users, 'blocked'); + * // => [{ 'user': 'fred', 'age': 40, 'blocked': true }] * * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36 }] + * _.filter(users, { 'age': 36 }); + * // => [{ 'user': 'barney', 'age': 36 }] */ function filter(collection, predicate, thisArg) { var func = isArray(collection) ? arrayFilter : baseFilter; @@ -4603,24 +4646,24 @@ * @returns {*} Returns the matched element, else `undefined`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true }, + * { 'user': 'pebbles', 'age': 1 } * ]; * - * _.find(characters, function(chr) { + * _.find(users, function(chr) { * return chr.age < 40; * }); - * // => { 'name': 'barney', 'age': 36 } + * // => { 'user': 'barney', 'age': 36 } * * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1 } + * _.find(users, { 'age': 1 }); + * // => { 'user': 'pebbles', 'age': 1 } * * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } + * _.find(users, 'blocked'); + * // => { 'user': 'fred', 'age': 40, 'blocked': true } */ function find(collection, predicate, thisArg) { if (isArray(collection)) { @@ -4667,16 +4710,16 @@ * @returns {*} Returns the matched element, else `undefined`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'employer': 'slate' }, - * { 'name': 'fred', 'age': 40, 'employer': 'slate' } + * var users = [ + * { 'user': 'barney', 'age': 36, 'employer': 'slate' }, + * { 'user': 'fred', 'age': 40, 'employer': 'slate' } * ]; * - * _.findWhere(characters, { 'employer': 'slate' }); - * // => { 'name': 'barney', 'age': 36, 'employer': 'slate' } + * _.findWhere(users, { 'employer': 'slate' }); + * // => { 'user': 'barney', 'age': 36, 'employer': 'slate' } * - * _.findWhere(characters, { 'age': 40 }); - * // => { 'name': 'fred', 'age': 40, 'employer': 'slate' } + * _.findWhere(users, { 'age': 40 }); + * // => { 'user': 'fred', 'age': 40, 'employer': 'slate' } */ function findWhere(collection, source) { return find(collection, matches(source)); @@ -4703,10 +4746,10 @@ * @example * * _([1, 2, 3]).forEach(function(n) { console.log(n); }); - * // => logs each value and returns the array + * // => logs each value from left to right and returns the array * * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(n, key) { console.log(n, key); }); - * // => logs each value-key pair and returns the object (property order is not guaranteed) + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) */ function forEach(collection, iteratee, thisArg) { return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) @@ -4877,15 +4920,15 @@ * // => [3, 6, 9] * * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(n) { return n * 3; }); - * // => [3, 6, 9] (property order is not guaranteed) + * // => [3, 6, 9] (iteration order is not guaranteed) * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); + * _.map(users, 'user'); * // => ['barney', 'fred'] */ function map(collection, iteratee, thisArg) { @@ -4926,17 +4969,17 @@ * _.max([]); * // => -Infinity * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; + * _.max(users, function(chr) { return chr.age; }); + * // => { 'user': 'fred', 'age': 40 }; * * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; + * _.max(users, 'age'); + * // => { 'user': 'fred', 'age': 40 }; */ function max(collection, iteratee, thisArg) { var computed = -Infinity, @@ -5009,17 +5052,17 @@ * _.min([]); * // => Infinity * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; + * _.min(users, function(chr) { return chr.age; }); + * // => { 'user': 'barney', 'age': 36 }; * * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; + * _.min(users, 'age'); + * // => { 'user': 'barney', 'age': 36 }; */ function min(collection, iteratee, thisArg) { var computed = Infinity, @@ -5091,18 +5134,18 @@ * _.partition([1.2, 2.3, 3.4], function(n) { return this.floor(n) % 2; }, Math); * // => [[1, 3], [2]] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true }, + * { 'user': 'pebbles', 'age': 1 } * ]; * * // using "_.where" callback shorthand - * _.map(_.partition(characters, { 'age': 1 }), function(array) { return _.pluck(array, 'name'); }); + * _.map(_.partition(users, { 'age': 1 }), function(array) { return _.pluck(array, 'user'); }); * // => [['pebbles'], ['barney', 'fred']] * * // using "_.pluck" callback shorthand - * _.map(_.partition(characters, 'blocked'), function(array) { return _.pluck(array, 'name'); }); + * _.map(_.partition(users, 'blocked'), function(array) { return _.pluck(array, 'user'); }); * // => [['fred'], ['barney', 'pebbles']] */ var partition = createAggregator(function(result, value, key) { @@ -5120,13 +5163,17 @@ * @returns {Array} Returns the property values. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * _.pluck(characters, 'name'); + * _.pluck(users, 'user'); * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) */ function pluck(collection, key) { return map(collection, property(key)); @@ -5158,7 +5205,7 @@ * result[key] = n * 3; * return result; * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } (property order is not guaranteed) + * // => { 'a': 3, 'b': 6, 'c': 9 } (iteration order is not guaranteed) */ function reduce(collection, iteratee, accumulator, thisArg) { var func = isArray(collection) ? arrayReduce : baseReduce; @@ -5214,18 +5261,18 @@ * var odds = _.reject([1, 2, 3, 4], function(n) { return n % 2 == 0; }); * // => [1, 3] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36 }] + * _.reject(users, 'blocked'); + * // => [{ 'user': 'barney', 'age': 36 }] * * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * _.reject(users, { 'age': 36 }); + * // => [{ 'user': 'fred', 'age': 40, 'blocked': true }] */ function reject(collection, predicate, thisArg) { var func = isArray(collection) ? arrayFilter : baseFilter; @@ -5353,17 +5400,17 @@ * _.some([null, 0, 'yes', false], Boolean); * // => true * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); + * _.some(users, 'blocked'); * // => true * * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); + * _.some(users, { 'age': 1 }); * // => false */ function some(collection, predicate, thisArg) { @@ -5408,19 +5455,19 @@ * _.sortBy([1, 2, 3], function(n) { return this.sin(n); }, Math); * // => [3, 1, 2] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 26 }, + * { 'user': 'fred', 'age': 30 } * ]; * * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); + * _.map(_.sortBy(users, 'age'), _.values); * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] * * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * _.map(_.sortBy(users, ['user', 'age']), _.values); * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] */ function sortBy(collection, iteratee, thisArg) { @@ -5491,18 +5538,18 @@ * @returns {Array} Returns the new filtered array. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'employer': 'slate', 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'employer': 'slate', 'pets': ['baby puss', 'dino'] } + * var users = [ + * { 'user': 'barney', 'age': 36, 'employer': 'slate', 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'employer': 'slate', 'pets': ['baby puss', 'dino'] } * ]; * - * _.pluck(_.where(characters, { 'age': 36 }), 'name'); + * _.pluck(_.where(users, { 'age': 36 }), 'user'); * // => ['barney'] * - * _.pluck(_.where(characters, { 'pets': ['dino'] }), 'name'); + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); * // => ['fred'] * - * _.pluck(_.where(characters, { 'employer': 'slate' }), 'name'); + * _.pluck(_.where(users, { 'employer': 'slate' }), 'user'); * // => ['barney', 'fred'] */ function where(collection, source) { @@ -5532,7 +5579,7 @@ * _.forEach(saves, function(type) { * asyncSave({ 'type': type, 'complete': done }); * }); - * // => logs 'done saving!' after all saves have completed + * // => logs 'done saving!' after the two async saves have completed */ function after(n, func) { if (!isFunction(func)) { @@ -5553,19 +5600,20 @@ } /** - * Creates a function that invokes `func`, with the `this` binding and - * arguments of the created function, until it is called `n` times. + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. * * @static * @memberOf _ * @category Function - * @param {number} n The number of times `func` may be called. + * @param {number} n The number of calls at which `func` is no longer invoked. * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * jQuery('#add').on('click', _.before(5, addContactToList)); - * // => allows adding up to 5 contacts to the list + * // => allows adding up to 4 contacts to the list */ function before(n, func) { var result; @@ -5606,10 +5654,10 @@ * @example * * var func = function(greeting) { - * return greeting + ' ' + this.name; + * return greeting + ' ' + this.user; * }; * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func = _.bind(func, { 'user': 'fred' }, 'hi'); * func(); * // => 'hi fred' */ @@ -5675,9 +5723,9 @@ * @example * * var object = { - * 'name': 'fred', + * 'user': 'fred', * 'greet': function(greeting) { - * return greeting + ' ' + this.name; + * return greeting + ' ' + this.user; * } * }; * @@ -5686,7 +5734,7 @@ * // => 'hi fred' * * object.greet = function(greeting) { - * return greeting + 'ya ' + this.name + '!'; + * return greeting + 'ya ' + this.user + '!'; * }; * * func(); @@ -5773,15 +5821,15 @@ } /** - * Creates a function that delays the invocation of `func` until after `wait` - * milliseconds have elapsed since the last time it was invoked. The created - * function comes with a `cancel` method to cancel delayed invokes. Provide an - * options object to indicate that `func` should be invoked on the leading - * and/or trailing edge of the `wait` timeout. Subsequent calls to the - * debounced function return the result of the last `func` invocation. + * Creates a function that delays invoking `func` until after `wait` milliseconds + * have elapsed since the last time it was invoked. The created function comes + * with a `cancel` method to cancel delayed invocations. Provide an options + * object to indicate that `func` should be invoked on the leading and/or + * trailing edge of the `wait` timeout. Subsequent calls to the debounced + * function return the result of the last `func` invocation. * - * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked on - * the trailing edge of the timeout only if the the debounced function is + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is * invoked more than once during the `wait` timeout. * * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) @@ -5822,7 +5870,7 @@ * Object.observe(models.todo, todoChanges); * * Object.observe(models, function(changes) { - * if (_.find(changes, { 'name': 'todo', 'type': 'delete'})) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { * todoChanges.cancel(); * } * }, ['delete']); @@ -6255,8 +6303,8 @@ /** * Creates a function that only invokes `func` at most once per every `wait` * milliseconds. The created function comes with a `cancel` method to cancel - * delayed invokes. Provide an options object to indicate that `func` should - * be invoked on the leading and/or trailing edge of the `wait` timeout. + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. * Subsequent calls to the throttled function return the result of the last * `func` call. * @@ -6359,17 +6407,17 @@ * @returns {*} Returns the cloned value. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; + * var shallow = _.clone(users); + * shallow[0] === users[0]; * // => true * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; + * var deep = _.clone(users, true); + * deep[0] === users[0]; * // => false * * _.mixin({ @@ -6421,13 +6469,13 @@ * @returns {*} Returns the deep cloned value. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * var deep = _.cloneDeep(characters); - * deep[0] === characters[0]; + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; * // => false * * var view = { @@ -6621,8 +6669,8 @@ * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * - * var object = { 'name': 'fred' }; - * var other = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; * * object == other; * // => false @@ -6977,15 +7025,15 @@ * @returns {Object} Returns the destination object. * @example * - * _.assign({ 'name': 'fred' }, { 'age': 40 }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'age': 40, 'employer': 'slate' } + * _.assign({ 'user': 'fred' }, { 'age': 40 }, { 'employer': 'slate' }); + * // => { 'user': 'fred', 'age': 40, 'employer': 'slate' } * * var defaults = _.partialRight(_.assign, function(value, other) { * return typeof value == 'undefined' ? other : value; * }); * - * defaults({ 'name': 'barney' }, { 'age': 36 }, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'age': 36, 'employer': 'slate' } + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred', 'employer': 'slate' }); + * // => { 'user': 'barney', 'age': 36, 'employer': 'slate' } */ var assign = createAssigner(baseAssign); @@ -7041,8 +7089,8 @@ * @returns {Object} Returns the destination object. * @example * - * _.defaults({ 'name': 'barney' }, { 'age': 36 }, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'age': 36, 'employer': 'slate' } + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred', 'employer': 'slate' }); + * // => { 'user': 'barney', 'age': 36, 'employer': 'slate' } */ function defaults(object) { if (object == null) { @@ -7075,23 +7123,23 @@ * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * var characters = { + * var users = { * 'barney': { 'age': 36 }, * 'fred': { 'age': 40, 'blocked': true }, * 'pebbles': { 'age': 1 } * }; * - * _.findKey(characters, function(chr) { + * _.findKey(users, function(chr) { * return chr.age < 40; * }); - * // => 'barney' (property order is not guaranteed) + * // => 'barney' (iteration order is not guaranteed) * * // using "_.where" callback shorthand - * _.findKey(characters, { 'age': 1 }); + * _.findKey(users, { 'age': 1 }); * // => 'pebbles' * * // using "_.pluck" callback shorthand - * _.findKey(characters, 'blocked'); + * _.findKey(users, 'blocked'); * // => 'fred' */ function findKey(object, predicate, thisArg) { @@ -7121,23 +7169,23 @@ * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * var characters = { + * var users = { * 'barney': { 'age': 36, 'blocked': true }, * 'fred': { 'age': 40 }, * 'pebbles': { 'age': 1, 'blocked': true } * }; * - * _.findLastKey(characters, function(chr) { + * _.findLastKey(users, function(chr) { * return chr.age < 40; * }); * // => returns `pebbles`, assuming `_.findKey` returns `barney` * * // using "_.where" callback shorthand - * _.findLastKey(characters, { 'age': 40 }); + * _.findLastKey(users, { 'age': 40 }); * // => 'fred' * * // using "_.pluck" callback shorthand - * _.findLastKey(characters, 'blocked'); + * _.findLastKey(users, 'blocked'); * // => 'pebbles' */ function findLastKey(object, predicate, thisArg) { @@ -7170,7 +7218,7 @@ * _.forIn(new Shape, function(value, key) { * console.log(key); * }); - * // => logs 'x', 'y', and 'z' (property order is not guaranteed) + * // => logs 'x', 'y', and 'z' (iteration order is not guaranteed) */ function forIn(object, iteratee, thisArg) { if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { @@ -7227,7 +7275,7 @@ * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(n, key) { * console.log(key); * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed) + * // => logs '0', '1', and 'length' (iteration order is not guaranteed) */ function forOwn(object, iteratee, thisArg) { if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { @@ -7364,19 +7412,18 @@ * Shape.prototype.z = 0; * * _.keys(new Shape); - * // => ['x', 'y'] (property order is not guaranteed) + * // => ['x', 'y'] (iteration order is not guaranteed) */ var keys = !nativeKeys ? shimKeys : function(object) { - object = toObject(object); - - var Ctor = object.constructor, - length = object.length; - - if ((Ctor && object === Ctor.prototype) || + if (object) { + var Ctor = object.constructor, + length = object.length; + } + if ((typeof Ctor == 'function' && Ctor.prototype === object) || (typeof length == 'number' && length > 0)) { return shimKeys(object); } - return nativeKeys(object); + return isObject(object) ? nativeKeys(object) : []; }; /** @@ -7397,14 +7444,15 @@ * Shape.prototype.z = 0; * * _.keysIn(new Shape); - * // => ['x', 'y', 'z'] (property order is not guaranteed) + * // => ['x', 'y', 'z'] (iteration order is not guaranteed) */ function keysIn(object) { if (object == null) { return []; } - object = toObject(object); - + if (!isObject(object)) { + object = Object(object); + } var length = object.length; length = (typeof length == 'number' && length > 0 && (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) >>> 0; @@ -7412,7 +7460,7 @@ var keyIndex, Ctor = object.constructor, index = -1, - isProto = Ctor && object === Ctor.prototype, + isProto = typeof Ctor == 'function' && Ctor.prototype == object, maxIndex = length - 1, result = Array(length), skipIndexes = length > 0; @@ -7456,19 +7504,19 @@ * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(n) { return n * 3; }); * // => { 'a': 3, 'b': 6, 'c': 9 } * - * var characters = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } * }; * * // using "_.pluck" callback shorthand - * _.mapValues(characters, 'age'); + * _.mapValues(users, 'age'); * // => { 'fred': 40, 'pebbles': 1 } */ function mapValues(object, iteratee, thisArg) { - var result = {}; iteratee = getCallback(iteratee, thisArg, 3); + var result = {} baseForOwn(object, function(value, key, object) { result[key] = iteratee(value, key, object); }); @@ -7494,22 +7542,16 @@ * @returns {Object} Returns the destination object. * @example * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] * }; * * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] + * 'data': [{ 'age': 36 }, { 'age': 40 }] * }; * - * _.merge(names, ages); - * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } * * var food = { * 'fruits': ['apple'], @@ -7547,25 +7589,24 @@ * @returns {Object} Returns the new object. * @example * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } + * _.omit({ 'user': 'fred', 'age': 40 }, 'age'); + * // => { 'user': 'fred' } * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * _.omit({ 'user': 'fred', 'age': 40 }, function(value) { * return typeof value == 'number'; * }); - * // => { 'name': 'fred' } + * // => { 'user': 'fred' } */ function omit(object, predicate, thisArg) { if (object == null) { return {}; } - var iterable = toObject(object); if (typeof predicate != 'function') { var props = arrayMap(baseFlatten(arguments, false, false, 1), String); - return pickByArray(iterable, baseDifference(keysIn(iterable), props)); + return pickByArray(object, baseDifference(keysIn(object), props)); } predicate = getCallback(predicate, thisArg, 3); - return pickByCallback(iterable, function(value, key, object) { + return pickByCallback(object, function(value, key, object) { return !predicate(value, key, object); }); } @@ -7582,7 +7623,7 @@ * @example * * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed) + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) */ function pairs(object) { var index = -1, @@ -7616,22 +7657,21 @@ * @returns {Object} Returns the new object. * @example * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } + * _.pick({ 'user': 'fred', '_userid': 'fred1' }, 'user'); + * // => { 'user': 'fred' } * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * _.pick({ 'user': 'fred', '_userid': 'fred1' }, function(value, key) { * return key.charAt(0) != '_'; * }); - * // => { 'name': 'fred' } + * // => { 'user': 'fred' } */ function pick(object, predicate, thisArg) { if (object == null) { return {}; } - var iterable = toObject(object); return typeof predicate == 'function' - ? pickByCallback(iterable, getCallback(predicate, thisArg, 3)) - : pickByArray(iterable, baseFlatten(arguments, false, false, 1)); + ? pickByCallback(object, getCallback(predicate, thisArg, 3)) + : pickByArray(object, baseFlatten(arguments, false, false, 1)); } /** @@ -7666,25 +7706,22 @@ * // => { 'a': 3, 'b': 6, 'c': 9 } */ function transform(object, iteratee, accumulator, thisArg) { - var isArr = isArrayLike(object); + iteratee = getCallback(iteratee, thisArg, 4); + var isArr = isArrayLike(object); if (accumulator == null) { if (isArr) { accumulator = []; + } else if (isObject(object)) { + var Ctor = object.constructor; + accumulator = baseCreate(typeof Ctor == 'function' && Ctor.prototype); } else { - if (isObject(object)) { - var Ctor = object.constructor, - proto = Ctor && Ctor.prototype; - } - accumulator = baseCreate(proto); + accumulator = {}; } } - if (iteratee) { - iteratee = getCallback(iteratee, thisArg, 4); - (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); return accumulator; } @@ -7706,7 +7743,7 @@ * Shape.prototype.z = 0; * * _.values(new Shape(2, 1)); - * // => [2, 1] (property order is not guaranteed) + * // => [2, 1] (iteration order is not guaranteed) */ function values(object) { return baseValues(object, keys); @@ -7731,7 +7768,7 @@ * Shape.prototype.z = 0; * * _.valuesIn(new Shape(2, 1)); - * // => [2, 1, 0] (property order is not guaranteed) + * // => [2, 1, 0] (iteration order is not guaranteed) */ function valuesIn(object) { return baseValues(object, keysIn); @@ -7760,10 +7797,8 @@ * // => 'helloWorld' */ var camelCase = createCompounder(function(result, word, index) { - if (!index && reAllCaps.test(word)) { - return result + word.toLowerCase(); - } - return result + (word.charAt(0)[index ? 'toUpperCase' : 'toLowerCase']() + word.slice(1)); + word = word.toLowerCase(); + return index ? (result + word.charAt(0).toUpperCase() + word.slice(1)) : word; }); /** @@ -7780,11 +7815,28 @@ * // => 'Fred' */ function capitalize(string) { - if (string == null) { - return ''; - } - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); + string = string == null ? '' : String(string); + return string ? (string.charAt(0).toUpperCase() + string.slice(1)) : string; + } + + /** + * Deburrs `string` by converting latin-1 supplementary letters to basic latin letters. + * See [Wikipedia](http://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the beburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = string == null ? '' : String(string); + return string ? string.replace(reLatin1, deburrLetter) : string; } /** @@ -7842,7 +7894,7 @@ function escape(string) { // reset `lastIndex` because in IE < 9 `String#replace` does not string = string == null ? '' : String(string); - return (reUnescapedHtml.lastIndex = 0, reUnescapedHtml.test(string)) + return string && (reUnescapedHtml.lastIndex = 0, reUnescapedHtml.test(string)) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string; } @@ -7858,12 +7910,12 @@ * @returns {string} Returns the escaped string. * @example * - * _.escapeRegExp('[lodash](http://lodash.com)'); - * // => '\[lodash\]\(http://lodash\.com\)' + * _.escapeRegExp('[lodash](http://lodash.com/)'); + * // => '\[lodash\]\(http://lodash\.com/\)' */ function escapeRegExp(string) { string = string == null ? '' : String(string); - return (reRegExpChars.lastIndex = 0, reRegExpChars.test(string)) + return string && (reRegExpChars.lastIndex = 0, reRegExpChars.test(string)) ? string.replace(reRegExpChars, '\\$&') : string; } @@ -7957,7 +8009,7 @@ */ function padLeft(string, length, chars) { string = string == null ? '' : String(string); - return createPad(string, length, chars) + string; + return string ? (createPad(string, length, chars) + string) : string; } /** @@ -7985,7 +8037,7 @@ */ function padRight(string, length, chars) { string = string == null ? '' : String(string); - return string + createPad(string, length, chars); + return string ? (string + createPad(string, length, chars)) : string; } /** @@ -8115,9 +8167,9 @@ * @example * * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'fred' }); - * // => 'hello fred' + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' * * // using the HTML "escape" delimiter to escape data property values * var compiled = _.template('<%- value %>'); @@ -8125,24 +8177,24 @@ * // => '<script>' * * // using the "evaluate" delimiter to execute JavaScript and generate HTML - * var compiled = _.template('<% _.forEach(people, function(name) { %>
  • <%- name %>
  • <% }); %>'); - * compiled({ 'people': ['fred', 'barney'] }); + * var compiled = _.template('<% _.forEach(users, function(user) { %>
  • <%- user %>
  • <% }); %>'); + * compiled({ 'users': ['fred', 'barney'] }); * // => '
  • fred
  • barney
  • ' * * // using the internal `print` function in "evaluate" delimiters - * var compiled = _.template('<% print("hello " + name); %>!'); - * compiled({ 'name': 'barney' }); + * var compiled = _.template('<% print("hello " + user); %>!'); + * compiled({ 'user': 'barney' }); * // => 'hello barney!' * * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter - * var compiled = _.template('hello ${ name }'); - * compiled({ 'name': 'pebbles' }); - * // => 'hello pebbles' + * var compiled = _.template('hello ${ user }!'); + * compiled({ 'user': 'pebbles' }); + * // => 'hello pebbles!' * * // using custom template delimiters * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; - * var compiled = _.template('hello {{ name }}!'); - * compiled({ 'name': 'mustache' }); + * var compiled = _.template('hello {{ user }}!'); + * compiled({ 'user': 'mustache' }); * // => 'hello mustache!' * * // using backslashes to treat delimiters as plain text @@ -8151,22 +8203,22 @@ * // => '<%- value %>' * * // using the `imports` option to import `jQuery` as `jq` - * var text = '<% jq.each(people, function(name) { %>
  • <%- name %>
  • <% }); %>'; + * var text = '<% jq.each(users, function(user) { %>
  • <%- user %>
  • <% }); %>'; * var compiled = _.template(text, { 'imports': { 'jq': jQuery } }); - * compiled({ 'people': ['fred', 'barney'] }); + * compiled({ 'users': ['fred', 'barney'] }); * // => '
  • fred
  • barney
  • ' * * // using the `sourceURL` option to specify a custom sourceURL for the template - * var compiled = _.template('hello <%= name %>', { 'sourceURL': '/basic/greeting.jst' }); + * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' }); * compiled(data); * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector * * // using the `variable` option to ensure a with-statement isn't used in the compiled template - * var compiled = _.template('hi <%= data.name %>!', { 'variable': 'data' }); + * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' }); * compiled.source; * // => function(data) { - * var __t, __p = '', __e = _.escape; - * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!'; + * var __t, __p = ''; + * __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; * return __p; * } * @@ -8461,16 +8513,38 @@ * @returns {string} Returns the unescaped string. * @example * - * _.unescape('fred, barney & pebbles'); - * // => 'fred, barney & pebbles' + * _.unescape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' */ function unescape(string) { string = string == null ? '' : String(string); - return (reEscapedHtml.lastIndex = 0, reEscapedHtml.test(string)) + return string && (reEscapedHtml.lastIndex = 0, reEscapedHtml.test(string)) ? string.replace(reEscapedHtml, unescapeHtmlChar) : string; } + /** + * Splits `string` into an array of its words. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to inspect. + * @param {RegExp|string} [pattern] The pattern to match words. + * @returns {Array} Returns the words of `string`. + * @example + * + * _.words('fred, barney, & pebbles'); + * // => ['fred', 'barney', 'pebbles'] + * + * _.words('fred, barney, & pebbles', /[^, ]+/g); + * // => ['fred', 'barney', '&', 'pebbles'] + */ + function words(string, pattern) { + string = string != null && String(string); + return (string && string.match(pattern || reWords)) || []; + } + /*------------------------------------------------------------------------*/ /** @@ -8516,9 +8590,9 @@ * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // wrap to create custom callback shorthands @@ -8532,8 +8606,8 @@ * }; * }); * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] + * _.filter(users, 'age__gt38'); + * // => [{ 'user': 'fred', 'age': 40 }] */ function callback(func, thisArg) { return baseCallback(func, thisArg); @@ -8549,7 +8623,7 @@ * @returns {Function} Returns the new function. * @example * - * var object = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; * var getter = _.constant(object); * getter() === object; * // => true @@ -8570,7 +8644,7 @@ * @returns {*} Returns `value`. * @example * - * var object = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; * _.identity(object) === object; * // => true */ @@ -8590,18 +8664,18 @@ * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } + * var users = [ + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } * ]; * * var matchesAge = _.matches({ 'age': 36 }); * - * _.filter(characters, matchesAge); - * // => [{ 'name': 'barney', 'age': 36 }] + * _.filter(users, matchesAge); + * // => [{ 'user': 'barney', 'age': 36 }] * - * _.find(characters, matchesAge); - * // => { 'name': 'barney', 'age': 36 } + * _.find(users, matchesAge); + * // => { 'user': 'barney', 'age': 36 } */ function matches(source) { var props = keys(source), @@ -8707,28 +8781,22 @@ length = methodNames.length; while (++index < length) { - var methodName = methodNames[index], - func = object[methodName] = source[methodName]; - + var methodName = methodNames[index]; + object[methodName] = source[methodName]; if (isFunc) { - object.prototype[methodName] = (function(func) { + object.prototype[methodName] = (function(methodName) { return function() { - var chainAll = this.__chain__, - value = this.__wrapped__, - args = [value]; - - push.apply(args, arguments); - var result = func.apply(object, args); - if (chain || chainAll) { - if (value === result && isObject(result)) { - return this; - } - result = new object(result); - result.__chain__ = chainAll; + if (chain || this.__chain__) { + var result = object(this.__wrapped__); + result.__chain__ = this.__chain__; + (result.__queue__ = baseSlice(this.__queue__)).push([methodName, object, arguments]); + return result; } - return result; + var args = [this.value()]; + push.apply(args, arguments); + return object[methodName].apply(object, args); }; - }(func)); + }(methodName)); } } return object; @@ -8759,7 +8827,7 @@ * @category Utility * @example * - * var object = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; * _.noop(object) === undefined; * // => true */ @@ -8789,8 +8857,7 @@ * in which case a `radix` of `16` is used. * * **Note:** This method avoids differences in native ES3 and ES5 `parseInt` - * implementations. See the [ES5 spec](http://es5.github.io/#E) - * for more details. + * implementations. See the [ES5 spec](http://es5.github.io/#E) for more details. * * @static * @memberOf _ @@ -8830,18 +8897,18 @@ * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } + * var users = [ + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } * ]; * - * var getName = _.property('name'); + * var getName = _.property('user'); * - * _.map(characters, getName); + * _.map(users, getName); * // => ['barney', 'fred'] * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + * _.sortBy(users, getName); + * // => [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] */ function property(key) { return function(object) { @@ -8992,13 +9059,13 @@ * @example * * var object = { - * 'name': 'fred', + * 'user': 'fred', * 'age': function() { * return 40; * } * }; * - * _.result(object, 'name'); + * _.result(object, 'user'); * // => 'fred' * * _.result(object, 'age'); @@ -9155,6 +9222,7 @@ lodash.takeWhile = takeWhile; lodash.tap = tap; lodash.throttle = throttle; + lodash.thru = thru; lodash.times = times; lodash.toArray = toArray; lodash.transform = transform; @@ -9185,7 +9253,7 @@ lodash.unique = uniq; // add functions to `lodash.prototype` - mixin(lodash, baseAssign({}, lodash)); + mixin(lodash, lodash); /*------------------------------------------------------------------------*/ @@ -9196,6 +9264,7 @@ lodash.clone = clone; lodash.cloneDeep = cloneDeep; lodash.contains = contains; + lodash.deburr = deburr; lodash.endsWith = endsWith; lodash.escape = escape; lodash.escapeRegExp = escapeRegExp; @@ -9261,6 +9330,7 @@ lodash.trunc = trunc; lodash.unescape = unescape; lodash.uniqueId = uniqueId; + lodash.words = words; // add aliases lodash.all = every; @@ -9287,19 +9357,15 @@ // add functions capable of returning wrapped and unwrapped values when chaining lodash.sample = sample; - baseForOwn(lodash, function(func, methodName) { - var callbackable = methodName != 'sample'; - if (!lodash.prototype[methodName]) { - lodash.prototype[methodName] = function(n, guard) { - var chainAll = this.__chain__, - result = func(this.__wrapped__, n, guard); - - return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function'))) - ? result - : new lodashWrapper(result, chainAll); - }; + lodash.prototype.sample = function(n, guard) { + n = guard ? null : n; + if (!this.__chain__ && n == null) { + return lodash.sample(this.value()); } - }); + return this.thru(function(value) { + return lodash.sample(value, n); + }); + }; /*------------------------------------------------------------------------*/ @@ -9325,33 +9391,20 @@ lodash[methodName].placeholder = lodash; }); - // add `Array` functions that return unwrapped values - arrayEach(['join', 'pop', 'shift'], function(methodName) { - var func = arrayProto[methodName]; - lodash.prototype[methodName] = function() { - var chainAll = this.__chain__, - result = func.apply(this.__wrapped__, arguments); + // add `Array.prototype` functions + arrayEach(['concat', 'join', 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { + var func = arrayProto[methodName], + retUnwrapped = /^(?:join|pop|shift)$/.test(methodName), + chainName = /^(?:push|reverse|sort|unshift)$/.test(methodName) ? 'tap' : 'thru'; - return chainAll - ? new lodashWrapper(result, chainAll) - : result; - }; - }); - - // add `Array` functions that return the existing wrapped value - arrayEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) { - var func = arrayProto[methodName]; lodash.prototype[methodName] = function() { - func.apply(this.__wrapped__, arguments); - return this; - }; - }); - - // add `Array` functions that return new wrapped values - arrayEach(['concat', 'splice'], function(methodName) { - var func = arrayProto[methodName]; - lodash.prototype[methodName] = function() { - return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__); + var args = arguments; + if (retUnwrapped && !this.__chain__) { + return func.apply(this.value(), args); + } + return this[chainName](function(value) { + return func.apply(value, args); + }); }; }); diff --git a/dist/lodash.min.js b/dist/lodash.min.js index 8df3e5fc6..1a746ef90 100644 --- a/dist/lodash.min.js +++ b/dist/lodash.min.js @@ -3,71 +3,71 @@ * Lo-Dash 3.0.0-pre (Custom Build) lodash.com/license | Underscore.js 1.7.0 underscorejs.org/LICENSE * Build: `lodash modern -o ./dist/lodash.js` */ -;(function(){function n(n,t){for(var r=-1,e=t.length,u=Array(e);++rt||typeof n=="undefined")return 1;if(n=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n) -}function v(n){for(var t=-1,r=n.length;++ti(t,a)&&c.push(a);return c}function Mt(n,t){var r=n?n.length:0;if(typeof r!="number"||-1>=r||r>F)return Xt(n,t); -for(var e=-1,u=Fr(n);++e=r||r>F)return Gt(n,t);for(var e=Fr(n);r--&&false!==t(e[r],r,e););return n}function qt(n,t){var r=true;return Mt(n,function(n,e,u){return r=!!t(n,e,u)}),r}function Zt(n,t){var r=[];return Mt(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function Kt(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function Pt(n,t,r,e){e=(e||0)-1;for(var u=n.length,o=-1,i=[];++el))return false}else{var g=s&&Je.call(n,"__wrapped__"),h=h&&Je.call(t,"__wrapped__"); -if(g||h)return Qt(g?n.__wrapped__:n,h?t.__wrapped__:t,r,e,u,o);if(!p)return false;if(!f&&!s){switch(c){case ot:case it:return+n==+t;case at:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case lt:case pt:return n==qe(t)}return false}if(g=l?Me:n.constructor,c=i?Me:t.constructor,f){if(g.prototype.name!=c.prototype.name)return false}else if(s=!l&&Je.call(n,"constructor"),h=!i&&Je.call(t,"constructor"),s!=h||!(s||g==c||ve(g)&&g instanceof g&&ve(c)&&c instanceof c)&&"constructor"in n&&"constructor"in t)return false;if(g=f?["message","name"]:Bu(n),c=f?g:Bu(t),l&&g.push("length"),i&&c.push("length"),l=g.length,s=c.length,l!=s&&!e)return false -}for(u||(u=[]),o||(o=[]),c=u.length;c--;)if(u[c]==n)return o[c]==t;if(u.push(n),o.push(t),i=true,a)for(;i&&++c>>1,a=r(n[f]),c=e?a<=t:ao(l,s)&&((t||a)&&l.push(s),c.push(p))}return c}function cr(n,t){for(var r=-1,e=t(n),u=e.length,o=We(u);++rt)return r;var e=typeof arguments[2];if("number"!=e&&"string"!=e||!arguments[3]||arguments[3][arguments[2]]!==arguments[1]||(t=2),3e?du(u+e,0):e||0;else if(e)return e=Br(n,t),u&&n[e]===t?e:-1;return r(n,t,e)}function Lr(n){return $r(n,1) -}function $r(n,t,r){var u=-1,o=n?n.length:0;if(t=null==t?0:+t||0,0>t&&(t=-t>o?0:o+t),r=typeof r=="undefined"||r>o?o:+r||0,0>r&&(r+=o),r&&r==o&&!t)return e(n);for(o=t>r?0:r-t,r=We(o);++ur?du(e+r,0):r||0:0,typeof n=="string"||!Wu(n)&&_e(n)?ru&&(u=f);else t=i&&f?o:wr(t,r,3),Mt(n,function(n,r,o){r=t(n,r,o),(r>e||-1/0===r&&r===u)&&(e=r,u=n)});return u}function Hr(n,t){return Xr(n,Ue(t))}function Qr(n,t,r,e){return(Wu(n)?Rt:or)(n,wr(t,e,4),r,3>arguments.length,Mt)}function ne(n,t,r,e){return(Wu(n)?kt:or)(n,wr(t,e,4),r,3>arguments.length,zt) -}function te(n){n=Fr(n);for(var t=-1,r=n.length,e=We(r);++targuments.length)return _r(n,w,null,t);var r=$r(arguments,2),e=kr(r,ue.placeholder);return er(n,w|O,r,e,t)}function oe(n,t){var r=w|j; -if(2=r||r>t?(f&&ru(f),r=s,f=p=s=b,r&&(h=Zu(),a=n.apply(l,i),p||f||(i=l=null))):p=au(e,r)}function u(){p&&ru(p),f=p=s=b,(v||g!==t)&&(h=Zu(),a=n.apply(l,i),p||f||(i=l=null))}function o(){if(i=arguments,c=Zu(),l=this,s=v&&(p||!y),false===g)var r=y&&!p; -else{f||y||(h=c);var o=g-(c-h),d=0>=o||o>g;d?(f&&(f=ru(f)),h=c,a=n.apply(l,i)):f||(f=au(u,o))}return d&&p?p=ru(p):p||t===g||(p=au(e,t)),r&&(d=true,a=n.apply(l,i)),!d||p||f||(i=l=null),a}var i,f,a,c,l,p,s,h=0,g=false,v=true;if(!ve(n))throw new Ze(S);if(t=0>t?0:t,true===r)var y=true,v=false;else ye(r)&&(y=r.leading,g="maxWait"in r&&du(+r.maxWait||0,t),v="trailing"in r?r.trailing:v);return o.cancel=function(){p&&ru(p),f&&ru(f),f=p=s=b},o}function ce(){var n=arguments,t=n.length-1;if(0>t)return function(){};if(!Et(n,ve))throw new Ze(S); -return function(){for(var r=t,e=n[r].apply(this,arguments);r--;)e=n[r].call(this,e);return e}}function le(n){var t=$r(arguments,1),r=kr(t,le.placeholder);return er(n,O,t,r)}function pe(n){var t=$r(arguments,1),r=kr(t,pe.placeholder);return er(n,I,t,r)}function se(n){var t=n&&typeof n=="object"?n.length:b;return typeof t=="number"&&-1>>0,e=n.constructor,u=-1,e=e&&n===e.prototype,o=r-1,i=We(r),f=0t||null==n||!vu(t))return r;n=qe(n);do t%2&&(r+=n),t=eu(t/2),n+=n;while(t);return r}function Oe(n,t){return(n=null==n?"":qe(n))?null==t?n.slice(v(n),y(n)+1):(t=qe(t),n.slice(i(n,t),f(n,t)+1)):n -}function Ie(n){try{return n()}catch(t){return ge(t)?t:Le(t)}}function Re(n,t){return Nt(n,t)}function ke(n){return n}function Se(n){var t=Bu(n),r=t.length;if(1==r){var e=t[0],u=n[e];if(Or(u))return function(n){return null!=n&&u===n[e]&&Je.call(n,e)}}for(var o=r,i=We(r),f=We(r);o--;){var u=n[t[o]],a=Or(u);i[o]=a,f[o]=a?u:Lt(u)}return function(n){if(o=r,null==n)return!o;for(;o--;)if(i[o]?f[o]!==n[t[o]]:!Je.call(n,t[o]))return false;for(o=r;o--;)if(i[o]?!Je.call(n,t[o]):!Qt(f[o],n[t[o]],null,true))return false; -return true}}function Ce(n,t,r){var e=true,u=ye(t),o=null==r,i=o&&u&&Bu(t),f=i&&Ht(t,i);(i&&i.length&&!f.length||o&&!u)&&(o&&(r=t),f=false,t=n,n=this),f||(f=Ht(t,Bu(t))),false===r?e=false:ye(r)&&"chain"in r&&(e=r.chain),r=-1,u=ve(n);for(o=f.length;++r=R)return r -}else n=0;return Ou(r,e)}}(),Su=hr(function(n,t,r){Je.call(n,r)?++n[r]:n[r]=1}),Cu=hr(function(n,t,r){Je.call(n,r)?n[r].push(t):n[r]=[t]}),Fu=hr(function(n,t,r){n[r]=t}),Tu=hr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Uu=le(ee,2),Wu=gu||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&Ge.call(n)==ut||false};Eu.dom||(he=function(n){return n&&typeof n=="object"&&1===n.nodeType&&!Lu(n)||false});var Nu=_u||function(n){return typeof n=="number"&&vu(n)},Lu=uu?function(n){if(!n||Ge.call(n)!=ct)return false; -var t=n.valueOf,r=de(t)&&(r=uu(t))&&uu(r);return r?n==r||uu(n)==r:Sr(n)}:Sr,$u=gr(Wt),Bu=yu?function(n){n=Tr(n);var t=n.constructor,r=n.length;return t&&n===t.prototype||typeof r=="number"&&0--n?t.apply(this,arguments):void 0}},g.assign=$u,g.at=function(t){var r=t?t.length:0;return typeof r=="number"&&-1t?0:t)},g.dropRight=function(n,t,r){var e=n?n.length:0; -return t=e-((null==t||r?1:t)||0),$r(n,0,0>t?0:t)},g.dropRightWhile=function(n,t,r){var e=n?n.length:0;for(t=wr(t,r,3);e--&&t(n[e],e,n););return $r(n,0,e+1)},g.dropWhile=function(n,t,r){var e=-1,u=n?n.length:0;for(t=wr(t,r,3);++e(s?u(s,a):i(p,a))){for(t=e;--t;){var h=o[t];if(0>(h?u(h,a):i(n[t],a)))continue n}s&&s.push(a),p.push(a)}return p},g.invert=function(n,t){for(var r=-1,e=Bu(n),u=e.length,o={};++rt?0:t)},g.takeRight=function(n,t,r){var e=n?n.length:0;return t=e-((null==t||r?1:t)||0),$r(n,0>t?0:t)},g.takeRightWhile=function(n,t,r){var e=n?n.length:0;for(t=wr(t,r,3);e--&&t(n[e],e,n););return $r(n,e+1)},g.takeWhile=function(n,t,r){var e=-1,u=n?n.length:0;for(t=wr(t,r,3);++er?0:+r||0,e))-t.length,0<=r&&n.indexOf(t,r)==r},g.escape=function(n){return n=null==n?"":qe(n),D.lastIndex=0,D.test(n)?n.replace(D,s):n},g.escapeRegExp=xe,g.every=Kr,g.find=Vr,g.findIndex=Ur,g.findKey=function(n,t,r){return t=wr(t,r,3),Kt(n,t,Xt,true)},g.findLast=function(n,t,r){return t=wr(t,r,3),Kt(n,t,zt)},g.findLastIndex=function(n,t,r){var e=n?n.length:0;for(t=wr(t,r,3);e--;)if(t(n[e],e,n))return e; -return-1},g.findLastKey=function(n,t,r){return t=wr(t,r,3),Kt(n,t,Gt,true)},g.findWhere=function(n,t){return Vr(n,Se(t))},g.first=Wr,g.has=function(n,t){return n?Je.call(n,t):false},g.identity=ke,g.indexOf=Nr,g.isArguments=se,g.isArray=Wu,g.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&Ge.call(n)==ot||false},g.isDate=function(n){return n&&typeof n=="object"&&Ge.call(n)==it||false},g.isElement=he,g.isEmpty=function(n){if(null==n)return true;var t=n.length;return typeof t=="number"&&-1r?du(u+r,0):mu(r||0,u-1))+1; -else if(r)return u=Dr(n,t)-1,e&&n[u]===t?u:-1;for(r=t===t;u--;)if(e=n[u],r?e===t:e!==e)return u;return-1},g.max=Gr,g.min=function(n,t,r){var e=1/0,u=e,i=typeof t;"number"!=i&&"string"!=i||!r||r[t]!==n||(t=null);var i=null==t,f=!(i&&Wu(n))&&_e(n);if(i&&!f)for(r=-1,n=Fr(n),i=n.length;++rr?0:+r||0,n.length),n.lastIndexOf(t,r)==r},g.template=function(n,t,r){var e=g.templateSettings;t=$u({},r||t,e,Ut),n=qe(null==n?"":n),r=$u({},t.imports,e.imports,Ut); -var u,o,i=Bu(r),f=Ae(r),a=0;r=t.interpolate||X;var c="__p+='";if(r=ze((t.escape||X).source+"|"+r.source+"|"+(r===q?Z:X).source+"|"+(t.evaluate||X).source+"|$","g"),n.replace(r,function(t,r,e,i,f,l){return e||(e=i),c+=n.slice(a,l).replace(Q,h),r&&(u=true,c+="'+__e("+r+")+'"),f&&(o=true,c+="';"+f+";\n__p+='"),e&&(c+="'+((__t=("+e+"))==null?'':__t)+'"),a=l+t.length,t}),c+="';",(t=t.variable)||(c="with(obj){"+c+"}"),c=(o?c.replace(N,""):c).replace(L,"$1").replace($,"$1;"),c="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+c+"return __p}",t=Ie(function(){return $e(i,"return "+c).apply(b,f) -}),t.source=c,ge(t))throw t;return t},g.trim=Oe,g.trimLeft=function(n,t){return(n=null==n?"":qe(n))?null==t?n.slice(v(n)):(t=qe(t),n.slice(i(n,t))):n},g.trimRight=function(n,t){return(n=null==n?"":qe(n))?null==t?n.slice(0,y(n)+1):(t=qe(t),n.slice(0,f(n,t)+1)):n},g.trunc=function(n,t){var r=30,e="...";if(ye(t))var u="separator"in t?t.separator:u,r="length"in t?+t.length||0:r,e="omission"in t?qe(t.omission):e;else null!=t&&(r=+t||0);if(n=null==n?"":qe(n),r>=n.length)return n;var o=r-e.length;if(1>o)return e; -if(r=n.slice(0,o),null==u)return r+e;if(be(u)){if(n.slice(o).search(u)){var i,f,a=n.slice(0,o);for(u.global||(u=ze(u.source,(K.exec(u)||"")+"g")),u.lastIndex=0;i=u.exec(a);)f=i.index;r=r.slice(0,null==f?o:f)}}else n.indexOf(u,o)!=o&&(u=r.lastIndexOf(u),-1t?0:+t||0,n.length),n)},Xt(g,function(n,t){var r="sample"!=t;g.prototype[t]||(g.prototype[t]=function(t,e){var u=this.__chain__,o=n(this.__wrapped__,t,e);return u||null!=t&&(!e||r&&typeof t=="function")?new J(o,u):o})}),g.VERSION=_,J.prototype=g.prototype,g.prototype.chain=function(){return this.__chain__=true,this},g.prototype.toString=function(){return qe(this.__wrapped__) -},g.prototype.toJSON=g.prototype.value=g.prototype.valueOf=function(){return this.__wrapped__},nt("bind bindKey curry curryRight partial partialRight".split(" "),function(n){g[n].placeholder=g}),nt(["join","pop","shift"],function(n){var t=Ke[n];g.prototype[n]=function(){var n=this.__chain__,r=t.apply(this.__wrapped__,arguments);return n?new J(r,n):r}}),nt(["push","reverse","sort","unshift"],function(n){var t=Ke[n];g.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),nt(["concat","splice"],function(n){var t=Ke[n]; -g.prototype[n]=function(){return new J(t.apply(this.__wrapped__,arguments),this.__chain__)}}),g}var b,_="3.0.0-pre",w=1,j=2,A=4,x=8,E=16,O=32,I=64,R=150,k=16,S="Expected a function",C=Math.pow(2,32)-1,F=Math.pow(2,53)-1,T="__lodash_placeholder__",U=0,W=/^[A-Z]+$/,N=/\b__p\+='';/g,L=/\b(__p\+=)''\+/g,$=/(__e\(.*?\)|\b__t\))\+'';/g,B=/&(?:amp|lt|gt|quot|#39|#96);/g,D=/[&<>"'`]/g,M=/<%-([\s\S]+?)%>/g,z=/<%([\s\S]+?)%>/g,q=/<%=([\s\S]+?)%>/g,Z=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,K=/\w*$/,P=/^\s*function[ \n\r\t]+\w/,V=/^0[xX]/,Y=/^\[object .+?Constructor\]$/,J=/[\xC0-\xFF]/g,X=/($^)/,G=/[.*+?^${}()|[\]\/\\]/g,H=/\bthis\b/,Q=/['\n\r\u2028\u2029\\]/g,nt=/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g,tt=" \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",rt="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window WinRTError".split(" "),et="[object Arguments]",ut="[object Array]",ot="[object Boolean]",it="[object Date]",ft="[object Error]",at="[object Number]",ct="[object Object]",lt="[object RegExp]",pt="[object String]",st="[object ArrayBuffer]",ht="[object Float32Array]",gt="[object Float64Array]",vt="[object Int8Array]",yt="[object Int16Array]",dt="[object Int32Array]",mt="[object Uint8Array]",bt="[object Uint8ClampedArray]",_t="[object Uint16Array]",wt="[object Uint32Array]",jt={}; -jt[et]=jt[ut]=jt[ht]=jt[gt]=jt[vt]=jt[yt]=jt[dt]=jt[mt]=jt[bt]=jt[_t]=jt[wt]=true,jt[st]=jt[ot]=jt[it]=jt[ft]=jt["[object Function]"]=jt["[object Map]"]=jt[at]=jt[ct]=jt[lt]=jt["[object Set]"]=jt[pt]=jt["[object WeakMap]"]=false;var At={};At[et]=At[ut]=At[st]=At[ot]=At[it]=At[ht]=At[gt]=At[vt]=At[yt]=At[dt]=At[at]=At[ct]=At[lt]=At[pt]=At[mt]=At[bt]=At[_t]=At[wt]=true,At[ft]=At["[object Function]"]=At["[object Map]"]=At["[object Set]"]=At["[object WeakMap]"]=false;var xt={leading:false,maxWait:0,trailing:false},Et={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Ot={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},It={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"AE","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\xd7":" ","\xf7":" "},Rt={"function":true,object:true},kt={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},St=Rt[typeof window]&&window||this,Ct=Rt[typeof exports]&&exports&&!exports.nodeType&&exports,Rt=Rt[typeof module]&&module&&!module.nodeType&&module,Ft=Ct&&Rt&&typeof global=="object"&&global; -!Ft||Ft.global!==Ft&&Ft.window!==Ft&&Ft.self!==Ft||(St=Ft);var Ft=Rt&&Rt.exports===Ct&&Ct,Tt=m();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(St._=Tt, define(function(){return Tt})):Ct&&Rt?Ft?(Rt.exports=Tt)._=Tt:Ct._=Tt:St._=Tt}).call(this); \ No newline at end of file +;(function(){function n(n,t){for(var r=-1,e=n.length;++rt||!r||typeof n=="undefined"&&e)return 1;if(n=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n) +}function w(n,t){for(var r=-1,e=n.length,u=-1,o=[];++ru(t,i)&&f.push(i);return f}function Kt(n,t){var r=n?n.length:0;if(typeof r!="number"||-1>=r||r>L)return Qt(n,t);for(var e=-1,u=Wr(n);++e=r||r>L)return nr(n,t);for(var e=Wr(n);r--&&false!==t(e[r],r,e););return n}function Zt(n,t){var r=true;return Kt(n,function(n,e,u){return r=!!t(n,e,u)}),r}function Vt(n,t){var r=[];return Kt(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function Yt(n,t,r,e){var u; +return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function Jt(n,t,r,e){e=(e||0)-1;for(var u=n.length,o=-1,i=[];++el))return false}else{var g=p&&tu.call(n,"__wrapped__"),h=h&&tu.call(t,"__wrapped__");if(g||h)return rr(g?n.value():n,h?t.value():t,r,e,u,o);if(!s)return false;if(!f&&!p){switch(c){case pt:case ht:return+n==+t;case vt:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case mt:case dt:return n==Je(t)}return false}if(g=l?Ve:n.constructor,c=i?Ve:t.constructor,f){if(g.prototype.name!=c.prototype.name)return false}else if(p=!l&&tu.call(n,"constructor"),h=!i&&tu.call(t,"constructor"),p!=h||!p&&g!=c&&"constructor"in n&&"constructor"in t&&!(typeof g=="function"&&g instanceof g&&typeof c=="function"&&c instanceof c))return false; +if(g=f?["message","name"]:Pu(n),c=f?g:Pu(t),l&&g.push("length"),i&&c.push("length"),l=g.length,p=c.length,l!=p&&!e)return false}for(u||(u=[]),o||(o=[]),c=u.length;c--;)if(u[c]==n)return o[c]==t;if(u.push(n),o.push(t),i=true,a)for(;i&&++ce(a,p)&&((t||i)&&a.push(p),f.push(l))}return f}function pr(n,t){for(var r=-1,e=t(n),u=e.length,o=Be(u);++rt)return r; +var e=typeof arguments[2];if("number"!=e&&"string"!=e||!arguments[3]||arguments[3][arguments[2]]!==arguments[1]||(t=2),3r?ju(e+r,0):r||0;else if(r)return r=Mr(n,t),e&&n[r]===t?r:-1;return c(n,t,r)}function Lr(n){return Br(n,1)}function Br(n,t,r){var e=-1,u=n?n.length:0;if(t=null==t?0:+t||0,0>t&&(t=-t>u?0:u+t),r=typeof r=="undefined"||r>u?u:+r||0,0>r&&(r+=u),r&&r==u&&!t)return l(n);for(u=t>r?0:r-t,r=Be(u);++er?ju(e+r,0):r||0:0,typeof n=="string"||!Bu(n)&&Ae(n)?ru&&(u=i);else t=o&&i?p:Er(t,r,3),Kt(n,function(n,r,o){r=t(n,r,o),(r>e||-1/0===r&&r===u)&&(e=r,u=n) +});return u}function re(n,t){return ne(n,Le(t))}function ee(n,t,r,e){return(Bu(n)?u:ar)(n,Er(t,e,4),r,3>arguments.length,Kt)}function ue(n,t,r,e){return(Bu(n)?o:ar)(n,Er(t,e,4),r,3>arguments.length,Pt)}function oe(n){n=Ur(n);for(var t=-1,r=n.length,e=Be(r);++targuments.length)return Ar(n,F,null,t);var r=Br(arguments,2),e=w(r,ae.placeholder);return ir(n,F|S,r,e,t)}function ce(n,t){var r=F|R;if(2=r||r>t?(f&&au(f),r=p,f=s=p=I,r&&(h=Xu(),a=n.apply(l,i),s||f||(i=l=null))):s=gu(e,r)}function u(){s&&au(s),f=s=p=I,(v||g!==t)&&(h=Xu(),a=n.apply(l,i),s||f||(i=l=null))}function o(){if(i=arguments,c=Xu(),l=this,p=v&&(s||!y),false===g)var r=y&&!s;else{f||y||(h=c);var o=g-(c-h),m=0>=o||o>g;m?(f&&(f=au(f)),h=c,a=n.apply(l,i)):f||(f=gu(u,o))}return m&&s?s=au(s):s||t===g||(s=gu(e,t)),r&&(m=true,a=n.apply(l,i)),!m||s||f||(i=l=null),a}var i,f,a,c,l,s,p,h=0,g=false,v=true;if(!be(n))throw new Xe(N);if(t=0>t?0:t,true===r)var y=true,v=false; +else _e(r)&&(y=r.leading,g="maxWait"in r&&ju(+r.maxWait||0,t),v="trailing"in r?r.trailing:v);return o.cancel=function(){s&&au(s),f&&au(f),f=s=p=I},o}function he(){var n=arguments,r=n.length-1;if(0>r)return function(){};if(!t(n,be))throw new Xe(N);return function(){for(var t=r,e=n[t].apply(this,arguments);t--;)e=n[t].call(this,e);return e}}function ge(n){var t=Br(arguments,1),r=w(t,ge.placeholder);return ir(n,S,t,r)}function ve(n){var t=Br(arguments,1),r=w(t,ve.placeholder);return ir(n,T,t,r)}function ye(n){var t=n&&typeof n=="object"?n.length:I; +return typeof t=="number"&&-1>>0,e=n.constructor,u=-1,e=typeof e=="function"&&e.prototype==n,o=r-1,i=Be(r),f=0t||null==n||!wu(t))return r;n=Je(n);do t%2&&(r+=n),t=cu(t/2),n+=n;while(t);return r}function ke(n,t){return(n=null==n?"":Je(n))?null==t?n.slice(x(n),j(n)+1):(t=Je(t),n.slice(h(n,t),g(n,t)+1)):n}function Ce(n,t){return(n=null!=n&&Je(n))&&n.match(t||ft)||[]}function Se(n){try{return n() +}catch(t){return de(t)?t:ze(t)}}function Te(n,t){return $t(n,t)}function Ue(n){return n}function We(n){var t=Pu(n),r=t.length;if(1==r){var e=t[0],u=n[e];if(Dr(u))return function(n){return null!=n&&u===n[e]&&tu.call(n,e)}}for(var o=r,i=Be(r),f=Be(r);o--;){var u=n[t[o]],a=Dr(u);i[o]=a,f[o]=a?u:qt(u)}return function(n){if(o=r,null==n)return!o;for(;o--;)if(i[o]?f[o]!==n[t[o]]:!tu.call(n,t[o]))return false;for(o=r;o--;)if(i[o]?!tu.call(n,t[o]):!rr(f[o],n[t[o]],null,true))return false;return true}}function Ne(n,t,r){var e=true,u=_e(t),o=null==r,i=o&&u&&Pu(t),f=i&&tr(t,i); +(i&&i.length&&!f.length||o&&!u)&&(o&&(r=t),f=false,t=n,n=this),f||(f=tr(t,Pu(t))),false===r?e=false:_e(r)&&"chain"in r&&(e=r.chain),r=-1,u=be(n);for(o=f.length;++r=U)return r +}else n=0;return Cu(r,e)}}(),Wu=yr(function(n,t,r){tu.call(n,r)?++n[r]:n[r]=1}),Nu=yr(function(n,t,r){tu.call(n,r)?n[r].push(t):n[r]=[t]}),$u=yr(function(n,t,r){n[r]=t}),qu=yr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Lu=ge(fe,2),Bu=_u||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&eu.call(n)==st||false};ku.dom||(me=function(n){return n&&typeof n=="object"&&1===n.nodeType&&!zu(n)||false});var Mu=Iu||function(n){return typeof n=="number"&&wu(n)},zu=lu?function(n){if(!n||eu.call(n)!=yt)return false; +var t=n.valueOf,r=we(t)&&(r=lu(t))&&lu(r);return r?n==r||lu(n)==r:Sr(n)}:Sr,Ku=mr(Wt),Pu=xu?function(n){if(n)var t=n.constructor,r=n.length;return typeof t=="function"&&t.prototype===n||typeof r=="number"&&0--n?t.apply(this,arguments):void 0}},Ct.assign=Ku,Ct.at=function(n){var t=n?n.length:0;return typeof t=="number"&&-1t?0:t)},Ct.dropRight=function(n,t,r){var e=n?n.length:0;return t=e-((null==t||r?1:t)||0),Br(n,0,0>t?0:t)},Ct.dropRightWhile=function(n,t,r){var e=n?n.length:0; +for(t=Er(t,r,3);e--&&t(n[e],e,n););return Br(n,0,e+1)},Ct.dropWhile=function(n,t,r){var e=-1,u=n?n.length:0;for(t=Er(t,r,3);++e(p?s(p,i):u(l,i))){for(t=r;--t;){var h=e[t];if(0>(h?s(h,i):u(n[t],i)))continue n}p&&p.push(i),l.push(i)}return l},Ct.invert=function(n,t){for(var r=-1,e=Pu(n),u=e.length,o={};++rt?0:t) +},Ct.takeRight=function(n,t,r){var e=n?n.length:0;return t=e-((null==t||r?1:t)||0),Br(n,0>t?0:t)},Ct.takeRightWhile=function(n,t,r){var e=n?n.length:0;for(t=Er(t,r,3);e--&&t(n[e],e,n););return Br(n,e+1)},Ct.takeWhile=function(n,t,r){var e=-1,u=n?n.length:0;for(t=Er(t,r,3);++er?0:+r||0,e))-t.length,0<=r&&n.indexOf(t,r)==r},Ct.escape=function(n){return(n=null==n?"":Je(n))&&(V.lastIndex=0,V.test(n))?n.replace(V,d):n +},Ct.escapeRegExp=Re,Ct.every=Jr,Ct.find=Gr,Ct.findIndex=Nr,Ct.findKey=function(n,t,r){return t=Er(t,r,3),Yt(n,t,Qt,true)},Ct.findLast=function(n,t,r){return t=Er(t,r,3),Yt(n,t,Pt)},Ct.findLastIndex=function(n,t,r){var e=n?n.length:0;for(t=Er(t,r,3);e--;)if(t(n[e],e,n))return e;return-1},Ct.findLastKey=function(n,t,r){return t=Er(t,r,3),Yt(n,t,nr,true)},Ct.findWhere=function(n,t){return Gr(n,We(t))},Ct.first=$r,Ct.has=function(n,t){return n?tu.call(n,t):false},Ct.identity=Ue,Ct.indexOf=qr,Ct.isArguments=ye,Ct.isArray=Bu,Ct.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&eu.call(n)==pt||false +},Ct.isDate=function(n){return n&&typeof n=="object"&&eu.call(n)==ht||false},Ct.isElement=me,Ct.isEmpty=function(n){if(null==n)return true;var t=n.length;return typeof t=="number"&&-1r?ju(u+r,0):Au(r||0,u-1))+1;else if(r)return u=zr(n,t)-1,e&&n[u]===t?u:-1;for(r=t===t;u--;)if(e=n[u],r?e===t:e!==e)return u;return-1},Ct.max=te,Ct.min=function(n,t,r){var e=1/0,u=e,o=typeof t;"number"!=o&&"string"!=o||!r||r[t]!==n||(t=null); +var o=null==t,i=!(o&&Bu(n))&&Ae(n);if(o&&!i)for(r=-1,n=Ur(n),o=n.length;++rr?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Ct.template=function(n,t,r){var e=Ct.templateSettings;t=Ku({},r||t,e,Ut),n=Je(null==n?"":n),r=Ku({},t.imports,e.imports,Ut);var u,o,i=Pu(r),f=Oe(r),a=0;r=t.interpolate||et;var c="__p+='";if(r=Ye((t.escape||et).source+"|"+r.source+"|"+(r===X?G:et).source+"|"+(t.evaluate||et).source+"|$","g"),n.replace(r,function(t,r,e,i,f,l){return e||(e=i),c+=n.slice(a,l).replace(it,b),r&&(u=true,c+="'+__e("+r+")+'"),f&&(o=true,c+="';"+f+";\n__p+='"),e&&(c+="'+((__t=("+e+"))==null?'':__t)+'"),a=l+t.length,t +}),c+="';",(t=t.variable)||(c="with(obj){"+c+"}"),c=(o?c.replace(z,""):c).replace(K,"$1").replace(P,"$1;"),c="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+c+"return __p}",t=Se(function(){return Ke(i,"return "+c).apply(I,f)}),t.source=c,de(t))throw t;return t},Ct.trim=ke,Ct.trimLeft=function(n,t){return(n=null==n?"":Je(n))?null==t?n.slice(x(n)):(t=Je(t),n.slice(h(n,t))):n +},Ct.trimRight=function(n,t){return(n=null==n?"":Je(n))?null==t?n.slice(0,j(n)+1):(t=Je(t),n.slice(0,g(n,t)+1)):n},Ct.trunc=function(n,t){var r=30,e="...";if(_e(t))var u="separator"in t?t.separator:u,r="length"in t?+t.length||0:r,e="omission"in t?Je(t.omission):e;else null!=t&&(r=+t||0);if(n=null==n?"":Je(n),r>=n.length)return n;var o=r-e.length;if(1>o)return e;if(r=n.slice(0,o),null==u)return r+e;if(je(u)){if(n.slice(o).search(u)){var i,f,a=n.slice(0,o);for(u.global||(u=Ye(u.source,(H.exec(u)||"")+"g")),u.lastIndex=0;i=u.exec(a);)f=i.index; +r=r.slice(0,null==f?o:f)}}else n.indexOf(u,o)!=o&&(u=r.lastIndexOf(u),-1t?0:+t||0,n.length),n) +},Ct.prototype.sample=function(n,t){return n=t?null:n,this.__chain__||null!=n?this.thru(function(t){return Ct.sample(t,n)}):Ct.sample(this.value())},Ct.VERSION=O,St.prototype=Ct.prototype,Ct.prototype.chain=function(){return Vr(this)},Ct.prototype.toString=function(){return Je(this.value())},Ct.prototype.toJSON=Ct.prototype.value=Ct.prototype.valueOf=function(){for(var n=-1,t=this.__queue__,r=t.length,e=this.__wrapped__;++n"'`]/g,Y=/<%-([\s\S]+?)%>/g,J=/<%([\s\S]+?)%>/g,X=/<%=([\s\S]+?)%>/g,G=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,H=/\w*$/,Q=/^\s*function[ \n\r\t]+\w/,nt=/^0[xX]/,tt=/^\[object .+?Constructor\]$/,rt=/[\xC0-\xFF]/g,et=/($^)/,ut=/[.*+?^${}()|[\]\/\\]/g,ot=/\bthis\b/,it=/['\n\r\u2028\u2029\\]/g,ft=RegExp("[A-Z\\xC0-\\xD6\\xD8-\\xDE]{2,}(?=[A-Z\\xC0-\\xD6\\xD8-\\xDE][a-z\\xDF-\\xF6\\xF8-\\xFF]+[0-9]*)|[A-Z\\xC0-\\xD6\\xD8-\\xDE]?[a-z\\xDF-\\xF6\\xF8-\\xFF]+[0-9]*|[A-Z\\xC0-\\xD6\\xD8-\\xDE]+|[0-9]+","g"),at=" \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",ct="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window WinRTError".split(" "),lt="[object Arguments]",st="[object Array]",pt="[object Boolean]",ht="[object Date]",gt="[object Error]",vt="[object Number]",yt="[object Object]",mt="[object RegExp]",dt="[object String]",bt="[object ArrayBuffer]",_t="[object Float32Array]",wt="[object Float64Array]",xt="[object Int8Array]",jt="[object Int16Array]",At="[object Int32Array]",Et="[object Uint8Array]",It="[object Uint8ClampedArray]",Ot="[object Uint16Array]",Ft="[object Uint32Array]",Rt={}; +Rt[lt]=Rt[st]=Rt[_t]=Rt[wt]=Rt[xt]=Rt[jt]=Rt[At]=Rt[Et]=Rt[It]=Rt[Ot]=Rt[Ft]=true,Rt[bt]=Rt[pt]=Rt[ht]=Rt[gt]=Rt["[object Function]"]=Rt["[object Map]"]=Rt[vt]=Rt[yt]=Rt[mt]=Rt["[object Set]"]=Rt[dt]=Rt["[object WeakMap]"]=false;var Dt={};Dt[lt]=Dt[st]=Dt[bt]=Dt[pt]=Dt[ht]=Dt[_t]=Dt[wt]=Dt[xt]=Dt[jt]=Dt[At]=Dt[vt]=Dt[yt]=Dt[mt]=Dt[dt]=Dt[Et]=Dt[It]=Dt[Ot]=Dt[Ft]=true,Dt[gt]=Dt["[object Function]"]=Dt["[object Map]"]=Dt["[object Set]"]=Dt["[object WeakMap]"]=false;var kt={leading:false,maxWait:0,trailing:false},Ct={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},St={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Tt={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\xd7":" ","\xf7":" "},Ut={"function":true,object:true},Wt={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Nt=Ut[typeof window]&&window||this,$t=Ut[typeof exports]&&exports&&!exports.nodeType&&exports,Ut=Ut[typeof module]&&module&&!module.nodeType&&module,qt=$t&&Ut&&typeof global=="object"&&global; +!qt||qt.global!==qt&&qt.window!==qt&&qt.self!==qt||(Nt=qt);var qt=Ut&&Ut.exports===$t&&$t,Lt=E();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Nt._=Lt, define(function(){return Lt})):$t&&Ut?qt?(Ut.exports=Lt)._=Lt:$t._=Lt:Nt._=Lt}).call(this); \ No newline at end of file diff --git a/dist/lodash.underscore.js b/dist/lodash.underscore.js index 9b4a725aa..dfc1a1b4d 100644 --- a/dist/lodash.underscore.js +++ b/dist/lodash.underscore.js @@ -29,8 +29,9 @@ /** Used as the TypeError message for "Functions" methods */ var FUNC_ERROR_TEXT = 'Expected a function'; - /** Used as a reference for the max length of an array */ - var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1; + /** Used as references for the max length and index of an array */ + var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; /** * Used as the maximum length of an array-like value. @@ -112,7 +113,7 @@ arrayLikeClasses[stringClass] = arrayLikeClasses[weakMapClass] = false; /** - * Used to convert characters to HTML entities. + * Used to map characters to HTML entities. * * **Note:** Though the ">" character is escaped for symmetry, characters like * ">" and "/" don't require escaping in HTML and have no special meaning @@ -134,7 +135,7 @@ '`': '`' }; - /** Used to convert HTML entities to characters */ + /** Used to map HTML entities to characters */ var htmlUnescapes = { '&': '&', '<': '<', @@ -180,320 +181,6 @@ /*--------------------------------------------------------------------------*/ - /** - * The base implementation of `compareAscending` which compares values and - * sorts them in ascending order without guaranteeing a stable sort. - * - * @private - * @param {*} value The value to compare to `other`. - * @param {*} other The value to compare to `value`. - * @returns {number} Returns the sort order indicator for `value`. - */ - function baseCompareAscending(value, other) { - if (value !== other) { - if (value > other || typeof value == 'undefined') { - return 1; - } - if (value < other || typeof other == 'undefined') { - return -1; - } - } - return 0; - } - - /** - * The base implementation of `_.indexOf` without support for binary searches. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0; - - while (++index < length) { - var other = array[index]; - if (other === value) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.slice` without support for `start` and `end` - * arguments. - * - * @private - * @param {Array} array The array to slice. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array) { - var index = -1, - length = array ? array.length : 0, - result = Array(length); - - while (++index < length) { - result[index] = array[index]; - } - return result; - } - - /** - * Used by `_.sortBy` to compare transformed elements of `collection` and stable - * sort them in ascending order. - * - * @private - * @param {Object} object The object to compare to `other`. - * @param {Object} other The object to compare to `object`. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareAscending(object, other) { - return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); - } - - /** - * Used by `_.escape` to convert characters to HTML entities. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(chr) { - return htmlEscapes[chr]; - } - - /** - * Used by `_.template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(chr) { - return '\\' + stringEscapes[chr]; - } - - /** - * Used by `_.unescape` to convert HTML entities to characters. - * - * @private - * @param {string} chr The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(chr) { - return htmlUnescapes[chr]; - } - - /*--------------------------------------------------------------------------*/ - - /** Used for native method references */ - var arrayProto = Array.prototype, - objectProto = Object.prototype; - - /** Used to resolve the decompiled source of functions */ - var fnToString = Function.prototype.toString; - - /** Used to check objects for own properties */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to restore the original `_` reference in `_.noConflict` */ - var oldDash = root._; - - /** Used to resolve the internal `[[Class]]` of values */ - var toString = objectProto.toString; - - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - escapeRegExp(toString) - .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** Native method references */ - var ceil = Math.ceil, - floor = Math.floor, - push = arrayProto.push, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - splice = arrayProto.splice; - - /* Native method references for those with the same name as other `lodash` methods */ - var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = root.isFinite, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeNow = isNative(nativeNow = Date.now) && nativeNow, - nativeRandom = Math.random; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps the given value to enable intuitive - * method chaining. - * - * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` - * - * Chaining is supported in custom builds as long as the `value` method is - * implicitly or explicitly included in the build. - * - * The chainable wrapper functions are: - * `after`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, `callback`, - * `chain`, `chunk`, `compact`, `concat`, `constant`, `countBy`, `create`, - * `curry`, `debounce`, `defaults`, `defer`, `delay`, `difference`, `drop`, - * `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, `flatten`, `flattenDeep`, - * `flow`, `flowRight`, `forEach`, `forEachRight`, `forIn`, `forInRight`, - * `forOwn`, `forOwnRight`, `functions`, `groupBy`, `indexBy`, `initial`, - * `intersection`, `invert`, `invoke`, `keys`, `keysIn`, `map`, `mapValues`, - * `matches`, `memoize`, `merge`, `mixin`, `negate`, `noop`, `omit`, `once`, - * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `pluck`, `property`, - * `pull`, `pullAt`, `push`, `range`, `reject`, `remove`, `rest`, `reverse`, - * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `take`, `takeRight`, - * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `times`, `toArray`, - * `transform`, `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, - * `where`, `without`, `wrap`, `xor`, `zip`, and `zipObject` - * - * The non-chainable wrapper functions are: - * `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `contains`, - * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, - * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, - * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, isDate`, - * `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`, `isFunction`, - * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, - * `isRegExp`, `isString`, `isUndefined`, `join`, `kebabCase`, `last`, - * `lastIndexOf`, `max`, `min`, `noConflict`, `now`, `pad`, `padLeft`, - * `padRight`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, - * `result`, `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, - * `sortedLastIndex`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, - * `trunc`, `unescape`, `uniqueId`, and `value` - * - * The wrapper function `sample` will return a wrapped value when `n` is - * provided, otherwise it will return an unwrapped value. - * - * Explicit chaining can be enabled by using the `_.chain` method. - * - * @name _ - * @constructor - * @category Chain - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(sum, n) { return sum + n; }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(n) { return n * n; }); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - return (value instanceof lodash) - ? value - : new lodashWrapper(value); - } - - /** - * A fast path for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap in a `lodash` instance. - * @param {boolean} [chainAll=false] Enable chaining for all methods. - * @returns {Object} Returns a `lodash` instance. - */ - function lodashWrapper(value, chainAll) { - this.__chain__ = !!chainAll; - this.__wrapped__ = value; - } - - /** - * An object environment feature flags. - * - * @static - * @memberOf _ - * @type Object - */ - var support = {}; - - (function(x) { - var object = { '0': 1, 'length': 1 }; - - /** - * Detect if `Array#shift` and `Array#splice` augment array-like objects - * correctly. - * - * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` - * and `splice()` functions that fail to remove the last element, `value[0]`, - * of array-like objects even though the `length` property is set to `0`. - * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` - * is buggy regardless of mode in IE < 9 and buggy in compatibility mode - * in IE 9. - * - * @memberOf _.support - * @type boolean - */ - support.spliceObjects = (splice.call(object, 0, 1), !object[0]); - }(0, 0)); - - /** - * By default, the template delimiters used by Lo-Dash are similar to those - * in embedded Ruby (ERB). Change the following template settings to use - * alternative delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': reEscape, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': reEvaluate, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '' - }; - - /*------------------------------------------------------------------------*/ - /** * A specialized version of `_.forEach` for arrays without support for * callback shorthands or `this` binding. @@ -652,6 +339,376 @@ return false; } + /** + * The base implementation of `compareAscending` which compares values and + * sorts them in ascending order without guaranteeing a stable sort. + * + * @private + * @param {*} value The value to compare to `other`. + * @param {*} other The value to compare to `value`. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsReflexive = value === value, + othIsReflexive = other === other; + + if (value > other || !valIsReflexive || (typeof value == 'undefined' && othIsReflexive)) { + return 1; + } + if (value < other || !othIsReflexive || (typeof other == 'undefined' && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * The base implementation of `_.indexOf` without support for binary searches. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + var other = array[index]; + if (other === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.slice` without support for `start` and `end` + * arguments. + * + * @private + * @param {Array} array The array to slice. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array) { + var index = -1, + length = array ? array.length : 0, + result = Array(length); + + while (++index < length) { + result[index] = array[index]; + } + return result; + } + + /** + * Used by `_.sortBy` to compare transformed elements of `collection` and stable + * sort them in ascending order. + * + * @private + * @param {Object} object The object to compare to `other`. + * @param {Object} other The object to compare to `object`. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareAscending(object, other) { + return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } + + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } + + /*--------------------------------------------------------------------------*/ + + /** Used for native method references */ + var arrayProto = Array.prototype, + objectProto = Object.prototype; + + /** Used to resolve the decompiled source of functions */ + var fnToString = Function.prototype.toString; + + /** Used to check objects for own properties */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to restore the original `_` reference in `_.noConflict` */ + var oldDash = root._; + + /** Used to resolve the internal `[[Class]]` of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + escapeRegExp(toString) + .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Native method references */ + var ceil = Math.ceil, + floor = Math.floor, + push = arrayProto.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Native method references for those with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = root.isFinite, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = isNative(nativeNow = Date.now) && nativeNow, + nativeRandom = Math.random; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, `callback`, + * `chain`, `chunk`, `compact`, `concat`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defer`, `delay`, `difference`, `drop`, + * `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, `flatten`, `flattenDeep`, + * `flow`, `flowRight`, `forEach`, `forEachRight`, `forIn`, `forInRight`, + * `forOwn`, `forOwnRight`, `functions`, `groupBy`, `indexBy`, `initial`, + * `intersection`, `invert`, `invoke`, `keys`, `keysIn`, `map`, `mapValues`, + * `matches`, `memoize`, `merge`, `mixin`, `negate`, `noop`, `omit`, `once`, + * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `pluck`, `property`, + * `pull`, `pullAt`, `push`, `range`, `reject`, `remove`, `rest`, `reverse`, + * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `take`, `takeRight`, + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `times`, + * `toArray`, `transform`, `union`, `uniq`, `unshift`, `unzip`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, and `zipObject` + * + * The non-chainable wrapper functions are: + * `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `contains`, + * `deburr`, endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `has`, `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, isDate`, + * `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`, `isFunction`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `join`, `kebabCase`, `last`, + * `lastIndexOf`, `max`, `min`, `noConflict`, `now`, `pad`, `padLeft`, + * `padRight`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, + * `result`, `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, + * `sortedLastIndex`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, + * `trunc`, `unescape`, `uniqueId`, `value`, and `words` + * + * The wrapper function `sample` will return a wrapped value when `n` is + * provided, otherwise it will return an unwrapped value. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, n) { return sum + n; }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { return n * n; }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + return (value instanceof lodash) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} [chainAll=false] Enable chaining for all methods. + * @param {Array} [queue=[]] Actions to peform to resolve the unwrapped value. + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = {}; + + (function(x) { + var object = { '0': 1, 'length': 1 }; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects + * correctly. + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode + * in IE 9. + * + * @memberOf _.support + * @type boolean + */ + support.spliceObjects = (splice.call(object, 0, 1), !object[0]); + }(0, 0)); + + /** + * By default, the template delimiters used by Lo-Dash are similar to those + * in embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '' + }; + + /*------------------------------------------------------------------------*/ + /** * The base implementation of `_.assign` without support for argument juggling, * multiple sources, and `this` binding. @@ -770,7 +827,7 @@ * * @private * @param {Array} array The array to inspect. - * @param {Array} [values] The array of values to exclude. + * @param {Array} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. */ function baseDifference(array, values) { @@ -806,7 +863,7 @@ return baseForOwn(collection, iteratee); } var index = -1, - iterable = toIterable(collection); + iterable = toObject(collection); while (++index < length) { if (iteratee(iterable[index], index, iterable) === BREAK_INDICATOR) { @@ -830,7 +887,7 @@ if (!(typeof length == 'number' && length > -1 && length <= MAX_SAFE_INTEGER)) { return baseForOwnRight(collection, iteratee); } - var iterable = toIterable(collection); + var iterable = toObject(collection); while (length--) { if (iteratee(iterable[length], length, iterable) === BREAK_INDICATOR) { break; @@ -958,12 +1015,13 @@ */ function baseFor(object, iteratee, keysFunc) { var index = -1, + iterable = toObject(object), props = keysFunc(object), length = props.length; while (++index < length) { var key = props[index]; - if (iteratee(object[key], key, object) === BREAK_INDICATOR) { + if (iteratee(iterable[key], key, iterable) === BREAK_INDICATOR) { break; } } @@ -981,12 +1039,13 @@ * @returns {Object} Returns `object`. */ function baseForRight(object, iteratee, keysFunc) { - var props = keysFunc(object), + var iterable = toObject(object), + props = keysFunc(object), length = props.length; while (length--) { var key = props[length]; - if (iteratee(object[key], key, object) === BREAK_INDICATOR) { + if (iteratee(iterable[key], key, iterable) === BREAK_INDICATOR) { break; } } @@ -1121,10 +1180,9 @@ var valCtor = value.constructor, othCtor = other.constructor; - if (valCtor != othCtor && - !(isFunction(valCtor) && valCtor instanceof valCtor && isFunction(othCtor) && othCtor instanceof othCtor) && - ('constructor' in value && 'constructor' in other) - ) { + if (valCtor != othCtor && ('constructor' in value && 'constructor' in other) && + !(typeof valCtor == 'function' && valCtor instanceof valCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { return false; } } @@ -1228,7 +1286,7 @@ * @private * @param {Function} func The function to partially apply arguments to. * @param {number} bitmask The bitmask of flags to compose. - * @param {Array} args The array of arguments to be partially applied. + * @param {Array} args The arguments to be partially applied. * @param {*} [thisArg] The `this` binding of `func`. * @returns {Function} Returns the new partially applied function. */ @@ -1317,17 +1375,21 @@ high = array ? array.length : low; value = iteratee(value); - var hintNum = typeof value == 'number' || - (value != null && isFunction(value.valueOf) && typeof value.valueOf() == 'number'); + + var valIsNaN = value !== value, + valIsUndef = typeof value == 'undefined'; while (low < high) { - var mid = (low + high) >>> 1, + var mid = floor((low + high) / 2), computed = iteratee(array[mid]), - setLow = retHighest ? (computed <= value) : (computed < value); + isReflexive = computed === computed; - if (hintNum && typeof computed != 'undefined') { - computed = +computed; - setLow = computed != computed || setLow; + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || typeof computed != 'undefined'); + } else { + setLow = retHighest ? (computed <= value) : (computed < value); } if (setLow) { low = mid + 1; @@ -1335,7 +1397,7 @@ high = mid; } } - return high; + return nativeMin(high, MAX_ARRAY_INDEX); } /** @@ -1395,8 +1457,8 @@ * placeholders, and provided arguments into a single array of arguments. * * @private - * @param {Array} partialArgs An array of arguments to prepend to those provided. - * @param {Array} partialHolders An array of `partialArgs` placeholder indexes. + * @param {Array} partialArgs The arguments to prepend to those provided. + * @param {Array} partialHolders The `partialArgs` placeholder indexes. * @param {Array|Object} args The provided arguments. * @returns {Array} Returns the new array of composed arguments. */ @@ -1434,9 +1496,9 @@ */ function createAggregator(setter, initializer) { return function(collection, iteratee, thisArg) { - var result = initializer ? initializer() : {}; iteratee = baseCallback(iteratee, thisArg, 3); + var result = initializer ? initializer() : {}; if (isArray(collection)) { var index = -1, length = collection.length; @@ -1500,10 +1562,10 @@ * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. * @param {number} arity The arity of `func`. * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partialArgs] An array of arguments to prepend to those provided to the new function. - * @param {Array} [partialHolders] An array of `partialArgs` placeholder indexes. - * @param {Array} [partialRightArgs] An array of arguments to append to those provided to the new function. - * @param {Array} [partialRightHolders] An array of `partialRightArgs` placeholder indexes. + * @param {Array} [partialArgs] The arguments to prepend to those provided to the new function. + * @param {Array} [partialHolders] The `partialArgs` placeholder indexes. + * @param {Array} [partialRightArgs] The arguments to append to those provided to the new function. + * @param {Array} [partialRightHolders] The `partialRightArgs` placeholder indexes. * @returns {Function} Returns the new function. */ function createHybridWrapper(func, bitmask, arity, thisArg, partialArgs, partialHolders, partialRightArgs, partialRightHolders) { @@ -1541,7 +1603,7 @@ * @private * @param {Function} func The function to partially apply arguments to. * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. - * @param {Array} partialArgs An array of arguments to prepend to those provided to the new function. + * @param {Array} partialArgs The arguments to prepend to those provided to the new function. * @param {*} [thisArg] The `this` binding of `func`. * @returns {Function} Returns the new bound function. */ @@ -1586,10 +1648,10 @@ * 64 - `_.partialRight` * @param {number} arity The arity of `func`. * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partialArgs] An array of arguments to prepend to those provided to the new function. - * @param {Array} [partialHolders] An array of `partialArgs` placeholder indexes. - * @param {Array} [partialRightArgs] An array of arguments to append to those provided to the new function. - * @param {Array} [partialRightHolders] An array of `partialRightArgs` placeholder indexes. + * @param {Array} [partialArgs] The arguments to prepend to those provided to the new function. + * @param {Array} [partialHolders] The `partialArgs` placeholder indexes. + * @param {Array} [partialRightArgs] The arguments to append to those provided to the new function. + * @param {Array} [partialRightHolders] The `partialRightArgs` placeholder indexes. * @returns {Function} Returns the new function. */ function createWrapper(func, bitmask, arity, thisArg, partialArgs, partialHolders, partialRightArgs, partialRightHolders) { @@ -1641,6 +1703,8 @@ * @returns {Object} Returns the new object. */ function pickByArray(object, props) { + object = toObject(object); + var index = -1, length = props.length, result = {}; @@ -1674,30 +1738,6 @@ return result; } - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - if (array[index] === placeholder) { - array[index] = PLACEHOLDER; - result[++resIndex] = index; - } - } - return result; - } - /** * A fallback implementation of `Object.keys` which creates an array of the * own enumerable property names of `object`. @@ -1721,34 +1761,6 @@ return result; } - /** - * An implementation of `_.uniq` optimized for sorted arrays without support - * for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. - */ - function sortedUniq(array, iteratee) { - var seen, - index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; - - if (!index || seen !== computed) { - seen = computed; - result[++resIndex] = value; - } - } - return result; - } - /** * Converts `value` to an array-like object if it is not one. * @@ -1764,8 +1776,7 @@ if (!(typeof length == 'number' && length > -1 && length <= MAX_SAFE_INTEGER)) { return values(value); } - value = toObject(value); - return value; + return isObject(value) ? value : Object(value); } /** @@ -1891,23 +1902,23 @@ * @returns {number} Returns the index of the found element, else `-1`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true }, + * { 'user': 'pebbles', 'age': 1 } * ]; * - * _.findIndex(characters, function(chr) { + * _.findIndex(users, function(chr) { * return chr.age < 20; * }); * // => 2 * * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); + * _.findIndex(users, { 'age': 36 }); * // => 0 * * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); + * _.findIndex(users, 'blocked'); * // => 1 */ function findIndex(array, predicate, thisArg) { @@ -2478,8 +2489,8 @@ * @memberOf _ * @alias object * @category Array - * @param {Array} props The array of property names. - * @param {Array} [vals=[]] The array of property values. + * @param {Array} props The property names. + * @param {Array} [vals=[]] The property values. * @returns {Object} Returns the new object. * @example * @@ -2518,15 +2529,15 @@ * @returns {Object} Returns the new wrapper object. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } * ]; * - * var youngest = _.chain(characters) + * var youngest = _.chain(users) * .sortBy('age') - * .map(function(chr) { return chr.name + ' is ' + chr.age; }) + * .map(function(chr) { return chr.user + ' is ' + chr.age; }) * .first() * .value(); * // => 'pebbles is 1' @@ -2552,11 +2563,11 @@ * @returns {*} Returns `value`. * @example * - * _([1, 2, 3, 4]) + * _([1, 2, 3]) * .tap(function(array) { array.pop(); }) * .reverse() * .value(); - * // => [3, 2, 1] + * // => [2, 1] */ function tap(value, interceptor) { interceptor(value); @@ -2572,35 +2583,34 @@ * @returns {*} Returns the wrapper object. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // without explicit chaining - * _(characters).first(); - * // => { 'name': 'barney', 'age': 36 } + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } * * // with explicit chaining - * _(characters).chain() + * _(users).chain() * .first() * .pick('age') * .value(); * // => { 'age': 36 } */ function wrapperChain() { - this.__chain__ = true; - return this; + return chain(this); } /** - * Extracts the wrapped value. + * Extracts the unwrapped value from its wrapper. * * @name valueOf * @memberOf _ * @alias toJSON, value * @category Chain - * @returns {*} Returns the wrapped value. + * @returns {*} Returns the unwrapped value. * @example * * _([1, 2, 3]).valueOf(); @@ -2637,7 +2647,7 @@ * _.contains([1, 2, 3], 1, 2); * // => false * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * _.contains({ 'user': 'fred', 'age': 40 }, 'fred'); * // => true * * _.contains('pebbles', 'eb'); @@ -2718,17 +2728,17 @@ * _.every([true, 1, null, 'yes']); * // => false * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); + * _.every(users, 'age'); * // => true * * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); + * _.every(users, { 'age': 36 }); * // => false */ function every(collection, predicate, thisArg) { @@ -2766,18 +2776,18 @@ * var evens = _.filter([1, 2, 3, 4], function(n) { return n % 2 == 0; }); * // => [2, 4] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * _.filter(users, 'blocked'); + * // => [{ 'user': 'fred', 'age': 40, 'blocked': true }] * * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36 }] + * _.filter(users, { 'age': 36 }); + * // => [{ 'user': 'barney', 'age': 36 }] */ function filter(collection, predicate, thisArg) { var func = isArray(collection) ? arrayFilter : baseFilter; @@ -2810,24 +2820,24 @@ * @returns {*} Returns the matched element, else `undefined`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true }, + * { 'user': 'pebbles', 'age': 1 } * ]; * - * _.find(characters, function(chr) { + * _.find(users, function(chr) { * return chr.age < 40; * }); - * // => { 'name': 'barney', 'age': 36 } + * // => { 'user': 'barney', 'age': 36 } * * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1 } + * _.find(users, { 'age': 1 }); + * // => { 'user': 'pebbles', 'age': 1 } * * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } + * _.find(users, 'blocked'); + * // => { 'user': 'fred', 'age': 40, 'blocked': true } */ function find(collection, predicate, thisArg) { if (isArray(collection)) { @@ -2851,16 +2861,16 @@ * @returns {*} Returns the matched element, else `undefined`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'employer': 'slate' }, - * { 'name': 'fred', 'age': 40, 'employer': 'slate' } + * var users = [ + * { 'user': 'barney', 'age': 36, 'employer': 'slate' }, + * { 'user': 'fred', 'age': 40, 'employer': 'slate' } * ]; * - * _.findWhere(characters, { 'employer': 'slate' }); - * // => { 'name': 'barney', 'age': 36, 'employer': 'slate' } + * _.findWhere(users, { 'employer': 'slate' }); + * // => { 'user': 'barney', 'age': 36, 'employer': 'slate' } * - * _.findWhere(characters, { 'age': 40 }); - * // => { 'name': 'fred', 'age': 40, 'employer': 'slate' } + * _.findWhere(users, { 'age': 40 }); + * // => { 'user': 'fred', 'age': 40, 'employer': 'slate' } */ function findWhere(collection, source) { return find(collection, matches(source)); @@ -2887,10 +2897,10 @@ * @example * * _([1, 2, 3]).forEach(function(n) { console.log(n); }); - * // => logs each value and returns the array + * // => logs each value from left to right and returns the array * * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(n, key) { console.log(n, key); }); - * // => logs each value-key pair and returns the object (property order is not guaranteed) + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) */ function forEach(collection, iteratee, thisArg) { return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) @@ -3038,15 +3048,15 @@ * // => [3, 6, 9] * * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(n) { return n * 3; }); - * // => [3, 6, 9] (property order is not guaranteed) + * // => [3, 6, 9] (iteration order is not guaranteed) * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); + * _.map(users, 'user'); * // => ['barney', 'fred'] */ function map(collection, iteratee, thisArg) { @@ -3087,17 +3097,17 @@ * _.max([]); * // => -Infinity * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; + * _.max(users, function(chr) { return chr.age; }); + * // => { 'user': 'fred', 'age': 40 }; * * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; + * _.max(users, 'age'); + * // => { 'user': 'fred', 'age': 40 }; */ function max(collection, iteratee, thisArg) { var computed = -Infinity, @@ -3165,17 +3175,17 @@ * _.min([]); * // => Infinity * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; + * _.min(users, function(chr) { return chr.age; }); + * // => { 'user': 'barney', 'age': 36 }; * * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; + * _.min(users, 'age'); + * // => { 'user': 'barney', 'age': 36 }; */ function min(collection, iteratee, thisArg) { var computed = Infinity, @@ -3242,18 +3252,18 @@ * _.partition([1.2, 2.3, 3.4], function(n) { return this.floor(n) % 2; }, Math); * // => [[1, 3], [2]] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true }, + * { 'user': 'pebbles', 'age': 1 } * ]; * * // using "_.where" callback shorthand - * _.map(_.partition(characters, { 'age': 1 }), function(array) { return _.pluck(array, 'name'); }); + * _.map(_.partition(users, { 'age': 1 }), function(array) { return _.pluck(array, 'user'); }); * // => [['pebbles'], ['barney', 'fred']] * * // using "_.pluck" callback shorthand - * _.map(_.partition(characters, 'blocked'), function(array) { return _.pluck(array, 'name'); }); + * _.map(_.partition(users, 'blocked'), function(array) { return _.pluck(array, 'user'); }); * // => [['fred'], ['barney', 'pebbles']] */ var partition = createAggregator(function(result, value, key) { @@ -3271,13 +3281,17 @@ * @returns {Array} Returns the property values. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * _.pluck(characters, 'name'); + * _.pluck(users, 'user'); * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) */ function pluck(collection, key) { return map(collection, property(key)); @@ -3309,7 +3323,7 @@ * result[key] = n * 3; * return result; * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } (property order is not guaranteed) + * // => { 'a': 3, 'b': 6, 'c': 9 } (iteration order is not guaranteed) */ function reduce(collection, iteratee, accumulator, thisArg) { var func = isArray(collection) ? arrayReduce : baseReduce; @@ -3365,18 +3379,18 @@ * var odds = _.reject([1, 2, 3, 4], function(n) { return n % 2 == 0; }); * // => [1, 3] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36 }] + * _.reject(users, 'blocked'); + * // => [{ 'user': 'barney', 'age': 36 }] * * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * _.reject(users, { 'age': 36 }); + * // => [{ 'user': 'fred', 'age': 40, 'blocked': true }] */ function reject(collection, predicate, thisArg) { var func = isArray(collection) ? arrayFilter : baseFilter; @@ -3504,17 +3518,17 @@ * _.some([null, 0, 'yes', false], Boolean); * // => true * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40, 'blocked': true } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); + * _.some(users, 'blocked'); * // => true * * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); + * _.some(users, { 'age': 1 }); * // => false */ function some(collection, predicate, thisArg) { @@ -3559,19 +3573,19 @@ * _.sortBy([1, 2, 3], function(n) { return this.sin(n); }, Math); * // => [3, 1, 2] * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 26 }, + * { 'user': 'fred', 'age': 30 } * ]; * * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); + * _.map(_.sortBy(users, 'age'), _.values); * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] * * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * _.map(_.sortBy(users, ['user', 'age']), _.values); * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] */ function sortBy(collection, iteratee, thisArg) { @@ -3630,18 +3644,18 @@ * @returns {Array} Returns the new filtered array. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'employer': 'slate', 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'employer': 'slate', 'pets': ['baby puss', 'dino'] } + * var users = [ + * { 'user': 'barney', 'age': 36, 'employer': 'slate', 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'employer': 'slate', 'pets': ['baby puss', 'dino'] } * ]; * - * _.pluck(_.where(characters, { 'age': 36 }), 'name'); + * _.pluck(_.where(users, { 'age': 36 }), 'user'); * // => ['barney'] * - * _.pluck(_.where(characters, { 'pets': ['dino'] }), 'name'); + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); * // => ['fred'] * - * _.pluck(_.where(characters, { 'employer': 'slate' }), 'name'); + * _.pluck(_.where(users, { 'employer': 'slate' }), 'user'); * // => ['barney', 'fred'] */ function where(collection, source) { @@ -3671,7 +3685,7 @@ * _.forEach(saves, function(type) { * asyncSave({ 'type': type, 'complete': done }); * }); - * // => logs 'done saving!' after all saves have completed + * // => logs 'done saving!' after the two async saves have completed */ function after(n, func) { if (!isFunction(func)) { @@ -3692,19 +3706,20 @@ } /** - * Creates a function that invokes `func`, with the `this` binding and - * arguments of the created function, until it is called `n` times. + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. * * @static * @memberOf _ * @category Function - * @param {number} n The number of times `func` may be called. + * @param {number} n The number of calls at which `func` is no longer invoked. * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * jQuery('#add').on('click', _.before(5, addContactToList)); - * // => allows adding up to 5 contacts to the list + * // => allows adding up to 4 contacts to the list */ function before(n, func) { var result; @@ -3745,10 +3760,10 @@ * @example * * var func = function(greeting) { - * return greeting + ' ' + this.name; + * return greeting + ' ' + this.user; * }; * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func = _.bind(func, { 'user': 'fred' }, 'hi'); * func(); * // => 'hi fred' */ @@ -3793,15 +3808,15 @@ } /** - * Creates a function that delays the invocation of `func` until after `wait` - * milliseconds have elapsed since the last time it was invoked. The created - * function comes with a `cancel` method to cancel delayed invokes. Provide an - * options object to indicate that `func` should be invoked on the leading - * and/or trailing edge of the `wait` timeout. Subsequent calls to the - * debounced function return the result of the last `func` invocation. + * Creates a function that delays invoking `func` until after `wait` milliseconds + * have elapsed since the last time it was invoked. The created function comes + * with a `cancel` method to cancel delayed invocations. Provide an options + * object to indicate that `func` should be invoked on the leading and/or + * trailing edge of the `wait` timeout. Subsequent calls to the debounced + * function return the result of the last `func` invocation. * - * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked on - * the trailing edge of the timeout only if the the debounced function is + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is * invoked more than once during the `wait` timeout. * * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) @@ -3842,7 +3857,7 @@ * Object.observe(models.todo, todoChanges); * * Object.observe(models, function(changes) { - * if (_.find(changes, { 'name': 'todo', 'type': 'delete'})) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { * todoChanges.cancel(); * } * }, ['delete']); @@ -4192,8 +4207,8 @@ /** * Creates a function that only invokes `func` at most once per every `wait` * milliseconds. The created function comes with a `cancel` method to cancel - * delayed invokes. Provide an options object to indicate that `func` should - * be invoked on the leading and/or trailing edge of the `wait` timeout. + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. * Subsequent calls to the throttled function return the result of the last * `func` call. * @@ -4297,17 +4312,17 @@ * @returns {*} Returns the cloned value. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; + * var shallow = _.clone(users); + * shallow[0] === users[0]; * // => true * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; + * var deep = _.clone(users, true); + * deep[0] === users[0]; * // => false * * _.mixin({ @@ -4499,8 +4514,8 @@ * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * - * var object = { 'name': 'fred' }; - * var other = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; * * object == other; * // => false @@ -4816,15 +4831,15 @@ * @returns {Object} Returns the destination object. * @example * - * _.assign({ 'name': 'fred' }, { 'age': 40 }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'age': 40, 'employer': 'slate' } + * _.assign({ 'user': 'fred' }, { 'age': 40 }, { 'employer': 'slate' }); + * // => { 'user': 'fred', 'age': 40, 'employer': 'slate' } * * var defaults = _.partialRight(_.assign, function(value, other) { * return typeof value == 'undefined' ? other : value; * }); * - * defaults({ 'name': 'barney' }, { 'age': 36 }, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'age': 36, 'employer': 'slate' } + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred', 'employer': 'slate' }); + * // => { 'user': 'barney', 'age': 36, 'employer': 'slate' } */ function assign(object) { if (object == null) { @@ -4860,8 +4875,8 @@ * @returns {Object} Returns the destination object. * @example * - * _.defaults({ 'name': 'barney' }, { 'age': 36 }, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'age': 36, 'employer': 'slate' } + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred', 'employer': 'slate' }); + * // => { 'user': 'barney', 'age': 36, 'employer': 'slate' } */ function defaults(object) { if (object == null) { @@ -4980,7 +4995,7 @@ * Shape.prototype.z = 0; * * _.keys(new Shape); - * // => ['x', 'y'] (property order is not guaranteed) + * // => ['x', 'y'] (iteration order is not guaranteed) */ var keys = !nativeKeys ? shimKeys : function(object) { return isObject(object) ? nativeKeys(object) : []; @@ -5004,7 +5019,7 @@ * Shape.prototype.z = 0; * * _.keysIn(new Shape); - * // => ['x', 'y', 'z'] (property order is not guaranteed) + * // => ['x', 'y', 'z'] (iteration order is not guaranteed) */ function keysIn(object) { var result = []; @@ -5036,25 +5051,24 @@ * @returns {Object} Returns the new object. * @example * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } + * _.omit({ 'user': 'fred', 'age': 40 }, 'age'); + * // => { 'user': 'fred' } * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * _.omit({ 'user': 'fred', 'age': 40 }, function(value) { * return typeof value == 'number'; * }); - * // => { 'name': 'fred' } + * // => { 'user': 'fred' } */ function omit(object, predicate, thisArg) { if (object == null) { return {}; } - var iterable = toObject(object); if (typeof predicate != 'function') { var props = arrayMap(baseFlatten(arguments, false, false, 1), String); - return pickByArray(iterable, baseDifference(keysIn(iterable), props)); + return pickByArray(object, baseDifference(keysIn(object), props)); } predicate = baseCallback(predicate, thisArg, 3); - return pickByCallback(iterable, function(value, key, object) { + return pickByCallback(object, function(value, key, object) { return !predicate(value, key, object); }); } @@ -5071,7 +5085,7 @@ * @example * * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed) + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) */ function pairs(object) { var index = -1, @@ -5105,22 +5119,21 @@ * @returns {Object} Returns the new object. * @example * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } + * _.pick({ 'user': 'fred', '_userid': 'fred1' }, 'user'); + * // => { 'user': 'fred' } * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * _.pick({ 'user': 'fred', '_userid': 'fred1' }, function(value, key) { * return key.charAt(0) != '_'; * }); - * // => { 'name': 'fred' } + * // => { 'user': 'fred' } */ function pick(object, predicate, thisArg) { if (object == null) { return {}; } - var iterable = toObject(object); return typeof predicate == 'function' - ? pickByCallback(iterable, baseCallback(predicate, thisArg, 3)) - : pickByArray(iterable, baseFlatten(arguments, false, false, 1)); + ? pickByCallback(object, baseCallback(predicate, thisArg, 3)) + : pickByArray(object, baseFlatten(arguments, false, false, 1)); } /** @@ -5141,7 +5154,7 @@ * Shape.prototype.z = 0; * * _.values(new Shape(2, 1)); - * // => [2, 1] (property order is not guaranteed) + * // => [2, 1] (iteration order is not guaranteed) */ function values(object) { return baseValues(object, keys); @@ -5173,7 +5186,7 @@ function escape(string) { // reset `lastIndex` because in IE < 9 `String#replace` does not string = string == null ? '' : String(string); - return (reUnescapedHtml.lastIndex = 0, reUnescapedHtml.test(string)) + return string && (reUnescapedHtml.lastIndex = 0, reUnescapedHtml.test(string)) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string; } @@ -5189,12 +5202,12 @@ * @returns {string} Returns the escaped string. * @example * - * _.escapeRegExp('[lodash](http://lodash.com)'); - * // => '\[lodash\]\(http://lodash\.com\)' + * _.escapeRegExp('[lodash](http://lodash.com/)'); + * // => '\[lodash\]\(http://lodash\.com/\)' */ function escapeRegExp(string) { string = string == null ? '' : String(string); - return (reRegExpChars.lastIndex = 0, reRegExpChars.test(string)) + return string && (reRegExpChars.lastIndex = 0, reRegExpChars.test(string)) ? string.replace(reRegExpChars, '\\$&') : string; } @@ -5232,9 +5245,9 @@ * @example * * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'fred' }); - * // => 'hello fred' + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' * * // using the HTML "escape" delimiter to escape data property values * var compiled = _.template('<%- value %>'); @@ -5242,24 +5255,24 @@ * // => '<script>' * * // using the "evaluate" delimiter to execute JavaScript and generate HTML - * var compiled = _.template('<% _.forEach(people, function(name) { %>
  • <%- name %>
  • <% }); %>'); - * compiled({ 'people': ['fred', 'barney'] }); + * var compiled = _.template('<% _.forEach(users, function(user) { %>
  • <%- user %>
  • <% }); %>'); + * compiled({ 'users': ['fred', 'barney'] }); * // => '
  • fred
  • barney
  • ' * * // using the internal `print` function in "evaluate" delimiters - * var compiled = _.template('<% print("hello " + name); %>!'); - * compiled({ 'name': 'barney' }); + * var compiled = _.template('<% print("hello " + user); %>!'); + * compiled({ 'user': 'barney' }); * // => 'hello barney!' * * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter - * var compiled = _.template('hello ${ name }'); - * compiled({ 'name': 'pebbles' }); - * // => 'hello pebbles' + * var compiled = _.template('hello ${ user }!'); + * compiled({ 'user': 'pebbles' }); + * // => 'hello pebbles!' * * // using custom template delimiters * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; - * var compiled = _.template('hello {{ name }}!'); - * compiled({ 'name': 'mustache' }); + * var compiled = _.template('hello {{ user }}!'); + * compiled({ 'user': 'mustache' }); * // => 'hello mustache!' * * // using backslashes to treat delimiters as plain text @@ -5268,22 +5281,22 @@ * // => '<%- value %>' * * // using the `imports` option to import `jQuery` as `jq` - * var text = '<% jq.each(people, function(name) { %>
  • <%- name %>
  • <% }); %>'; + * var text = '<% jq.each(users, function(user) { %>
  • <%- user %>
  • <% }); %>'; * var compiled = _.template(text, { 'imports': { 'jq': jQuery } }); - * compiled({ 'people': ['fred', 'barney'] }); + * compiled({ 'users': ['fred', 'barney'] }); * // => '
  • fred
  • barney
  • ' * * // using the `sourceURL` option to specify a custom sourceURL for the template - * var compiled = _.template('hello <%= name %>', { 'sourceURL': '/basic/greeting.jst' }); + * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' }); * compiled(data); * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector * * // using the `variable` option to ensure a with-statement isn't used in the compiled template - * var compiled = _.template('hi <%= data.name %>!', { 'variable': 'data' }); + * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' }); * compiled.source; * // => function(data) { - * var __t, __p = '', __e = _.escape; - * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!'; + * var __t, __p = ''; + * __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; * return __p; * } * @@ -5363,12 +5376,12 @@ * @returns {string} Returns the unescaped string. * @example * - * _.unescape('fred, barney & pebbles'); - * // => 'fred, barney & pebbles' + * _.unescape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' */ function unescape(string) { string = string == null ? '' : String(string); - return (reEscapedHtml.lastIndex = 0, reEscapedHtml.test(string)) + return string && (reEscapedHtml.lastIndex = 0, reEscapedHtml.test(string)) ? string.replace(reEscapedHtml, unescapeHtmlChar) : string; } @@ -5418,9 +5431,9 @@ * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } * ]; * * // wrap to create custom callback shorthands @@ -5434,8 +5447,8 @@ * }; * }); * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] + * _.filter(users, 'age__gt38'); + * // => [{ 'user': 'fred', 'age': 40 }] */ function callback(func, thisArg) { return baseCallback(func, thisArg); @@ -5451,7 +5464,7 @@ * @returns {Function} Returns the new function. * @example * - * var object = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; * var getter = _.constant(object); * getter() === object; * // => true @@ -5472,7 +5485,7 @@ * @returns {*} Returns `value`. * @example * - * var object = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; * _.identity(object) === object; * // => true */ @@ -5492,18 +5505,18 @@ * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } + * var users = [ + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } * ]; * * var matchesAge = _.matches({ 'age': 36 }); * - * _.filter(characters, matchesAge); - * // => [{ 'name': 'barney', 'age': 36 }] + * _.filter(users, matchesAge); + * // => [{ 'user': 'barney', 'age': 36 }] * - * _.find(characters, matchesAge); - * // => { 'name': 'barney', 'age': 36 } + * _.find(users, matchesAge); + * // => { 'user': 'barney', 'age': 36 } */ function matches(source) { var keyVals = pairs(source), @@ -5577,9 +5590,7 @@ push.apply(args, arguments); var result = func.apply(lodash, args); - return this.__chain__ - ? new lodashWrapper(result, true) - : result; + return this.__chain__ ? new lodashWrapper(result, true) : result; }; }()); } @@ -5610,7 +5621,7 @@ * @category Utility * @example * - * var object = { 'name': 'fred' }; + * var object = { 'user': 'fred' }; * _.noop(object) === undefined; * // => true */ @@ -5645,18 +5656,18 @@ * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } + * var users = [ + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } * ]; * - * var getName = _.property('name'); + * var getName = _.property('user'); * - * _.map(characters, getName); + * _.map(users, getName); * // => ['barney', 'fred'] * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + * _.sortBy(users, getName); + * // => [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] */ function property(key) { return function(object) { @@ -5784,13 +5795,13 @@ * @example * * var object = { - * 'name': 'fred', + * 'user': 'fred', * 'age': function() { * return 40; * } * }; * - * _.result(object, 'name'); + * _.result(object, 'user'); * // => 'fred' * * _.result(object, 'age'); @@ -6024,34 +6035,25 @@ // assign default placeholders partial.placeholder = lodash; - // add `Array` mutator functions to the wrapper - arrayEach(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { - var func = arrayProto[methodName]; - lodash.prototype[methodName] = function() { - var value = this.__wrapped__; - func.apply(value, arguments); + // add `Array.prototype` functions + arrayEach(['concat', 'join', 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { + var func = arrayProto[methodName], + retValue = !/^(?:concat|join|slice)$/.test(methodName), + fixObjects = !support.spliceObjects && /^(?:pop|shift|splice)$/.test(methodName); - // avoid array-like object bugs with `Array#shift` and `Array#splice` - // in Firefox < 10 and IE < 9 - if (!support.spliceObjects && value.length === 0) { - delete value[0]; - } - return this; - }; - }); - - // add `Array` accessor functions to the wrapper - arrayEach(['concat', 'join', 'slice'], function(methodName) { - var func = arrayProto[methodName]; lodash.prototype[methodName] = function() { var value = this.__wrapped__, result = func.apply(value, arguments); - if (this.__chain__) { - result = new lodashWrapper(result); - result.__chain__ = true; + // avoid array-like object bugs with `Array#shift` and `Array#splice` in + // IE < 9, Firefox < 10, and RingoJS + if (fixObjects && value.length === 0) { + delete value[0]; } - return result; + if (retValue) { + result = value; + } + return this.__chain__ ? new lodashWrapper(result, true) : result; }; }); diff --git a/dist/lodash.underscore.min.js b/dist/lodash.underscore.min.js index 89ddbc85a..20d4c3883 100644 --- a/dist/lodash.underscore.min.js +++ b/dist/lodash.underscore.min.js @@ -3,43 +3,45 @@ * Lo-Dash 3.0.0-pre (Custom Build) lodash.com/license | Underscore.js 1.7.0 underscorejs.org/LICENSE * Build: `lodash underscore -o ./dist/lodash.underscore.js` */ -;(function(){function n(n,r,t){t=(t||0)-1;for(var e=n?n.length:0;++te||typeof t=="undefined"){t=1;break n}if(tu(r,i)&&o.push(i)}return o}function b(n,r){var t=n?n.length:0;if(typeof t!="number"||-1>=t||t>Rr)return x(n,r,Wt);for(var e=-1,u=V(n);++e=t||t>Rr){for(var t=Wt(n),e=t.length;e--;){var u=t[e];if(r(n[u],u,n)===Fr)break}return n}for(e=V(n);t--&&r(e[t],t,e)!==Fr;);return n}function d(n,r){var t=true;return b(n,function(n,e,u){return(t=!!r(n,e,u))||Fr -}),t}function j(n,r){var t=[];return b(n,function(n,e,u){r(n,e,u)&&t.push(n)}),t}function w(n,r,t){var e;return t(n,function(n,t,u){return r(n,t,u)?(e=n,Fr):void 0}),e}function A(n,r,t,e){e=(e||0)-1;for(var u=n.length,o=-1,i=[];++ee(i,a)&&(r&&i.push(a),o.push(f))}return o}function B(n,r){return function(t,e,u){var o=r?r():{};if(e=v(e,u,3),Ut(t)){u=-1; -for(var i=t.length;++ur?0:r) -}function H(r,t,e){var u=r?r.length:0;if(typeof e=="number")e=0>e?Et(u+e,0):e||0;else if(e)return e=L(r,t),u&&r[e]===t?e:-1;return n(r,t,e)}function J(n,r,t){return K(n,null==r||t?1:0>r?0:r)}function K(n,t,e){var u=-1,o=n?n.length:0;if(t=null==t?0:+t||0,0>t&&(t=-t>o?0:o+t),e=typeof e=="undefined"||e>o?o:+e||0,0>e&&(e+=o),e&&e==o&&!t)return r(n);for(o=t>e?0:e-t,e=Array(o);++u>>1,f=t(n[i]),a=fu&&(u=i)}else r=v(r,t,3),b(n,function(n,t,o){t=r(n,t,o),(t>e||-1/0===t&&t===u)&&(e=t,u=n)});return u}function ur(n,r){return tr(n,Sr(r))}function or(n,r,t,e){return(Ut(n)?s:F)(n,v(r,e,4),t,3>arguments.length,b)}function ir(n,r,t,e){return(Ut(n)?g:F)(n,v(r,e,4),t,3>arguments.length,_)}function fr(n){n=V(n);for(var r=-1,t=n.length,e=Array(t);++r=t||t>r?(f&&clearTimeout(f),t=s,f=p=s=Ir,t&&(g=Dt(),a=n.apply(l,i),p||f||(i=l=null))):p=setTimeout(e,t)}function u(){p&&clearTimeout(p),f=p=s=Ir,(v||h!==r)&&(g=Dt(),a=n.apply(l,i),p||f||(i=l=null))}function o(){if(i=arguments,c=Dt(),l=this,s=v&&(p||!y),false===h)var t=y&&!p;else{f||y||(g=c);var o=h-(c-g),m=0>=o||o>h; -m?(f&&(f=clearTimeout(f)),g=c,a=n.apply(l,i)):f||(f=setTimeout(u,o))}return m&&p?p=clearTimeout(p):p||r===h||(p=setTimeout(e,r)),t&&(m=true,a=n.apply(l,i)),!m||p||f||(i=l=null),a}var i,f,a,c,l,p,s,g=0,h=false,v=true;if(!hr(n))throw new TypeError($r);if(r=0>r?0:r,true===t)var y=true,v=false;else vr(t)&&(y=t.leading,h="maxWait"in t&&Et(+t.maxWait||0,r),v="trailing"in t?t.trailing:v);return o.cancel=function(){p&&clearTimeout(p),f&&clearTimeout(f),f=p=s=Ir},o}function pr(n){for(var r=K(arguments,1),t=r,e=pr.placeholder,u=-1,o=t.length,i=-1,f=[];++u"'`]/g,Cr=/^\[object .+?Constructor\]$/,Pr=/($^)/,Vr=/[.*+?^${}()|[\]\/\\]/g,Gr=/['\n\r\u2028\u2029\\]/g,Hr="[object Arguments]",Jr="[object Boolean]",Kr="[object Date]",Lr="[object Error]",Qr="[object Number]",Xr="[object Object]",Yr="[object RegExp]",Zr="[object String]",nt={}; -nt[Hr]=nt["[object Array]"]=nt["[object Float32Array]"]=nt["[object Float64Array]"]=nt["[object Int8Array]"]=nt["[object Int16Array]"]=nt["[object Int32Array]"]=nt["[object Uint8Array]"]=nt["[object Uint8ClampedArray]"]=nt["[object Uint16Array]"]=nt["[object Uint32Array]"]=true,nt["[object ArrayBuffer]"]=nt[Jr]=nt[Kr]=nt[Lr]=nt["[object Function]"]=nt["[object Map]"]=nt[Qr]=nt[Xr]=nt[Yr]=nt["[object Set]"]=nt[Zr]=nt["[object WeakMap]"]=false;var rt={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},tt={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},et={"function":true,object:true},ut={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},ot=et[typeof window]&&window||this,it=et[typeof exports]&&exports&&!exports.nodeType&&exports,ft=et[typeof module]&&module&&!module.nodeType&&module,at=it&&ft&&typeof global=="object"&&global; -!at||at.global!==at&&at.window!==at&&at.self!==at||(ot=at);var ct=ft&&ft.exports===it&&it,lt=Array.prototype,pt=Object.prototype,st=Function.prototype.toString,gt=pt.hasOwnProperty,ht=ot._,vt=pt.toString,yt=RegExp("^"+function(n){return n=null==n?"":n+"",Vr.lastIndex=0,Vr.test(n)?n.replace(Vr,"\\$&"):n}(vt).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),mt=Math.ceil,bt=Math.floor,_t=lt.push,dt=pt.propertyIsEnumerable,jt=lt.splice,wt=yr(wt=Object.create)&&wt,At=yr(At=Array.isArray)&&At,xt=ot.isFinite,Tt=yr(Tt=Object.keys)&&Tt,Et=Math.max,Ot=Math.min,kt=yr(kt=Date.now)&&kt,St=Math.random,It={}; -!function(){var n={0:1,length:1};It.spliceObjects=(jt.call(n,0,1),!n[0])}(0,0),i.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},wt||(y=function(){function n(){}return function(r){if(vr(r)){n.prototype=r;var t=new n;n.prototype=null}return t||ot.Object()}}());var Ft=J,Mt=G,qt=B(function(n,r,t){gt.call(n,t)?++n[t]:n[t]=1}),Bt=B(function(n,r,t){gt.call(n,t)?n[t].push(r):n[t]=[r]}),$t=B(function(n,r,t){n[t]=r}),Nt=B(function(n,r,t){n[t?0:1].push(r) -},function(){return[[],[]]}),Rt=pr(cr,2);sr(arguments)||(sr=function(n){var r=n&&typeof n=="object"?n.length:Ir;return typeof r=="number"&&-1--n?r.apply(this,arguments):void 0}},i.before=cr,i.bind=function(n,r){return 3>arguments.length?W(n,Mr,r):S(n,Mr|Br,K(arguments,2),[],r)},i.bindAll=function(n){for(var r=n,t=1r?0:r)},i.intersection=function(){for(var n=[],r=-1,t=arguments.length;++ri(a,e)){for(r=t;--r;)if(0>i(n[r],e))continue n;a.push(e)}return a},i.invert=function(n){for(var r=-1,t=Wt(n),e=t.length,u={};++ro?0:o>>>0);for(r=v(r,e,3),b(n,function(n,t,e){i[++u]={a:r(n,t,e),b:u,c:n}}),o=i.length,i.sort(t);o--;)i[o]=i[o].c;return i},i.take=Mt,i.tap=function(n,r){return r(n),n},i.throttle=function(n,r,t){var e=true,u=true;if(!hr(n))throw new TypeError(funcErrorText);return false===t?e=false:vr(t)&&(e="leading"in t?t.leading:e,u="trailing"in t?t.trailing:u),lr(n,r,{leading:e,maxWait:r,trailing:u}) -},i.times=function(n,r,t){n=xt(n=+n)&&-1r)return function(){};if(!c(n,hr))throw new TypeError($r);return function(){for(var t=r,e=n[t].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},i.each=rr,i.extend=_r,i.iteratee=function(n,r){return v(n,r)},i.methods=jr,i.object=function(n,r){var t=-1,e=n?n.length:0,u={};for(r||!e||Ut(n[0])||(r=[]);++tr?0:r)) -},i.lastIndexOf=function(n,r,t){var e=n?n.length:0;for(typeof t=="number"&&(e=(0>t?Et(e+t,0):Ot(t||0,e-1))+1);e--;)if(n[e]===r)return e;return-1},i.max=er,i.min=function(n,r,t){var e=1/0,u=e,o=typeof r;if("number"!=o&&"string"!=o||!t||t[r]!==n||(r=null),null==r)for(t=-1,n=V(n),o=n.length;++tr?0:+r||0,n.length),n) -},kr(_r({},i)),i.VERSION="3.0.0-pre",f.prototype=i.prototype,i.prototype.chain=function(){return this.__chain__=true,this},i.prototype.value=function(){return this.__wrapped__},pr.placeholder=i,a("pop push reverse shift sort splice unshift".split(" "),function(n){var r=lt[n];i.prototype[n]=function(){var n=this.__wrapped__;return r.apply(n,arguments),It.spliceObjects||0!==n.length||delete n[0],this}}),a(["concat","join","slice"],function(n){var r=lt[n];i.prototype[n]=function(){var n=r.apply(this.__wrapped__,arguments); -return this.__chain__&&(n=new f(n),n.__chain__=true),n}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(ot._=i, define("underscore",function(){return i})):it&&ft?ct?(ft.exports=i)._=i:it._=i:ot._=i}).call(this); \ No newline at end of file +;(function(){function n(n,r){for(var t=-1,e=n.length;++te||!u||typeof t=="undefined"&&o){t=1;break n}if(tu(r,i)&&o.push(i)}return o}function b(n,r){var t=n?n.length:0;if(typeof t!="number"||-1>=t||t>Dr)return x(n,r,Ct);for(var e=-1,u=G(n);++e=t||t>Dr){for(var t=G(n),e=Ct(n),u=e.length;u--;){var o=e[u];if(r(t[o],o,t)===$r)break}return n}for(e=G(n);t--&&r(e[t],t,e)!==$r;);return n +}function _(n,r){var t=true;return b(n,function(n,e,u){return(t=!!r(n,e,u))||$r}),t}function j(n,r){var t=[];return b(n,function(n,e,u){r(n,e,u)&&t.push(n)}),t}function w(n,r,t){var e;return t(n,function(n,t,u){return r(n,t,u)?(e=n,$r):void 0}),e}function A(n,r,t,e){e=(e||0)-1;for(var u=n.length,o=-1,i=[];++ee(i,a)&&(r&&i.push(a),o.push(f))}return o}function q(n,r){return function(t,e,u){e=v(e,u,3);var o=r?r():{};if(zt(t)){u=-1;for(var i=t.length;++ur?0:r)}function J(n,r,t){var e=n?n.length:0;if(typeof t=="number")t=0>t?St(e+t,0):t||0;else if(t)return t=Q(n,r),e&&n[t]===r?t:-1;return f(n,r,t)}function K(n,r,t){return L(n,null==r||t?1:0>r?0:r)}function L(n,r,t){var e=-1,u=n?n.length:0;if(r=null==r?0:+r||0,0>r&&(r=-r>u?0:u+r),t=typeof t=="undefined"||t>u?u:+t||0,0>t&&(t+=u),t&&t==u&&!r)return a(n); +for(u=r>t?0:t-r,t=Array(u);++eu&&(u=i)}else r=v(r,t,3),b(n,function(n,t,o){t=r(n,t,o),(t>e||-1/0===t&&t===u)&&(e=t,u=n)});return u}function ir(n,r){return ur(n,Fr(r))}function fr(n,r,t,e){return(zt(n)?u:F)(n,v(r,e,4),t,3>arguments.length,b) +}function ar(n,r,t,e){return(zt(n)?o:F)(n,v(r,e,4),t,3>arguments.length,d)}function cr(n){n=V(n);for(var r=-1,t=n.length,e=Array(t);++r=t||t>r?(f&&clearTimeout(f),t=s,f=p=s=Mr,t&&(g=Pt(),a=n.apply(l,i),p||f||(i=l=null))):p=setTimeout(e,t) +}function u(){p&&clearTimeout(p),f=p=s=Mr,(v||h!==r)&&(g=Pt(),a=n.apply(l,i),p||f||(i=l=null))}function o(){if(i=arguments,c=Pt(),l=this,s=v&&(p||!y),false===h)var t=y&&!p;else{f||y||(g=c);var o=h-(c-g),m=0>=o||o>h;m?(f&&(f=clearTimeout(f)),g=c,a=n.apply(l,i)):f||(f=setTimeout(u,o))}return m&&p?p=clearTimeout(p):p||r===h||(p=setTimeout(e,r)),t&&(m=true,a=n.apply(l,i)),!m||p||f||(i=l=null),a}var i,f,a,c,l,p,s,g=0,h=false,v=true;if(!yr(n))throw new TypeError(Rr);if(r=0>r?0:r,true===t)var y=true,v=false;else mr(t)&&(y=t.leading,h="maxWait"in t&&St(+t.maxWait||0,r),v="trailing"in t?t.trailing:v); +return o.cancel=function(){p&&clearTimeout(p),f&&clearTimeout(f),f=p=s=Mr},o}function gr(n){for(var r=L(arguments,1),t=r,e=gr.placeholder,u=-1,o=t.length,i=-1,f=[];++u"'`]/g,Gr=/^\[object .+?Constructor\]$/,Hr=/($^)/,Jr=/[.*+?^${}()|[\]\/\\]/g,Kr=/['\n\r\u2028\u2029\\]/g,Lr="[object Arguments]",Qr="[object Boolean]",Xr="[object Date]",Yr="[object Error]",Zr="[object Number]",nt="[object Object]",rt="[object RegExp]",tt="[object String]",et={}; +et[Lr]=et["[object Array]"]=et["[object Float32Array]"]=et["[object Float64Array]"]=et["[object Int8Array]"]=et["[object Int16Array]"]=et["[object Int32Array]"]=et["[object Uint8Array]"]=et["[object Uint8ClampedArray]"]=et["[object Uint16Array]"]=et["[object Uint32Array]"]=true,et["[object ArrayBuffer]"]=et[Qr]=et[Xr]=et[Yr]=et["[object Function]"]=et["[object Map]"]=et[Zr]=et[nt]=et[rt]=et["[object Set]"]=et[tt]=et["[object WeakMap]"]=false;var ut={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},ot={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},it={"function":true,object:true},ft={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},at=it[typeof window]&&window||this,ct=it[typeof exports]&&exports&&!exports.nodeType&&exports,lt=it[typeof module]&&module&&!module.nodeType&&module,pt=ct&<&&typeof global=="object"&&global; +!pt||pt.global!==pt&&pt.window!==pt&&pt.self!==pt||(at=pt);var st=lt&<.exports===ct&&ct,gt=Array.prototype,ht=Object.prototype,vt=Function.prototype.toString,yt=ht.hasOwnProperty,mt=at._,bt=ht.toString,dt=RegExp("^"+function(n){return(n=null==n?"":n+"")&&(Jr.lastIndex=0,Jr.test(n))?n.replace(Jr,"\\$&"):n}(bt).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),_t=Math.ceil,jt=Math.floor,wt=gt.push,At=ht.propertyIsEnumerable,xt=gt.splice,Tt=br(Tt=Object.create)&&Tt,Et=br(Et=Array.isArray)&&Et,Ot=at.isFinite,kt=br(kt=Object.keys)&&kt,St=Math.max,It=Math.min,Ft=br(Ft=Date.now)&&Ft,Mt=Math.random,$t={}; +!function(){var n={0:1,length:1};$t.spliceObjects=(xt.call(n,0,1),!n[0])}(0,0),g.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},Tt||(y=function(){function n(){}return function(r){if(mr(r)){n.prototype=r;var t=new n;n.prototype=null}return t||at.Object()}}());var qt=K,Bt=H,Nt=q(function(n,r,t){yt.call(n,t)?++n[t]:n[t]=1}),Rt=q(function(n,r,t){yt.call(n,t)?n[t].push(r):n[t]=[r]}),Ut=q(function(n,r,t){n[t]=r}),Wt=q(function(n,r,t){n[t?0:1].push(r) +},function(){return[[],[]]}),Dt=gr(pr,2);hr(arguments)||(hr=function(n){var r=n&&typeof n=="object"?n.length:Mr;return typeof r=="number"&&-1--n?r.apply(this,arguments):void 0}},g.before=pr,g.bind=function(n,r){return 3>arguments.length?W(n,qr,r):S(n,qr|Nr,L(arguments,2),[],r)},g.bindAll=function(n){for(var r=n,t=1r?0:r)},g.intersection=function(){for(var n=[],r=-1,t=arguments.length;++ri(a,e)){for(r=t;--r;)if(0>i(n[r],e))continue n;a.push(e)}return a},g.invert=function(n){for(var r=-1,t=Ct(n),e=t.length,u={};++ru?0:u>>>0);for(r=v(r,t,3),b(n,function(n,t,u){o[++e]={a:r(n,t,u),b:e,c:n}}),u=o.length,o.sort(c);u--;)o[u]=o[u].c;return o},g.take=Bt,g.tap=function(n,r){return r(n),n},g.throttle=function(n,r,t){var e=true,u=true;if(!yr(n))throw new TypeError(funcErrorText);return false===t?e=false:mr(t)&&(e="leading"in t?t.leading:e,u="trailing"in t?t.trailing:u),sr(n,r,{leading:e,maxWait:r,trailing:u}) +},g.times=function(n,r,t){n=Ot(n=+n)&&-1t)return function(){};if(!r(n,yr))throw new TypeError(Rr);return function(){for(var r=t,e=n[r].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},g.each=er,g.extend=jr,g.iteratee=function(n,r){return v(n,r)},g.methods=Ar,g.object=function(n,r){var t=-1,e=n?n.length:0,u={};for(r||!e||zt(n[0])||(r=[]);++tr?0:r))},g.lastIndexOf=function(n,r,t){var e=n?n.length:0;for(typeof t=="number"&&(e=(0>t?St(e+t,0):It(t||0,e-1))+1);e--;)if(n[e]===r)return e;return-1},g.max=or,g.min=function(n,r,t){var e=1/0,u=e,o=typeof r;if("number"!=o&&"string"!=o||!t||t[r]!==n||(r=null),null==r)for(t=-1,n=V(n),o=n.length;++tr?0:+r||0,n.length),n)},Ir(jr({},g)),g.VERSION="3.0.0-pre",h.prototype=g.prototype,g.prototype.chain=function(){return Y(this) +},g.prototype.value=function(){return this.__wrapped__},gr.placeholder=g,n("concat join pop push reverse shift sort splice unshift".split(" "),function(n){var r=gt[n],t=!/^(?:concat|join|slice)$/.test(n),e=!$t.spliceObjects&&/^(?:pop|shift|splice)$/.test(n);g.prototype[n]=function(){var n=this.__wrapped__,u=r.apply(n,arguments);return e&&0===n.length&&delete n[0],t&&(u=n),this.__chain__?new h(u,true):u}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(at._=g, define("underscore",function(){return g +})):ct&<?st?(lt.exports=g)._=g:ct._=g:at._=g}).call(this); \ No newline at end of file