diff --git a/.travis.yml b/.travis.yml index 87dfd45659..33f4238c56 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,7 @@ node_js: - "0.12" env: global: - - PATTERN1="s|^.+?!support\.funcNames\b[\s\S]+?\.name\b[\s\S]+?\}\n||m" - - PATTERN2="s|\s*else\s*\{\s*iteratee\(index\);\s*\}||" + - PATTERN1="s|\s*else\s*\{\s*iteratee\(index\);\s*\}||" - BIN="node" BUILD="compat" ISTANBUL=false OPTION="" - NPM_VERSION="^2.0.0" SAUCE_LABS=false SAUCE_USERNAME="lodash" - secure: "tg1JFsIFnxzLaTboFPOnm+aJCuMm5+JdhLlESlqg9x3fwro++7KCnwHKLNovhchaPe4otC43ZMB/nfWhDnDm11dKbm/V6HlTkED+dadTsaLxVDg6J+7yK41QhokBPJOxLV78iDaNaAQVYEirAgZ0yn8kFubxmNKV+bpCGQNc9yU=" @@ -16,12 +15,12 @@ env: - BIN="phantomjs" - BIN="rhino" OPTION="-opt -1" - BIN="rhino" OPTION="-opt -1 -require" - - BIN="ringo" + - BIN="ringo" OPTION="-o -1" matrix: include: - - node_js: "io.js" + - node_js: "iojs" env: - - node_js: "io.js" + - node_js: "iojs" env: BUILD="modern" - node_js: "0.8" env: NPM_VERSION="~1.4.0" @@ -51,19 +50,19 @@ before_install: - "npm config set loglevel error" - "npm i -g npm@\"$NPM_VERSION\"" - "[ $SAUCE_LABS == false ] || npm i chalk@\"^1.0.0\" ecstatic@\"0.8.0\" request@\"^2.0.0\" sauce-tunnel@\"2.2.3\"" - - "[ $ISTANBUL == false ] || (npm i -g coveralls@\"^2.0.0\" && npm i istanbul@\"0.3.14\")" + - "[ $ISTANBUL == false ] || (npm i -g coveralls@\"^2.0.0\" && npm i istanbul@\"0.3.17\")" - "[ $BIN != 'rhino' ] || (sudo mkdir /opt/rhino-1.7.6 && sudo wget --no-check-certificate -O $_/js.jar https://lodash.com/_travis/rhino-1.7.6.jar)" - "[ $BIN != 'rhino' ] || (echo -e '#!/bin/sh\\njava -jar /opt/rhino-1.7.6/js.jar $@' | sudo tee /usr/local/bin/rhino && sudo chmod +x /usr/local/bin/rhino)" - "[ $BIN != 'ringo' ] || (wget --no-check-certificate https://lodash.com/_travis/ringojs-0.11.zip && sudo unzip ringojs-0.11 -d /opt && rm ringojs-0.11.zip)" - "[ $BIN != 'ringo' ] || (sudo ln -s /opt/ringojs-0.11/bin/ringo /usr/local/bin/ringo && sudo chmod +x $_)" - "perl -pi -e 's|\"lodash\"|\"lodash-compat\"|' ./package.json" - - "git clone --depth=10 --branch=master git://github.com/lodash/lodash-cli.git ./node_modules/lodash-cli && mkdir $_/node_modules && cd $_ && ln -s ../../../ ./lodash-compat && cd ../ && npm i && cd ../../" + - "git clone --depth=10 --branch=master git://github.com/lodash/lodash-cli ./node_modules/lodash-cli && mkdir $_/node_modules && cd $_ && ln -s ../../../ ./lodash-compat && cd ../ && npm i && cd ../../" - "node ./node_modules/lodash-cli/bin/lodash $BUILD -o ./lodash.$BUILD.js" script: - "[ $ISTANBUL == false ] || cp ./lodash.$BUILD.js ./lodash.js" - - "[ $ISTANBUL == false ] || perl -0pi -e \"$PATTERN1\" ./lodash.js && perl -0pi -e \"$PATTERN2\" $_" + - "[ $ISTANBUL == false ] || perl -0pi -e \"$PATTERN\" ./lodash.js" - "[ $ISTANBUL == false ] || node ./node_modules/istanbul/lib/cli.js cover -x \"**/vendor/**\" --report lcovonly ./test/test.js -- ./lodash.js" - - "[ $ISTANBUL == false ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || (cat ./coverage/lcov.info | coveralls)" + - "[ $ISTANBUL == false ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || (cat ./coverage/lcov.info | coveralls) || true" - "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || cd ./test" - "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || $BIN $OPTION ./test.js ../lodash.$BUILD.js" - "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || $BIN $OPTION ./test.js ../lodash.$BUILD.min.js" diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/README.md b/README.md index 48fd725f2a..f36e4d4e4c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash v3.9.3 +# lodash v3.10.0 The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) with packages for [Bower](http://bower.io/), [Component](http://component.github.io/), & [Volo](http://volojs.org/). @@ -16,8 +16,8 @@ $ lodash modern -o ./lodash.js lodash is also available in a variety of other builds & module formats. * npm packages for [modern](https://www.npmjs.com/package/lodash), [compatibility](https://www.npmjs.com/package/lodash-compat), & [per method](https://www.npmjs.com/browse/keyword/lodash-modularized) builds - * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.9.3-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.9.3-amd) builds - * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.9.3-es) build + * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.10.0-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.10.0-amd) builds + * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.10.0-es) build ## Further Reading diff --git a/bower.json b/bower.json index 8804a04198..23c390577d 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,5 @@ { "name": "lodash", - "version": "3.9.3", "main": "lodash.js", "ignore": [ ".*", diff --git a/component.json b/component.json index dad68e0675..82986672d5 100644 --- a/component.json +++ b/component.json @@ -1,7 +1,7 @@ { "name": "lodash", "repo": "lodash/lodash", - "version": "3.9.3", + "version": "3.10.0", "description": "The modern build of lodash.", "license": "MIT", "main": "lodash.js", diff --git a/doc/README.md b/doc/README.md index 86bf6f6a74..c7a94e15a4 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -# lodash v3.9.3 +# lodash v3.10.0 @@ -59,6 +59,7 @@ * `_.thru` * `_.prototype.chain` * `_.prototype.commit` +* `_.prototype.concat` * `_.prototype.plant` * `_.prototype.reverse` * `_.prototype.run` -> `value` @@ -140,6 +141,7 @@ * `_.flow` * `_.flowRight` * `_.memoize` +* `_.modArgs` * `_.negate` * `_.once` * `_.partial` @@ -192,8 +194,11 @@ ## `Math` * `_.add` +* `_.ceil` +* `_.floor` * `_.max` * `_.min` +* `_.round` * `_.sum` @@ -212,6 +217,7 @@ * `_.assign` * `_.create` * `_.defaults` +* `_.defaultsDeep` * `_.extend` -> `assign` * `_.findKey` * `_.findLastKey` @@ -304,10 +310,8 @@ ## `Properties` * `_.VERSION` * `_.support` -* `_.support.argsTag` * `_.support.enumErrorProps` * `_.support.enumPrototypes` -* `_.support.nodeTag` * `_.support.nonEnumShadows` * `_.support.ownLast` * `_.support.spliceObjects` @@ -332,7 +336,7 @@ ### `_.chunk(array, [size=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L4651 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.chunk "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L4623 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.chunk "See the npm package") Creates an array of elements split into groups the length of `size`. If `collection` can't be split evenly, the final chunk will be the remaining @@ -360,7 +364,7 @@ _.chunk(['a', 'b', 'c', 'd'], 3); ### `_.compact(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L4682 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.compact "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L4654 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.compact "See the npm package") Creates an array with all falsey values removed. The values `false`, `null`, `0`, `""`, `undefined`, and `NaN` are falsey. @@ -383,10 +387,10 @@ _.compact([0, 1, false, 2, '', 3]); ### `_.difference(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L4713 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.difference "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L4685 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.difference "See the npm package") Creates an array of unique `array` values not included in the other -provided arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) +provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) for equality comparisons. #### Arguments @@ -408,7 +412,7 @@ _.difference([1, 2, 3], [4, 2]); ### `_.drop(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L4743 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.drop "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L4715 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.drop "See the npm package") Creates a slice of `array` with `n` elements dropped from the beginning. @@ -440,7 +444,7 @@ _.drop([1, 2, 3], 0); ### `_.dropRight(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L4778 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L4750 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropright "See the npm package") Creates a slice of `array` with `n` elements dropped from the end. @@ -472,7 +476,7 @@ _.dropRight([1, 2, 3], 0); ### `_.dropRightWhile(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L4839 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.droprightwhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L4811 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.droprightwhile "See the npm package") Creates a slice of `array` excluding elements dropped from the end. Elements are dropped until `predicate` returns falsey. The predicate is @@ -532,7 +536,7 @@ _.pluck(_.dropRightWhile(users, 'active'), 'user'); ### `_.dropWhile(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L4894 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropwhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L4866 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropwhile "See the npm package") Creates a slice of `array` excluding elements dropped from the beginning. Elements are dropped until `predicate` returns falsey. The predicate is @@ -592,7 +596,7 @@ _.pluck(_.dropWhile(users, 'active'), 'user'); ### `_.fill(array, value, [start=0], [end=array.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L4928 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.fill "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L4900 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.fill "See the npm package") Fills elements of `array` with `value` from `start` up to, but not including, `end`. @@ -630,7 +634,7 @@ _.fill([4, 6, 8], '*', 1, 2); ### `_.findIndex(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L4988 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L4960 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findindex "See the npm package") This method is like `_.find` except that it returns the index of the first element `predicate` returns truthy for instead of the element itself. @@ -689,7 +693,7 @@ _.findIndex(users, 'active'); ### `_.findLastIndex(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5038 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5010 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastindex "See the npm package") This method is like `_.findIndex` except that it iterates over elements of `collection` from right to left. @@ -748,7 +752,7 @@ _.findLastIndex(users, 'active'); ### `_.first(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5057 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.first "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5029 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.first "See the npm package") Gets the first element of `array`. @@ -776,7 +780,7 @@ _.first([]); ### `_.flatten(array, [isDeep])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5081 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flatten "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5053 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flatten "See the npm package") Flattens a nested array. If `isDeep` is `true` the array is recursively flattened, otherwise it is only flattened a single level. @@ -804,7 +808,7 @@ _.flatten([1, [2, 3, [4]]], true); ### `_.flattenDeep(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5102 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flattendeep "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5074 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flattendeep "See the npm package") Recursively flattens a nested array. @@ -826,10 +830,10 @@ _.flattenDeep([1, [2, 3, [4]]]); ### `_.indexOf(array, value, [fromIndex=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5135 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5107 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexof "See the npm package") Gets the index at which the first occurrence of `value` is found in `array` -using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) +using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) for equality comparisons. If `fromIndex` is negative, it is used as the offset from the end of `array`. If `array` is sorted providing `true` for `fromIndex` performs a faster binary search. @@ -862,7 +866,7 @@ _.indexOf([1, 1, 2, 2], 2, true); ### `_.initial(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5167 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.initial "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5138 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.initial "See the npm package") Gets all but the last element of `array`. @@ -884,10 +888,10 @@ _.initial([1, 2, 3]); ### `_.intersection([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5185 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersection "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5156 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersection "See the npm package") Creates an array of unique values that are included in all of the provided -arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) +arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) for equality comparisons. #### Arguments @@ -908,7 +912,7 @@ _.intersection([1, 2], [4, 2], [2, 1]); ### `_.last(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5235 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.last "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5206 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.last "See the npm package") Gets the last element of `array`. @@ -930,7 +934,7 @@ _.last([1, 2, 3]); ### `_.lastIndexOf(array, value, [fromIndex=array.length-1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5265 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lastindexof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5236 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lastindexof "See the npm package") This method is like `_.indexOf` except that it iterates over elements of `array` from right to left. @@ -963,10 +967,10 @@ _.lastIndexOf([1, 1, 2, 2], 2, true); ### `_.pull(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5313 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pull "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5284 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pull "See the npm package") Removes all provided values from `array` using -[`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) +[`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) for equality comparisons.

@@ -994,7 +998,7 @@ console.log(array); ### `_.pullAt(array, [indexes])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5360 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullat "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5331 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullat "See the npm package") Removes elements from `array` corresponding to the given indexes and returns an array of the removed elements. Indexes may be specified as an array of @@ -1028,7 +1032,7 @@ console.log(evens); ### `_.remove(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5407 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.remove "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5378 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.remove "See the npm package") Removes all elements from `array` that `predicate` returns truthy for and returns an array of the removed elements. The predicate is bound to @@ -1079,7 +1083,7 @@ console.log(evens); ### `_.rest(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5442 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rest "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5413 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rest "See the npm package") Gets all but the first element of `array`. @@ -1104,7 +1108,7 @@ _.rest([1, 2, 3]); ### `_.slice(array, [start=0], [end=array.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5460 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.slice "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5431 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.slice "See the npm package") Creates a slice of `array` from `start` up to, but not including, `end`.
@@ -1127,7 +1131,7 @@ lists in IE < 9 and to ensure dense arrays are returned. ### `_.sortedIndex(array, value, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5520 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5491 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindex "See the npm package") Uses a binary search to determine the lowest index at which `value` should be inserted into `array` in order to maintain its sort order. If an iteratee @@ -1186,7 +1190,7 @@ _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); ### `_.sortedLastIndex(array, value, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5542 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5513 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindex "See the npm package") This method is like `_.sortedIndex` except that it returns the highest index at which `value` should be inserted into `array` in order to @@ -1214,7 +1218,7 @@ _.sortedLastIndex([4, 4, 5, 5], 5); ### `_.take(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5568 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.take "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5539 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.take "See the npm package") Creates a slice of `array` with `n` elements taken from the beginning. @@ -1246,7 +1250,7 @@ _.take([1, 2, 3], 0); ### `_.takeRight(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5603 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takeright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5574 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takeright "See the npm package") Creates a slice of `array` with `n` elements taken from the end. @@ -1278,7 +1282,7 @@ _.takeRight([1, 2, 3], 0); ### `_.takeRightWhile(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5664 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takerightwhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5635 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takerightwhile "See the npm package") Creates a slice of `array` with elements taken from the end. Elements are taken until `predicate` returns falsey. The predicate is bound to `thisArg` @@ -1338,7 +1342,7 @@ _.pluck(_.takeRightWhile(users, 'active'), 'user'); ### `_.takeWhile(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5719 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takewhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5690 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takewhile "See the npm package") Creates a slice of `array` with elements taken from the beginning. Elements are taken until `predicate` returns falsey. The predicate is bound to @@ -1398,10 +1402,10 @@ _.pluck(_.takeWhile(users, 'active'), 'user'); ### `_.union([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5740 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.union "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5711 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.union "See the npm package") Creates an array of unique values, in order, from all of the provided arrays -using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) +using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) for equality comparisons. #### Arguments @@ -1422,10 +1426,10 @@ _.union([1, 2], [4, 2], [2, 1]); ### `_.uniq(array, [isSorted], [iteratee], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5793 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniq "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5764 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniq "See the npm package") Creates a duplicate-free version of an array, using -[`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) +[`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) for equality comparisons, in which only the first occurence of each element is kept. Providing `true` for `isSorted` performs a faster search algorithm for sorted arrays. If an iteratee function is provided it is invoked for @@ -1485,7 +1489,7 @@ _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); ### `_.unzip(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5830 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzip "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5801 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzip "See the npm package") This method is like `_.zip` except that it accepts an array of grouped elements and creates an array regrouping the elements to their pre-zip @@ -1512,7 +1516,7 @@ _.unzip(zipped); ### `_.unzipWith(array, [iteratee], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5870 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzipwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5841 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzipwith "See the npm package") This method is like `_.unzip` except that it accepts an iteratee to specify how regrouped values should be combined. The `iteratee` is bound to `thisArg` @@ -1541,10 +1545,10 @@ _.unzipWith(zipped, _.add); ### `_.without(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5901 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.without "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5872 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.without "See the npm package") Creates an array excluding all provided values using -[`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) +[`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) for equality comparisons. #### Arguments @@ -1566,7 +1570,7 @@ _.without([1, 2, 1, 3], 1, 2); ### `_.xor([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5921 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xor "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5892 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xor "See the npm package") Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) of the provided arrays. @@ -1589,7 +1593,7 @@ _.xor([1, 2], [4, 2]); ### `_.zip([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5951 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zip "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5922 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zip "See the npm package") Creates an array of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements @@ -1613,7 +1617,7 @@ _.zip(['fred', 'barney'], [30, 40], [true, false]); ### `_.zipObject(props, [values=[]])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L5974 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5945 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipobject "See the npm package") The inverse of `_.pairs`; this method returns an object composed from arrays of property names and values. Provide either a single two dimensional array, @@ -1645,7 +1649,7 @@ _.zipObject(['fred', 'barney'], [30, 40]); ### `_.zipWith([arrays], [iteratee], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6010 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L5981 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipwith "See the npm package") This method is like `_.zip` except that it accepts an iteratee to specify how grouped values should be combined. The `iteratee` is bound to `thisArg` @@ -1677,20 +1681,21 @@ _.zipWith([1, 2], [10, 20], [100, 200], _.add); ### `_(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L957 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L944 "View in source") [Ⓣ][1] Creates a `lodash` object which wraps `value` to enable implicit chaining. Methods that operate on and return arrays, collections, and functions can -be chained together. Methods that return a boolean or single value will -automatically end the chain returning the unwrapped value. Explicit chaining -may be enabled using `_.chain`. The execution of chained methods is lazy, -that is, execution is deferred until `_#value` is implicitly or explicitly -called. +be chained together. Methods that retrieve a single value or may return a +primitive value will automatically end the chain returning the unwrapped +value. Explicit chaining may be enabled using `_.chain`. The execution of +chained methods is lazy, that is, execution is deferred until `_#value` +is implicitly or explicitly called.

Lazy evaluation allows several methods to support shortcut fusion. Shortcut -fusion is an optimization that merges iteratees to avoid creating intermediate -arrays and reduce the number of iteratee executions. +fusion is an optimization strategy which merge iteratee calls; this can help +to avoid the creation of intermediate data structures and greatly reduce the +number of iteratee executions.

Chaining is supported in custom builds as long as the `_#value` method is @@ -1719,37 +1724,38 @@ and `where` The chainable wrapper methods are:
`after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, -`countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, -`difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, -`filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, -`forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, -`groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, -`keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, -`memoize`, `merge`, `method`, `methodOf`, `mixin`, `negate`, `omit`, `once`, -`pairs`, `partial`, `partialRight`, `partition`, `pick`, `plant`, `pluck`, -`property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, `rearg`, -`reject`, `remove`, `rest`, `restParam`, `reverse`, `set`, `shuffle`, -`slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, `spread`, -`take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, -`thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`, -`unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `where`, `without`, -`wrap`, `xor`, `zip`, `zipObject`, `zipWith` +`countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, +`defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, +`dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, +`forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, +`functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, +`invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, +`matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, +`modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, +`partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, +`pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, +`reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, +`sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, +`takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, +`transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, +`valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`

The wrapper methods that are **not** chainable by default are:
-`add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, -`endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, -`findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `get`, -`gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, -`isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, -`isFinite` `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, -`isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, -`isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lt`, `lte`, -`max`, `min`, `noConflict`, `noop`, `now`, `pad`, `padLeft`, `padRight`, -`parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, -`runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, -`sortedLastIndex`, `startCase`, `startsWith`, `sum`, `template`, `trim`, -`trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, `value`, and `words` +`add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, +`deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, +`findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, +`floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, +`inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, +`isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, +`isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, +`isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, +`last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, +`now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, +`reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, +`snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, +`startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, +`unescape`, `uniqueId`, `value`, and `words`

The wrapper method `sample` will return a wrapped value when `n` is provided, @@ -1789,7 +1795,7 @@ _.isArray(squares.value()); ### `_.chain(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6053 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6024 "View in source") [Ⓣ][1] Creates a `lodash` object that wraps `value` with explicit method chaining enabled. @@ -1824,7 +1830,7 @@ var youngest = _.chain(users) ### `_.tap(value, interceptor, [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6082 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6053 "View in source") [Ⓣ][1] This method invokes `interceptor` and returns `value`. The interceptor is bound to `thisArg` and invoked with one argument; (value). The purpose of @@ -1856,7 +1862,7 @@ _([1, 2, 3]) ### `_.thru(value, interceptor, [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6108 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6079 "View in source") [Ⓣ][1] This method is like `_.tap` except that it returns the result of `interceptor`. @@ -1886,7 +1892,7 @@ _(' abc ') ### `_.prototype.chain()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6137 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6108 "View in source") [Ⓣ][1] Enables explicit method chaining on the wrapper object. @@ -1918,7 +1924,7 @@ _(users).chain() ### `_.prototype.commit()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6166 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6137 "View in source") [Ⓣ][1] Executes the chained sequence and returns the wrapped result. @@ -1928,16 +1934,16 @@ Executes the chained sequence and returns the wrapped result. #### Example ```js var array = [1, 2]; -var wrapper = _(array).push(3); +var wrapped = _(array).push(3); console.log(array); // => [1, 2] -wrapper = wrapper.commit(); +wrapped = wrapped.commit(); console.log(array); // => [1, 2, 3] -wrapper.last(); +wrapped.last(); // => 3 console.log(array); @@ -1949,8 +1955,37 @@ console.log(array); +### `_.prototype.concat([values])` +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6161 "View in source") [Ⓣ][1] + +Creates a new array joining a wrapped array with any additional arrays +and/or values. + +#### Arguments +1. `[values]` *(...*)*: The values to concatenate. + +#### Returns +*(Array)*: Returns the new concatenated array. + +#### Example +```js +var array = [1]; +var wrapped = _(array).concat(2, [3], [[4]]); + +console.log(wrapped.value()); +// => [1, 2, 3, [4]] + +console.log(array); +// => [1] +``` +* * * + + + + + ### `_.prototype.plant()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6193 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6191 "View in source") [Ⓣ][1] Creates a clone of the chained sequence planting `value` as the wrapped value. @@ -1960,17 +1995,17 @@ Creates a clone of the chained sequence planting `value` as the wrapped value. #### Example ```js var array = [1, 2]; -var wrapper = _(array).map(function(value) { +var wrapped = _(array).map(function(value) { return Math.pow(value, 2); }); var other = [3, 4]; -var otherWrapper = wrapper.plant(other); +var otherWrapped = wrapped.plant(other); -otherWrapper.value(); +otherWrapped.value(); // => [9, 16] -wrapper.value(); +wrapped.value(); // => [1, 4] ``` * * * @@ -1980,7 +2015,7 @@ wrapper.value(); ### `_.prototype.reverse()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6231 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6229 "View in source") [Ⓣ][1] Reverses the wrapped array so the first element becomes the last, the second element becomes the second to last, and so on. @@ -2008,7 +2043,7 @@ console.log(array); ### `_.prototype.toString()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6256 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6259 "View in source") [Ⓣ][1] Produces the result of coercing the unwrapped value to a string. @@ -2027,7 +2062,7 @@ _([1, 2, 3]).toString(); ### `_.prototype.value()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6273 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6276 "View in source") [Ⓣ][1] Executes the chained sequence to extract the unwrapped value. @@ -2055,7 +2090,7 @@ _([1, 2, 3]).value(); ### `_.at(collection, [props])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6299 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.at "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6302 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.at "See the npm package") Creates an array of elements corresponding to the given keys, or indexes, of `collection`. Keys may be specified as individual arguments or as arrays @@ -2083,7 +2118,7 @@ _.at(['barney', 'fred', 'pebbles'], 0, 2); ### `_.countBy(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6347 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.countby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6350 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.countby "See the npm package") Creates an object composed of keys generated from the results of running each element of `collection` through `iteratee`. The corresponding value @@ -2135,7 +2170,7 @@ _.countBy(['one', 'two', 'three'], 'length'); ### `_.every(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6399 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.every "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6402 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.every "See the npm package") Checks if `predicate` returns truthy for **all** elements of `collection`. The predicate is bound to `thisArg` and invoked with three arguments:
@@ -2196,7 +2231,7 @@ _.every(users, 'active'); ### `_.filter(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6459 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.filter "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6462 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.filter "See the npm package") Iterates over elements of `collection`, returning an array of all elements `predicate` returns truthy for. The predicate is bound to `thisArg` and @@ -2258,7 +2293,7 @@ _.pluck(_.filter(users, 'active'), 'user'); ### `_.find(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6515 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.find "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6518 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.find "See the npm package") Iterates over elements of `collection`, returning the first element `predicate` returns truthy for. The predicate is bound to `thisArg` and @@ -2321,7 +2356,7 @@ _.result(_.find(users, 'active'), 'user'); ### `_.findLast(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6536 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlast "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6539 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlast "See the npm package") This method is like `_.find` except that it iterates over elements of `collection` from right to left. @@ -2348,7 +2383,7 @@ _.findLast([1, 2, 3, 4], function(n) { ### `_.findWhere(collection, source)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6567 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findwhere "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6570 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findwhere "See the npm package") Performs a deep comparison between each element in `collection` and the source object, returning the first element that has equivalent property @@ -2387,7 +2422,7 @@ _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); ### `_.forEach(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6601 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreach "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6604 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreach "See the npm package") Iterates over elements of `collection` invoking `iteratee` for each element. The `iteratee` is bound to `thisArg` and invoked with three arguments:
@@ -2429,7 +2464,7 @@ _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { ### `_.forEachRight(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6622 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreachright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6625 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreachright "See the npm package") This method is like `_.forEach` except that it iterates over elements of `collection` from right to left. @@ -2459,7 +2494,7 @@ _([1, 2]).forEachRight(function(n) { ### `_.groupBy(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6666 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.groupby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6669 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.groupby "See the npm package") Creates an object composed of keys generated from the results of running each element of `collection` through `iteratee`. The corresponding value @@ -2512,10 +2547,10 @@ _.groupBy(['one', 'two', 'three'], 'length'); ### `_.includes(collection, target, [fromIndex=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6703 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.includes "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6706 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.includes "See the npm package") Checks if `value` is in `collection` using -[`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) +[`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) for equality comparisons. If `fromIndex` is negative, it is used as the offset from the end of `collection`. @@ -2551,7 +2586,7 @@ _.includes('pebbles', 'eb'); ### `_.indexBy(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6768 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6768 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexby "See the npm package") Creates an object composed of keys generated from the results of running each element of `collection` through `iteratee`. The corresponding value @@ -2608,7 +2643,7 @@ _.indexBy(keyData, function(object) { ### `_.invoke(collection, path, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6794 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invoke "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6794 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invoke "See the npm package") Invokes the method at `path` of each element in `collection`, returning an array of the results of each invoked method. Any additional arguments @@ -2638,7 +2673,7 @@ _.invoke([123, 456], String.prototype.split, ''); ### `_.map(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6863 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.map "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6863 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.map "See the npm package") Creates an array of values by running each element in `collection` through `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three @@ -2709,7 +2744,7 @@ _.map(users, 'user'); ### `_.partition(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6928 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partition "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6928 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partition "See the npm package") Creates an array of elements split into two groups, the first of which contains elements `predicate` returns truthy for, while the second of which @@ -2779,7 +2814,7 @@ _.map(_.partition(users, 'active'), mapper); ### `_.pluck(collection, path)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6955 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pluck "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6955 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pluck "See the npm package") Gets the property value of `path` from all elements in `collection`. @@ -2811,7 +2846,7 @@ _.pluck(userIndex, 'age'); ### `_.reduce(collection, [iteratee=_.identity], [accumulator], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L6995 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduce "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L6996 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduce "See the npm package") Reduces `collection` to a value which is the accumulated result of running each element in `collection` through `iteratee`, where each successive @@ -2826,7 +2861,8 @@ Many lodash methods are guarded to work as iteratees for methods like

The guarded methods are:
-`assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder` +`assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, +and `sortByOrder` #### Aliases *_.foldl, _.inject* @@ -2860,7 +2896,7 @@ _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { ### `_.reduceRight(collection, [iteratee=_.identity], [accumulator], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7019 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduceright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7020 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduceright "See the npm package") This method is like `_.reduce` except that it iterates over elements of `collection` from right to left. @@ -2893,7 +2929,7 @@ _.reduceRight(array, function(flattened, other) { ### `_.reject(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7057 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7058 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reject "See the npm package") The opposite of `_.filter`; this method returns the elements of `collection` that `predicate` does **not** return truthy for. @@ -2937,7 +2973,7 @@ _.pluck(_.reject(users, 'active'), 'user'); ### `_.sample(collection, [n])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7083 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sample "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7084 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sample "See the npm package") Gets a random element or `n` random elements from a collection. @@ -2963,7 +2999,7 @@ _.sample([1, 2, 3, 4], 2); ### `_.shuffle(collection)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7120 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.shuffle "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7121 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.shuffle "See the npm package") Creates an array of shuffled values, using a version of the [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). @@ -2986,7 +3022,7 @@ _.shuffle([1, 2, 3, 4]); ### `_.size(collection)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7144 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.size "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7145 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.size "See the npm package") Gets the size of `collection` by returning its length for array-like values or the number of own enumerable properties for objects. @@ -3015,7 +3051,7 @@ _.size('pebbles'); ### `_.some(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7198 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.some "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7199 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.some "See the npm package") Checks if `predicate` returns truthy for **any** element of `collection`. The function returns as soon as it finds a passing value and does not iterate @@ -3077,7 +3113,7 @@ _.some(users, 'active'); ### `_.sortBy(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7257 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7258 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortby "See the npm package") Creates an array of elements, sorted in ascending order by the results of running each element in a collection through `iteratee`. This method performs @@ -3136,7 +3172,7 @@ _.pluck(_.sortBy(users, 'user'), 'user'); ### `_.sortByAll(collection, iteratees)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7308 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortbyall "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7309 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortbyall "See the npm package") This method is like `_.sortBy` except that it can sort by multiple iteratees or property names. @@ -3180,13 +3216,13 @@ _.map(_.sortByAll(users, 'user', function(chr) { -### `_.sortByOrder(collection, iteratees, orders)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7353 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortbyorder "See the npm package") +### `_.sortByOrder(collection, iteratees, [orders])` +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7354 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortbyorder "See the npm package") This method is like `_.sortByAll` except that it allows specifying the -sort orders of the iteratees to sort by. A truthy value in `orders` will -sort the corresponding property name in ascending order while a falsey -value will sort it in descending order. +sort orders of the iteratees to sort by. If `orders` is unspecified, all +values are sorted in ascending order. Otherwise, a value is sorted in +ascending order if its corresponding order is "asc", and descending if "desc".

If a property name is provided for an iteratee the created `_.property` @@ -3200,7 +3236,7 @@ object, else `false`. #### Arguments 1. `collection` *(Array|Object|string)*: The collection to iterate over. 2. `iteratees` *(Function[]|Object[]|string[])*: The iteratees to sort by. -3. `orders` *(boolean[])*: The sort orders of `iteratees`. +3. `[orders]` *(boolean[])*: The sort orders of `iteratees`. #### Returns *(Array)*: Returns the new sorted array. @@ -3215,7 +3251,7 @@ var users = [ ]; // sort by `user` in ascending order and by `age` in descending order -_.map(_.sortByOrder(users, ['user', 'age'], [true, false]), _.values); +_.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] ``` * * * @@ -3225,7 +3261,7 @@ _.map(_.sortByOrder(users, ['user', 'age'], [true, false]), _.values); ### `_.where(collection, source)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7398 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.where "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7399 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.where "See the npm package") Performs a deep comparison between each element in `collection` and the source object, returning an array of all elements that have equivalent @@ -3270,7 +3306,7 @@ _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); ### `_.now` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7418 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.now "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7419 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.now "See the npm package") Gets the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC). @@ -3295,7 +3331,7 @@ _.defer(function(stamp) { ### `_.after(n, func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7447 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.after "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7448 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.after "See the npm package") The opposite of `_.before`; this method creates a function that invokes `func` once it is called `n` or more times. @@ -3327,7 +3363,7 @@ _.forEach(saves, function(type) { ### `_.ary(func, [n=func.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7481 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ary "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7482 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ary "See the npm package") Creates a function that accepts up to `n` arguments ignoring any additional arguments. @@ -3351,7 +3387,7 @@ _.map(['6', '8', '10'], _.ary(parseInt, 1)); ### `_.before(n, func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7505 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.before "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7506 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.before "See the npm package") 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 @@ -3376,7 +3412,7 @@ jQuery('#add').on('click', _.before(5, addContactToList)); ### `_.bind(func, thisArg, [partials])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7562 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bind "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7563 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bind "See the npm package") Creates a function that invokes `func` with the `this` binding of `thisArg` and prepends any additional `_.bind` arguments to those provided to the @@ -3422,7 +3458,7 @@ bound('hi'); ### `_.bindAll(object, [methodNames])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7599 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindall "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7600 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindall "See the npm package") Binds methods of an object to the object itself, overwriting the existing method. Method names may be specified as individual arguments or as arrays @@ -3459,7 +3495,7 @@ jQuery('#docs').on('click', view.onClick); ### `_.bindKey(object, key, [partials])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7656 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindkey "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7657 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindkey "See the npm package") Creates a function that invokes the method at `object[key]` and prepends any additional `_.bindKey` arguments to those provided to the bound function. @@ -3514,7 +3550,7 @@ bound('hi'); ### `_.curry(func, [arity=func.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7705 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curry "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7706 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curry "See the npm package") Creates a function that accepts one or more arguments of `func` that when called either invokes `func` returning its result, if all `func` arguments @@ -3564,7 +3600,7 @@ curried(1)(_, 3)(2); ### `_.curryRight(func, [arity=func.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7744 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curryright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7745 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curryright "See the npm package") This method is like `_.curry` except that arguments are applied to `func` in the manner of `_.partialRight` instead of `_.partial`. @@ -3611,7 +3647,7 @@ curried(3)(1, _)(2); ### `_.debounce(func, [wait=0], [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7809 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.debounce "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7810 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.debounce "See the npm package") Creates a debounced function that delays invoking `func` until after `wait` milliseconds have elapsed since the last time the debounced function was @@ -3682,7 +3718,7 @@ delete models.todo; ### `_.defer(func, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7940 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defer "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7935 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defer "See the npm package") Defers invoking the `func` until the current call stack has cleared. Any additional arguments are provided to `func` when it is invoked. @@ -3708,7 +3744,7 @@ _.defer(function(text) { ### `_.delay(func, wait, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7962 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.delay "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7957 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.delay "See the npm package") Invokes `func` after `wait` milliseconds. Any additional arguments are provided to `func` when it is invoked. @@ -3735,7 +3771,7 @@ _.delay(function(text) { ### `_.flow([funcs])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L7986 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flow "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L7981 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flow "See the npm package") Creates a function that returns the result of invoking the provided functions with the `this` binding of the created function, where each @@ -3764,7 +3800,7 @@ addSquare(1, 2); ### `_.flowRight([funcs])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8008 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flowright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8003 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flowright "See the npm package") This method is like `_.flow` except that it creates a function that invokes the provided functions from right to left. @@ -3795,7 +3831,7 @@ addSquare(1, 2); ### `_.memoize(func, [resolver])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8061 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.memoize "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8056 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.memoize "See the npm package") Creates a function that memoizes the result of `func`. If `resolver` is provided it determines the cache key for storing the result based on the @@ -3807,7 +3843,7 @@ function.
**Note:** The cache is exposed as the `cache` property on the memoized function. Its creation may be customized by replacing the `_.memoize.Cache` -constructor with one whose instances implement the [`Map`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) +constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) method interface of `get`, `has`, and `set`. #### Arguments @@ -3855,8 +3891,47 @@ identity(other); +### `_.modArgs(func, [transforms])` +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8107 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.modargs "See the npm package") + +Creates a function that runs each argument through a corresponding +transform function. + +#### Arguments +1. `func` *(Function)*: The function to wrap. +2. `[transforms]` *(...(Function|Function[])*: The functions to transform arguments, specified as individual functions or arrays of functions. + +#### Returns +*(Function)*: Returns the new function. + +#### Example +```js +function doubled(n) { + return n * 2; +} + +function square(n) { + return n * n; +} + +var modded = _.modArgs(function(x, y) { + return [x, y]; +}, square, doubled); + +modded(1, 2); +// => [1, 4] + +modded(5, 10); +// => [25, 20] +``` +* * * + + + + + ### `_.negate(predicate)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8100 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.negate "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8141 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.negate "See the npm package") Creates a function that negates the result of the predicate `func`. The `func` predicate is invoked with the `this` binding and arguments of the @@ -3884,7 +3959,7 @@ _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); ### `_.once(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8126 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.once "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8167 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.once "See the npm package") Creates a function that is restricted to invoking `func` once. Repeat calls to the function return the value of the first call. The `func` is invoked @@ -3910,7 +3985,7 @@ initialize(); ### `_.partial(func, [partials])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8162 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partial "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8203 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partial "See the npm package") Creates a function that invokes `func` with `partial` arguments prepended to those provided to the new function. This method is like `_.bind` except @@ -3953,7 +4028,7 @@ greetFred('hi'); ### `_.partialRight(func, [partials])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8195 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partialright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8236 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partialright "See the npm package") This method is like `_.partial` except that partially applied arguments are appended to those provided to the new function. @@ -3995,7 +4070,7 @@ sayHelloTo('fred'); ### `_.rearg(func, indexes)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8225 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rearg "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8266 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rearg "See the npm package") Creates a function that invokes `func` with arguments arranged according to the specified indexes where the argument value at the first index is @@ -4031,7 +4106,7 @@ map(function(n) { ### `_.restParam(func, [start=func.length-1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8251 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.restparam "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8292 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.restparam "See the npm package") Creates a function that invokes `func` with the `this` binding of the created function and arguments from `start` and beyond provided as an array. @@ -4063,7 +4138,7 @@ say('hello', 'fred', 'barney', 'pebbles'); ### `_.spread(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8311 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.spread "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8352 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.spread "See the npm package") Creates a function that invokes `func` with the `this` binding of the created function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). @@ -4104,7 +4179,7 @@ numbers.then(_.spread(function(x, y) { ### `_.throttle(func, [wait=0], [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8359 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.throttle "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8400 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.throttle "See the npm package") Creates a throttled function that only invokes `func` at most once per every `wait` milliseconds. The throttled function comes with a `cancel` @@ -4152,7 +4227,7 @@ jQuery(window).on('popstate', throttled.cancel); ### `_.wrap(value, wrapper)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8399 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.wrap "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8437 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.wrap "See the npm package") Creates a function that provides `value` to the wrapper function as its first argument. Any additional arguments provided to the function are @@ -4188,7 +4263,7 @@ p('fred, barney, & pebbles'); ### `_.clone(value, [isDeep], [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8457 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clone "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8495 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clone "See the npm package") Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, otherwise they are assigned by reference. If `customizer` is provided it is @@ -4249,7 +4324,7 @@ el.childNodes.length; ### `_.cloneDeep(value, [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8516 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonedeep "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8554 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonedeep "See the npm package") Creates a deep clone of `value`. If `customizer` is provided it is invoked to produce the cloned values. If `customizer` returns `undefined` cloning @@ -4304,7 +4379,7 @@ el.childNodes.length; ### `_.gt(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8542 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.gt "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8580 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.gt "See the npm package") Checks if `value` is greater than `other`. @@ -4333,7 +4408,7 @@ _.gt(1, 3); ### `_.gte(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8566 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.gte "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8604 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.gte "See the npm package") Checks if `value` is greater than or equal to `other`. @@ -4362,7 +4437,7 @@ _.gte(1, 3); ### `_.isArguments(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8586 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarguments "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8624 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarguments "See the npm package") Checks if `value` is classified as an `arguments` object. @@ -4387,7 +4462,7 @@ _.isArguments([1, 2, 3]); ### `_.isArray(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8613 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarray "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8645 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarray "See the npm package") Checks if `value` is classified as an `Array` object. @@ -4412,7 +4487,7 @@ _.isArray(function() { return arguments; }()); ### `_.isBoolean(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8633 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isboolean "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8665 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isboolean "See the npm package") Checks if `value` is classified as a boolean primitive or object. @@ -4437,7 +4512,7 @@ _.isBoolean(null); ### `_.isDate(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8653 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isdate "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8685 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isdate "See the npm package") Checks if `value` is classified as a `Date` object. @@ -4462,7 +4537,7 @@ _.isDate('Mon April 23 2012'); ### `_.isElement(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8673 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iselement "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8705 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iselement "See the npm package") Checks if `value` is a DOM element. @@ -4487,7 +4562,7 @@ _.isElement(''); ### `_.isEmpty(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8711 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isempty "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8736 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isempty "See the npm package") Checks if `value` is empty. A value is considered empty unless it is an `arguments` object, array, string, or jQuery-like collection with a length @@ -4523,7 +4598,7 @@ _.isEmpty({ 'a': 1 }); ### `_.isEqual(value, other, [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8766 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isequal "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8791 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isequal "See the npm package") Performs a deep comparison between two values to determine if they are equivalent. If `customizer` is provided it is invoked to compare values. @@ -4579,7 +4654,7 @@ _.isEqual(array, other, function(value, other) { ### `_.isError(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8789 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iserror "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8814 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iserror "See the npm package") Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`, or `URIError` object. @@ -4605,12 +4680,12 @@ _.isError(Error); ### `_.isFinite(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8820 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfinite "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8845 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfinite "See the npm package") Checks if `value` is a finite primitive number.

-**Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). +**Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). #### Arguments 1. `value` *(*)*: The value to check. @@ -4642,7 +4717,7 @@ _.isFinite(Infinity); ### `_.isFunction(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8840 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfunction "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8865 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfunction "See the npm package") Checks if `value` is classified as a `Function` object. @@ -4667,7 +4742,7 @@ _.isFunction(/abc/); ### `_.isMatch(object, source, [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8913 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismatch "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8938 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismatch "See the npm package") Performs a deep comparison between `object` and `source` to determine if `object` contains equivalent property values. If `customizer` is provided @@ -4716,7 +4791,7 @@ _.isMatch(object, source, function(value, other) { ### `_.isNaN(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8943 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnan "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8968 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnan "See the npm package") Checks if `value` is `NaN`.
@@ -4751,7 +4826,7 @@ _.isNaN(undefined); ### `_.isNative(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8965 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnative "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8990 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnative "See the npm package") Checks if `value` is a native function. @@ -4776,7 +4851,7 @@ _.isNative(_); ### `_.isNull(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8991 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnull "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9016 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnull "See the npm package") Checks if `value` is `null`. @@ -4801,7 +4876,7 @@ _.isNull(void 0); ### `_.isNumber(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9017 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnumber "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9042 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnumber "See the npm package") Checks if `value` is classified as a `Number` primitive or object.
@@ -4833,7 +4908,7 @@ _.isNumber('8.4'); ### `_.isObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L8867 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L8892 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isobject "See the npm package") Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) @@ -4862,7 +4937,7 @@ _.isObject(1); ### `_.isPlainObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9051 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isplainobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9076 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isplainobject "See the npm package") Checks if `value` is a plain object, that is, an object created by the `Object` constructor or one with a `[[Prototype]]` of `null`. @@ -4902,7 +4977,7 @@ _.isPlainObject(Object.create(null)); ### `_.isRegExp(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9079 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isregexp "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9120 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isregexp "See the npm package") Checks if `value` is classified as a `RegExp` object. @@ -4927,7 +5002,7 @@ _.isRegExp('/abc/'); ### `_.isString(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9099 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isstring "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9140 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isstring "See the npm package") Checks if `value` is classified as a `String` primitive or object. @@ -4952,7 +5027,7 @@ _.isString(1); ### `_.isTypedArray(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9119 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.istypedarray "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9160 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.istypedarray "See the npm package") Checks if `value` is classified as a typed array. @@ -4977,7 +5052,7 @@ _.isTypedArray([]); ### `_.isUndefined(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9139 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isundefined "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9180 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isundefined "See the npm package") Checks if `value` is `undefined`. @@ -5002,7 +5077,7 @@ _.isUndefined(null); ### `_.lt(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9163 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lt "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9204 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lt "See the npm package") Checks if `value` is less than `other`. @@ -5031,7 +5106,7 @@ _.lt(3, 1); ### `_.lte(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9187 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lte "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9228 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lte "See the npm package") Checks if `value` is less than or equal to `other`. @@ -5060,7 +5135,7 @@ _.lte(3, 1); ### `_.toArray(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9206 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toarray "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9247 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toarray "See the npm package") Converts `value` to an array. @@ -5084,7 +5159,7 @@ Converts `value` to an array. ### `_.toPlainObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9242 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toplainobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9283 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toplainobject "See the npm package") Converts `value` to a plain object flattening inherited enumerable properties of `value` to own properties of the plain object. @@ -5122,7 +5197,7 @@ _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); ### `_.add(augend, addend)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11759 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.add "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11802 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.add "See the npm package") Adds two numbers. @@ -5144,8 +5219,66 @@ _.add(6, 4); +### `_.ceil(n, [precision=0])` +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11826 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ceil "See the npm package") + +Calculates `n` rounded up to `precision`. + +#### Arguments +1. `n` *(number)*: The number to round up. +2. `[precision=0]` *(number)*: The precision to round up to. + +#### Returns +*(number)*: Returns the rounded up number. + +#### Example +```js +_.ceil(4.006); +// => 5 + +_.ceil(6.004, 2); +// => 6.01 + +_.ceil(6040, -2); +// => 6100 +``` +* * * + + + + + +### `_.floor(n, [precision=0])` +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11848 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.floor "See the npm package") + +Calculates `n` rounded down to `precision`. + +#### Arguments +1. `n` *(number)*: The number to round down. +2. `[precision=0]` *(number)*: The precision to round down to. + +#### Returns +*(number)*: Returns the rounded down number. + +#### Example +```js +_.floor(4.006); +// => 4 + +_.floor(0.046, 2); +// => 0.04 + +_.floor(4060, -2); +// => 4000 +``` +* * * + + + + + ### `_.max(collection, [iteratee], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11810 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.max "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11897 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.max "See the npm package") Gets the maximum value of `collection`. If `collection` is empty or falsey `-Infinity` is returned. If an iteratee function is provided it is invoked @@ -5204,7 +5337,7 @@ _.max(users, 'age'); ### `_.min(collection, [iteratee], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11859 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.min "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11946 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.min "See the npm package") Gets the minimum value of `collection`. If `collection` is empty or falsey `Infinity` is returned. If an iteratee function is provided it is invoked @@ -5262,8 +5395,37 @@ _.min(users, 'age'); +### `_.round(n, [precision=0])` +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11968 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.round "See the npm package") + +Calculates `n` rounded to `precision`. + +#### Arguments +1. `n` *(number)*: The number to round. +2. `[precision=0]` *(number)*: The precision to round to. + +#### Returns +*(number)*: Returns the rounded number. + +#### Example +```js +_.round(4.006); +// => 4 + +_.round(4.006, 2); +// => 4.01 + +_.round(4060, -2); +// => 4100 +``` +* * * + + + + + ### `_.sum(collection, [iteratee], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11893 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sum "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L12002 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sum "See the npm package") Gets the sum of the values in `collection`. @@ -5310,7 +5472,7 @@ _.sum(objects, 'n'); ### `_.inRange(n, [start=0], end)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10266 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.inrange "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10320 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.inrange "See the npm package") Checks if `n` is between `start` and up to but not including, `end`. If `end` is not specified it is set to `start` with `start` then set to `0`. @@ -5350,7 +5512,7 @@ _.inRange(5.2, 4); ### `_.random([min=0], [max=1], [floating])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10304 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.random "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10358 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.random "See the npm package") Produces a random number between `min` and `max` (inclusive). If only one argument is provided a number between `0` and the given number is returned. @@ -5392,7 +5554,7 @@ _.random(1.2, 5.2); ### `_.assign(object, [sources], [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9280 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assign "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9371 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assign "See the npm package") Assigns own enumerable properties of source object(s) to the destination object. Subsequent sources overwrite property assignments of previous sources. @@ -5402,7 +5564,7 @@ The `customizer` is bound to `thisArg` and invoked with five arguments:


**Note:** This method mutates `object` and is based on -[`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). +[`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). #### Aliases *_.extend* @@ -5436,7 +5598,7 @@ defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); ### `_.create(prototype, [properties])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9320 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.create "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9411 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.create "See the npm package") Creates an object that inherits from the given `prototype` object. If a `properties` object is provided its own enumerable properties are assigned @@ -5478,7 +5640,7 @@ circle instanceof Shape; ### `_.defaults(object, [sources])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9346 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defaults "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9437 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defaults "See the npm package") Assigns own enumerable properties of source object(s) to the destination object for all destination properties that resolve to `undefined`. Once a @@ -5505,8 +5667,35 @@ _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); +### `_.defaultsDeep(object, [sources])` +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9457 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defaultsdeep "See the npm package") + +This method is like `_.defaults` except that it recursively assigns +default properties. +
+
+**Note:** This method mutates `object`. + +#### Arguments +1. `object` *(Object)*: The destination object. +2. `[sources]` *(...Object)*: The source objects. + +#### Returns +*(Object)*: Returns `object`. + +#### Example +```js +_.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); +// => { 'user': { 'name': 'barney', 'age': 36 } } +``` +* * * + + + + + ### `_.findKey(object, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9403 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findkey "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9507 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findkey "See the npm package") This method is like `_.find` except that it returns the key of the first element `predicate` returns truthy for instead of the element itself. @@ -5565,7 +5754,7 @@ _.findKey(users, 'active'); ### `_.findLastKey(object, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9453 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastkey "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9557 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastkey "See the npm package") This method is like `_.findKey` except that it iterates over elements of a collection in the opposite order. @@ -5624,7 +5813,7 @@ _.findLastKey(users, 'active'); ### `_.forIn(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9482 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9586 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forin "See the npm package") Iterates over own and inherited enumerable properties of an object invoking `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked @@ -5660,7 +5849,7 @@ _.forIn(new Foo, function(value, key) { ### `_.forInRight(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9509 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forinright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9613 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forinright "See the npm package") This method is like `_.forIn` except that it iterates over properties of `object` in the opposite order. @@ -5694,7 +5883,7 @@ _.forInRight(new Foo, function(value, key) { ### `_.forOwn(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9538 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forown "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9642 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forown "See the npm package") Iterates over own enumerable properties of an object invoking `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked with @@ -5730,7 +5919,7 @@ _.forOwn(new Foo, function(value, key) { ### `_.forOwnRight(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9565 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forownright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9669 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forownright "See the npm package") This method is like `_.forOwn` except that it iterates over properties of `object` in the opposite order. @@ -5764,7 +5953,7 @@ _.forOwnRight(new Foo, function(value, key) { ### `_.functions(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9582 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.functions "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9686 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.functions "See the npm package") Creates an array of function property names from all enumerable properties, own and inherited, of `object`. @@ -5790,7 +5979,7 @@ _.functions(_); ### `_.get(object, path, [defaultValue])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9610 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.get "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9714 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.get "See the npm package") Gets the property value at `path` of `object`. If the resolved value is `undefined` the `defaultValue` is used in its place. @@ -5823,7 +6012,7 @@ _.get(object, 'a.b.c', 'default'); ### `_.has(object, path)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9637 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.has "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9741 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.has "See the npm package") Checks if `path` is a direct property. @@ -5854,7 +6043,7 @@ _.has(object, ['a', 'b', 'c']); ### `_.invert(object, [multiValue])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9678 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invert "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9782 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invert "See the npm package") Creates an object composed of the inverted keys and values of `object`. If `object` contains duplicate values, subsequent values overwrite property @@ -5885,13 +6074,13 @@ _.invert(object, true); ### `_.keys(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9732 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keys "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9836 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keys "See the npm package") Creates an array of the own enumerable property names of `object`.

**Note:** Non-object values are coerced to objects. See the -[ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) +[ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) for more details. #### Arguments @@ -5922,7 +6111,7 @@ _.keys('hi'); ### `_.keysIn(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9763 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keysin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9867 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keysin "See the npm package") Creates an array of the own and inherited enumerable property names of `object`.
@@ -5954,7 +6143,7 @@ _.keysIn(new Foo); ### `_.mapKeys(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9840 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapkeys "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9944 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapkeys "See the npm package") The opposite of `_.mapValues`; this method creates an object with the same values as `object` and keys generated by running each own enumerable @@ -5982,7 +6171,7 @@ _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { ### `_.mapValues(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9883 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapvalues "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9987 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapvalues "See the npm package") Creates an object with the same keys as `object` and values generated by running each own enumerable property of `object` through `iteratee`. The @@ -6034,7 +6223,7 @@ _.mapValues(users, 'age'); ### `_.merge(object, [sources], [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9933 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.merge "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L9337 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.merge "See the npm package") Recursively merges own enumerable properties of the source object(s), that don't resolve to `undefined` into the destination object. Subsequent sources @@ -6091,7 +6280,7 @@ _.merge(object, other, function(a, b) { ### `_.omit(object, [predicate], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9958 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.omit "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10012 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.omit "See the npm package") The opposite of `_.pick`; this method creates an object composed of the own and inherited enumerable properties of `object` that are not omitted. @@ -6121,7 +6310,7 @@ _.omit(object, _.isNumber); ### `_.pairs(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L9986 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pairs "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10040 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pairs "See the npm package") Creates a two dimensional array of the key-value pairs for `object`, e.g. `[[key1, value1], [key2, value2]]`. @@ -6144,7 +6333,7 @@ _.pairs({ 'barney': 36, 'fred': 40 }); ### `_.pick(object, [predicate], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10027 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pick "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10081 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pick "See the npm package") Creates an object composed of the picked `object` properties. Property names may be specified as individual arguments or as arrays of property @@ -6177,7 +6366,7 @@ _.pick(object, _.isString); ### `_.result(object, path, [defaultValue])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10064 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.result "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10118 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.result "See the npm package") This method is like `_.get` except that if the resolved value is a function it is invoked with the `this` binding of its parent object and its result @@ -6214,7 +6403,7 @@ _.result(object, 'a.b.c', _.constant('default')); ### `_.set(object, path, value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10100 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.set "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10154 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.set "See the npm package") Sets the property value of `path` on `object`. If a portion of `path` does not exist it is created. @@ -6246,7 +6435,7 @@ console.log(object.x[0].y.z); ### `_.transform(object, [iteratee=_.identity], [accumulator], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10155 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.transform "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10209 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.transform "See the npm package") An alternative to `_.reduce`; this method transforms `object` to a new `accumulator` object which is the result of running each of its own enumerable @@ -6284,7 +6473,7 @@ _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { ### `_.values(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10202 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.values "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10256 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.values "See the npm package") Creates an array of the own enumerable property values of `object`.
@@ -6319,7 +6508,7 @@ _.values('hi'); ### `_.valuesIn(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10229 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.valuesin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10283 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.valuesin "See the npm package") Creates an array of the own and inherited enumerable property values of `object`. @@ -6358,7 +6547,7 @@ _.valuesIn(new Foo); ### `_.camelCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10360 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.camelcase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10414 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.camelcase "See the npm package") Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). @@ -6386,7 +6575,7 @@ _.camelCase('__foo_bar__'); ### `_.capitalize([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10378 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.capitalize "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10432 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.capitalize "See the npm package") Capitalizes the first character of `string`. @@ -6408,7 +6597,7 @@ _.capitalize('fred'); ### `_.deburr([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10397 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.deburr "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10451 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.deburr "See the npm package") Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). @@ -6431,7 +6620,7 @@ _.deburr('déjà vu'); ### `_.endsWith([string=''], [target], [position=string.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10423 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.endswith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10477 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.endswith "See the npm package") Checks if `string` ends with the given target string. @@ -6461,7 +6650,7 @@ _.endsWith('abc', 'b', 2); ### `_.escape([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10468 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escape "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10522 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escape "See the npm package") Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to their corresponding HTML entities. @@ -6506,7 +6695,7 @@ _.escape('fred, barney, & pebbles'); ### `_.escapeRegExp([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10490 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escaperegexp "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10544 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escaperegexp "See the npm package") Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. @@ -6529,7 +6718,7 @@ _.escapeRegExp('[lodash](https://lodash.com/)'); ### `_.kebabCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10516 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.kebabcase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10570 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.kebabcase "See the npm package") Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). @@ -6557,7 +6746,7 @@ _.kebabCase('__foo_bar__'); ### `_.pad([string=''], [length=0], [chars=' '])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10542 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pad "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10596 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pad "See the npm package") Pads `string` on the left and right sides if it's shorter than `length`. Padding characters are truncated if they can't be evenly divided by `length`. @@ -6588,7 +6777,7 @@ _.pad('abc', 3); ### `_.padLeft([string=''], [length=0], [chars=' '])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10580 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padleft "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10634 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padleft "See the npm package") Pads `string` on the left side if it's shorter than `length`. Padding characters are truncated if they exceed `length`. @@ -6619,7 +6808,7 @@ _.padLeft('abc', 3); ### `_.padRight([string=''], [length=0], [chars=' '])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10604 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10658 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padright "See the npm package") Pads `string` on the right side if it's shorter than `length`. Padding characters are truncated if they exceed `length`. @@ -6650,7 +6839,7 @@ _.padRight('abc', 3); ### `_.parseInt(string, [radix])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10629 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.parseint "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10683 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.parseint "See the npm package") Converts `string` to an integer of the specified radix. If `radix` is `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, @@ -6682,7 +6871,7 @@ _.map(['6', '08', '10'], _.parseInt); ### `_.repeat([string=''], [n=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10671 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.repeat "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10716 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.repeat "See the npm package") Repeats the given string `n` times. @@ -6711,7 +6900,7 @@ _.repeat('abc', 0); ### `_.snakeCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10710 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.snakecase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10755 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.snakecase "See the npm package") Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). @@ -6739,7 +6928,7 @@ _.snakeCase('--foo-bar'); ### `_.startCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10733 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startcase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10778 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startcase "See the npm package") Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). @@ -6767,7 +6956,7 @@ _.startCase('__foo_bar__'); ### `_.startsWith([string=''], [target], [position=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10758 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startswith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10803 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startswith "See the npm package") Checks if `string` starts with the given target string. @@ -6797,7 +6986,7 @@ _.startsWith('abc', 'b', 1); ### `_.template([string=''], [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10863 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.template "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L10908 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.template "See the npm package") Creates a compiled template function that can interpolate data properties in "interpolate" delimiters, HTML-escape interpolated data properties in @@ -6904,7 +7093,7 @@ fs.writeFileSync(path.join(cwd, 'jst.js'), '\ ### `_.trim([string=''], [chars=whitespace])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L10990 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trim "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11035 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trim "See the npm package") Removes leading and trailing whitespace or specified characters from `string`. @@ -6933,7 +7122,7 @@ _.map([' foo ', ' bar '], _.trim); ### `_.trimLeft([string=''], [chars=whitespace])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11021 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimleft "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11066 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimleft "See the npm package") Removes leading whitespace or specified characters from `string`. @@ -6959,7 +7148,7 @@ _.trimLeft('-_-abc-_-', '_-'); ### `_.trimRight([string=''], [chars=whitespace])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11051 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11096 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimright "See the npm package") Removes trailing whitespace or specified characters from `string`. @@ -6985,7 +7174,7 @@ _.trimRight('-_-abc-_-', '_-'); ### `_.trunc([string=''], [options], [options.length=30], [options.omission='...'], [options.separator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11103 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trunc "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11148 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trunc "See the npm package") Truncates `string` if it's longer than the given maximum string length. The last characters of the truncated string are replaced with the omission @@ -7033,7 +7222,7 @@ _.trunc('hi-diddly-ho there, neighborino', { ### `_.unescape([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11173 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unescape "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11218 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unescape "See the npm package") The inverse of `_.escape`; this method converts the HTML entities `&`, `<`, `>`, `"`, `'`, and ``` in `string` to their @@ -7061,7 +7250,7 @@ _.unescape('fred, barney, & pebbles'); ### `_.words([string=''], [pattern])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11198 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.words "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11243 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.words "See the npm package") Splits `string` into an array of its words. @@ -7093,7 +7282,7 @@ _.words('fred, barney, & pebbles', /[^, ]+/g); ### `_.attempt(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11228 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.attempt "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11273 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.attempt "See the npm package") Attempts to invoke `func`, returning either the result or the caught error object. Any additional arguments are provided to `func` when it is invoked. @@ -7122,7 +7311,7 @@ if (_.isError(elements)) { ### `_.callback([func=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11274 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.callback "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11319 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.callback "See the npm package") Creates a function that invokes `func` with the `this` binding of `thisArg` and arguments of the created function. If `func` is a property name the @@ -7170,7 +7359,7 @@ _.filter(users, 'age__gt36'); ### `_.constant(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11299 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.constant "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11344 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.constant "See the npm package") Creates a function that returns `value`. @@ -7195,7 +7384,7 @@ getter() === object; ### `_.identity(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11320 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.identity "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11365 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.identity "See the npm package") This method returns the first argument provided to it. @@ -7219,7 +7408,7 @@ _.identity(object) === object; ### `_.matches(source)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11349 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matches "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11394 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matches "See the npm package") Creates a function that performs a deep comparison between a given object and `source`, returning `true` if the given object has equivalent property @@ -7254,7 +7443,7 @@ _.filter(users, _.matches({ 'age': 40, 'active': false })); ### `_.matchesProperty(path, srcValue)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11377 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matchesproperty "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11422 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matchesproperty "See the npm package") Creates a function that compares the property value of `path` on a given object to `value`. @@ -7288,7 +7477,7 @@ _.find(users, _.matchesProperty('user', 'fred')); ### `_.method(path, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11404 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.method "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11449 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.method "See the npm package") Creates a function that invokes the method at `path` on a given object. Any additional arguments are provided to the invoked method. @@ -7320,7 +7509,7 @@ _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c'); ### `_.methodOf(object, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11432 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.methodof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11477 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.methodof "See the npm package") The opposite of `_.method`; this method creates a function that invokes the method at a given path on `object`. Any additional arguments are @@ -7351,7 +7540,7 @@ _.map([['a', '2'], ['c', '0']], _.methodOf(object)); ### `_.mixin([object=lodash], source, [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11474 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mixin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11519 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mixin "See the npm package") Adds all own enumerable function properties of a source object to the destination object. If `object` is a function then methods are added to @@ -7396,7 +7585,7 @@ _('fred').vowels(); ### `_.noConflict()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11539 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noconflict "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11582 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noconflict "See the npm package") Reverts the `_` variable to its previous value and returns a reference to the `lodash` function. @@ -7415,7 +7604,7 @@ var lodash = _.noConflict(); ### `_.noop()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11558 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noop "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11601 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noop "See the npm package") A no-operation function that returns `undefined` regardless of the arguments it receives. @@ -7434,7 +7623,7 @@ _.noop(object) === undefined; ### `_.property(path)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11584 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.property "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11627 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.property "See the npm package") Creates a function that returns the property value at `path` on a given object. @@ -7465,7 +7654,7 @@ _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); ### `_.propertyOf(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11608 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.propertyof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11651 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.propertyof "See the npm package") The opposite of `_.property`; this method creates a function that returns the property value at a given path on `object`. @@ -7494,7 +7683,7 @@ _.map([['a', '2'], ['c', '0']], _.propertyOf(object)); ### `_.range([start=0], end, [step=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11647 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.range "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11690 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.range "See the npm package") Creates an array of numbers (positive and/or negative) progressing from `start` up to, but not including, `end`. If `end` is not specified it is @@ -7536,7 +7725,7 @@ _.range(0); ### `_.runInContext([context=root])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L717 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.runincontext "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L723 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.runincontext "See the npm package") Create a new pristine `lodash` function using the given `context` object. @@ -7580,7 +7769,7 @@ var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; ### `_.times(n, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11700 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.times "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11743 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.times "See the npm package") Invokes the iteratee function `n` times, returning an array of the results of each invocation. The `iteratee` is bound to `thisArg` and invoked with @@ -7616,7 +7805,7 @@ _.times(3, function(n) { ### `_.uniqueId([prefix])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L11738 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqueid "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L11781 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqueid "See the npm package") Generates a unique ID. If `prefix` is provided the ID is appended to it. @@ -7647,7 +7836,7 @@ _.uniqueId(); ### `_.templateSettings.imports._` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1164 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1122 "View in source") [Ⓣ][1] A reference to the `lodash` function. @@ -7664,7 +7853,7 @@ A reference to the `lodash` function. ### `_.VERSION` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L12191 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L12299 "View in source") [Ⓣ][1] (string): The semantic version number. @@ -7675,7 +7864,7 @@ A reference to the `lodash` function. ### `_.support` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L999 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.support "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L986 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.support "See the npm package") (Object): An object environment feature flags. @@ -7685,20 +7874,8 @@ A reference to the `lodash` function. -### `_.support.argsTag` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1016 "View in source") [Ⓣ][1] - -(boolean): Detect if the `toStringTag` of `arguments` objects is resolvable -(all but Firefox < 4, IE < 9). - -* * * - - - - - ### `_.support.enumErrorProps` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1025 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1003 "View in source") [Ⓣ][1] (boolean): Detect if `name` or `message` properties of `Error.prototype` are enumerable by default (IE < 9, Safari < 5.1). @@ -7710,7 +7887,7 @@ enumerable by default (IE < 9, Safari < 5.1). ### `_.support.enumPrototypes` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1039 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1017 "View in source") [Ⓣ][1] (boolean): Detect if `prototype` properties are enumerable by default.
@@ -7726,19 +7903,8 @@ property to `true`. -### `_.support.nodeTag` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1047 "View in source") [Ⓣ][1] - -(boolean): Detect if the `toStringTag` of DOM nodes is resolvable (all but IE < 9). - -* * * - - - - - ### `_.support.nonEnumShadows` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1058 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1028 "View in source") [Ⓣ][1] (boolean): Detect if properties shadowing those on `Object.prototype` are non-enumerable.
@@ -7753,7 +7919,7 @@ are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). ### `_.support.ownLast` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1066 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1036 "View in source") [Ⓣ][1] (boolean): Detect if own properties are iterated after inherited properties (IE < 9). @@ -7764,7 +7930,7 @@ are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). ### `_.support.spliceObjects` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1081 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1051 "View in source") [Ⓣ][1] (boolean): Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. @@ -7783,7 +7949,7 @@ while `splice()` is buggy regardless of mode in IE < 9. ### `_.support.unindexedChars` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1092 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1062 "View in source") [Ⓣ][1] (boolean): Detect lack of support for accessing string characters by index.
@@ -7798,7 +7964,7 @@ by index on string literals, not string objects. ### `_.templateSettings` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1116 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.templatesettings "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1074 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.templatesettings "See the npm package") (Object): By default, the template delimiters used by lodash are like those in embedded Ruby (ERB). Change the following template settings to use @@ -7811,7 +7977,7 @@ alternative delimiters. ### `_.templateSettings.escape` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1124 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1082 "View in source") [Ⓣ][1] (RegExp): Used to detect `data` property values to be HTML-escaped. @@ -7822,7 +7988,7 @@ alternative delimiters. ### `_.templateSettings.evaluate` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1132 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1090 "View in source") [Ⓣ][1] (RegExp): Used to detect code to be evaluated. @@ -7833,7 +7999,7 @@ alternative delimiters. ### `_.templateSettings.imports` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1156 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1114 "View in source") [Ⓣ][1] (Object): Used to import variables into the compiled template. @@ -7844,7 +8010,7 @@ alternative delimiters. ### `_.templateSettings.interpolate` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1140 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1098 "View in source") [Ⓣ][1] (RegExp): Used to detect `data` property values to inject. @@ -7855,7 +8021,7 @@ alternative delimiters. ### `_.templateSettings.variable` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.9.3/lodash.src.js#L1148 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.10.0/lodash.src.js#L1106 "View in source") [Ⓣ][1] (string): Used to reference the data object in the template text. diff --git a/lodash.js b/lodash.js index 73bf0b122c..e1eb0ad15e 100644 --- a/lodash.js +++ b/lodash.js @@ -1,6 +1,6 @@ /** * @license - * lodash 3.9.3 (Custom Build) + * lodash 3.10.0 (Custom Build) * Build: `lodash modern -o ./lodash.js` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.8.3 @@ -13,7 +13,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '3.9.3'; + var VERSION = '3.10.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -34,9 +34,11 @@ var HOT_COUNT = 150, HOT_SPAN = 16; + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + /** Used to indicate the type of lazy iteratees. */ - var LAZY_DROP_WHILE_FLAG = 0, - LAZY_FILTER_FLAG = 1, + var LAZY_FILTER_FLAG = 1, LAZY_MAP_FLAG = 2; /** Used as the `TypeError` message for "Functions" methods. */ @@ -93,11 +95,10 @@ rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; /** - * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special). - * In addition to special characters the forward slash is escaped to allow for - * easier `eval` use and `Function` compilation. + * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) + * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). */ - var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, + var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, reHasRegExpChars = RegExp(reRegExpChars.source); /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ @@ -106,7 +107,7 @@ /** Used to match backslashes in property paths. */ var reEscapeChar = /\\(\\)?/g; - /** Used to match [ES template delimiters](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components). */ + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; /** Used to match `RegExp` flags from their coerced string values. */ @@ -138,25 +139,13 @@ return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); }()); - /** Used to detect and test for whitespace. */ - var whitespace = ( - // Basic whitespace characters. - ' \t\x0b\f\xa0\ufeff' + - - // Line terminators. - '\n\r\u2028\u2029' + - - // Unicode category "Zs" space separators. - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); - /** Used to assign default `context` object properties. */ var contextProps = [ 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', - 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', - 'isFinite', 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', - 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', 'window' + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', + 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' ]; /** Used to make template sourceURLs easier to identify. */ @@ -192,13 +181,6 @@ cloneableTags[mapTag] = cloneableTags[setTag] = cloneableTags[weakMapTag] = false; - /** Used as an internal `_.debounce` options object by `_.throttle`. */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; - /** 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', @@ -246,6 +228,15 @@ 'object': true }; + /** Used to escape characters for inclusion in compiled regexes. */ + var regexpEscapes = { + '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', + '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', + 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', + 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', + 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' + }; + /** Used to escape characters for inclusion in compiled string literals. */ var stringEscapes = { '\\': '\\', @@ -386,9 +377,6 @@ * @returns {string} Returns the string. */ function baseToString(value) { - if (typeof value == 'string') { - return value; - } return value == null ? '' : (value + ''); } @@ -430,8 +418,8 @@ * sort them in ascending order. * * @private - * @param {Object} object The object to compare to `other`. - * @param {Object} other The object to compare to `object`. + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. * @returns {number} Returns the sort order indicator for `object`. */ function compareAscending(object, other) { @@ -439,16 +427,16 @@ } /** - * Used by `_.sortByOrder` to compare multiple properties of each element - * in a collection and stable sort them in the following order: + * Used by `_.sortByOrder` to compare multiple properties of a value to another + * and stable sort them. * - * If `orders` is unspecified, sort in ascending order for all properties. - * Otherwise, for each property, sort in ascending order if its corresponding value in - * orders is true, and descending order if false. + * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, + * a value is sorted in ascending order if its corresponding order is "asc", and + * descending if "desc". * * @private - * @param {Object} object The object to compare to `other`. - * @param {Object} other The object to compare to `object`. + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. * @param {boolean[]} orders The order to sort by for each property. * @returns {number} Returns the sort order indicator for `object`. */ @@ -465,7 +453,8 @@ if (index >= ordersLength) { return result; } - return result * (orders[index] ? 1 : -1); + var order = orders[index]; + return result * ((order === 'asc' || order === true) ? 1 : -1); } } // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications @@ -501,8 +490,25 @@ } /** - * Used by `_.template` to escape characters for inclusion in compiled - * string literals. + * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. + * + * @private + * @param {string} chr The matched character to escape. + * @param {string} leadingChar The capture group for a leading character. + * @param {string} whitespaceChar The capture group for a whitespace character. + * @returns {string} Returns the escaped character. + */ + function escapeRegExpChar(chr, leadingChar, whitespaceChar) { + if (leadingChar) { + chr = regexpEscapes[chr]; + } else if (whitespaceChar) { + chr = stringEscapes[chr]; + } + return '\\' + chr; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. * * @private * @param {string} chr The matched character to escape. @@ -713,9 +719,6 @@ objectProto = Object.prototype, stringProto = String.prototype; - /** Used to detect DOM support. */ - var document = (document = context.window) ? document.document : null; - /** Used to resolve the decompiled source of functions. */ var fnToString = Function.prototype.toString; @@ -726,56 +729,42 @@ var idCounter = 0; /** - * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) * of values. */ var objToString = objectProto.toString; /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = context._; + var oldDash = root._; /** Used to detect if a method is native. */ var reIsNative = RegExp('^' + - escapeRegExp(fnToString.call(hasOwnProperty)) + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); /** Native method references. */ - var ArrayBuffer = getNative(context, 'ArrayBuffer'), - bufferSlice = getNative(ArrayBuffer && new ArrayBuffer(0), 'slice'), - ceil = Math.ceil, + var ArrayBuffer = context.ArrayBuffer, clearTimeout = context.clearTimeout, - floor = Math.floor, - getPrototypeOf = getNative(Object, 'getPrototypeOf'), parseFloat = context.parseFloat, - push = arrayProto.push, + pow = Math.pow, + propertyIsEnumerable = objectProto.propertyIsEnumerable, Set = getNative(context, 'Set'), setTimeout = context.setTimeout, splice = arrayProto.splice, - Uint8Array = getNative(context, 'Uint8Array'), + Uint8Array = context.Uint8Array, WeakMap = getNative(context, 'WeakMap'); - /** Used to clone array buffers. */ - var Float64Array = (function() { - // Safari 5 errors when using an array buffer to initialize a typed array - // where the array buffer's `byteLength` is not a multiple of the typed - // array's `BYTES_PER_ELEMENT`. - try { - var func = getNative(context, 'Float64Array'), - result = new func(new ArrayBuffer(10), 0, 1) && func; - } catch(e) {} - return result || null; - }()); - /* Native method references for those with the same name as other `lodash` methods. */ - var nativeCreate = getNative(Object, 'create'), + var nativeCeil = Math.ceil, + nativeCreate = getNative(Object, 'create'), + nativeFloor = Math.floor, nativeIsArray = getNative(Array, 'isArray'), nativeIsFinite = context.isFinite, nativeKeys = getNative(Object, 'keys'), nativeMax = Math.max, nativeMin = Math.min, nativeNow = getNative(Date, 'now'), - nativeNumIsFinite = getNative(Number, 'isFinite'), nativeParseInt = context.parseInt, nativeRandom = Math.random; @@ -788,11 +777,8 @@ MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - /** Used as the size, in bytes, of each `Float64Array` element. */ - var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; - /** - * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) * of an array-like value. */ var MAX_SAFE_INTEGER = 9007199254740991; @@ -808,15 +794,16 @@ /** * Creates a `lodash` object which wraps `value` to enable implicit chaining. * Methods that operate on and return arrays, collections, and functions can - * be chained together. Methods that return a boolean or single value will - * automatically end the chain returning the unwrapped value. Explicit chaining - * may be enabled using `_.chain`. The execution of chained methods is lazy, - * that is, execution is deferred until `_#value` is implicitly or explicitly - * called. + * be chained together. Methods that retrieve a single value or may return a + * primitive value will automatically end the chain returning the unwrapped + * value. Explicit chaining may be enabled using `_.chain`. The execution of + * chained methods is lazy, that is, execution is deferred until `_#value` + * is implicitly or explicitly called. * * Lazy evaluation allows several methods to support shortcut fusion. Shortcut - * fusion is an optimization that merges iteratees to avoid creating intermediate - * arrays and reduce the number of iteratee executions. + * fusion is an optimization strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly reduce the + * number of iteratee executions. * * Chaining is supported in custom builds as long as the `_#value` method is * directly or indirectly included in the build. @@ -839,36 +826,37 @@ * The chainable wrapper methods are: * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, - * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, - * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, - * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, - * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, - * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, - * `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, - * `memoize`, `merge`, `method`, `methodOf`, `mixin`, `negate`, `omit`, `once`, - * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `plant`, `pluck`, - * `property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, `rearg`, - * `reject`, `remove`, `rest`, `restParam`, `reverse`, `set`, `shuffle`, - * `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, `spread`, - * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, - * `thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`, - * `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `where`, `without`, - * `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, + * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` * * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, - * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, - * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `get`, - * `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, - * `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, - * `isFinite` `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, - * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lt`, `lte`, - * `max`, `min`, `noConflict`, `noop`, `now`, `pad`, `padLeft`, `padRight`, - * `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, - * `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, - * `sortedLastIndex`, `startCase`, `startsWith`, `sum`, `template`, `trim`, - * `trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, `value`, and `words` + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, + * `unescape`, `uniqueId`, `value`, and `words` * * The wrapper method `sample` will return a wrapped value when `n` is provided, * otherwise an unwrapped value is returned. @@ -943,27 +931,6 @@ */ var support = lodash.support = {}; - (function(x) { - var Ctor = function() { this.x = x; }, - object = { '0': x, 'length': x }, - props = []; - - Ctor.prototype = { 'valueOf': x, 'y': x }; - for (var key in new Ctor) { props.push(key); } - - /** - * Detect if the DOM is supported. - * - * @memberOf _.support - * @type boolean - */ - try { - support.dom = document.createDocumentFragment().nodeType === 11; - } catch(e) { - support.dom = false; - } - }(1, 0)); - /** * By default, the template delimiters used by lodash are like those in * embedded Ruby (ERB). Change the following template settings to use @@ -1035,13 +1002,12 @@ */ function LazyWrapper(value) { this.__wrapped__ = value; - this.__actions__ = null; + this.__actions__ = []; this.__dir__ = 1; - this.__dropCount__ = 0; this.__filtered__ = false; - this.__iteratees__ = null; + this.__iteratees__ = []; this.__takeCount__ = POSITIVE_INFINITY; - this.__views__ = null; + this.__views__ = []; } /** @@ -1053,17 +1019,13 @@ * @returns {Object} Returns the cloned `LazyWrapper` object. */ function lazyClone() { - var actions = this.__actions__, - iteratees = this.__iteratees__, - views = this.__views__, - result = new LazyWrapper(this.__wrapped__); - - result.__actions__ = actions ? arrayCopy(actions) : null; + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = arrayCopy(this.__actions__); result.__dir__ = this.__dir__; result.__filtered__ = this.__filtered__; - result.__iteratees__ = iteratees ? arrayCopy(iteratees) : null; + result.__iteratees__ = arrayCopy(this.__iteratees__); result.__takeCount__ = this.__takeCount__; - result.__views__ = views ? arrayCopy(views) : null; + result.__views__ = arrayCopy(this.__views__); return result; } @@ -1096,22 +1058,25 @@ * @returns {*} Returns the unwrapped value. */ function lazyValue() { - var array = this.__wrapped__.value(); - if (!isArray(array)) { - return baseWrapperValue(array, this.__actions__); - } - var dir = this.__dir__, + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), isRight = dir < 0, - view = getView(0, array.length, this.__views__), + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), start = view.start, end = view.end, length = end - start, index = isRight ? end : (start - 1), - takeCount = nativeMin(length, this.__takeCount__), iteratees = this.__iteratees__, - iterLength = iteratees ? iteratees.length : 0, + iterLength = iteratees.length, resIndex = 0, - result = []; + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); + } + var result = []; outer: while (length-- && resIndex < takeCount) { @@ -1123,30 +1088,16 @@ while (++iterIndex < iterLength) { var data = iteratees[iterIndex], iteratee = data.iteratee, - type = data.type; + type = data.type, + computed = iteratee(value); - if (type == LAZY_DROP_WHILE_FLAG) { - if (data.done && (isRight ? (index > data.index) : (index < data.index))) { - data.count = 0; - data.done = false; - } - data.index = index; - if (!data.done) { - var limit = data.limit; - if (!(data.done = limit > -1 ? (data.count++ >= limit) : !iteratee(value))) { - continue outer; - } - } - } else { - var computed = iteratee(value); - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; } } } @@ -1278,6 +1229,30 @@ /*------------------------------------------------------------------------*/ + /** + * Creates a new array joining `array` with `other`. + * + * @private + * @param {Array} array The array to join. + * @param {Array} other The other array to join. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } + /** * Copies the values of `source` to `array`. * @@ -1433,6 +1408,25 @@ return result; } + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + /** * A specialized version of `_.reduce` for arrays without support for callback * shorthands and `this` binding. @@ -1504,18 +1498,20 @@ } /** - * A specialized version of `_.sum` for arrays without support for iteratees. + * A specialized version of `_.sum` for arrays without support for callback + * shorthands and `this` binding.. * * @private * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. * @returns {number} Returns the sum. */ - function arraySum(array) { + function arraySum(array, iteratee) { var length = array.length, result = 0; while (length--) { - result += +array[length] || 0; + result += +iteratee(array[length]) || 0; } return result; } @@ -1719,7 +1715,7 @@ : (object ? value : {}); } } - // Check for circular references and return corresponding clone. + // Check for circular references and return its corresponding clone. stackA || (stackA = []); stackB || (stackB = []); @@ -1754,7 +1750,7 @@ if (isObject(prototype)) { object.prototype = prototype; var result = new object; - object.prototype = null; + object.prototype = undefined; } return result || {}; }; @@ -1796,7 +1792,7 @@ var index = -1, indexOf = getIndexOf(), isCommon = indexOf == baseIndexOf, - cache = (isCommon && values.length >= 200) ? createCache(values) : null, + cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, valuesLength = values.length; if (cache) { @@ -1972,13 +1968,14 @@ * @param {Array} array The array to flatten. * @param {boolean} [isDeep] Specify a deep flatten. * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ - function baseFlatten(array, isDeep, isStrict) { + function baseFlatten(array, isDeep, isStrict, result) { + result || (result = []); + var index = -1, - length = array.length, - resIndex = -1, - result = []; + length = array.length; while (++index < length) { var value = array[index]; @@ -1986,16 +1983,12 @@ (isStrict || isArray(value) || isArguments(value))) { if (isDeep) { // Recursively flatten arrays (susceptible to call stack limits). - value = baseFlatten(value, isDeep, isStrict); - } - var valIndex = -1, - valLength = value.length; - - while (++valIndex < valLength) { - result[++resIndex] = value[valIndex]; + baseFlatten(value, isDeep, isStrict, result); + } else { + arrayPush(result, value); } } else if (!isStrict) { - result[++resIndex] = value; + result[result.length] = value; } } return result; @@ -2350,7 +2343,7 @@ * @private * @param {Object} object The destination object. * @param {Object} source The source object. - * @param {Function} [customizer] The function to customize merging properties. + * @param {Function} [customizer] The function to customize merged values. * @param {Array} [stackA=[]] Tracks traversed source objects. * @param {Array} [stackB=[]] Associates values with source counterparts. * @returns {Object} Returns `object`. @@ -2360,7 +2353,7 @@ return object; } var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), - props = isSrcArr ? null : keys(source); + props = isSrcArr ? undefined : keys(source); arrayEach(props || source, function(srcValue, key) { if (props) { @@ -2399,7 +2392,7 @@ * @param {Object} source The source object. * @param {string} key The key of the value to merge. * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize merging properties. + * @param {Function} [customizer] The function to customize merged values. * @param {Array} [stackA=[]] Tracks traversed source objects. * @param {Array} [stackB=[]] Associates values with source counterparts. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. @@ -2506,7 +2499,7 @@ * @returns {number} Returns the random number. */ function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); + return min + nativeFloor(nativeRandom() * (max - min + 1)); } /** @@ -2672,7 +2665,7 @@ indexOf = getIndexOf(), length = array.length, isCommon = indexOf == baseIndexOf, - isLarge = isCommon && length >= 200, + isLarge = isCommon && length >= LARGE_ARRAY_SIZE, seen = isLarge ? createCache() : null, result = []; @@ -2771,11 +2764,8 @@ length = actions.length; while (++index < length) { - var args = [result], - action = actions[index]; - - push.apply(args, action.args); - result = action.func.apply(action.thisArg, args); + var action = actions[index]; + result = action.func.apply(action.thisArg, arrayPush([result], action.args)); } return result; } @@ -2834,7 +2824,7 @@ valIsUndef = value === undefined; while (low < high) { - var mid = floor((low + high) / 2), + var mid = nativeFloor((low + high) / 2), computed = iteratee(array[mid]), isDef = computed !== undefined, isReflexive = computed === computed; @@ -2903,26 +2893,11 @@ * @returns {ArrayBuffer} Returns the cloned array buffer. */ function bufferClone(buffer) { - return bufferSlice.call(buffer, 0); - } - if (!bufferSlice) { - // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`. - bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) { - var byteLength = buffer.byteLength, - floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, - offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, - result = new ArrayBuffer(byteLength); + var result = new ArrayBuffer(buffer.byteLength), + view = new Uint8Array(result); - if (floatLength) { - var view = new Float64Array(result, 0, floatLength); - view.set(new Float64Array(buffer, 0, floatLength)); - } - if (byteLength != offset) { - view = new Uint8Array(result, offset); - view.set(new Uint8Array(buffer, offset)); - } - return result; - }; + view.set(new Uint8Array(buffer)); + return result; } /** @@ -2941,7 +2916,7 @@ argsLength = nativeMax(args.length - holdersLength, 0), leftIndex = -1, leftLength = partials.length, - result = Array(argsLength + leftLength); + result = Array(leftLength + argsLength); while (++leftIndex < leftLength) { result[leftIndex] = partials[leftIndex]; @@ -2988,12 +2963,7 @@ } /** - * Creates a function that aggregates a collection, creating an accumulator - * object composed from the results of running each element in the collection - * through an iteratee. - * - * **Note:** This function is used to create `_.countBy`, `_.groupBy`, `_.indexBy`, - * and `_.partition`. + * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. * * @private * @param {Function} setter The function to set keys and values of the accumulator object. @@ -3023,10 +2993,7 @@ } /** - * Creates a function that assigns properties of source object(s) to a given - * destination object. - * - * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`. + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. * * @private * @param {Function} assigner The function to assign values. @@ -3137,9 +3104,9 @@ * @param {Array} [values] The values to cache. * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. */ - var createCache = !(nativeCreate && Set) ? constant(null) : function(values) { - return new SetCache(values); - }; + function createCache(values) { + return (nativeCreate && Set) ? new SetCache(values) : null; + } /** * Creates a function that produces compound words out of the words in a @@ -3174,7 +3141,7 @@ function createCtorWrapper(Ctor) { return function() { // Use a `switch` statement to work with class constructors. - // See https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist // for more details. var args = arguments; switch (args.length) { @@ -3184,6 +3151,8 @@ case 3: return new Ctor(args[0], args[1], args[2]); case 4: return new Ctor(args[0], args[1], args[2], args[3]); case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); } var thisBinding = baseCreate(Ctor.prototype), result = Ctor.apply(thisBinding, args); @@ -3204,15 +3173,34 @@ function createCurry(flag) { function curryFunc(func, arity, guard) { if (guard && isIterateeCall(func, arity, guard)) { - arity = null; + arity = undefined; } - var result = createWrapper(func, flag, null, null, null, null, null, arity); + var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); result.placeholder = curryFunc.placeholder; return result; } return curryFunc; } + /** + * Creates a `_.defaults` or `_.defaultsDeep` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @param {Function} customizer The function to customize assigned values. + * @returns {Function} Returns the new defaults function. + */ + function createDefaults(assigner, customizer) { + return restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(customizer); + return assigner.apply(undefined, args); + }); + } + /** * Creates a `_.max` or `_.min` function. * @@ -3224,11 +3212,11 @@ function createExtremum(comparator, exValue) { return function(collection, iteratee, thisArg) { if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; + iteratee = undefined; } iteratee = getCallback(iteratee, thisArg, 3); if (iteratee.length == 1) { - collection = toIterable(collection); + collection = isArray(collection) ? collection : toIterable(collection); var result = arrayExtremum(collection, iteratee, comparator, exValue); if (!(collection.length && result === exValue)) { return result; @@ -3309,7 +3297,7 @@ throw new TypeError(FUNC_ERROR_TEXT); } if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { - wrapper = new LodashWrapper([]); + wrapper = new LodashWrapper([], true); } } index = wrapper ? -1 : length; @@ -3317,7 +3305,7 @@ func = funcs[index]; var funcName = getFuncName(func), - data = funcName == 'wrapper' ? getData(func) : null; + data = funcName == 'wrapper' ? getData(func) : undefined; if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); @@ -3326,12 +3314,14 @@ } } return function() { - var args = arguments; - if (wrapper && args.length == 1 && isArray(args[0])) { - return wrapper.plant(args[0]).value(); + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); } var index = 0, - result = length ? funcs[index].apply(this, args) : args[0]; + result = length ? funcs[index].apply(this, args) : value; while (++index < length) { result = funcs[index].call(this, result); @@ -3435,7 +3425,7 @@ function createPartial(flag) { var partialFunc = restParam(function(func, partials) { var holders = replaceHolders(partials, partialFunc.placeholder); - return createWrapper(func, flag, null, partials, holders); + return createWrapper(func, flag, undefined, partials, holders); }); return partialFunc; } @@ -3481,7 +3471,7 @@ isCurry = bitmask & CURRY_FLAG, isCurryBound = bitmask & CURRY_BOUND_FLAG, isCurryRight = bitmask & CURRY_RIGHT_FLAG, - Ctor = isBindKey ? null : createCtorWrapper(func); + Ctor = isBindKey ? undefined : createCtorWrapper(func); function wrapper() { // Avoid `arguments` object use disqualifying optimizations by @@ -3505,12 +3495,12 @@ length -= argsHolders.length; if (length < arity) { - var newArgPos = argPos ? arrayCopy(argPos) : null, + var newArgPos = argPos ? arrayCopy(argPos) : undefined, newArity = nativeMax(arity - length, 0), - newsHolders = isCurry ? argsHolders : null, - newHoldersRight = isCurry ? null : argsHolders, - newPartials = isCurry ? args : null, - newPartialsRight = isCurry ? null : args; + newsHolders = isCurry ? argsHolders : undefined, + newHoldersRight = isCurry ? undefined : argsHolders, + newPartials = isCurry ? args : undefined, + newPartialsRight = isCurry ? undefined : args; bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); @@ -3564,7 +3554,7 @@ } var padLength = length - strLength; chars = chars == null ? ' ' : (chars + ''); - return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength); + return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); } /** @@ -3590,7 +3580,7 @@ argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, - args = Array(argsLength + leftLength); + args = Array(leftLength + argsLength); while (++leftIndex < leftLength) { args[leftIndex] = partials[leftIndex]; @@ -3604,6 +3594,25 @@ return wrapper; } + /** + * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + precision = precision === undefined ? 0 : (+precision || 0); + if (precision) { + precision = pow(10, precision); + return func(number * precision) / precision; + } + return func(number); + }; + } + /** * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. * @@ -3653,16 +3662,16 @@ var length = partials ? partials.length : 0; if (!length) { bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); - partials = holders = null; + partials = holders = undefined; } length -= (holders ? holders.length : 0); if (bitmask & PARTIAL_RIGHT_FLAG) { var partialsRight = partials, holdersRight = holders; - partials = holders = null; + partials = holders = undefined; } - var data = isBindKey ? null : getData(func), + var data = isBindKey ? undefined : getData(func), newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; if (data) { @@ -3741,7 +3750,7 @@ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * * @private - * @param {Object} value The object to compare. + * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {string} tag The `toStringTag` of the objects to compare. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. @@ -3941,13 +3950,13 @@ * @private * @param {number} start The start of the view. * @param {number} end The end of the view. - * @param {Array} [transforms] The transformations to apply to the view. + * @param {Array} transforms The transformations to apply to the view. * @returns {Object} Returns an object containing the `start` and `end` * positions of the view. */ function getView(start, end, transforms) { var index = -1, - length = transforms ? transforms.length : 0; + length = transforms.length; while (++index < length) { var data = transforms[index], @@ -4146,7 +4155,7 @@ /** * Checks if `value` is a valid array-like length. * - * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). * * @private * @param {*} value The value to check. @@ -4238,6 +4247,18 @@ return data; } + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function mergeDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); + } + /** * A specialized version of `_.pick` which picks `object` properties specified * by `props`. @@ -4337,38 +4358,6 @@ }; }()); - /** - * A fallback implementation of `_.isPlainObject` which checks if `value` - * is an object created by the `Object` constructor or has a `[[Prototype]]` - * of `null`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var Ctor, - support = lodash.support; - - // Exit early for non `Object` objects. - if (!(isObjectLike(value) && objToString.call(value) == objectTag) || - (!hasOwnProperty.call(value, 'constructor') && - (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - var result; - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - baseForIn(value, function(subValue, key) { - result = key; - }); - return result === undefined || hasOwnProperty.call(value, result); - } - /** * A fallback implementation of `Object.keys` which creates an array of the * own enumerable property names of `object`. @@ -4482,12 +4471,12 @@ if (guard ? isIterateeCall(array, size, guard) : size == null) { size = 1; } else { - size = nativeMax(+size || 1, 1); + size = nativeMax(nativeFloor(size) || 1, 1); } var index = 0, length = array ? array.length : 0, resIndex = -1, - result = Array(ceil(length / size)); + result = Array(nativeCeil(length / size)); while (index < length) { result[++resIndex] = baseSlice(array, index, (index += size)); @@ -4526,7 +4515,7 @@ /** * Creates an array of unique `array` values not included in the other - * provided arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -4541,7 +4530,7 @@ * // => [1, 3] */ var difference = restParam(function(array, values) { - return isArrayLike(array) + return (isObjectLike(array) && isArrayLike(array)) ? baseDifference(array, baseFlatten(values, false, true)) : []; }); @@ -4936,7 +4925,7 @@ /** * Gets the index at which the first occurrence of `value` is found in `array` - * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. If `fromIndex` is negative, it is used as the offset * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` * performs a faster binary search. @@ -4970,10 +4959,9 @@ if (typeof fromIndex == 'number') { fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; } else if (fromIndex) { - var index = binaryIndex(array, value), - other = array[index]; - - if (value === value ? (value === other) : (other !== other)) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { return index; } return -1; @@ -5000,7 +4988,7 @@ /** * Creates an array of unique values that are included in all of the provided - * arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -5121,7 +5109,7 @@ /** * Removes all provided values from `array` using - * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * **Note:** Unlike `_.without`, this method mutates `array`. @@ -5554,7 +5542,7 @@ /** * Creates an array of unique values, in order, from all of the provided arrays - * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -5573,7 +5561,7 @@ /** * Creates a duplicate-free version of an array, using - * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons, in which only the first occurence of each element * is kept. Providing `true` for `isSorted` performs a faster search algorithm * for sorted arrays. If an iteratee function is provided it is invoked for @@ -5627,7 +5615,7 @@ } if (isSorted != null && typeof isSorted != 'boolean') { thisArg = iteratee; - iteratee = isIterateeCall(array, isSorted, thisArg) ? null : isSorted; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; isSorted = false; } var callback = getCallback(); @@ -5714,7 +5702,7 @@ /** * Creates an array excluding all provided values using - * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -5756,7 +5744,7 @@ var array = arguments[index]; if (isArrayLike(array)) { var result = result - ? baseDifference(result, array).concat(baseDifference(array, result)) + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) : array; } } @@ -5978,16 +5966,16 @@ * @example * * var array = [1, 2]; - * var wrapper = _(array).push(3); + * var wrapped = _(array).push(3); * * console.log(array); * // => [1, 2] * - * wrapper = wrapper.commit(); + * wrapped = wrapped.commit(); * console.log(array); * // => [1, 2, 3] * - * wrapper.last(); + * wrapped.last(); * // => 3 * * console.log(array); @@ -5997,6 +5985,33 @@ return new LodashWrapper(this.value(), this.__chain__); } + /** + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. + * + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); + }); + /** * Creates a clone of the chained sequence planting `value` as the wrapped value. * @@ -6007,17 +6022,17 @@ * @example * * var array = [1, 2]; - * var wrapper = _(array).map(function(value) { + * var wrapped = _(array).map(function(value) { * return Math.pow(value, 2); * }); * * var other = [3, 4]; - * var otherWrapper = wrapper.plant(other); + * var otherWrapped = wrapped.plant(other); * - * otherWrapper.value(); + * otherWrapped.value(); * // => [9, 16] * - * wrapper.value(); + * wrapped.value(); * // => [1, 4] */ function wrapperPlant(value) { @@ -6060,15 +6075,20 @@ */ function wrapperReverse() { var value = this.__wrapped__; + + var interceptor = function(value) { + return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); + }; if (value instanceof LazyWrapper) { + var wrapped = value; if (this.__actions__.length) { - value = new LazyWrapper(this); + wrapped = new LazyWrapper(this); } - return new LodashWrapper(value.reverse(), this.__chain__); + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); } - return this.thru(function(value) { - return value.reverse(); - }); + return this.thru(interceptor); } /** @@ -6226,7 +6246,7 @@ function every(collection, predicate, thisArg) { var func = isArray(collection) ? arrayEvery : baseEvery; if (thisArg && isIterateeCall(collection, predicate, thisArg)) { - predicate = null; + predicate = undefined; } if (typeof predicate != 'function' || thisArg !== undefined) { predicate = getCallback(predicate, thisArg, 3); @@ -6500,7 +6520,7 @@ /** * Checks if `value` is in `collection` using - * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. If `fromIndex` is negative, it is used as the offset * from the end of `collection`. * @@ -6533,17 +6553,14 @@ collection = values(collection); length = collection.length; } - if (!length) { - return false; - } if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { fromIndex = 0; } else { fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); } return (typeof collection == 'string' || !isArray(collection) && isString(collection)) - ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) - : (getIndexOf(collection, target, fromIndex) > -1); + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && getIndexOf(collection, target, fromIndex) > -1); } /** @@ -6625,7 +6642,7 @@ result = isArrayLike(collection) ? Array(collection.length) : []; baseEach(collection, function(value) { - var func = isFunc ? path : ((isProp && value != null) ? value[path] : null); + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); }); return result; @@ -6795,7 +6812,8 @@ * `_.reduce`, `_.reduceRight`, and `_.transform`. * * The guarded methods are: - * `assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder` + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` * * @static * @memberOf _ @@ -7025,7 +7043,7 @@ function some(collection, predicate, thisArg) { var func = isArray(collection) ? arraySome : baseSome; if (thisArg && isIterateeCall(collection, predicate, thisArg)) { - predicate = null; + predicate = undefined; } if (typeof predicate != 'function' || thisArg !== undefined) { predicate = getCallback(predicate, thisArg, 3); @@ -7086,7 +7104,7 @@ return []; } if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; + iteratee = undefined; } var index = -1; iteratee = getCallback(iteratee, thisArg, 3); @@ -7145,9 +7163,9 @@ /** * This method is like `_.sortByAll` except that it allows specifying the - * sort orders of the iteratees to sort by. A truthy value in `orders` will - * sort the corresponding property name in ascending order while a falsey - * value will sort it in descending order. + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". * * If a property name is provided for an iteratee the created `_.property` * style callback returns the property value of the given element. @@ -7161,7 +7179,7 @@ * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {boolean[]} orders The sort orders of `iteratees`. + * @param {boolean[]} [orders] The sort orders of `iteratees`. * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. * @returns {Array} Returns the new sorted array. * @example @@ -7174,7 +7192,7 @@ * ]; * * // sort by `user` in ascending order and by `age` in descending order - * _.map(_.sortByOrder(users, ['user', 'age'], [true, false]), _.values); + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ function sortByOrder(collection, iteratees, orders, guard) { @@ -7182,7 +7200,7 @@ return []; } if (guard && isIterateeCall(iteratees, orders, guard)) { - orders = null; + orders = undefined; } if (!isArray(iteratees)) { iteratees = iteratees == null ? [] : [iteratees]; @@ -7307,10 +7325,10 @@ */ function ary(func, n, guard) { if (guard && isIterateeCall(func, n, guard)) { - n = null; + n = undefined; } n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); - return createWrapper(func, ARY_FLAG, null, null, null, null, n); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); } /** @@ -7345,7 +7363,7 @@ result = func.apply(this, arguments); } if (n <= 1) { - func = null; + func = undefined; } return result; }; @@ -7653,9 +7671,9 @@ var leading = true; trailing = false; } else if (isObject(options)) { - leading = options.leading; + leading = !!options.leading; maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); - trailing = 'trailing' in options ? options.trailing : trailing; + trailing = 'trailing' in options ? !!options.trailing : trailing; } function cancel() { @@ -7665,41 +7683,35 @@ if (maxTimeoutId) { clearTimeout(maxTimeoutId); } + lastCalled = 0; maxTimeoutId = timeoutId = trailingCall = undefined; } + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + function delayed() { var remaining = wait - (now() - stamp); if (remaining <= 0 || remaining > wait) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } + complete(trailingCall, maxTimeoutId); } else { timeoutId = setTimeout(delayed, remaining); } } function maxDelayed() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } + complete(trailing, timeoutId); } function debounced() { @@ -7739,7 +7751,7 @@ result = func.apply(thisArg, args); } if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; + args = thisArg = undefined; } return result; } @@ -7844,7 +7856,7 @@ * * **Note:** The cache is exposed as the `cache` property on the memoized * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the [`Map`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) * method interface of `get`, `has`, and `set`. * * @static @@ -7905,6 +7917,52 @@ return memoized; } + /** + * Creates a function that runs each argument through a corresponding + * transform function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * modded(1, 2); + * // => [1, 4] + * + * modded(5, 10); + * // => [25, 20] + */ + var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); + }); + /** * Creates a function that negates the result of the predicate `func`. The * `func` predicate is invoked with the `this` binding and arguments of the @@ -8050,7 +8108,7 @@ * // => [3, 6, 9] */ var rearg = restParam(function(func, indexes) { - return createWrapper(func, REARG_FLAG, null, null, null, baseFlatten(indexes)); + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); }); /** @@ -8196,10 +8254,7 @@ leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } - debounceOptions.leading = leading; - debounceOptions.maxWait = +wait; - debounceOptions.trailing = trailing; - return debounce(func, wait, debounceOptions); + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); } /** @@ -8225,7 +8280,7 @@ */ function wrap(value, wrapper) { wrapper = wrapper == null ? identity : wrapper; - return createWrapper(wrapper, PARTIAL_FLAG, null, [value], []); + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); } /*------------------------------------------------------------------------*/ @@ -8411,7 +8466,8 @@ * // => false */ function isArguments(value) { - return isObjectLike(value) && isArrayLike(value) && objToString.call(value) == argsTag; + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); } /** @@ -8491,14 +8547,7 @@ * // => false */ function isElement(value) { - return !!value && value.nodeType === 1 && isObjectLike(value) && - (objToString.call(value).indexOf('Element') > -1); - } - // Fallback for environments without DOM support. - if (!support.dom) { - isElement = function(value) { - return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); - }; + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); } /** @@ -8613,7 +8662,7 @@ /** * Checks if `value` is a finite primitive number. * - * **Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). + * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). * * @static * @memberOf _ @@ -8637,9 +8686,9 @@ * _.isFinite(Infinity); * // => false */ - var isFinite = nativeNumIsFinite || function(value) { + function isFinite(value) { return typeof value == 'number' && nativeIsFinite(value); - }; + } /** * Checks if `value` is classified as a `Function` object. @@ -8657,12 +8706,12 @@ * _.isFunction(/abc/); * // => false */ - var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) { + function isFunction(value) { // The use of `Object#toString` avoids issues with the `typeof` operator // in older versions of Chrome and Safari which return 'function' for regexes // and Safari 8 equivalents which return 'object' for typed array constructors. - return objToString.call(value) == funcTag; - }; + return isObject(value) && objToString.call(value) == funcTag; + } /** * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. @@ -8786,7 +8835,7 @@ if (value == null) { return false; } - if (objToString.call(value) == funcTag) { + if (isFunction(value)) { return reIsNative.test(fnToString.call(value)); } return isObjectLike(value) && reIsHostCtor.test(value); @@ -8868,17 +8917,26 @@ * _.isPlainObject(Object.create(null)); * // => true */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && objToString.call(value) == objectTag)) { + function isPlainObject(value) { + var Ctor; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || + (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { return false; } - var valueOf = getNative(value, 'valueOf'), - objProto = valueOf && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return result === undefined || hasOwnProperty.call(value, result); + } /** * Checks if `value` is classified as a `RegExp` object. @@ -8897,7 +8955,7 @@ * // => false */ function isRegExp(value) { - return isObjectLike(value) && objToString.call(value) == regexpTag; + return isObject(value) && objToString.call(value) == regexpTag; } /** @@ -9063,6 +9121,56 @@ /*------------------------------------------------------------------------*/ + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it is invoked to produce the merged values of the destination and + * source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments: (objectValue, sourceValue, key, object, source). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + * + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var merge = createAssigner(baseMerge); + /** * Assigns own enumerable properties of source object(s) to the destination * object. Subsequent sources overwrite property assignments of previous sources. @@ -9071,7 +9179,7 @@ * (objectValue, sourceValue, key, object, source). * * **Note:** This method mutates `object` and is based on - * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). * * @static * @memberOf _ @@ -9138,7 +9246,7 @@ function create(prototype, properties, guard) { var result = baseCreate(prototype); if (guard && isIterateeCall(prototype, properties, guard)) { - properties = null; + properties = undefined; } return properties ? baseAssign(result, properties) : result; } @@ -9161,14 +9269,27 @@ * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); * // => { 'user': 'barney', 'age': 36 } */ - var defaults = restParam(function(args) { - var object = args[0]; - if (object == null) { - return object; - } - args.push(assignDefaults); - return assign.apply(undefined, args); - }); + var defaults = createDefaults(assign, assignDefaults); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ + var defaultsDeep = createDefaults(merge, mergeDefaults); /** * This method is like `_.find` except that it returns the key of the first @@ -9495,7 +9616,7 @@ */ function invert(object, multiValue, guard) { if (guard && isIterateeCall(object, multiValue, guard)) { - multiValue = null; + multiValue = undefined; } var index = -1, props = keys(object), @@ -9524,7 +9645,7 @@ * Creates an array of the own enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) * for more details. * * @static @@ -9548,7 +9669,7 @@ * // => ['0', '1'] */ var keys = !nativeKeys ? shimKeys : function(object) { - var Ctor = object == null ? null : object.constructor; + var Ctor = object == null ? undefined : object.constructor; if ((typeof Ctor == 'function' && Ctor.prototype === object) || (typeof object != 'function' && isArrayLike(object))) { return shimKeys(object); @@ -9672,56 +9793,6 @@ */ var mapValues = createObjectMapper(); - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * overwrite property assignments of previous sources. If `customizer` is - * provided it is invoked to produce the merged values of the destination and - * source properties. If `customizer` returns `undefined` merging is handled - * by the method instead. The `customizer` is bound to `thisArg` and invoked - * with five arguments: (objectValue, sourceValue, key, object, source). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {Object} Returns `object`. - * @example - * - * var users = { - * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] - * }; - * - * var ages = { - * 'data': [{ 'age': 36 }, { 'age': 40 }] - * }; - * - * _.merge(users, ages); - * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } - * - * // using a customizer callback - * var object = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var other = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(object, other, function(a, b) { - * if (_.isArray(a)) { - * return a.concat(b); - * } - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } - */ - var merge = createAssigner(baseMerge); - /** * The opposite of `_.pick`; this method creates an object composed of the * own and inherited enumerable properties of `object` that are not omitted. @@ -9952,7 +10023,7 @@ if (isArr) { accumulator = isArray(object) ? new Ctor : []; } else { - accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : null); + accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); } } else { accumulator = {}; @@ -10055,7 +10126,7 @@ */ function inRange(value, start, end) { start = +start || 0; - if (typeof end === 'undefined') { + if (end === undefined) { end = start; start = 0; } else { @@ -10093,7 +10164,7 @@ */ function random(min, max, floating) { if (floating && isIterateeCall(min, max, floating)) { - max = floating = null; + max = floating = undefined; } var noMin = min == null, noMax = max == null; @@ -10280,8 +10351,8 @@ function escapeRegExp(string) { string = baseToString(string); return (string && reHasRegExpChars.test(string)) - ? string.replace(reRegExpChars, '\\$&') - : string; + ? string.replace(reRegExpChars, escapeRegExpChar) + : (string || '(?:)'); } /** @@ -10338,8 +10409,8 @@ return string; } var mid = (length - strLength) / 2, - leftLength = floor(mid), - rightLength = ceil(mid); + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); chars = createPadding('', rightLength, chars); return chars.slice(0, leftLength) + string + chars; @@ -10417,25 +10488,16 @@ * // => [6, 8, 10] */ function parseInt(string, radix, guard) { - if (guard && isIterateeCall(string, radix, guard)) { + // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard ? isIterateeCall(string, radix, guard) : radix == null) { radix = 0; + } else if (radix) { + radix = +radix; } - return nativeParseInt(string, radix); - } - // Fallback for environments with pre-ES5 implementations. - if (nativeParseInt(whitespace + '08') != 8) { - parseInt = function(string, radix, guard) { - // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. - // Chrome fails to trim leading whitespace characters. - // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. - if (guard ? isIterateeCall(string, radix, guard) : radix == null) { - radix = 0; - } else if (radix) { - radix = +radix; - } - string = trim(string); - return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); - }; + string = trim(string); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); } /** @@ -10471,7 +10533,7 @@ if (n % 2) { result += string; } - n = floor(n / 2); + n = nativeFloor(n / 2); string += string; } while (n); @@ -10656,7 +10718,7 @@ var settings = lodash.templateSettings; if (otherOptions && isIterateeCall(string, options, otherOptions)) { - options = otherOptions = null; + options = otherOptions = undefined; } string = baseToString(string); options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults); @@ -10892,7 +10954,7 @@ */ function trunc(string, options, guard) { if (guard && isIterateeCall(string, options, guard)) { - options = null; + options = undefined; } var length = DEFAULT_TRUNC_LENGTH, omission = DEFAULT_TRUNC_OMISSION; @@ -10987,7 +11049,7 @@ */ function words(string, pattern, guard) { if (guard && isIterateeCall(string, pattern, guard)) { - pattern = null; + pattern = undefined; } string = baseToString(string); return string.match(pattern || reWords) || []; @@ -11063,7 +11125,7 @@ */ function callback(func, thisArg, guard) { if (guard && isIterateeCall(func, thisArg, guard)) { - thisArg = null; + thisArg = undefined; } return isObjectLike(func) ? matches(func) @@ -11264,8 +11326,8 @@ function mixin(object, source, options) { if (options == null) { var isObj = isObject(source), - props = isObj ? keys(source) : null, - methodNames = (props && props.length) ? baseFunctions(source, props) : null; + props = isObj ? keys(source) : undefined, + methodNames = (props && props.length) ? baseFunctions(source, props) : undefined; if (!(methodNames ? methodNames.length : isObj)) { methodNames = false; @@ -11304,9 +11366,7 @@ result.__chain__ = chainAll; return result; } - var args = [this.value()]; - push.apply(args, arguments); - return func.apply(object, args); + return func.apply(object, arrayPush([this.value()], arguments)); }; }(func)); } @@ -11327,7 +11387,7 @@ * var lodash = _.noConflict(); */ function noConflict() { - context._ = oldDash; + root._ = oldDash; return this; } @@ -11436,7 +11496,7 @@ */ function range(start, end, step) { if (step && isIterateeCall(start, end, step)) { - end = step = null; + end = step = undefined; } start = +start || 0; step = step == null ? 1 : (+step || 0); @@ -11450,7 +11510,7 @@ // Use `Array(length)` so engines like Chakra and V8 avoid slower modes. // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details. var index = -1, - length = nativeMax(ceil((end - start) / (step || 1)), 0), + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), result = Array(length); while (++index < length) { @@ -11488,7 +11548,7 @@ * // => also invokes `mage.castSpell(n)` three times */ function times(n, iteratee, thisArg) { - n = floor(n); + n = nativeFloor(n); // Exit early to avoid a JSC JIT bug in Safari 8 // where `Array(0)` is treated as `Array(1)`. @@ -11550,6 +11610,50 @@ return (+augend || 0) + (+addend || 0); } + /** + * Calculates `n` rounded up to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} n The number to round up. + * @param {number} [precision=0] The precision to round up to. + * @returns {number} Returns the rounded up number. + * @example + * + * _.ceil(4.006); + * // => 5 + * + * _.ceil(6.004, 2); + * // => 6.01 + * + * _.ceil(6040, -2); + * // => 6100 + */ + var ceil = createRound('ceil'); + + /** + * Calculates `n` rounded down to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} n The number to round down. + * @param {number} [precision=0] The precision to round down to. + * @returns {number} Returns the rounded down number. + * @example + * + * _.floor(4.006); + * // => 4 + * + * _.floor(0.046, 2); + * // => 0.04 + * + * _.floor(4060, -2); + * // => 4000 + */ + var floor = createRound('floor'); + /** * Gets the maximum value of `collection`. If `collection` is empty or falsey * `-Infinity` is returned. If an iteratee function is provided it is invoked @@ -11648,6 +11752,28 @@ */ var min = createExtremum(lt, POSITIVE_INFINITY); + /** + * Calculates `n` rounded to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} n The number to round. + * @param {number} [precision=0] The precision to round to. + * @returns {number} Returns the rounded number. + * @example + * + * _.round(4.006); + * // => 4 + * + * _.round(4.006, 2); + * // => 4.01 + * + * _.round(4060, -2); + * // => 4100 + */ + var round = createRound('round'); + /** * Gets the sum of the values in `collection`. * @@ -11682,17 +11808,11 @@ */ function sum(collection, iteratee, thisArg) { if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; - } - var callback = getCallback(), - noIteratee = iteratee == null; - - if (!(noIteratee && callback === baseCallback)) { - noIteratee = false; - iteratee = callback(iteratee, thisArg, 3); + iteratee = undefined; } - return noIteratee - ? arraySum(isArray(collection) ? collection : toIterable(collection)) + iteratee = getCallback(iteratee, thisArg, 3); + return iteratee.length == 1 + ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee) : baseSum(collection, iteratee); } @@ -11739,6 +11859,7 @@ lodash.curryRight = curryRight; lodash.debounce = debounce; lodash.defaults = defaults; + lodash.defaultsDeep = defaultsDeep; lodash.defer = defer; lodash.delay = delay; lodash.difference = difference; @@ -11777,6 +11898,7 @@ lodash.method = method; lodash.methodOf = methodOf; lodash.mixin = mixin; + lodash.modArgs = modArgs; lodash.negate = negate; lodash.omit = omit; lodash.once = once; @@ -11852,6 +11974,7 @@ lodash.attempt = attempt; lodash.camelCase = camelCase; lodash.capitalize = capitalize; + lodash.ceil = ceil; lodash.clone = clone; lodash.cloneDeep = cloneDeep; lodash.deburr = deburr; @@ -11867,6 +11990,7 @@ lodash.findLastKey = findLastKey; lodash.findWhere = findWhere; lodash.first = first; + lodash.floor = floor; lodash.get = get; lodash.gt = gt; lodash.gte = gte; @@ -11915,6 +12039,7 @@ lodash.reduceRight = reduceRight; lodash.repeat = repeat; lodash.result = result; + lodash.round = round; lodash.runInContext = runInContext; lodash.size = size; lodash.snakeCase = snakeCase; @@ -11985,48 +12110,20 @@ lodash[methodName].placeholder = lodash; }); - // Add `LazyWrapper` methods that accept an `iteratee` value. - arrayEach(['dropWhile', 'filter', 'map', 'takeWhile'], function(methodName, type) { - var isFilter = type != LAZY_MAP_FLAG, - isDropWhile = type == LAZY_DROP_WHILE_FLAG; - - LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { - var filtered = this.__filtered__, - result = (filtered && isDropWhile) ? new LazyWrapper(this) : this.clone(), - iteratees = result.__iteratees__ || (result.__iteratees__ = []); - - iteratees.push({ - 'done': false, - 'count': 0, - 'index': 0, - 'iteratee': getCallback(iteratee, thisArg, 1), - 'limit': -1, - 'type': type - }); - - result.__filtered__ = filtered || isFilter; - return result; - }; - }); - // Add `LazyWrapper` methods for `_.drop` and `_.take` variants. arrayEach(['drop', 'take'], function(methodName, index) { - var whileName = methodName + 'While'; - LazyWrapper.prototype[methodName] = function(n) { - var filtered = this.__filtered__, - result = (filtered && !index) ? this.dropWhile() : this.clone(); + var filtered = this.__filtered__; + if (filtered && !index) { + return new LazyWrapper(this); + } + n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0); - n = n == null ? 1 : nativeMax(floor(n) || 0, 0); + var result = this.clone(); if (filtered) { - if (index) { - result.__takeCount__ = nativeMin(result.__takeCount__, n); - } else { - last(result.__iteratees__).limit = n; - } + result.__takeCount__ = nativeMin(result.__takeCount__, n); } else { - var views = result.__views__ || (result.__views__ = []); - views.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); + result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); } return result; }; @@ -12034,9 +12131,18 @@ LazyWrapper.prototype[methodName + 'Right'] = function(n) { return this.reverse()[methodName](n).reverse(); }; + }); + + // Add `LazyWrapper` methods that accept an `iteratee` value. + arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { + var type = index + 1, + isFilter = type != LAZY_MAP_FLAG; - LazyWrapper.prototype[methodName + 'RightWhile'] = function(predicate, thisArg) { - return this.reverse()[whileName](predicate, thisArg).reverse(); + LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { + var result = this.clone(); + result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type }); + result.__filtered__ = result.__filtered__ || isFilter; + return result; }; }); @@ -12054,7 +12160,7 @@ var dropName = 'drop' + (index ? '' : 'Right'); LazyWrapper.prototype[methodName] = function() { - return this[dropName](1); + return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1); }; }); @@ -12083,10 +12189,13 @@ start = start == null ? 0 : (+start || 0); var result = this; + if (result.__filtered__ && (start > 0 || end < 0)) { + return new LazyWrapper(result); + } if (start < 0) { - result = this.takeRight(-start); + result = result.takeRight(-start); } else if (start) { - result = this.drop(start); + result = result.drop(start); } if (end !== undefined) { end = (+end || 0); @@ -12095,21 +12204,25 @@ return result; }; + LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) { + return this.reverse().takeWhile(predicate, thisArg).reverse(); + }; + LazyWrapper.prototype.toArray = function() { - return this.drop(0); + return this.take(POSITIVE_INFINITY); }; // Add `LazyWrapper` methods to `lodash.prototype`. baseForOwn(LazyWrapper.prototype, function(func, methodName) { - var lodashFunc = lodash[methodName]; + var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName), + retUnwrapped = /^(?:first|last)$/.test(methodName), + lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName]; + if (!lodashFunc) { return; } - var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName), - retUnwrapped = /^(?:first|last)$/.test(methodName); - lodash.prototype[methodName] = function() { - var args = arguments, + var args = retUnwrapped ? [1] : arguments, chainAll = this.__chain__, value = this.__wrapped__, isHybrid = !!this.__actions__.length, @@ -12118,28 +12231,30 @@ useLazy = isLazy || isArray(value); if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) { - // avoid lazy use if the iteratee has a "length" value other than `1` + // Avoid lazy use if the iteratee has a "length" value other than `1`. isLazy = useLazy = false; } - var onlyLazy = isLazy && !isHybrid; - if (retUnwrapped && !chainAll) { - return onlyLazy - ? func.call(value) - : lodashFunc.call(lodash, this.value()); - } var interceptor = function(value) { - var otherArgs = [value]; - push.apply(otherArgs, args); - return lodashFunc.apply(lodash, otherArgs); + return (retUnwrapped && chainAll) + ? lodashFunc(value, 1)[0] + : lodashFunc.apply(undefined, arrayPush([value], args)); }; - if (useLazy) { - var wrapper = onlyLazy ? value : new LazyWrapper(this), - result = func.apply(wrapper, args); - if (!retUnwrapped && (isHybrid || result.__actions__)) { - var actions = result.__actions__ || (result.__actions__ = []); - actions.push({ 'func': thru, 'args': [interceptor], 'thisArg': lodash }); + var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined }, + onlyLazy = isLazy && !isHybrid; + + if (retUnwrapped && !chainAll) { + if (onlyLazy) { + value = value.clone(); + value.__actions__.push(action); + return func.call(value); } + return lodashFunc.call(undefined, this.value())[0]; + } + if (!retUnwrapped && useLazy) { + value = onlyLazy ? value : new LazyWrapper(this); + var result = func.apply(value, args); + result.__actions__.push(action); return new LodashWrapper(result, chainAll); } return this.thru(interceptor); @@ -12147,7 +12262,7 @@ }); // Add `Array` and `String` methods to `lodash.prototype`. - arrayEach(['concat', 'join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) { + arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) { var func = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName], chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName); @@ -12174,7 +12289,7 @@ } }); - realNames[createHybridWrapper(null, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': null }]; + realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }]; // Add functions to the lazy wrapper. LazyWrapper.prototype.clone = lazyClone; @@ -12184,6 +12299,7 @@ // Add chaining functions to the `lodash` wrapper. lodash.prototype.chain = wrapperChain; lodash.prototype.commit = wrapperCommit; + lodash.prototype.concat = wrapperConcat; lodash.prototype.plant = wrapperPlant; lodash.prototype.reverse = wrapperReverse; lodash.prototype.toString = wrapperToString; diff --git a/lodash.min.js b/lodash.min.js index 4d6e9ff0bf..f57c37beeb 100644 --- a/lodash.min.js +++ b/lodash.min.js @@ -1,98 +1,99 @@ /** * @license - * lodash 3.9.3 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + * lodash 3.10.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE * Build: `lodash modern -o ./lodash.js` */ -;(function(){function n(n,t){if(n!==t){var r=null===n,e=n===m,u=n===n,i=null===t,o=t===m,f=t===t;if(n>t&&!i||!u||r&&!o&&f||e&&f)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 _(n,t){for(var r=-1,e=n.length,u=-1,i=[];++ro(t,l,0)&&u.push(l);return u}function at(n,t){var r=true;return Mu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function ct(n,t,r,e){var u=e,i=u;return Mu(n,function(n,o,f){o=+t(n,o,f),(r(o,u)||o===e&&o===i)&&(u=o,i=n)}),i}function st(n,t){var r=[];return Mu(n,function(n,e,u){t(n,e,u)&&r.push(n); -}),r}function pt(n,t,r,e){var u;return r(n,function(n,r,i){return t(n,r,i)?(u=e?r:n,false):void 0}),u}function ht(n,t,r){for(var e=-1,u=n.length,i=-1,o=[];++et&&(t=-t>u?0:u+t),r=r===m||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Me(u);++eu(l,s,0)&&((t||f)&&l.push(s),a.push(c))}return a}function Ft(n,t){for(var r=-1,e=t.length,u=Me(e);++r>>1,o=n[i];(r?o<=t:ou?m:i,u=1);++earguments.length;return typeof e=="function"&&i===m&&Ti(r)?n(r,e,u,o):Et(r,mr(e,i,4),u,o,t)}}function sr(n,t,r,e,u,i,o,f,l,a){function c(){for(var w=arguments.length,A=w,j=Me(w);A--;)j[A]=arguments[A];if(e&&(j=qt(j,e,u)),i&&(j=Dt(j,i,o)),v||y){var A=c.placeholder,k=_(j,A),w=w-k.length; -if(wt?0:t)):[]}function qr(n,t,r){var e=n?n.length:0;return e?((r?Cr(n,t,r):null==t)&&(t=1), -t=e-(+t||0),Ct(n,0,0>t?0:t)):[]}function Dr(n){return n?n[0]:m}function Kr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?ku(u+e,0):e;else if(e)return e=zt(n,t),n=n[e],(t===t?t===n:n!==n)?e:-1;return r(n,t,e||0)}function Vr(n){var t=n?n.length:0;return t?n[t-1]:m}function Yr(n){return Pr(n,1)}function Zr(n,t,e,u){if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=Cr(n,t,u)?null:t,t=false);var i=mr();if((null!=e||i!==it)&&(e=i(e,u,3)),t&&br()==r){t=e;var o;e=-1,u=n.length; -for(var i=-1,f=[];++er?ku(u+r,0):r||0,typeof n=="string"||!Ti(n)&&me(n)?rt?0:+t||0,e);++r=n&&(t=null),r}}function fe(n,t,r){function e(){var r=t-(wi()-a);0>=r||r>t?(f&&cu(f),r=p,f=s=p=m,r&&(h=wi(),l=n.apply(c,o),s||f||(o=c=null))):s=gu(e,r)}function u(){s&&cu(s),f=s=p=m,(v||_!==t)&&(h=wi(),l=n.apply(c,o),s||f||(o=c=null))}function i(){if(o=arguments,a=wi(),c=this,p=v&&(s||!g),false===_)var r=g&&!s;else{f||g||(h=a);var i=_-(a-h),y=0>=i||i>_;y?(f&&(f=cu(f)),h=a,l=n.apply(c,o)):f||(f=gu(u,i))}return y&&s?s=cu(s):s||t===_||(s=gu(e,t)),r&&(y=true,l=n.apply(c,o)), -!y||s||f||(o=c=null),l}var o,f,l,a,c,s,p,h=0,_=false,v=true;if(typeof n!="function")throw new Je(N);if(t=0>t?0:+t||0,true===r)var g=true,v=false;else ve(r)&&(g=r.leading,_="maxWait"in r&&ku(+r.maxWait||0,t),v="trailing"in r?r.trailing:v);return i.cancel=function(){s&&cu(s),f&&cu(f),f=s=p=m},i}function le(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new Je(N);return r.cache=new le.Cache, -r}function ae(n,t){if(typeof n!="function")throw new Je(N);return t=ku(t===m?n.length-1:+t||0,0),function(){for(var r=arguments,e=-1,u=ku(r.length-t,0),i=Me(u);++et}function se(n){return p(n)&&Ir(n)&&uu.call(n)==z}function pe(n){return!!n&&1===n.nodeType&&p(n)&&-1t||!n||!Au(t))return r;do t%2&&(r+=n),t=su(t/2),n+=n;while(t);return r}function Se(n,t,r){var e=n;return(n=u(n))?(r?Cr(e,t,r):null==t)?n.slice(v(n),g(n)+1):(t+="",n.slice(i(n,t),o(n,t)+1)):n}function Te(n,t,r){ -return r&&Cr(n,t,r)&&(t=null),n=u(n),n.match(t||Wn)||[]}function Ue(n,t,r){return r&&Cr(n,t,r)&&(t=null),p(n)?Ne(n):it(n,t)}function $e(n){return function(){return n}}function Fe(n){return n}function Ne(n){return xt(ot(n,true))}function Le(n,t,r){if(null==r){var e=ve(t),u=e?Ki(t):null;((u=u&&u.length?yt(t,u):null)?u.length:e)||(u=false,r=t,t=n,n=this)}u||(u=yt(t,Ki(t)));var i=true,e=-1,o=$i(n),f=u.length;false===r?i=false:ve(r)&&"chain"in r&&(i=r.chain);for(;++e=S)return r}else n=0;return Ku(r,e)}}(),Ju=ae(function(n,t){return Ir(n)?lt(n,ht(t,false,true)):[]}),Xu=tr(),Hu=tr(true),Qu=ae(function(n){for(var t=n.length,e=t,u=Me(c),i=br(),o=i==r,f=[];e--;){var l=n[e]=Ir(l=n[e])?l:[];u[e]=o&&120<=l.length?Vu(e&&l):null}var o=n[0],a=-1,c=o?o.length:0,s=u[0]; -n:for(;++a(s?qn(s,l):i(f,l,0))){for(e=t;--e;){var p=u[e];if(0>(p?qn(p,l):i(n[e],l,0)))continue n}s&&s.push(l),f.push(l)}return f}),ni=ae(function(t,r){r=ht(r);var e=et(t,r);return Rt(t,r.sort(n)),e}),ti=_r(),ri=_r(true),ei=ae(function(n){return $t(ht(n,false,true))}),ui=ae(function(n,t){return Ir(n)?lt(n,t):[]}),ii=ae(Gr),oi=ae(function(n){var t=n.length,r=2--n?t.apply(this,arguments):void 0}},Nn.ary=function(n,t,r){return r&&Cr(n,t,r)&&(t=null),t=n&&null==t?n.length:ku(+t||0,0),vr(n,I,null,null,null,null,t)},Nn.assign=Ni,Nn.at=fi,Nn.before=oe,Nn.bind=bi,Nn.bindAll=xi,Nn.bindKey=Ai,Nn.callback=Ue,Nn.chain=Hr,Nn.chunk=function(n,t,r){t=(r?Cr(n,t,r):null==t)?1:ku(+t||1,1),r=0;for(var e=n?n.length:0,u=-1,i=Me(au(e/t));rr&&(r=-r>u?0:u+r),e=e===m||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;rt?0:t)):[]},Nn.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?Cr(n,t,r):null==t)&&(t=1),t=e-(+t||0),Ct(n,0>t?0:t)):[]},Nn.takeRightWhile=function(n,t,r){return n&&n.length?Nt(n,mr(t,r,3),false,true):[]},Nn.takeWhile=function(n,t,r){return n&&n.length?Nt(n,mr(t,r,3)):[]; -},Nn.tap=function(n,t,r){return t.call(r,n),n},Nn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Je(N);return false===r?e=false:ve(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),Fn.leading=e,Fn.maxWait=+t,Fn.trailing=u,fe(n,t,Fn)},Nn.thru=Qr,Nn.times=function(n,t,r){if(n=su(n),1>n||!Au(n))return[];var e=-1,u=Me(Ou(n,4294967295));for(t=Mt(t,r,1);++ee?u[e]=t(e):t(e);return u},Nn.toArray=xe,Nn.toPlainObject=Ae,Nn.transform=function(n,t,r,e){var u=Ti(n)||we(n); -return t=mr(t,e,4),null==r&&(u||ve(n)?(e=n.constructor,r=u?Ti(n)?new e:[]:Bu($i(e)?e.prototype:null)):r={}),(u?Kn:vt)(n,function(n,e,u){return t(r,n,e,u)}),r},Nn.union=ei,Nn.uniq=Zr,Nn.unzip=Gr,Nn.unzipWith=Jr,Nn.values=Re,Nn.valuesIn=function(n){return Ft(n,ke(n))},Nn.where=function(n,t){return te(n,xt(t))},Nn.without=ui,Nn.wrap=function(n,t){return t=null==t?Fe:t,vr(t,O,null,[n],[])},Nn.xor=function(){for(var n=-1,t=arguments.length;++nr?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Nn.escape=function(n){return(n=u(n))&&pn.test(n)?n.replace(cn,a):n},Nn.escapeRegExp=Ee,Nn.every=ne,Nn.find=ai,Nn.findIndex=Xu,Nn.findKey=zi,Nn.findLast=ci,Nn.findLastIndex=Hu,Nn.findLastKey=Bi,Nn.findWhere=function(n,t){return ai(n,xt(t))},Nn.first=Dr,Nn.get=function(n,t,r){ -return n=null==n?m:dt(n,Br(t),t+""),n===m?r:n},Nn.gt=ce,Nn.gte=function(n,t){return n>=t},Nn.has=function(n,t){if(null==n)return false;var r=ru.call(n,t);if(!r&&!Wr(t)){if(t=Br(t),n=1==t.length?n:dt(n,Ct(t,0,-1)),null==n)return false;t=Vr(t),r=ru.call(n,t)}return r||Tr(n.length)&&Er(t,n.length)&&(Ti(n)||se(n))},Nn.identity=Fe,Nn.includes=re,Nn.indexOf=Kr,Nn.inRange=function(n,t,r){return t=+t||0,"undefined"===typeof r?(r=t,t=0):r=+r||0,n>=Ou(t,r)&&nr?ku(e+r,0):Ou(r||0,e-1))+1;else if(r)return u=zt(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;if(t!==t)return s(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},Nn.lt=be,Nn.lte=function(n,t){return n<=t},Nn.max=oo,Nn.min=fo,Nn.noConflict=function(){return h._=iu,this},Nn.noop=ze,Nn.now=wi, -Nn.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return er?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Nn.sum=function(n,t,r){r&&Cr(n,t,r)&&(t=null);var e=mr(),u=null==t;if(u&&e===it||(u=false, -t=e(t,r,3)),u){for(n=Ti(n)?n:Lr(n),t=n.length,r=0;t--;)r+=+n[t]||0;n=r}else n=Ut(n,t);return n},Nn.template=function(n,t,r){var e=Nn.templateSettings;r&&Cr(n,t,r)&&(t=r=null),n=u(n),t=tt(rt({},r||t),e,nt),r=tt(rt({},t.imports),e.imports,nt);var i,o,f=Ki(r),l=Ft(r,f),a=0;r=t.interpolate||En;var s="__p+='";r=Ze((t.escape||En).source+"|"+r.source+"|"+(r===vn?An:En).source+"|"+(t.evaluate||En).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,l){ -return e||(e=u),s+=n.slice(a,l).replace(Cn,c),r&&(i=true,s+="'+__e("+r+")+'"),f&&(o=true,s+="';"+f+";\n__p+='"),e&&(s+="'+((__t=("+e+"))==null?'':__t)+'"),a=l+t.length,t}),s+="';",(t=t.variable)||(s="with(obj){"+s+"}"),s=(o?s.replace(on,""):s).replace(fn,"$1").replace(ln,"$1;"),s="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(i?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+s+"return __p}",t=eo(function(){return De(f,p+"return "+s).apply(m,l); -}),t.source=s,_e(t))throw t;return t},Nn.trim=Se,Nn.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?Cr(e,t,r):null==t)?v(n):i(n,t+"")):n},Nn.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?Cr(e,t,r):null==t)?n.slice(0,g(n)+1):n.slice(0,o(n,t+"")+1):n},Nn.trunc=function(n,t,r){r&&Cr(n,t,r)&&(t=null);var e=C;if(r=W,null!=t)if(ve(t)){var i="separator"in t?t.separator:i,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length, -1>e)return r;if(t=n.slice(0,e),null==i)return t+r;if(de(i)){if(n.slice(e).search(i)){var o,f=n.slice(0,e);for(i.global||(i=Ze(i.source,(jn.exec(i)||"")+"g")),i.lastIndex=0;n=i.exec(f);)o=n.index;t=t.slice(0,null==o?e:o)}}else n.indexOf(i,e)!=e&&(i=t.lastIndexOf(i),-1u.__dir__?"Right":"")}),u},Bn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse(); -},Bn.prototype[n+"RightWhile"]=function(n,t){return this.reverse()[r](n,t).reverse()}}),Kn(["first","last"],function(n,t){var r="take"+(t?"Right":"");Bn.prototype[n]=function(){return this[r](1).value()[0]}}),Kn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");Bn.prototype[n]=function(){return this[r](1)}}),Kn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?xt:Be;Bn.prototype[n]=function(n){return this[r](e(n))}}),Bn.prototype.compact=function(){return this.filter(Fe)},Bn.prototype.reject=function(n,t){ -return n=mr(n,t,1),this.filter(function(t){return!n(t)})},Bn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return 0>n?r=this.takeRight(-n):n&&(r=this.drop(n)),t!==m&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r},Bn.prototype.toArray=function(){return this.drop(0)},vt(Bn.prototype,function(n,t){var r=Nn[t];if(r){var e=/^(?:filter|map|reject)|While$/.test(t),u=/^(?:first|last)$/.test(t);Nn.prototype[t]=function(){function t(n){return n=[n],_u.apply(n,i),r.apply(Nn,n)}var i=arguments,o=this.__chain__,f=this.__wrapped__,l=!!this.__actions__.length,a=f instanceof Bn,c=i[0],s=a||Ti(f); -return s&&e&&typeof c=="function"&&1!=c.length&&(a=s=false),a=a&&!l,u&&!o?a?n.call(f):r.call(Nn,this.value()):s?(f=n.apply(a?f:new Bn(this),i),u||!l&&!f.__actions__||(f.__actions__||(f.__actions__=[])).push({func:Qr,args:[t],thisArg:Nn}),new zn(f,o)):this.thru(t)}}}),Kn("concat join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?Qe:Xe)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|replace|shift)$/.test(n);Nn.prototype[n]=function(){ -var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),vt(Bn.prototype,function(n,t){var r=Nn[t];if(r){var e=r.name;(Lu[e]||(Lu[e]=[])).push({name:t,func:r})}}),Lu[sr(null,x).name]=[{name:"wrapper",func:null}],Bn.prototype.clone=function(){var n=this.__actions__,t=this.__iteratees__,r=this.__views__,e=new Bn(this.__wrapped__);return e.__actions__=n?Dn(n):null,e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=t?Dn(t):null, -e.__takeCount__=this.__takeCount__,e.__views__=r?Dn(r):null,e},Bn.prototype.reverse=function(){if(this.__filtered__){var n=new Bn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Bn.prototype.value=function(){var n=this.__wrapped__.value();if(!Ti(n))return Lt(n,this.__actions__);var t,r=this.__dir__,e=0>r;t=n.length;for(var u=this.__views__,i=0,o=-1,f=u?u.length:0;++op.index:u=_:!h(s))))continue n}else if(p=h(s),_==F)s=p;else if(!p){if(_==$)continue n;break n}}a[l++]=s}return a},Nn.prototype.chain=function(){ -return Hr(this)},Nn.prototype.commit=function(){return new zn(this.value(),this.__chain__)},Nn.prototype.plant=function(n){for(var t,r=this;r instanceof Ln;){var e=Mr(r);t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},Nn.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Bn?(this.__actions__.length&&(n=new Bn(this)),new zn(n.reverse(),this.__chain__)):this.thru(function(n){return n.reverse()})},Nn.prototype.toString=function(){return this.value()+""},Nn.prototype.run=Nn.prototype.toJSON=Nn.prototype.valueOf=Nn.prototype.value=function(){ -return Lt(this.__wrapped__,this.__actions__)},Nn.prototype.collect=Nn.prototype.map,Nn.prototype.head=Nn.prototype.first,Nn.prototype.select=Nn.prototype.filter,Nn.prototype.tail=Nn.prototype.rest,Nn}var m,w="3.9.3",b=1,x=2,A=4,j=8,k=16,O=32,R=64,I=128,E=256,C=30,W="...",S=150,T=16,U=0,$=1,F=2,N="Expected a function",L="__lodash_placeholder__",z="[object Arguments]",B="[object Array]",M="[object Boolean]",P="[object Date]",q="[object Error]",D="[object Function]",K="[object Number]",V="[object Object]",Y="[object RegExp]",Z="[object String]",G="[object ArrayBuffer]",J="[object Float32Array]",X="[object Float64Array]",H="[object Int8Array]",Q="[object Int16Array]",nn="[object Int32Array]",tn="[object Uint8Array]",rn="[object Uint8ClampedArray]",en="[object Uint16Array]",un="[object Uint32Array]",on=/\b__p\+='';/g,fn=/\b(__p\+=)''\+/g,ln=/(__e\(.*?\)|\b__t\))\+'';/g,an=/&(?:amp|lt|gt|quot|#39|#96);/g,cn=/[&<>"'`]/g,sn=RegExp(an.source),pn=RegExp(cn.source),hn=/<%-([\s\S]+?)%>/g,_n=/<%([\s\S]+?)%>/g,vn=/<%=([\s\S]+?)%>/g,gn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,yn=/^\w*$/,dn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,mn=/[.*+?^${}()|[\]\/\\]/g,wn=RegExp(mn.source),bn=/[\u0300-\u036f\ufe20-\ufe23]/g,xn=/\\(\\)?/g,An=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,jn=/\w*$/,kn=/^0[xX]/,On=/^\[object .+?Constructor\]$/,Rn=/^\d+$/,In=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,En=/($^)/,Cn=/['\n\r\u2028\u2029\\]/g,Wn=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),Sn=" \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",Tn="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseFloat parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window".split(" "),Un={}; -Un[J]=Un[X]=Un[H]=Un[Q]=Un[nn]=Un[tn]=Un[rn]=Un[en]=Un[un]=true,Un[z]=Un[B]=Un[G]=Un[M]=Un[P]=Un[q]=Un[D]=Un["[object Map]"]=Un[K]=Un[V]=Un[Y]=Un["[object Set]"]=Un[Z]=Un["[object WeakMap]"]=false;var $n={};$n[z]=$n[B]=$n[G]=$n[M]=$n[P]=$n[J]=$n[X]=$n[H]=$n[Q]=$n[nn]=$n[K]=$n[V]=$n[Y]=$n[Z]=$n[tn]=$n[rn]=$n[en]=$n[un]=true,$n[q]=$n[D]=$n["[object Map]"]=$n["[object Set]"]=$n["[object WeakMap]"]=false;var Fn={leading:false,maxWait:0,trailing:false},Nn={"\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"},Ln={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},zn={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Bn={"function":true,object:true},Mn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Pn=Bn[typeof exports]&&exports&&!exports.nodeType&&exports,qn=Bn[typeof module]&&module&&!module.nodeType&&module,Dn=Bn[typeof self]&&self&&self.Object&&self,Kn=Bn[typeof window]&&window&&window.Object&&window,Vn=qn&&qn.exports===Pn&&Pn,Yn=Pn&&qn&&typeof global=="object"&&global&&global.Object&&global||Kn!==(this&&this.window)&&Kn||Dn||this,Zn=d(); -typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Yn._=Zn, define(function(){return Zn})):Pn&&qn?Vn?(qn.exports=Zn)._=Zn:Pn._=Zn:Yn._=Zn}).call(this); \ No newline at end of file +;(function(){function n(n,t){if(n!==t){var r=null===n,e=n===w,u=n===n,o=null===t,i=t===w,f=t===t;if(n>t&&!o||!u||r&&!i&&f||e&&f)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,t){for(var r=-1,e=n.length,u=-1,o=[];++r=F&&gu&&lu?new Dn(t):null,c=t.length;a&&(i=Mn,f=false,t=a);n:for(;++oi(t,a,0)&&u.push(a);return u}function at(n,t){var r=true;return Su(n,function(n,e,u){return r=!!t(n,e,u)}),r}function ct(n,t,r,e){var u=e,o=u;return Su(n,function(n,i,f){i=+t(n,i,f),(r(i,u)||i===e&&i===o)&&(u=i, +o=n)}),o}function lt(n,t){var r=[];return Su(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function st(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=[]);for(var u=-1,o=n.length;++ut&&(t=-t>u?0:u+t),r=r===w||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Be(u);++e=c)break n;o=e[o],u*="asc"===o||true===o?1:-1;break n}u=t.b-r.b}return u})}function $t(n,t){ +var r=0;return Su(n,function(n,e,u){r+=+t(n,e,u)||0}),r}function St(n,t){var e=-1,u=xr(),o=n.length,i=u==r,f=i&&o>=F,a=f&&gu&&lu?new Dn(void 0):null,c=[];a?(u=Mn,i=false):(f=false,a=t?[]:c);n:for(;++eu(a,s,0)&&((t||f)&&a.push(s),c.push(l))}return c}function Ft(n,t){for(var r=-1,e=t.length,u=Be(e);++r>>1,i=n[o];(r?i<=t:iu?w:o,u=1);++e=F)return t.plant(e).value();for(var u=0,n=r?o[u].apply(this,n):e;++uarguments.length;return typeof e=="function"&&o===w&&Oo(r)?n(r,e,u,i):Ot(r,wr(e,o,4),u,i,t)}}function sr(n,t,r,e,u,o,i,f,a,c){function l(){for(var m=arguments.length,b=m,j=Be(m);b--;)j[b]=arguments[b];if(e&&(j=Mt(j,e,u)),o&&(j=qt(j,o,i)),_||y){var b=l.placeholder,k=v(j,b),m=m-k.length;if(mt?0:t)):[]}function Pr(n,t,r){var e=n?n.length:0;return e?((r?Ur(n,t,r):null==t)&&(t=1),t=e-(+t||0),Et(n,0,0>t?0:t)):[]}function Kr(n){return n?n[0]:w}function Vr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?bu(u+e,0):e;else if(e)return e=Lt(n,t), +er?bu(u+r,0):r||0,typeof n=="string"||!Oo(n)&&be(n)?r<=u&&-1t?0:+t||0,e);++r=n&&(t=w),r}}function ae(n,t,r){function e(t,r){r&&iu(r),a=p=h=w,t&&(_=ho(),c=n.apply(s,f),p||a||(f=s=w))}function u(){var n=t-(ho()-l);0>=n||n>t?e(h,a):p=su(u,n)}function o(){e(g,p); +}function i(){if(f=arguments,l=ho(),s=this,h=g&&(p||!y),false===v)var r=y&&!p;else{a||y||(_=l);var e=v-(l-_),i=0>=e||e>v;i?(a&&(a=iu(a)),_=l,c=n.apply(s,f)):a||(a=su(o,e))}return i&&p?p=iu(p):p||t===v||(p=su(u,t)),r&&(i=true,c=n.apply(s,f)),!i||p||a||(f=s=w),c}var f,a,c,l,s,p,h,_=0,v=false,g=true;if(typeof n!="function")throw new Ge(L);if(t=0>t?0:+t||0,true===r)var y=true,g=false;else ge(r)&&(y=!!r.leading,v="maxWait"in r&&bu(+r.maxWait||0,t),g="trailing"in r?!!r.trailing:g);return i.cancel=function(){p&&iu(p),a&&iu(a), +_=0,a=p=h=w},i}function ce(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=n.apply(this,e),r.cache=o.set(u,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new Ge(L);return r.cache=new ce.Cache,r}function le(n,t){if(typeof n!="function")throw new Ge(L);return t=bu(t===w?n.length-1:+t||0,0),function(){for(var r=arguments,e=-1,u=bu(r.length-t,0),o=Be(u);++et}function pe(n){return h(n)&&Er(n)&&nu.call(n,"callee")&&!cu.call(n,"callee")}function he(n,t,r,e){return e=(r=typeof r=="function"?Bt(r,e,3):w)?r(n,t):w,e===w?dt(n,t,r):!!e}function _e(n){return h(n)&&typeof n.message=="string"&&ru.call(n)==P}function ve(n){return ge(n)&&ru.call(n)==K}function ge(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function ye(n){ +return null==n?false:ve(n)?uu.test(Qe.call(n)):h(n)&&Rn.test(n)}function de(n){return typeof n=="number"||h(n)&&ru.call(n)==V}function me(n){var t;if(!h(n)||ru.call(n)!=Z||pe(n)||!(nu.call(n,"constructor")||(t=n.constructor,typeof t!="function"||t instanceof t)))return false;var r;return ht(n,function(n,t){r=t}),r===w||nu.call(n,r)}function we(n){return ge(n)&&ru.call(n)==Y}function be(n){return typeof n=="string"||h(n)&&ru.call(n)==G}function xe(n){return h(n)&&Sr(n.length)&&!!Sn[ru.call(n)]}function Ae(n,t){ +return nt||!n||!mu(t))return r;do t%2&&(r+=n),t=yu(t/2),n+=n;while(t);return r}function We(n,t,r){var e=n;return(n=u(n))?(r?Ur(e,t,r):null==t)?n.slice(g(n),y(n)+1):(t+="",n.slice(o(n,t),i(n,t)+1)):n}function $e(n,t,r){return r&&Ur(n,t,r)&&(t=w),n=u(n),n.match(t||Wn)||[]}function Se(n,t,r){return r&&Ur(n,t,r)&&(t=w),h(n)?Ne(n):ut(n,t)}function Fe(n){ +return n}function Ne(n){return bt(ot(n,true))}function Te(n,t,r){if(null==r){var e=ge(t),u=e?zo(t):w;((u=u&&u.length?gt(t,u):w)?u.length:e)||(u=false,r=t,t=n,n=this)}u||(u=gt(t,zo(t)));var o=true,e=-1,i=ve(n),f=u.length;false===r?o=false:ge(r)&&"chain"in r&&(o=r.chain);for(;++e=$)return r}else n=0;return Lu(r,e)}}(),Mu=le(function(n,t){ +return h(n)&&Er(n)?ft(n,pt(t,false,true)):[]}),qu=tr(),Pu=tr(true),Ku=le(function(n){for(var t=n.length,e=t,u=Be(l),o=xr(),i=o==r,f=[];e--;){var a=n[e]=Er(a=n[e])?a:[];u[e]=i&&120<=a.length&&gu&&lu?new Dn(e&&a):null}var i=n[0],c=-1,l=i?i.length:0,s=u[0];n:for(;++c(s?Mn(s,a):o(f,a,0))){for(e=t;--e;){var p=u[e];if(0>(p?Mn(p,a):o(n[e],a,0)))continue n}s&&s.push(a),f.push(a)}return f}),Vu=le(function(t,r){r=pt(r);var e=rt(t,r);return It(t,r.sort(n)),e}),Zu=vr(),Yu=vr(true),Gu=le(function(n){return St(pt(n,false,true)); +}),Ju=le(function(n,t){return Er(n)?ft(n,t):[]}),Xu=le(Jr),Hu=le(function(n){var t=n.length,r=2--n?t.apply(this,arguments):void 0}},Nn.ary=function(n,t,r){return r&&Ur(n,t,r)&&(t=w),t=n&&null==t?n.length:bu(+t||0,0),gr(n,E,w,w,w,w,t)},Nn.assign=Co,Nn.at=no,Nn.before=fe,Nn.bind=_o,Nn.bindAll=vo,Nn.bindKey=go,Nn.callback=Se,Nn.chain=Qr,Nn.chunk=function(n,t,r){t=(r?Ur(n,t,r):null==t)?1:bu(yu(t)||1,1),r=0;for(var e=n?n.length:0,u=-1,o=Be(vu(e/t));rr&&(r=-r>u?0:u+r),e=e===w||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;rt?0:t)):[]},Nn.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?Ur(n,t,r):null==t)&&(t=1),t=e-(+t||0),Et(n,0>t?0:t)):[]},Nn.takeRightWhile=function(n,t,r){ +return n&&n.length?Nt(n,wr(t,r,3),false,true):[]},Nn.takeWhile=function(n,t,r){return n&&n.length?Nt(n,wr(t,r,3)):[]},Nn.tap=function(n,t,r){return t.call(r,n),n},Nn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Ge(L);return false===r?e=false:ge(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ae(n,t,{leading:e,maxWait:+t,trailing:u})},Nn.thru=ne,Nn.times=function(n,t,r){if(n=yu(n),1>n||!mu(n))return[];var e=-1,u=Be(xu(n,4294967295));for(t=Bt(t,r,1);++ee?u[e]=t(e):t(e); +return u},Nn.toArray=je,Nn.toPlainObject=ke,Nn.transform=function(n,t,r,e){var u=Oo(n)||xe(n);return t=wr(t,e,4),null==r&&(u||ge(n)?(e=n.constructor,r=u?Oo(n)?new e:[]:$u(ve(e)?e.prototype:w)):r={}),(u?Pn:_t)(n,function(n,e,u){return t(r,n,e,u)}),r},Nn.union=Gu,Nn.uniq=Gr,Nn.unzip=Jr,Nn.unzipWith=Xr,Nn.values=Ee,Nn.valuesIn=function(n){return Ft(n,Re(n))},Nn.where=function(n,t){return re(n,bt(t))},Nn.without=Ju,Nn.wrap=function(n,t){return t=null==t?Fe:t,gr(t,R,w,[n],[])},Nn.xor=function(){for(var n=-1,t=arguments.length;++nr?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Nn.escape=function(n){return(n=u(n))&&hn.test(n)?n.replace(sn,c):n},Nn.escapeRegExp=function(n){return(n=u(n))&&bn.test(n)?n.replace(wn,l):n||"(?:)"},Nn.every=te,Nn.find=ro,Nn.findIndex=qu,Nn.findKey=$o,Nn.findLast=eo, +Nn.findLastIndex=Pu,Nn.findLastKey=So,Nn.findWhere=function(n,t){return ro(n,bt(t))},Nn.first=Kr,Nn.floor=ni,Nn.get=function(n,t,r){return n=null==n?w:yt(n,Dr(t),t+""),n===w?r:n},Nn.gt=se,Nn.gte=function(n,t){return n>=t},Nn.has=function(n,t){if(null==n)return false;var r=nu.call(n,t);if(!r&&!Wr(t)){if(t=Dr(t),n=1==t.length?n:yt(n,Et(t,0,-1)),null==n)return false;t=Zr(t),r=nu.call(n,t)}return r||Sr(n.length)&&Cr(t,n.length)&&(Oo(n)||pe(n))},Nn.identity=Fe,Nn.includes=ee,Nn.indexOf=Vr,Nn.inRange=function(n,t,r){ +return t=+t||0,r===w?(r=t,t=0):r=+r||0,n>=xu(t,r)&&nr?bu(e+r,0):xu(r||0,e-1))+1;else if(r)return u=Lt(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1; +if(t!==t)return p(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},Nn.lt=Ae,Nn.lte=function(n,t){return n<=t},Nn.max=ti,Nn.min=ri,Nn.noConflict=function(){return Zn._=eu,this},Nn.noop=Le,Nn.now=ho,Nn.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return er?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Nn.sum=function(n,t,r){if(r&&Ur(n,t,r)&&(t=w),t=wr(t,r,3),1==t.length){n=Oo(n)?n:zr(n),r=n.length;for(var e=0;r--;)e+=+t(n[r])||0;n=e}else n=$t(n,t);return n},Nn.template=function(n,t,r){var e=Nn.templateSettings;r&&Ur(n,t,r)&&(t=r=w),n=u(n),t=nt(tt({},r||t),e,Qn),r=nt(tt({},t.imports),e.imports,Qn); +var o,i,f=zo(r),a=Ft(r,f),c=0;r=t.interpolate||Cn;var l="__p+='";r=Ze((t.escape||Cn).source+"|"+r.source+"|"+(r===gn?jn:Cn).source+"|"+(t.evaluate||Cn).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,a){return e||(e=u),l+=n.slice(c,a).replace(Un,s),r&&(o=true,l+="'+__e("+r+")+'"),f&&(i=true,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),c=a+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(i?l.replace(fn,""):l).replace(an,"$1").replace(cn,"$1;"), +l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(o?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}",t=Jo(function(){return qe(f,p+"return "+l).apply(w,a)}),t.source=l,_e(t))throw t;return t},Nn.trim=We,Nn.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?Ur(e,t,r):null==t)?g(n):o(n,t+"")):n},Nn.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?Ur(e,t,r):null==t)?n.slice(0,y(n)+1):n.slice(0,i(n,t+"")+1):n; +},Nn.trunc=function(n,t,r){r&&Ur(n,t,r)&&(t=w);var e=U;if(r=W,null!=t)if(ge(t)){var o="separator"in t?t.separator:o,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length,1>e)return r;if(t=n.slice(0,e),null==o)return t+r;if(we(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Ze(o.source,(kn.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o), +-1u.__dir__?"Right":"")}),u},zn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),Pn(["filter","map","takeWhile"],function(n,t){ +var r=t+1,e=r!=T;zn.prototype[n]=function(n,t){var u=this.clone();return u.__iteratees__.push({iteratee:wr(n,t,1),type:r}),u.__filtered__=u.__filtered__||e,u}}),Pn(["first","last"],function(n,t){var r="take"+(t?"Right":"");zn.prototype[n]=function(){return this[r](1).value()[0]}}),Pn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");zn.prototype[n]=function(){return this.__filtered__?new zn(this):this[r](1)}}),Pn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?bt:ze;zn.prototype[n]=function(n){ +return this[r](e(n))}}),zn.prototype.compact=function(){return this.filter(Fe)},zn.prototype.reject=function(n,t){return n=wr(n,t,1),this.filter(function(t){return!n(t)})},zn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return r.__filtered__&&(0t)?new zn(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==w&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r)},zn.prototype.takeRightWhile=function(n,t){return this.reverse().takeWhile(n,t).reverse()},zn.prototype.toArray=function(){return this.take(Ru); +},_t(zn.prototype,function(n,t){var r=/^(?:filter|map|reject)|While$/.test(t),e=/^(?:first|last)$/.test(t),u=Nn[e?"take"+("last"==t?"Right":""):t];u&&(Nn.prototype[t]=function(){function t(n){return e&&i?u(n,1)[0]:u.apply(w,Jn([n],o))}var o=e?[1]:arguments,i=this.__chain__,f=this.__wrapped__,a=!!this.__actions__.length,c=f instanceof zn,l=o[0],s=c||Oo(f);return s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false),l={func:ne,args:[t],thisArg:w},a=c&&!a,e&&!i?a?(f=f.clone(),f.__actions__.push(l),n.call(f)):u.call(w,this.value())[0]:!e&&s?(f=a?f:new zn(this), +f=n.apply(f,o),f.__actions__.push(l),new Ln(f,i)):this.thru(t)})}),Pn("join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?He:Je)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|replace|shift)$/.test(n);Nn.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),_t(zn.prototype,function(n,t){var r=Nn[t];if(r){var e=r.name;(Wu[e]||(Wu[e]=[])).push({ +name:t,func:r})}}),Wu[sr(w,A).name]=[{name:"wrapper",func:w}],zn.prototype.clone=function(){var n=new zn(this.__wrapped__);return n.__actions__=qn(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=qn(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=qn(this.__views__),n},zn.prototype.reverse=function(){if(this.__filtered__){var n=new zn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},zn.prototype.value=function(){ +var n,t=this.__wrapped__.value(),r=this.__dir__,e=Oo(t),u=0>r,o=e?t.length:0;n=o;for(var i=this.__views__,f=0,a=-1,c=i.length;++ar.__dir__?n:n.reverse()}var t=this.__wrapped__; +if(t instanceof zn){var r=t;return this.__actions__.length&&(r=new zn(this)),r=r.reverse(),r.__actions__.push({func:ne,args:[n],thisArg:w}),new Ln(r,this.__chain__)}return this.thru(n)},Nn.prototype.toString=function(){return this.value()+""},Nn.prototype.run=Nn.prototype.toJSON=Nn.prototype.valueOf=Nn.prototype.value=function(){return Tt(this.__wrapped__,this.__actions__)},Nn.prototype.collect=Nn.prototype.map,Nn.prototype.head=Nn.prototype.first,Nn.prototype.select=Nn.prototype.filter,Nn.prototype.tail=Nn.prototype.rest, +Nn}var w,b="3.10.0",x=1,A=2,j=4,k=8,I=16,R=32,O=64,E=128,C=256,U=30,W="...",$=150,S=16,F=200,N=1,T=2,L="Expected a function",z="__lodash_placeholder__",B="[object Arguments]",D="[object Array]",M="[object Boolean]",q="[object Date]",P="[object Error]",K="[object Function]",V="[object Number]",Z="[object Object]",Y="[object RegExp]",G="[object String]",J="[object ArrayBuffer]",X="[object Float32Array]",H="[object Float64Array]",Q="[object Int8Array]",nn="[object Int16Array]",tn="[object Int32Array]",rn="[object Uint8Array]",en="[object Uint8ClampedArray]",un="[object Uint16Array]",on="[object Uint32Array]",fn=/\b__p\+='';/g,an=/\b(__p\+=)''\+/g,cn=/(__e\(.*?\)|\b__t\))\+'';/g,ln=/&(?:amp|lt|gt|quot|#39|#96);/g,sn=/[&<>"'`]/g,pn=RegExp(ln.source),hn=RegExp(sn.source),_n=/<%-([\s\S]+?)%>/g,vn=/<%([\s\S]+?)%>/g,gn=/<%=([\s\S]+?)%>/g,yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,dn=/^\w*$/,mn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,wn=/^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,bn=RegExp(wn.source),xn=/[\u0300-\u036f\ufe20-\ufe23]/g,An=/\\(\\)?/g,jn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,kn=/\w*$/,In=/^0[xX]/,Rn=/^\[object .+?Constructor\]$/,On=/^\d+$/,En=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Cn=/($^)/,Un=/['\n\r\u2028\u2029\\]/g,Wn=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),$n="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout isFinite parseFloat parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap".split(" "),Sn={}; +Sn[X]=Sn[H]=Sn[Q]=Sn[nn]=Sn[tn]=Sn[rn]=Sn[en]=Sn[un]=Sn[on]=true,Sn[B]=Sn[D]=Sn[J]=Sn[M]=Sn[q]=Sn[P]=Sn[K]=Sn["[object Map]"]=Sn[V]=Sn[Z]=Sn[Y]=Sn["[object Set]"]=Sn[G]=Sn["[object WeakMap]"]=false;var Fn={};Fn[B]=Fn[D]=Fn[J]=Fn[M]=Fn[q]=Fn[X]=Fn[H]=Fn[Q]=Fn[nn]=Fn[tn]=Fn[V]=Fn[Z]=Fn[Y]=Fn[G]=Fn[rn]=Fn[en]=Fn[un]=Fn[on]=true,Fn[P]=Fn[K]=Fn["[object Map]"]=Fn["[object Set]"]=Fn["[object WeakMap]"]=false;var Nn={"\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"},Tn={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Ln={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},zn={"function":true,object:true},Bn={0:"x30",1:"x31",2:"x32",3:"x33",4:"x34",5:"x35",6:"x36",7:"x37",8:"x38",9:"x39",A:"x41",B:"x42",C:"x43",D:"x44",E:"x45",F:"x46",a:"x61",b:"x62",c:"x63",d:"x64",e:"x65",f:"x66",n:"x6e",r:"x72",t:"x74",u:"x75",v:"x76",x:"x78"},Dn={"\\":"\\", +"'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Mn=zn[typeof exports]&&exports&&!exports.nodeType&&exports,qn=zn[typeof module]&&module&&!module.nodeType&&module,Pn=zn[typeof self]&&self&&self.Object&&self,Kn=zn[typeof window]&&window&&window.Object&&window,Vn=qn&&qn.exports===Mn&&Mn,Zn=Mn&&qn&&typeof global=="object"&&global&&global.Object&&global||Kn!==(this&&this.window)&&Kn||Pn||this,Yn=m();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Zn._=Yn, define(function(){ +return Yn})):Mn&&qn?Vn?(qn.exports=Yn)._=Yn:Mn._=Yn:Zn._=Yn}).call(this); \ No newline at end of file diff --git a/lodash.src.js b/lodash.src.js index fedf96ae77..1ec2ebe50b 100644 --- a/lodash.src.js +++ b/lodash.src.js @@ -1,6 +1,6 @@ /** * @license - * lodash 3.9.3 + * lodash 3.10.0 * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.8.3 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors @@ -12,7 +12,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '3.9.3'; + var VERSION = '3.10.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -33,9 +33,11 @@ var HOT_COUNT = 150, HOT_SPAN = 16; + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + /** Used to indicate the type of lazy iteratees. */ - var LAZY_DROP_WHILE_FLAG = 0, - LAZY_FILTER_FLAG = 1, + var LAZY_FILTER_FLAG = 1, LAZY_MAP_FLAG = 2; /** Used as the `TypeError` message for "Functions" methods. */ @@ -92,11 +94,10 @@ rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; /** - * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special). - * In addition to special characters the forward slash is escaped to allow for - * easier `eval` use and `Function` compilation. + * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) + * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). */ - var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, + var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, reHasRegExpChars = RegExp(reRegExpChars.source); /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ @@ -105,7 +106,7 @@ /** Used to match backslashes in property paths. */ var reEscapeChar = /\\(\\)?/g; - /** Used to match [ES template delimiters](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components). */ + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; /** Used to match `RegExp` flags from their coerced string values. */ @@ -137,25 +138,13 @@ return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); }()); - /** Used to detect and test for whitespace. */ - var whitespace = ( - // Basic whitespace characters. - ' \t\x0b\f\xa0\ufeff' + - - // Line terminators. - '\n\r\u2028\u2029' + - - // Unicode category "Zs" space separators. - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); - /** Used to assign default `context` object properties. */ var contextProps = [ 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', - 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', - 'isFinite', 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', - 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', 'window' + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', + 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' ]; /** Used to fix the JScript `[[DontEnum]]` bug. */ @@ -197,13 +186,6 @@ cloneableTags[mapTag] = cloneableTags[setTag] = cloneableTags[weakMapTag] = false; - /** Used as an internal `_.debounce` options object by `_.throttle`. */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; - /** 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', @@ -251,6 +233,15 @@ 'object': true }; + /** Used to escape characters for inclusion in compiled regexes. */ + var regexpEscapes = { + '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', + '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', + 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', + 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', + 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' + }; + /** Used to escape characters for inclusion in compiled string literals. */ var stringEscapes = { '\\': '\\', @@ -391,9 +382,6 @@ * @returns {string} Returns the string. */ function baseToString(value) { - if (typeof value == 'string') { - return value; - } return value == null ? '' : (value + ''); } @@ -435,8 +423,8 @@ * sort them in ascending order. * * @private - * @param {Object} object The object to compare to `other`. - * @param {Object} other The object to compare to `object`. + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. * @returns {number} Returns the sort order indicator for `object`. */ function compareAscending(object, other) { @@ -444,16 +432,16 @@ } /** - * Used by `_.sortByOrder` to compare multiple properties of each element - * in a collection and stable sort them in the following order: + * Used by `_.sortByOrder` to compare multiple properties of a value to another + * and stable sort them. * - * If `orders` is unspecified, sort in ascending order for all properties. - * Otherwise, for each property, sort in ascending order if its corresponding value in - * orders is true, and descending order if false. + * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, + * a value is sorted in ascending order if its corresponding order is "asc", and + * descending if "desc". * * @private - * @param {Object} object The object to compare to `other`. - * @param {Object} other The object to compare to `object`. + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. * @param {boolean[]} orders The order to sort by for each property. * @returns {number} Returns the sort order indicator for `object`. */ @@ -470,7 +458,8 @@ if (index >= ordersLength) { return result; } - return result * (orders[index] ? 1 : -1); + var order = orders[index]; + return result * ((order === 'asc' || order === true) ? 1 : -1); } } // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications @@ -506,8 +495,25 @@ } /** - * Used by `_.template` to escape characters for inclusion in compiled - * string literals. + * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. + * + * @private + * @param {string} chr The matched character to escape. + * @param {string} leadingChar The capture group for a leading character. + * @param {string} whitespaceChar The capture group for a whitespace character. + * @returns {string} Returns the escaped character. + */ + function escapeRegExpChar(chr, leadingChar, whitespaceChar) { + if (leadingChar) { + chr = regexpEscapes[chr]; + } else if (whitespaceChar) { + chr = stringEscapes[chr]; + } + return '\\' + chr; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. * * @private * @param {string} chr The matched character to escape. @@ -739,9 +745,6 @@ objectProto = Object.prototype, stringProto = String.prototype; - /** Used to detect DOM support. */ - var document = (document = context.window) ? document.document : null; - /** Used to resolve the decompiled source of functions. */ var fnToString = Function.prototype.toString; @@ -752,57 +755,42 @@ var idCounter = 0; /** - * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) * of values. */ var objToString = objectProto.toString; /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = context._; + var oldDash = root._; /** Used to detect if a method is native. */ var reIsNative = RegExp('^' + - escapeRegExp(fnToString.call(hasOwnProperty)) + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); /** Native method references. */ - var ArrayBuffer = getNative(context, 'ArrayBuffer'), - bufferSlice = getNative(ArrayBuffer && new ArrayBuffer(0), 'slice'), - ceil = Math.ceil, + var ArrayBuffer = context.ArrayBuffer, clearTimeout = context.clearTimeout, - floor = Math.floor, - getPrototypeOf = getNative(Object, 'getPrototypeOf'), parseFloat = context.parseFloat, - push = arrayProto.push, + pow = Math.pow, propertyIsEnumerable = objectProto.propertyIsEnumerable, Set = getNative(context, 'Set'), setTimeout = context.setTimeout, splice = arrayProto.splice, - Uint8Array = getNative(context, 'Uint8Array'), + Uint8Array = context.Uint8Array, WeakMap = getNative(context, 'WeakMap'); - /** Used to clone array buffers. */ - var Float64Array = (function() { - // Safari 5 errors when using an array buffer to initialize a typed array - // where the array buffer's `byteLength` is not a multiple of the typed - // array's `BYTES_PER_ELEMENT`. - try { - var func = getNative(context, 'Float64Array'), - result = new func(new ArrayBuffer(10), 0, 1) && func; - } catch(e) {} - return result || null; - }()); - /* Native method references for those with the same name as other `lodash` methods. */ - var nativeCreate = getNative(Object, 'create'), + var nativeCeil = Math.ceil, + nativeCreate = getNative(Object, 'create'), + nativeFloor = Math.floor, nativeIsArray = getNative(Array, 'isArray'), nativeIsFinite = context.isFinite, nativeKeys = getNative(Object, 'keys'), nativeMax = Math.max, nativeMin = Math.min, nativeNow = getNative(Date, 'now'), - nativeNumIsFinite = getNative(Number, 'isFinite'), nativeParseInt = context.parseInt, nativeRandom = Math.random; @@ -815,11 +803,8 @@ MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - /** Used as the size, in bytes, of each `Float64Array` element. */ - var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; - /** - * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) * of an array-like value. */ var MAX_SAFE_INTEGER = 9007199254740991; @@ -837,7 +822,7 @@ ctorByTag[int8Tag] = context.Int8Array; ctorByTag[int16Tag] = context.Int16Array; ctorByTag[int32Tag] = context.Int32Array; - ctorByTag[uint8Tag] = context.Uint8Array; + ctorByTag[uint8Tag] = Uint8Array; ctorByTag[uint8ClampedTag] = context.Uint8ClampedArray; ctorByTag[uint16Tag] = context.Uint16Array; ctorByTag[uint32Tag] = context.Uint32Array; @@ -863,15 +848,16 @@ /** * Creates a `lodash` object which wraps `value` to enable implicit chaining. * Methods that operate on and return arrays, collections, and functions can - * be chained together. Methods that return a boolean or single value will - * automatically end the chain returning the unwrapped value. Explicit chaining - * may be enabled using `_.chain`. The execution of chained methods is lazy, - * that is, execution is deferred until `_#value` is implicitly or explicitly - * called. + * be chained together. Methods that retrieve a single value or may return a + * primitive value will automatically end the chain returning the unwrapped + * value. Explicit chaining may be enabled using `_.chain`. The execution of + * chained methods is lazy, that is, execution is deferred until `_#value` + * is implicitly or explicitly called. * * Lazy evaluation allows several methods to support shortcut fusion. Shortcut - * fusion is an optimization that merges iteratees to avoid creating intermediate - * arrays and reduce the number of iteratee executions. + * fusion is an optimization strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly reduce the + * number of iteratee executions. * * Chaining is supported in custom builds as long as the `_#value` method is * directly or indirectly included in the build. @@ -894,36 +880,37 @@ * The chainable wrapper methods are: * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, - * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, - * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, - * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, - * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, - * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, - * `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, - * `memoize`, `merge`, `method`, `methodOf`, `mixin`, `negate`, `omit`, `once`, - * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `plant`, `pluck`, - * `property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, `rearg`, - * `reject`, `remove`, `rest`, `restParam`, `reverse`, `set`, `shuffle`, - * `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, `spread`, - * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, - * `thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`, - * `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `where`, `without`, - * `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, + * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` * * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, - * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, - * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `get`, - * `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, - * `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, - * `isFinite` `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, - * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lt`, `lte`, - * `max`, `min`, `noConflict`, `noop`, `now`, `pad`, `padLeft`, `padRight`, - * `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, - * `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, - * `sortedLastIndex`, `startCase`, `startsWith`, `sum`, `template`, `trim`, - * `trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, `value`, and `words` + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, + * `unescape`, `uniqueId`, `value`, and `words` * * The wrapper method `sample` will return a wrapped value when `n` is provided, * otherwise an unwrapped value is returned. @@ -1006,15 +993,6 @@ Ctor.prototype = { 'valueOf': x, 'y': x }; for (var key in new Ctor) { props.push(key); } - /** - * Detect if the `toStringTag` of `arguments` objects is resolvable - * (all but Firefox < 4, IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.argsTag = objToString.call(arguments) == argsTag; - /** * Detect if `name` or `message` properties of `Error.prototype` are * enumerable by default (IE < 9, Safari < 5.1). @@ -1038,14 +1016,6 @@ */ support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype'); - /** - * Detect if the `toStringTag` of DOM nodes is resolvable (all but IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.nodeTag = objToString.call(document) != objectTag; - /** * Detect if properties shadowing those on `Object.prototype` are non-enumerable. * @@ -1090,18 +1060,6 @@ * @type boolean */ support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; - - /** - * Detect if the DOM is supported. - * - * @memberOf _.support - * @type boolean - */ - try { - support.dom = document.createDocumentFragment().nodeType === 11; - } catch(e) { - support.dom = false; - } }(1, 0)); /** @@ -1175,13 +1133,12 @@ */ function LazyWrapper(value) { this.__wrapped__ = value; - this.__actions__ = null; + this.__actions__ = []; this.__dir__ = 1; - this.__dropCount__ = 0; this.__filtered__ = false; - this.__iteratees__ = null; + this.__iteratees__ = []; this.__takeCount__ = POSITIVE_INFINITY; - this.__views__ = null; + this.__views__ = []; } /** @@ -1193,17 +1150,13 @@ * @returns {Object} Returns the cloned `LazyWrapper` object. */ function lazyClone() { - var actions = this.__actions__, - iteratees = this.__iteratees__, - views = this.__views__, - result = new LazyWrapper(this.__wrapped__); - - result.__actions__ = actions ? arrayCopy(actions) : null; + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = arrayCopy(this.__actions__); result.__dir__ = this.__dir__; result.__filtered__ = this.__filtered__; - result.__iteratees__ = iteratees ? arrayCopy(iteratees) : null; + result.__iteratees__ = arrayCopy(this.__iteratees__); result.__takeCount__ = this.__takeCount__; - result.__views__ = views ? arrayCopy(views) : null; + result.__views__ = arrayCopy(this.__views__); return result; } @@ -1236,22 +1189,25 @@ * @returns {*} Returns the unwrapped value. */ function lazyValue() { - var array = this.__wrapped__.value(); - if (!isArray(array)) { - return baseWrapperValue(array, this.__actions__); - } - var dir = this.__dir__, + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), isRight = dir < 0, - view = getView(0, array.length, this.__views__), + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), start = view.start, end = view.end, length = end - start, index = isRight ? end : (start - 1), - takeCount = nativeMin(length, this.__takeCount__), iteratees = this.__iteratees__, - iterLength = iteratees ? iteratees.length : 0, + iterLength = iteratees.length, resIndex = 0, - result = []; + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); + } + var result = []; outer: while (length-- && resIndex < takeCount) { @@ -1263,30 +1219,16 @@ while (++iterIndex < iterLength) { var data = iteratees[iterIndex], iteratee = data.iteratee, - type = data.type; + type = data.type, + computed = iteratee(value); - if (type == LAZY_DROP_WHILE_FLAG) { - if (data.done && (isRight ? (index > data.index) : (index < data.index))) { - data.count = 0; - data.done = false; - } - data.index = index; - if (!data.done) { - var limit = data.limit; - if (!(data.done = limit > -1 ? (data.count++ >= limit) : !iteratee(value))) { - continue outer; - } - } - } else { - var computed = iteratee(value); - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; } } } @@ -1418,6 +1360,30 @@ /*------------------------------------------------------------------------*/ + /** + * Creates a new array joining `array` with `other`. + * + * @private + * @param {Array} array The array to join. + * @param {Array} other The other array to join. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } + /** * Copies the values of `source` to `array`. * @@ -1573,6 +1539,25 @@ return result; } + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + /** * A specialized version of `_.reduce` for arrays without support for callback * shorthands and `this` binding. @@ -1644,18 +1629,20 @@ } /** - * A specialized version of `_.sum` for arrays without support for iteratees. + * A specialized version of `_.sum` for arrays without support for callback + * shorthands and `this` binding.. * * @private * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. * @returns {number} Returns the sum. */ - function arraySum(array) { + function arraySum(array, iteratee) { var length = array.length, result = 0; while (length--) { - result += +array[length] || 0; + result += +iteratee(array[length]) || 0; } return result; } @@ -1862,7 +1849,7 @@ : (object ? value : {}); } } - // Check for circular references and return corresponding clone. + // Check for circular references and return its corresponding clone. stackA || (stackA = []); stackB || (stackB = []); @@ -1897,7 +1884,7 @@ if (isObject(prototype)) { object.prototype = prototype; var result = new object; - object.prototype = null; + object.prototype = undefined; } return result || {}; }; @@ -1939,7 +1926,7 @@ var index = -1, indexOf = getIndexOf(), isCommon = indexOf == baseIndexOf, - cache = (isCommon && values.length >= 200) ? createCache(values) : null, + cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, valuesLength = values.length; if (cache) { @@ -2115,13 +2102,14 @@ * @param {Array} array The array to flatten. * @param {boolean} [isDeep] Specify a deep flatten. * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ - function baseFlatten(array, isDeep, isStrict) { + function baseFlatten(array, isDeep, isStrict, result) { + result || (result = []); + var index = -1, - length = array.length, - resIndex = -1, - result = []; + length = array.length; while (++index < length) { var value = array[index]; @@ -2129,16 +2117,12 @@ (isStrict || isArray(value) || isArguments(value))) { if (isDeep) { // Recursively flatten arrays (susceptible to call stack limits). - value = baseFlatten(value, isDeep, isStrict); - } - var valIndex = -1, - valLength = value.length; - - while (++valIndex < valLength) { - result[++resIndex] = value[valIndex]; + baseFlatten(value, isDeep, isStrict, result); + } else { + arrayPush(result, value); } } else if (!isStrict) { - result[++resIndex] = value; + result[result.length] = value; } } return result; @@ -2495,7 +2479,7 @@ * @private * @param {Object} object The destination object. * @param {Object} source The source object. - * @param {Function} [customizer] The function to customize merging properties. + * @param {Function} [customizer] The function to customize merged values. * @param {Array} [stackA=[]] Tracks traversed source objects. * @param {Array} [stackB=[]] Associates values with source counterparts. * @returns {Object} Returns `object`. @@ -2505,7 +2489,7 @@ return object; } var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), - props = isSrcArr ? null : keys(source); + props = isSrcArr ? undefined : keys(source); arrayEach(props || source, function(srcValue, key) { if (props) { @@ -2544,7 +2528,7 @@ * @param {Object} source The source object. * @param {string} key The key of the value to merge. * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize merging properties. + * @param {Function} [customizer] The function to customize merged values. * @param {Array} [stackA=[]] Tracks traversed source objects. * @param {Array} [stackB=[]] Associates values with source counterparts. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. @@ -2651,7 +2635,7 @@ * @returns {number} Returns the random number. */ function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); + return min + nativeFloor(nativeRandom() * (max - min + 1)); } /** @@ -2817,7 +2801,7 @@ indexOf = getIndexOf(), length = array.length, isCommon = indexOf == baseIndexOf, - isLarge = isCommon && length >= 200, + isLarge = isCommon && length >= LARGE_ARRAY_SIZE, seen = isLarge ? createCache() : null, result = []; @@ -2916,11 +2900,8 @@ length = actions.length; while (++index < length) { - var args = [result], - action = actions[index]; - - push.apply(args, action.args); - result = action.func.apply(action.thisArg, args); + var action = actions[index]; + result = action.func.apply(action.thisArg, arrayPush([result], action.args)); } return result; } @@ -2979,7 +2960,7 @@ valIsUndef = value === undefined; while (low < high) { - var mid = floor((low + high) / 2), + var mid = nativeFloor((low + high) / 2), computed = iteratee(array[mid]), isDef = computed !== undefined, isReflexive = computed === computed; @@ -3048,26 +3029,11 @@ * @returns {ArrayBuffer} Returns the cloned array buffer. */ function bufferClone(buffer) { - return bufferSlice.call(buffer, 0); - } - if (!bufferSlice) { - // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`. - bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) { - var byteLength = buffer.byteLength, - floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, - offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, - result = new ArrayBuffer(byteLength); + var result = new ArrayBuffer(buffer.byteLength), + view = new Uint8Array(result); - if (floatLength) { - var view = new Float64Array(result, 0, floatLength); - view.set(new Float64Array(buffer, 0, floatLength)); - } - if (byteLength != offset) { - view = new Uint8Array(result, offset); - view.set(new Uint8Array(buffer, offset)); - } - return result; - }; + view.set(new Uint8Array(buffer)); + return result; } /** @@ -3086,7 +3052,7 @@ argsLength = nativeMax(args.length - holdersLength, 0), leftIndex = -1, leftLength = partials.length, - result = Array(argsLength + leftLength); + result = Array(leftLength + argsLength); while (++leftIndex < leftLength) { result[leftIndex] = partials[leftIndex]; @@ -3133,12 +3099,7 @@ } /** - * Creates a function that aggregates a collection, creating an accumulator - * object composed from the results of running each element in the collection - * through an iteratee. - * - * **Note:** This function is used to create `_.countBy`, `_.groupBy`, `_.indexBy`, - * and `_.partition`. + * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. * * @private * @param {Function} setter The function to set keys and values of the accumulator object. @@ -3168,10 +3129,7 @@ } /** - * Creates a function that assigns properties of source object(s) to a given - * destination object. - * - * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`. + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. * * @private * @param {Function} assigner The function to assign values. @@ -3282,9 +3240,9 @@ * @param {Array} [values] The values to cache. * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. */ - var createCache = !(nativeCreate && Set) ? constant(null) : function(values) { - return new SetCache(values); - }; + function createCache(values) { + return (nativeCreate && Set) ? new SetCache(values) : null; + } /** * Creates a function that produces compound words out of the words in a @@ -3319,7 +3277,7 @@ function createCtorWrapper(Ctor) { return function() { // Use a `switch` statement to work with class constructors. - // See https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist // for more details. var args = arguments; switch (args.length) { @@ -3329,6 +3287,8 @@ case 3: return new Ctor(args[0], args[1], args[2]); case 4: return new Ctor(args[0], args[1], args[2], args[3]); case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); } var thisBinding = baseCreate(Ctor.prototype), result = Ctor.apply(thisBinding, args); @@ -3349,15 +3309,34 @@ function createCurry(flag) { function curryFunc(func, arity, guard) { if (guard && isIterateeCall(func, arity, guard)) { - arity = null; + arity = undefined; } - var result = createWrapper(func, flag, null, null, null, null, null, arity); + var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); result.placeholder = curryFunc.placeholder; return result; } return curryFunc; } + /** + * Creates a `_.defaults` or `_.defaultsDeep` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @param {Function} customizer The function to customize assigned values. + * @returns {Function} Returns the new defaults function. + */ + function createDefaults(assigner, customizer) { + return restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(customizer); + return assigner.apply(undefined, args); + }); + } + /** * Creates a `_.max` or `_.min` function. * @@ -3369,11 +3348,11 @@ function createExtremum(comparator, exValue) { return function(collection, iteratee, thisArg) { if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; + iteratee = undefined; } iteratee = getCallback(iteratee, thisArg, 3); if (iteratee.length == 1) { - collection = toIterable(collection); + collection = isArray(collection) ? collection : toIterable(collection); var result = arrayExtremum(collection, iteratee, comparator, exValue); if (!(collection.length && result === exValue)) { return result; @@ -3454,7 +3433,7 @@ throw new TypeError(FUNC_ERROR_TEXT); } if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { - wrapper = new LodashWrapper([]); + wrapper = new LodashWrapper([], true); } } index = wrapper ? -1 : length; @@ -3462,7 +3441,7 @@ func = funcs[index]; var funcName = getFuncName(func), - data = funcName == 'wrapper' ? getData(func) : null; + data = funcName == 'wrapper' ? getData(func) : undefined; if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); @@ -3471,12 +3450,14 @@ } } return function() { - var args = arguments; - if (wrapper && args.length == 1 && isArray(args[0])) { - return wrapper.plant(args[0]).value(); + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); } var index = 0, - result = length ? funcs[index].apply(this, args) : args[0]; + result = length ? funcs[index].apply(this, args) : value; while (++index < length) { result = funcs[index].call(this, result); @@ -3580,7 +3561,7 @@ function createPartial(flag) { var partialFunc = restParam(function(func, partials) { var holders = replaceHolders(partials, partialFunc.placeholder); - return createWrapper(func, flag, null, partials, holders); + return createWrapper(func, flag, undefined, partials, holders); }); return partialFunc; } @@ -3626,7 +3607,7 @@ isCurry = bitmask & CURRY_FLAG, isCurryBound = bitmask & CURRY_BOUND_FLAG, isCurryRight = bitmask & CURRY_RIGHT_FLAG, - Ctor = isBindKey ? null : createCtorWrapper(func); + Ctor = isBindKey ? undefined : createCtorWrapper(func); function wrapper() { // Avoid `arguments` object use disqualifying optimizations by @@ -3650,12 +3631,12 @@ length -= argsHolders.length; if (length < arity) { - var newArgPos = argPos ? arrayCopy(argPos) : null, + var newArgPos = argPos ? arrayCopy(argPos) : undefined, newArity = nativeMax(arity - length, 0), - newsHolders = isCurry ? argsHolders : null, - newHoldersRight = isCurry ? null : argsHolders, - newPartials = isCurry ? args : null, - newPartialsRight = isCurry ? null : args; + newsHolders = isCurry ? argsHolders : undefined, + newHoldersRight = isCurry ? undefined : argsHolders, + newPartials = isCurry ? args : undefined, + newPartialsRight = isCurry ? undefined : args; bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); @@ -3709,7 +3690,7 @@ } var padLength = length - strLength; chars = chars == null ? ' ' : (chars + ''); - return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength); + return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); } /** @@ -3735,7 +3716,7 @@ argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, - args = Array(argsLength + leftLength); + args = Array(leftLength + argsLength); while (++leftIndex < leftLength) { args[leftIndex] = partials[leftIndex]; @@ -3749,6 +3730,25 @@ return wrapper; } + /** + * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + precision = precision === undefined ? 0 : (+precision || 0); + if (precision) { + precision = pow(10, precision); + return func(number * precision) / precision; + } + return func(number); + }; + } + /** * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. * @@ -3798,16 +3798,16 @@ var length = partials ? partials.length : 0; if (!length) { bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); - partials = holders = null; + partials = holders = undefined; } length -= (holders ? holders.length : 0); if (bitmask & PARTIAL_RIGHT_FLAG) { var partialsRight = partials, holdersRight = holders; - partials = holders = null; + partials = holders = undefined; } - var data = isBindKey ? null : getData(func), + var data = isBindKey ? undefined : getData(func), newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; if (data) { @@ -3886,7 +3886,7 @@ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * * @private - * @param {Object} value The object to compare. + * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {string} tag The `toStringTag` of the objects to compare. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. @@ -4086,13 +4086,13 @@ * @private * @param {number} start The start of the view. * @param {number} end The end of the view. - * @param {Array} [transforms] The transformations to apply to the view. + * @param {Array} transforms The transformations to apply to the view. * @returns {Object} Returns an object containing the `start` and `end` * positions of the view. */ function getView(start, end, transforms) { var index = -1, - length = transforms ? transforms.length : 0; + length = transforms.length; while (++index < length) { var data = transforms[index], @@ -4295,7 +4295,7 @@ /** * Checks if `value` is a valid array-like length. * - * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). * * @private * @param {*} value The value to check. @@ -4387,6 +4387,18 @@ return data; } + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function mergeDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); + } + /** * A specialized version of `_.pick` which picks `object` properties specified * by `props`. @@ -4486,46 +4498,6 @@ }; }()); - /** - * A fallback implementation of `_.isPlainObject` which checks if `value` - * is an object created by the `Object` constructor or has a `[[Prototype]]` - * of `null`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var Ctor, - support = lodash.support; - - // Exit early for non `Object` objects. - if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value)) || - (!hasOwnProperty.call(value, 'constructor') && - (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor))) || - (!support.argsTag && isArguments(value))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - var result; - if (support.ownLast) { - baseForIn(value, function(subValue, key, object) { - result = hasOwnProperty.call(object, key); - return false; - }); - return result !== false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - baseForIn(value, function(subValue, key) { - result = key; - }); - return result === undefined || hasOwnProperty.call(value, result); - } - /** * A fallback implementation of `Object.keys` which creates an array of the * own enumerable property names of `object`. @@ -4652,12 +4624,12 @@ if (guard ? isIterateeCall(array, size, guard) : size == null) { size = 1; } else { - size = nativeMax(+size || 1, 1); + size = nativeMax(nativeFloor(size) || 1, 1); } var index = 0, length = array ? array.length : 0, resIndex = -1, - result = Array(ceil(length / size)); + result = Array(nativeCeil(length / size)); while (index < length) { result[++resIndex] = baseSlice(array, index, (index += size)); @@ -4696,7 +4668,7 @@ /** * Creates an array of unique `array` values not included in the other - * provided arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -4711,7 +4683,7 @@ * // => [1, 3] */ var difference = restParam(function(array, values) { - return isArrayLike(array) + return (isObjectLike(array) && isArrayLike(array)) ? baseDifference(array, baseFlatten(values, false, true)) : []; }); @@ -5106,7 +5078,7 @@ /** * Gets the index at which the first occurrence of `value` is found in `array` - * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. If `fromIndex` is negative, it is used as the offset * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` * performs a faster binary search. @@ -5140,10 +5112,9 @@ if (typeof fromIndex == 'number') { fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; } else if (fromIndex) { - var index = binaryIndex(array, value), - other = array[index]; - - if (value === value ? (value === other) : (other !== other)) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { return index; } return -1; @@ -5170,7 +5141,7 @@ /** * Creates an array of unique values that are included in all of the provided - * arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -5291,7 +5262,7 @@ /** * Removes all provided values from `array` using - * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * **Note:** Unlike `_.without`, this method mutates `array`. @@ -5724,7 +5695,7 @@ /** * Creates an array of unique values, in order, from all of the provided arrays - * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -5743,7 +5714,7 @@ /** * Creates a duplicate-free version of an array, using - * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons, in which only the first occurence of each element * is kept. Providing `true` for `isSorted` performs a faster search algorithm * for sorted arrays. If an iteratee function is provided it is invoked for @@ -5797,7 +5768,7 @@ } if (isSorted != null && typeof isSorted != 'boolean') { thisArg = iteratee; - iteratee = isIterateeCall(array, isSorted, thisArg) ? null : isSorted; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; isSorted = false; } var callback = getCallback(); @@ -5884,7 +5855,7 @@ /** * Creates an array excluding all provided values using - * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -5926,7 +5897,7 @@ var array = arguments[index]; if (isArrayLike(array)) { var result = result - ? baseDifference(result, array).concat(baseDifference(array, result)) + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) : array; } } @@ -6148,16 +6119,16 @@ * @example * * var array = [1, 2]; - * var wrapper = _(array).push(3); + * var wrapped = _(array).push(3); * * console.log(array); * // => [1, 2] * - * wrapper = wrapper.commit(); + * wrapped = wrapped.commit(); * console.log(array); * // => [1, 2, 3] * - * wrapper.last(); + * wrapped.last(); * // => 3 * * console.log(array); @@ -6167,6 +6138,33 @@ return new LodashWrapper(this.value(), this.__chain__); } + /** + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. + * + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); + }); + /** * Creates a clone of the chained sequence planting `value` as the wrapped value. * @@ -6177,17 +6175,17 @@ * @example * * var array = [1, 2]; - * var wrapper = _(array).map(function(value) { + * var wrapped = _(array).map(function(value) { * return Math.pow(value, 2); * }); * * var other = [3, 4]; - * var otherWrapper = wrapper.plant(other); + * var otherWrapped = wrapped.plant(other); * - * otherWrapper.value(); + * otherWrapped.value(); * // => [9, 16] * - * wrapper.value(); + * wrapped.value(); * // => [1, 4] */ function wrapperPlant(value) { @@ -6230,15 +6228,20 @@ */ function wrapperReverse() { var value = this.__wrapped__; + + var interceptor = function(value) { + return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); + }; if (value instanceof LazyWrapper) { + var wrapped = value; if (this.__actions__.length) { - value = new LazyWrapper(this); + wrapped = new LazyWrapper(this); } - return new LodashWrapper(value.reverse(), this.__chain__); + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); } - return this.thru(function(value) { - return value.reverse(); - }); + return this.thru(interceptor); } /** @@ -6399,7 +6402,7 @@ function every(collection, predicate, thisArg) { var func = isArray(collection) ? arrayEvery : baseEvery; if (thisArg && isIterateeCall(collection, predicate, thisArg)) { - predicate = null; + predicate = undefined; } if (typeof predicate != 'function' || thisArg !== undefined) { predicate = getCallback(predicate, thisArg, 3); @@ -6673,7 +6676,7 @@ /** * Checks if `value` is in `collection` using - * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. If `fromIndex` is negative, it is used as the offset * from the end of `collection`. * @@ -6706,17 +6709,14 @@ collection = values(collection); length = collection.length; } - if (!length) { - return false; - } if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { fromIndex = 0; } else { fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); } return (typeof collection == 'string' || !isArray(collection) && isString(collection)) - ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) - : (getIndexOf(collection, target, fromIndex) > -1); + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && getIndexOf(collection, target, fromIndex) > -1); } /** @@ -6798,7 +6798,7 @@ result = isArrayLike(collection) ? Array(collection.length) : []; baseEach(collection, function(value) { - var func = isFunc ? path : ((isProp && value != null) ? value[path] : null); + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); }); return result; @@ -6968,7 +6968,8 @@ * `_.reduce`, `_.reduceRight`, and `_.transform`. * * The guarded methods are: - * `assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder` + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` * * @static * @memberOf _ @@ -7198,7 +7199,7 @@ function some(collection, predicate, thisArg) { var func = isArray(collection) ? arraySome : baseSome; if (thisArg && isIterateeCall(collection, predicate, thisArg)) { - predicate = null; + predicate = undefined; } if (typeof predicate != 'function' || thisArg !== undefined) { predicate = getCallback(predicate, thisArg, 3); @@ -7259,7 +7260,7 @@ return []; } if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; + iteratee = undefined; } var index = -1; iteratee = getCallback(iteratee, thisArg, 3); @@ -7318,9 +7319,9 @@ /** * This method is like `_.sortByAll` except that it allows specifying the - * sort orders of the iteratees to sort by. A truthy value in `orders` will - * sort the corresponding property name in ascending order while a falsey - * value will sort it in descending order. + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". * * If a property name is provided for an iteratee the created `_.property` * style callback returns the property value of the given element. @@ -7334,7 +7335,7 @@ * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {boolean[]} orders The sort orders of `iteratees`. + * @param {boolean[]} [orders] The sort orders of `iteratees`. * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. * @returns {Array} Returns the new sorted array. * @example @@ -7347,7 +7348,7 @@ * ]; * * // sort by `user` in ascending order and by `age` in descending order - * _.map(_.sortByOrder(users, ['user', 'age'], [true, false]), _.values); + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ function sortByOrder(collection, iteratees, orders, guard) { @@ -7355,7 +7356,7 @@ return []; } if (guard && isIterateeCall(iteratees, orders, guard)) { - orders = null; + orders = undefined; } if (!isArray(iteratees)) { iteratees = iteratees == null ? [] : [iteratees]; @@ -7480,10 +7481,10 @@ */ function ary(func, n, guard) { if (guard && isIterateeCall(func, n, guard)) { - n = null; + n = undefined; } n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); - return createWrapper(func, ARY_FLAG, null, null, null, null, n); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); } /** @@ -7518,7 +7519,7 @@ result = func.apply(this, arguments); } if (n <= 1) { - func = null; + func = undefined; } return result; }; @@ -7826,9 +7827,9 @@ var leading = true; trailing = false; } else if (isObject(options)) { - leading = options.leading; + leading = !!options.leading; maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); - trailing = 'trailing' in options ? options.trailing : trailing; + trailing = 'trailing' in options ? !!options.trailing : trailing; } function cancel() { @@ -7838,41 +7839,35 @@ if (maxTimeoutId) { clearTimeout(maxTimeoutId); } + lastCalled = 0; maxTimeoutId = timeoutId = trailingCall = undefined; } + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + function delayed() { var remaining = wait - (now() - stamp); if (remaining <= 0 || remaining > wait) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } + complete(trailingCall, maxTimeoutId); } else { timeoutId = setTimeout(delayed, remaining); } } function maxDelayed() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } + complete(trailing, timeoutId); } function debounced() { @@ -7912,7 +7907,7 @@ result = func.apply(thisArg, args); } if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; + args = thisArg = undefined; } return result; } @@ -8017,7 +8012,7 @@ * * **Note:** The cache is exposed as the `cache` property on the memoized * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the [`Map`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) * method interface of `get`, `has`, and `set`. * * @static @@ -8078,6 +8073,52 @@ return memoized; } + /** + * Creates a function that runs each argument through a corresponding + * transform function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * modded(1, 2); + * // => [1, 4] + * + * modded(5, 10); + * // => [25, 20] + */ + var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); + }); + /** * Creates a function that negates the result of the predicate `func`. The * `func` predicate is invoked with the `this` binding and arguments of the @@ -8223,7 +8264,7 @@ * // => [3, 6, 9] */ var rearg = restParam(function(func, indexes) { - return createWrapper(func, REARG_FLAG, null, null, null, baseFlatten(indexes)); + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); }); /** @@ -8369,10 +8410,7 @@ leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } - debounceOptions.leading = leading; - debounceOptions.maxWait = +wait; - debounceOptions.trailing = trailing; - return debounce(func, wait, debounceOptions); + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); } /** @@ -8398,7 +8436,7 @@ */ function wrap(value, wrapper) { wrapper = wrapper == null ? identity : wrapper; - return createWrapper(wrapper, PARTIAL_FLAG, null, [value], []); + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); } /*------------------------------------------------------------------------*/ @@ -8584,14 +8622,8 @@ * // => false */ function isArguments(value) { - return isObjectLike(value) && isArrayLike(value) && objToString.call(value) == argsTag; - } - // Fallback for environments without a `toStringTag` for `arguments` objects. - if (!support.argsTag) { - isArguments = function(value) { - return isObjectLike(value) && isArrayLike(value) && - hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); - }; + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); } /** @@ -8671,14 +8703,7 @@ * // => false */ function isElement(value) { - return !!value && value.nodeType === 1 && isObjectLike(value) && - (lodash.support.nodeTag ? (objToString.call(value).indexOf('Element') > -1) : isHostObject(value)); - } - // Fallback for environments without DOM support. - if (!support.dom) { - isElement = function(value) { - return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); - }; + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); } /** @@ -8793,7 +8818,7 @@ /** * Checks if `value` is a finite primitive number. * - * **Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). + * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). * * @static * @memberOf _ @@ -8817,9 +8842,9 @@ * _.isFinite(Infinity); * // => false */ - var isFinite = nativeNumIsFinite || function(value) { + function isFinite(value) { return typeof value == 'number' && nativeIsFinite(value); - }; + } /** * Checks if `value` is classified as a `Function` object. @@ -8837,12 +8862,12 @@ * _.isFunction(/abc/); * // => false */ - var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) { + function isFunction(value) { // The use of `Object#toString` avoids issues with the `typeof` operator // in older versions of Chrome and Safari which return 'function' for regexes // and Safari 8 equivalents which return 'object' for typed array constructors. - return objToString.call(value) == funcTag; - }; + return isObject(value) && objToString.call(value) == funcTag; + } /** * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. @@ -8966,7 +8991,7 @@ if (value == null) { return false; } - if (objToString.call(value) == funcTag) { + if (isFunction(value)) { return reIsNative.test(fnToString.call(value)); } return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); @@ -9048,17 +9073,33 @@ * _.isPlainObject(Object.create(null)); * // => true */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && objToString.call(value) == objectTag) || (!lodash.support.argsTag && isArguments(value))) { + function isPlainObject(value) { + var Ctor; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) || + (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { return false; } - var valueOf = getNative(value, 'valueOf'), - objProto = valueOf && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + if (lodash.support.ownLast) { + baseForIn(value, function(subValue, key, object) { + result = hasOwnProperty.call(object, key); + return false; + }); + return result !== false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return result === undefined || hasOwnProperty.call(value, result); + } /** * Checks if `value` is classified as a `RegExp` object. @@ -9245,6 +9286,56 @@ /*------------------------------------------------------------------------*/ + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it is invoked to produce the merged values of the destination and + * source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments: (objectValue, sourceValue, key, object, source). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + * + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var merge = createAssigner(baseMerge); + /** * Assigns own enumerable properties of source object(s) to the destination * object. Subsequent sources overwrite property assignments of previous sources. @@ -9253,7 +9344,7 @@ * (objectValue, sourceValue, key, object, source). * * **Note:** This method mutates `object` and is based on - * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). * * @static * @memberOf _ @@ -9320,7 +9411,7 @@ function create(prototype, properties, guard) { var result = baseCreate(prototype); if (guard && isIterateeCall(prototype, properties, guard)) { - properties = null; + properties = undefined; } return properties ? baseAssign(result, properties) : result; } @@ -9343,14 +9434,27 @@ * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); * // => { 'user': 'barney', 'age': 36 } */ - var defaults = restParam(function(args) { - var object = args[0]; - if (object == null) { - return object; - } - args.push(assignDefaults); - return assign.apply(undefined, args); - }); + var defaults = createDefaults(assign, assignDefaults); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ + var defaultsDeep = createDefaults(merge, mergeDefaults); /** * This method is like `_.find` except that it returns the key of the first @@ -9677,7 +9781,7 @@ */ function invert(object, multiValue, guard) { if (guard && isIterateeCall(object, multiValue, guard)) { - multiValue = null; + multiValue = undefined; } var index = -1, props = keys(object), @@ -9706,7 +9810,7 @@ * Creates an array of the own enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) * for more details. * * @static @@ -9730,7 +9834,7 @@ * // => ['0', '1'] */ var keys = !nativeKeys ? shimKeys : function(object) { - var Ctor = object == null ? null : object.constructor; + var Ctor = object == null ? undefined : object.constructor; if ((typeof Ctor == 'function' && Ctor.prototype === object) || (typeof object == 'function' ? lodash.support.enumPrototypes : isArrayLike(object))) { return shimKeys(object); @@ -9882,56 +9986,6 @@ */ var mapValues = createObjectMapper(); - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * overwrite property assignments of previous sources. If `customizer` is - * provided it is invoked to produce the merged values of the destination and - * source properties. If `customizer` returns `undefined` merging is handled - * by the method instead. The `customizer` is bound to `thisArg` and invoked - * with five arguments: (objectValue, sourceValue, key, object, source). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {Object} Returns `object`. - * @example - * - * var users = { - * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] - * }; - * - * var ages = { - * 'data': [{ 'age': 36 }, { 'age': 40 }] - * }; - * - * _.merge(users, ages); - * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } - * - * // using a customizer callback - * var object = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var other = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(object, other, function(a, b) { - * if (_.isArray(a)) { - * return a.concat(b); - * } - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } - */ - var merge = createAssigner(baseMerge); - /** * The opposite of `_.pick`; this method creates an object composed of the * own and inherited enumerable properties of `object` that are not omitted. @@ -10162,7 +10216,7 @@ if (isArr) { accumulator = isArray(object) ? new Ctor : []; } else { - accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : null); + accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); } } else { accumulator = {}; @@ -10265,7 +10319,7 @@ */ function inRange(value, start, end) { start = +start || 0; - if (typeof end === 'undefined') { + if (end === undefined) { end = start; start = 0; } else { @@ -10303,7 +10357,7 @@ */ function random(min, max, floating) { if (floating && isIterateeCall(min, max, floating)) { - max = floating = null; + max = floating = undefined; } var noMin = min == null, noMax = max == null; @@ -10490,8 +10544,8 @@ function escapeRegExp(string) { string = baseToString(string); return (string && reHasRegExpChars.test(string)) - ? string.replace(reRegExpChars, '\\$&') - : string; + ? string.replace(reRegExpChars, escapeRegExpChar) + : (string || '(?:)'); } /** @@ -10548,8 +10602,8 @@ return string; } var mid = (length - strLength) / 2, - leftLength = floor(mid), - rightLength = ceil(mid); + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); chars = createPadding('', rightLength, chars); return chars.slice(0, leftLength) + string + chars; @@ -10627,25 +10681,16 @@ * // => [6, 8, 10] */ function parseInt(string, radix, guard) { - if (guard && isIterateeCall(string, radix, guard)) { + // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard ? isIterateeCall(string, radix, guard) : radix == null) { radix = 0; + } else if (radix) { + radix = +radix; } - return nativeParseInt(string, radix); - } - // Fallback for environments with pre-ES5 implementations. - if (nativeParseInt(whitespace + '08') != 8) { - parseInt = function(string, radix, guard) { - // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. - // Chrome fails to trim leading whitespace characters. - // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. - if (guard ? isIterateeCall(string, radix, guard) : radix == null) { - radix = 0; - } else if (radix) { - radix = +radix; - } - string = trim(string); - return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); - }; + string = trim(string); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); } /** @@ -10681,7 +10726,7 @@ if (n % 2) { result += string; } - n = floor(n / 2); + n = nativeFloor(n / 2); string += string; } while (n); @@ -10866,7 +10911,7 @@ var settings = lodash.templateSettings; if (otherOptions && isIterateeCall(string, options, otherOptions)) { - options = otherOptions = null; + options = otherOptions = undefined; } string = baseToString(string); options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults); @@ -11102,7 +11147,7 @@ */ function trunc(string, options, guard) { if (guard && isIterateeCall(string, options, guard)) { - options = null; + options = undefined; } var length = DEFAULT_TRUNC_LENGTH, omission = DEFAULT_TRUNC_OMISSION; @@ -11197,7 +11242,7 @@ */ function words(string, pattern, guard) { if (guard && isIterateeCall(string, pattern, guard)) { - pattern = null; + pattern = undefined; } string = baseToString(string); return string.match(pattern || reWords) || []; @@ -11273,7 +11318,7 @@ */ function callback(func, thisArg, guard) { if (guard && isIterateeCall(func, thisArg, guard)) { - thisArg = null; + thisArg = undefined; } return isObjectLike(func) ? matches(func) @@ -11474,8 +11519,8 @@ function mixin(object, source, options) { if (options == null) { var isObj = isObject(source), - props = isObj ? keys(source) : null, - methodNames = (props && props.length) ? baseFunctions(source, props) : null; + props = isObj ? keys(source) : undefined, + methodNames = (props && props.length) ? baseFunctions(source, props) : undefined; if (!(methodNames ? methodNames.length : isObj)) { methodNames = false; @@ -11514,9 +11559,7 @@ result.__chain__ = chainAll; return result; } - var args = [this.value()]; - push.apply(args, arguments); - return func.apply(object, args); + return func.apply(object, arrayPush([this.value()], arguments)); }; }(func)); } @@ -11537,7 +11580,7 @@ * var lodash = _.noConflict(); */ function noConflict() { - context._ = oldDash; + root._ = oldDash; return this; } @@ -11646,7 +11689,7 @@ */ function range(start, end, step) { if (step && isIterateeCall(start, end, step)) { - end = step = null; + end = step = undefined; } start = +start || 0; step = step == null ? 1 : (+step || 0); @@ -11660,7 +11703,7 @@ // Use `Array(length)` so engines like Chakra and V8 avoid slower modes. // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details. var index = -1, - length = nativeMax(ceil((end - start) / (step || 1)), 0), + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), result = Array(length); while (++index < length) { @@ -11698,7 +11741,7 @@ * // => also invokes `mage.castSpell(n)` three times */ function times(n, iteratee, thisArg) { - n = floor(n); + n = nativeFloor(n); // Exit early to avoid a JSC JIT bug in Safari 8 // where `Array(0)` is treated as `Array(1)`. @@ -11760,6 +11803,50 @@ return (+augend || 0) + (+addend || 0); } + /** + * Calculates `n` rounded up to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} n The number to round up. + * @param {number} [precision=0] The precision to round up to. + * @returns {number} Returns the rounded up number. + * @example + * + * _.ceil(4.006); + * // => 5 + * + * _.ceil(6.004, 2); + * // => 6.01 + * + * _.ceil(6040, -2); + * // => 6100 + */ + var ceil = createRound('ceil'); + + /** + * Calculates `n` rounded down to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} n The number to round down. + * @param {number} [precision=0] The precision to round down to. + * @returns {number} Returns the rounded down number. + * @example + * + * _.floor(4.006); + * // => 4 + * + * _.floor(0.046, 2); + * // => 0.04 + * + * _.floor(4060, -2); + * // => 4000 + */ + var floor = createRound('floor'); + /** * Gets the maximum value of `collection`. If `collection` is empty or falsey * `-Infinity` is returned. If an iteratee function is provided it is invoked @@ -11858,6 +11945,28 @@ */ var min = createExtremum(lt, POSITIVE_INFINITY); + /** + * Calculates `n` rounded to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} n The number to round. + * @param {number} [precision=0] The precision to round to. + * @returns {number} Returns the rounded number. + * @example + * + * _.round(4.006); + * // => 4 + * + * _.round(4.006, 2); + * // => 4.01 + * + * _.round(4060, -2); + * // => 4100 + */ + var round = createRound('round'); + /** * Gets the sum of the values in `collection`. * @@ -11892,17 +12001,11 @@ */ function sum(collection, iteratee, thisArg) { if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; - } - var callback = getCallback(), - noIteratee = iteratee == null; - - if (!(noIteratee && callback === baseCallback)) { - noIteratee = false; - iteratee = callback(iteratee, thisArg, 3); + iteratee = undefined; } - return noIteratee - ? arraySum(isArray(collection) ? collection : toIterable(collection)) + iteratee = getCallback(iteratee, thisArg, 3); + return iteratee.length == 1 + ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee) : baseSum(collection, iteratee); } @@ -11949,6 +12052,7 @@ lodash.curryRight = curryRight; lodash.debounce = debounce; lodash.defaults = defaults; + lodash.defaultsDeep = defaultsDeep; lodash.defer = defer; lodash.delay = delay; lodash.difference = difference; @@ -11987,6 +12091,7 @@ lodash.method = method; lodash.methodOf = methodOf; lodash.mixin = mixin; + lodash.modArgs = modArgs; lodash.negate = negate; lodash.omit = omit; lodash.once = once; @@ -12062,6 +12167,7 @@ lodash.attempt = attempt; lodash.camelCase = camelCase; lodash.capitalize = capitalize; + lodash.ceil = ceil; lodash.clone = clone; lodash.cloneDeep = cloneDeep; lodash.deburr = deburr; @@ -12077,6 +12183,7 @@ lodash.findLastKey = findLastKey; lodash.findWhere = findWhere; lodash.first = first; + lodash.floor = floor; lodash.get = get; lodash.gt = gt; lodash.gte = gte; @@ -12125,6 +12232,7 @@ lodash.reduceRight = reduceRight; lodash.repeat = repeat; lodash.result = result; + lodash.round = round; lodash.runInContext = runInContext; lodash.size = size; lodash.snakeCase = snakeCase; @@ -12195,48 +12303,20 @@ lodash[methodName].placeholder = lodash; }); - // Add `LazyWrapper` methods that accept an `iteratee` value. - arrayEach(['dropWhile', 'filter', 'map', 'takeWhile'], function(methodName, type) { - var isFilter = type != LAZY_MAP_FLAG, - isDropWhile = type == LAZY_DROP_WHILE_FLAG; - - LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { - var filtered = this.__filtered__, - result = (filtered && isDropWhile) ? new LazyWrapper(this) : this.clone(), - iteratees = result.__iteratees__ || (result.__iteratees__ = []); - - iteratees.push({ - 'done': false, - 'count': 0, - 'index': 0, - 'iteratee': getCallback(iteratee, thisArg, 1), - 'limit': -1, - 'type': type - }); - - result.__filtered__ = filtered || isFilter; - return result; - }; - }); - // Add `LazyWrapper` methods for `_.drop` and `_.take` variants. arrayEach(['drop', 'take'], function(methodName, index) { - var whileName = methodName + 'While'; - LazyWrapper.prototype[methodName] = function(n) { - var filtered = this.__filtered__, - result = (filtered && !index) ? this.dropWhile() : this.clone(); + var filtered = this.__filtered__; + if (filtered && !index) { + return new LazyWrapper(this); + } + n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0); - n = n == null ? 1 : nativeMax(floor(n) || 0, 0); + var result = this.clone(); if (filtered) { - if (index) { - result.__takeCount__ = nativeMin(result.__takeCount__, n); - } else { - last(result.__iteratees__).limit = n; - } + result.__takeCount__ = nativeMin(result.__takeCount__, n); } else { - var views = result.__views__ || (result.__views__ = []); - views.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); + result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); } return result; }; @@ -12244,9 +12324,18 @@ LazyWrapper.prototype[methodName + 'Right'] = function(n) { return this.reverse()[methodName](n).reverse(); }; + }); - LazyWrapper.prototype[methodName + 'RightWhile'] = function(predicate, thisArg) { - return this.reverse()[whileName](predicate, thisArg).reverse(); + // Add `LazyWrapper` methods that accept an `iteratee` value. + arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { + var type = index + 1, + isFilter = type != LAZY_MAP_FLAG; + + LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { + var result = this.clone(); + result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type }); + result.__filtered__ = result.__filtered__ || isFilter; + return result; }; }); @@ -12264,7 +12353,7 @@ var dropName = 'drop' + (index ? '' : 'Right'); LazyWrapper.prototype[methodName] = function() { - return this[dropName](1); + return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1); }; }); @@ -12293,10 +12382,13 @@ start = start == null ? 0 : (+start || 0); var result = this; + if (result.__filtered__ && (start > 0 || end < 0)) { + return new LazyWrapper(result); + } if (start < 0) { - result = this.takeRight(-start); + result = result.takeRight(-start); } else if (start) { - result = this.drop(start); + result = result.drop(start); } if (end !== undefined) { end = (+end || 0); @@ -12305,21 +12397,25 @@ return result; }; + LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) { + return this.reverse().takeWhile(predicate, thisArg).reverse(); + }; + LazyWrapper.prototype.toArray = function() { - return this.drop(0); + return this.take(POSITIVE_INFINITY); }; // Add `LazyWrapper` methods to `lodash.prototype`. baseForOwn(LazyWrapper.prototype, function(func, methodName) { - var lodashFunc = lodash[methodName]; + var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName), + retUnwrapped = /^(?:first|last)$/.test(methodName), + lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName]; + if (!lodashFunc) { return; } - var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName), - retUnwrapped = /^(?:first|last)$/.test(methodName); - lodash.prototype[methodName] = function() { - var args = arguments, + var args = retUnwrapped ? [1] : arguments, chainAll = this.__chain__, value = this.__wrapped__, isHybrid = !!this.__actions__.length, @@ -12328,28 +12424,30 @@ useLazy = isLazy || isArray(value); if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) { - // avoid lazy use if the iteratee has a "length" value other than `1` + // Avoid lazy use if the iteratee has a "length" value other than `1`. isLazy = useLazy = false; } - var onlyLazy = isLazy && !isHybrid; - if (retUnwrapped && !chainAll) { - return onlyLazy - ? func.call(value) - : lodashFunc.call(lodash, this.value()); - } var interceptor = function(value) { - var otherArgs = [value]; - push.apply(otherArgs, args); - return lodashFunc.apply(lodash, otherArgs); + return (retUnwrapped && chainAll) + ? lodashFunc(value, 1)[0] + : lodashFunc.apply(undefined, arrayPush([value], args)); }; - if (useLazy) { - var wrapper = onlyLazy ? value : new LazyWrapper(this), - result = func.apply(wrapper, args); - if (!retUnwrapped && (isHybrid || result.__actions__)) { - var actions = result.__actions__ || (result.__actions__ = []); - actions.push({ 'func': thru, 'args': [interceptor], 'thisArg': lodash }); + var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined }, + onlyLazy = isLazy && !isHybrid; + + if (retUnwrapped && !chainAll) { + if (onlyLazy) { + value = value.clone(); + value.__actions__.push(action); + return func.call(value); } + return lodashFunc.call(undefined, this.value())[0]; + } + if (!retUnwrapped && useLazy) { + value = onlyLazy ? value : new LazyWrapper(this); + var result = func.apply(value, args); + result.__actions__.push(action); return new LodashWrapper(result, chainAll); } return this.thru(interceptor); @@ -12357,7 +12455,7 @@ }); // Add `Array` and `String` methods to `lodash.prototype`. - arrayEach(['concat', 'join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) { + arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) { var protoFunc = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName], chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', fixObjects = !support.spliceObjects && /^(?:pop|shift|splice)$/.test(methodName), @@ -12395,7 +12493,7 @@ } }); - realNames[createHybridWrapper(null, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': null }]; + realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }]; // Add functions to the lazy wrapper. LazyWrapper.prototype.clone = lazyClone; @@ -12405,6 +12503,7 @@ // Add chaining functions to the `lodash` wrapper. lodash.prototype.chain = wrapperChain; lodash.prototype.commit = wrapperCommit; + lodash.prototype.concat = wrapperConcat; lodash.prototype.plant = wrapperPlant; lodash.prototype.reverse = wrapperReverse; lodash.prototype.toString = wrapperToString; diff --git a/package.json b/package.json index f7f7c43b73..61ea18af70 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash", - "version": "3.9.3", + "version": "3.10.0", "main": "lodash.src.js", "private": true, "devDependencies": { diff --git a/perf/index.html b/perf/index.html index be070ef105..b5cd14fbef 100644 --- a/perf/index.html +++ b/perf/index.html @@ -1,82 +1,82 @@ - - - lodash Performance Suite - - - -
- - - - - - - - - - + + + + + + + + + - + // is the applet permitted? + if (!/[?&]nojava=true(?:&|$)/.test(location.search)) { + // is the applet really needed? + while (!(measured = new Date - begin)) {} + if (measured > 1 && !((perfNow = window.performance) && typeof (perfNow.now || perfNow.webkitNow) == 'function')) { + // load applet + document.write(''); + } + } + window.onload = init; + }()); + + diff --git a/perf/perf.js b/perf/perf.js index f1ee17006e..da375fbb7a 100644 --- a/perf/perf.js +++ b/perf/perf.js @@ -1881,6 +1881,18 @@ /*--------------------------------------------------------------------------*/ + suites.push( + Benchmark.Suite('`_.sum`') + .add(buildName, '\ + lodash.sum(numbers)' + ) + .add(otherName, '\ + _.sum(numbers)' + ) + ); + + /*--------------------------------------------------------------------------*/ + suites.push( Benchmark.Suite('`_.template` (slow path)') .add(buildName, { diff --git a/test/backbone.html b/test/backbone.html index ff0179e52c..b01da499e1 100644 --- a/test/backbone.html +++ b/test/backbone.html @@ -1,133 +1,133 @@ - - - Backbone Test Suite - - - - - - - - - - - + + + + + + + - + - + if (ui.isModularize) { + window._ = lodash; + } + require(getConfig(), [ + 'test/setup/dom-setup', + 'test/setup/environment', + 'test/noconflict', + 'test/events', + 'test/model', + 'test/collection', + 'test/router', + 'test/view', + 'test/sync' + ], function() { + QUnit.start(); + }); + }); + }()); + + diff --git a/test/index.html b/test/index.html index 55e8688c5e..05ec942915 100644 --- a/test/index.html +++ b/test/index.html @@ -1,404 +1,319 @@ - - - lodash Test Suite - - - - - - - - - - - -
-
- - - - + + + lodash Test Suite + + + + + + + + + + + +
+
+ + + + diff --git a/test/saucelabs.js b/test/saucelabs.js index d076e9897a..72b9d46ab6 100644 --- a/test/saucelabs.js +++ b/test/saucelabs.js @@ -76,7 +76,7 @@ var advisor = getOption('advisor', false), framework = getOption('framework', 'qunit'), idleTimeout = getOption('idleTimeout', 60), jobName = getOption('name', 'unit tests'), - maxDuration = getOption('maxDuration', 120), + maxDuration = getOption('maxDuration', 180), port = ports[Math.min(_.sortedIndex(ports, getOption('port', 9001)), ports.length - 1)], publicAccess = getOption('public', true), queueTimeout = getOption('queueTimeout', 240), @@ -105,11 +105,11 @@ var platforms = [ ['Linux', 'android', '5.0'], ['Linux', 'android', '4.4'], ['Linux', 'android', '4.0'], + ['Windows 8.1', 'firefox', '38'], ['Windows 8.1', 'firefox', '37'], - ['Windows 8.1', 'firefox', '36'], ['Windows 8.1', 'firefox', '20'], + ['Windows 8.1', 'chrome', '43'], ['Windows 8.1', 'chrome', '42'], - ['Windows 8.1', 'chrome', '41'], ['Windows 8.1', 'internet explorer', '11'], ['Windows 8', 'internet explorer', '10'], ['Windows 7', 'internet explorer', '9'], diff --git a/test/test.js b/test/test.js index 274616e8c6..327c858099 100644 --- a/test/test.js +++ b/test/test.js @@ -62,6 +62,7 @@ /** Math helpers. */ var add = function(x, y) { return x + y; }, + doubled = function(n) { return n * 2; }, square = function(n) { return n * n; }; /** Used to set property descriptors. */ @@ -284,6 +285,15 @@ new URIError ]; + /** Used to check escaped regexp characters. */ + var regexpEscapes = { + '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', + '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', + 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', + 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', + 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' + }; + /** Used to check problem JScript properties (a.k.a. the `[[DontEnum]]` bug). */ var shadowProps = [ 'constructor', @@ -422,9 +432,6 @@ var _now = Date.now; setProperty(Date, 'now', _.noop); - var _getPrototypeOf = Object.getPrototypeOf; - setProperty(Object, 'getPrototypeOf', _.noop); - var _keys = Object.keys; setProperty(Object, 'keys', _.noop); @@ -436,73 +443,12 @@ return _propertyIsEnumerable.call(this, key); }); - var _isFinite = Number.isFinite; - setProperty(Number, 'isFinite', _.noop); - - var _ArrayBuffer = ArrayBuffer; - setProperty(root, 'ArrayBuffer', (function() { - function ArrayBuffer(byteLength) { - var buffer = new _ArrayBuffer(byteLength); - if (!byteLength) { - setProperty(buffer, 'slice', buffer.slice ? null : bufferSlice); - } - return buffer; - } - function bufferSlice() { - var newBuffer = new _ArrayBuffer(this.byteLength), - view = new Uint8Array(newBuffer); - - view.set(new Uint8Array(this)); - return newBuffer; - } - setProperty(ArrayBuffer, 'toString', createToString('ArrayBuffer')); - setProperty(bufferSlice, 'toString', createToString('slice')); - return ArrayBuffer; - }())); - - var _Float64Array = root.Float64Array; - if (!_Float64Array) { - setProperty(root, 'Float64Array', (function() { - function Float64Array(buffer, byteOffset, length) { - return arguments.length == 1 - ? new Uint8Array(buffer) - : new Uint8Array(buffer, byteOffset || 0, length || buffer.byteLength); - } - setProperty(Float64Array, 'BYTES_PER_ELEMENT', 8); - setProperty(Float64Array, 'toString', createToString('Float64Array')); - return Float64Array; - }())); - } - var _parseInt = parseInt; - setProperty(root, 'parseInt', (function() { - var checkStr = whitespace + '08', - isFaked = _parseInt(checkStr) != 8, - reHexPrefix = /^0[xX]/, - reTrim = RegExp('^[' + whitespace + ']+|[' + whitespace + ']+$'); - - return function(value, radix) { - if (value == checkStr && !isFaked) { - isFaked = true; - return 0; - } - value = String(value == null ? '' : value).replace(reTrim, ''); - return _parseInt(value, +radix || (reHexPrefix.test(value) ? 16 : 10)); - }; - }())); - var _Set = root.Set; setProperty(root, 'Set', _.noop); var _WeakMap = root.WeakMap; setProperty(root, 'WeakMap', _.noop); - // Fake the DOM. - setProperty(root, 'window', {}); - setProperty(root.window, 'document', {}); - setProperty(root.window.document, 'createDocumentFragment', function() { - return { 'nodeType': 11 }; - }); - // Fake `WinRTError`. setProperty(root, 'WinRTError', Error); @@ -515,25 +461,10 @@ // Restore built-in methods. setProperty(Array, 'isArray', _isArray); setProperty(Date, 'now', _now); - setProperty(Object, 'getPrototypeOf', _getPrototypeOf); setProperty(Object, 'keys', _keys); setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable); - setProperty(root, 'parseInt', _parseInt); - if (_isFinite) { - setProperty(Number, 'isFinite', _isFinite); - } else { - delete Number.isFinite; - } - if (_ArrayBuffer) { - setProperty(root, 'ArrayBuffer', _ArrayBuffer); - } else { - delete root.ArrayBuffer; - } - if (!_Float64Array) { - delete root.Float64Array; - } if (_Set) { setProperty(root, 'Set', Set); } else { @@ -545,7 +476,6 @@ delete root.WeakMap; } delete root.WinRTError; - delete root.window; delete funcProto._method; }()); @@ -710,7 +640,7 @@ } }); - test('should avoid overwritten native methods', 12, function() { + test('should avoid overwritten native methods', 7, function() { function Foo() {} function message(lodashMethod, nativeMethod) { @@ -736,13 +666,6 @@ } ok(typeof actual == 'number', message('_.now', 'Date.now')); - try { - actual = [lodashBizarro.isPlainObject({}), lodashBizarro.isPlainObject([])]; - } catch(e) { - actual = null; - } - deepEqual(actual, [true, false], message('_.isPlainObject', 'Object.getPrototypeOf')); - try { actual = [lodashBizarro.keys(object), lodashBizarro.keys()]; } catch(e) { @@ -750,13 +673,6 @@ } deepEqual(actual, [['a'], []], message('_.keys', 'Object.keys')); - try { - actual = [lodashBizarro.isFinite(1), lodashBizarro.isFinite(NaN)]; - } catch(e) { - actual = null; - } - deepEqual(actual, [true, false], message('_.isFinite', 'Number.isFinite')); - try { actual = [ lodashBizarro.difference([object, otherObject], largeArray), @@ -768,27 +684,7 @@ } deepEqual(actual, [[otherObject], [object], [object]], message('_.difference`, `_.intersection`, and `_.uniq', 'Set')); - try { - actual = _.map(['6', '08', '10'], lodashBizarro.parseInt); - } catch(e) { - actual = null; - } - deepEqual(actual, [6, 8, 10], '`_.parseInt` should work in its bizarro form'); - // Avoid comparing buffers with `deepEqual` in Rhino because it errors. - if (ArrayBuffer && !isRhino) { - try { - var buffer = new ArrayBuffer(10); - actual = lodashBizarro.clone(buffer); - } catch(e) { - actual = null; - } - deepEqual(actual, buffer, message('_.clone', 'ArrayBuffer#slice')); - notStrictEqual(actual, buffer, message('_.clone', 'ArrayBuffer#slice')); - } - else { - skipTest(2); - } if (ArrayBuffer && Uint8Array) { try { var array = new Uint8Array(new ArrayBuffer(10)); @@ -805,7 +701,7 @@ } } else { - skipTest(12); + skipTest(7); } }); }()); @@ -942,7 +838,7 @@ var values = empties.concat(true, 1, 'a'), expected = _.map(values, _.constant(true)); - test('creates a new instance when called without the `new` operator', 1, function() { + test('should create a new instance when called without the `new` operator', 1, function() { if (!isNpm) { var actual = _.map(values, function(value) { return _(value) instanceof _; @@ -1478,9 +1374,10 @@ } var bound = _.bind(Foo, { 'a': 1 }), - expected = _.times(7, _.constant(undefined)); + count = 9, + expected = _.times(count, _.constant(undefined)); - var actual = _.times(7, function(index) { + var actual = _.times(count, function(index) { try { switch (index) { case 0: return (new bound).a; @@ -1490,6 +1387,8 @@ case 4: return (new bound(1, 2, 3, 4)).a; case 5: return (new bound(1, 2, 3, 4, 5)).a; case 6: return (new bound(1, 2, 3, 4, 5, 6)).a; + case 7: return (new bound(1, 2, 3, 4, 5, 6, 7)).a; + case 8: return (new bound(1, 2, 3, 4, 5, 6, 7, 8)).a; } } catch(e) {} }); @@ -1497,7 +1396,7 @@ deepEqual(actual, expected); }); - test('ensure `new bound` is an instance of `func`', 2, function() { + test('should ensure `new bound` is an instance of `func`', 2, function() { function Foo(value) { return value && object; } @@ -1530,14 +1429,34 @@ deepEqual(bound3(), [object1, 'b']); }); + test('should not error when instantiating bound built-ins', 2, function() { + var Ctor = _.bind(Date, null), + expected = new Date(2012, 4, 23, 0, 0, 0, 0); + + try { + var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0); + } catch(e) {} + + deepEqual(actual, expected); + + Ctor = _.bind(Date, null, 2012, 4, 23); + + try { + actual = new Ctor(0, 0, 0, 0); + } catch(e) {} + + deepEqual(actual, expected); + }); + test('should not error when calling bound class constructors with the `new` operator', 1, function() { var createCtor = _.attempt(Function, '"use strict";return class A{}'); if (typeof createCtor == 'function') { var bound = _.bind(createCtor()), - expected = _.times(6, _.constant(true)); + count = 8, + expected = _.times(count, _.constant(true)); - var actual = _.times(6, function(index) { + var actual = _.times(count, function(index) { try { switch (index) { case 0: return !!(new bound); @@ -1546,6 +1465,8 @@ case 3: return !!(new bound(1, 2, 3)); case 4: return !!(new bound(1, 2, 3, 4)); case 5: return !!(new bound(1, 2, 3, 4, 5)); + case 6: return !!(new bound(1, 2, 3, 4, 5, 6)); + case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7)); } } catch(e) {} }); @@ -1971,6 +1892,10 @@ deepEqual(actual, expected); }); + test('should floor `size` values', 1, function() { + deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4], [5]]); + }); + test('should work as an iteratee for methods like `_.map`', 1, function() { var actual = _.map([[1, 2], [3, 4]], _.chunk); deepEqual(actual, [[[1], [2]], [[3], [4]]]); @@ -2270,10 +2195,10 @@ test('should work in a lazy chain sequence', 1, function() { if (!isNpm) { - var array = [1, null, 3], - actual = _(array).map(square).compact().reverse().take().value(); + var array = _.range(0, LARGE_ARRAY_SIZE).concat(null), + actual = _(array).slice(1).compact().reverse().take().value(); - deepEqual(actual, [9]); + deepEqual(actual, _.take(_.compact(_.slice(array, 1)).reverse())); } else { skipTest(); @@ -2323,38 +2248,68 @@ notStrictEqual(combined, _.identity); }); - test('`_.' + methodName + '` should support shortcut fusion', 6, function() { + test('`_.' + methodName + '` should work with a curried function and `_.first`', 1, function() { + var curried = _.curry(_.identity); + + var combined = isFlow + ? func(_.first, curried) + : func(curried, _.first); + + strictEqual(combined([1]), 1); + }); + + test('`_.' + methodName + '` should support shortcut fusion', 12, function() { var filterCount, mapCount; - var filter = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2), - map = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2), - take = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2); + var iteratee = function(value) { + mapCount++; + return value * value; + }; - var filter2 = filter(function(value) { filterCount++; return value % 2 == 0; }), - map2 = map(function(value) { mapCount++; return value * value; }), - take2 = take(2); + var predicate = function(value) { + filterCount++; + return value % 2 == 0; + }; _.times(2, function(index) { - var fn = index ? _['_' + methodName] : func; - if (!fn) { - skipTest(3); - return; - } - var combined = isFlow - ? fn(map2, filter2, _.compact, take2) - : fn(take2, _.compact, filter2, map2); + var filter1 = _.filter, + filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2), + filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate)); - filterCount = mapCount = 0; - deepEqual(combined(_.range(100)), [4, 16]); + var map1 = _.map, + map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2), + map3 = (_.map = index ? map2 : map1, map2(iteratee)); - if (!isNpm && WeakMap && WeakMap.name) { - strictEqual(filterCount, 5, 'filterCount'); - strictEqual(mapCount, 5, 'mapCount'); - } - else { - skipTest(2); - } + var take1 = _.take, + take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2), + take3 = (_.take = index ? take2 : take1, take2(2)); + + _.times(2, function(index) { + var fn = index ? _['_' + methodName] : func; + if (!fn) { + skipTest(3); + return; + } + var combined = isFlow + ? fn(map3, filter3, _.compact, take3) + : fn(take3, _.compact, filter3, map3); + + filterCount = mapCount = 0; + deepEqual(combined(_.range(200)), [4, 16]); + + if (!isNpm && WeakMap && WeakMap.name) { + strictEqual(filterCount, 5, 'filterCount'); + strictEqual(mapCount, 5, 'mapCount'); + } + else { + skipTest(2); + } + }); + + _.filter = filter1; + _.map = map1; + _.take = take1; }); }); @@ -2510,11 +2465,15 @@ test('should work in a lazy chain sequence', 1, function() { if (!isNpm) { - var array = [1, 2, 1, 3], - predicate = function(value) { return value > 2; }, - actual = _(array).countBy(_.identity).map(square).filter(predicate).take().value(); + var array = _.range(LARGE_ARRAY_SIZE).concat( + _.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE), + _.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE) + ); + + var predicate = function(value) { return value > 2; }, + actual = _(array).countBy().map(square).filter(predicate).take().value(); - deepEqual(actual, [4]); + deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), predicate))); } else { skipTest(); @@ -2608,11 +2567,11 @@ (function() { test('should provide arguments to `func`', 3, function() { - function fn() { + var fn = function() { var result = [this]; push.apply(result, arguments); return result; - } + }; var callback = _.callback(fn), actual = callback('a', 'b', 'c', 'd', 'e', 'f'); @@ -2749,11 +2708,11 @@ }); test('should work with functions created by `_.partial` and `_.partialRight`', 2, function() { - function fn() { + var fn = function() { var result = [this.a]; push.apply(result, arguments); return result; - } + }; var expected = [1, 2, 3], object = { 'a': 1 }, @@ -3272,7 +3231,7 @@ }); }); - test('ensure `new curried` is an instance of `func`', 2, function() { + test('should ensure `new curried` is an instance of `func`', 2, function() { var Foo = function(value) { return value && object; }; @@ -3375,7 +3334,7 @@ }); }); - test('ensure `new curried` is an instance of `func`', 2, function() { + test('should ensure `new curried` is an instance of `func`', 2, function() { var Foo = function(value) { return value && object; }; @@ -3741,6 +3700,47 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.defaultsDeep'); + + (function() { + test('should deep assign properties of a source object if missing on the destination object', 1, function() { + var object = { 'a': { 'b': 2 }, 'd': 4 }, + source = { 'a': { 'b': 1, 'c': 3 }, 'e': 5 }, + expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 }; + + deepEqual(_.defaultsDeep(object, source), expected); + }); + + test('should accept multiple source objects', 2, function() { + var source1 = { 'a': { 'b': 3 } }, + source2 = { 'a': { 'c': 3 } }, + source3 = { 'a': { 'b': 3, 'c': 3 } }, + source4 = { 'a': { 'c': 4 } }, + expected = { 'a': { 'b': 2, 'c': 3 } }; + + deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), expected); + deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), expected); + }); + + test('should not overwrite `null` values', 1, function() { + var object = { 'a': { 'b': null } }, + source = { 'a': { 'b': 2 } }, + actual = _.defaultsDeep(object, source); + + strictEqual(actual.a.b, null); + }); + + test('should overwrite `undefined` values', 1, function() { + var object = { 'a': { 'b': undefined } }, + source = { 'a': { 'b': 2 } }, + actual = _.defaultsDeep(object, source); + + strictEqual(actual.a.b, 2); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.defer'); (function() { @@ -3752,7 +3752,7 @@ setTimeout(function() { ok(pass); QUnit.start(); - }, 128); + }, 32); } else { skipTest(); @@ -3771,7 +3771,7 @@ setTimeout(function() { deepEqual(args, [1, 2]); QUnit.start(); - }, 128); + }, 32); } else { skipTest(); @@ -3792,7 +3792,7 @@ setTimeout(function() { ok(pass); QUnit.start(); - }, 128); + }, 32); } else { skipTest(); @@ -3809,16 +3809,16 @@ asyncTest('should delay `func` execution', 2, function() { if (!(isRhino && isModularize)) { var pass = false; - _.delay(function() { pass = true; }, 96); + _.delay(function() { pass = true; }, 32); setTimeout(function() { ok(!pass); - }, 32); + }, 1); setTimeout(function() { ok(pass); QUnit.start(); - }, 160); + }, 64); } else { skipTest(2); @@ -3837,7 +3837,7 @@ setTimeout(function() { deepEqual(args, [1, 2]); QUnit.start(); - }, 128); + }, 64); } else { skipTest(); @@ -3858,7 +3858,7 @@ setTimeout(function() { ok(pass); QUnit.start(); - }, 128); + }, 64); } else { skipTest(); @@ -3964,25 +3964,25 @@ test('should work in a lazy chain sequence', 6, function() { if (!isNpm) { - var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + var array = _.range(1, LARGE_ARRAY_SIZE + 1), values = [], predicate = function(value) { values.push(value); return value > 2; }, actual = _(array).drop(2).drop().value(); - deepEqual(actual, [4, 5, 6, 7, 8, 9, 10]); + deepEqual(actual, array.slice(3)); actual = _(array).filter(predicate).drop(2).drop().value(); - deepEqual(actual, [6, 7, 8, 9, 10]); deepEqual(values, array); + deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2))); actual = _(array).drop(2).dropRight().drop().dropRight(2).value(); - deepEqual(actual, [4, 5, 6, 7]); + deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2)); values = []; actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value(); - deepEqual(actual, [6, 7]); deepEqual(values, array.slice(1)); + deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2)); } else { skipTest(6); @@ -4034,25 +4034,25 @@ test('should work in a lazy chain sequence', 6, function() { if (!isNpm) { - var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + var array = _.range(1, LARGE_ARRAY_SIZE + 1), values = [], predicate = function(value) { values.push(value); return value < 9; }, actual = _(array).dropRight(2).dropRight().value(); - deepEqual(actual, [1, 2, 3, 4, 5, 6, 7]); + deepEqual(actual, array.slice(0, -3)); actual = _(array).filter(predicate).dropRight(2).dropRight().value(); - deepEqual(actual, [1, 2, 3, 4, 5]); deepEqual(values, array); + deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2))); actual = _(array).dropRight(2).drop().dropRight().drop(2).value(); - deepEqual(actual, [4, 5, 6, 7]); + deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2)); values = []; actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value(); - deepEqual(actual, [4, 5]); deepEqual(values, array.slice(0, -1)); + deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2)); } else { skipTest(6); @@ -4124,46 +4124,6 @@ skipTest(2); } }); - - test('should provide the correct `predicate` arguments in a lazy chain sequence', 5, function() { - if (!isNpm) { - var args, - expected = [16, 3, [1, 4, 9 ,16]]; - - _(array).dropRightWhile(function(value, index, array) { - args = slice.call(arguments); - }).value(); - - deepEqual(args, [4, 3, array]); - - _(array).map(square).dropRightWhile(function(value, index, array) { - args = slice.call(arguments); - }).value(); - - deepEqual(args, expected); - - _(array).map(square).dropRightWhile(function(value, index) { - args = slice.call(arguments); - }).value(); - - deepEqual(args, expected); - - _(array).map(square).dropRightWhile(function(value) { - args = slice.call(arguments); - }).value(); - - deepEqual(args, [16]); - - _(array).map(square).dropRightWhile(function() { - args = slice.call(arguments); - }).value(); - - deepEqual(args, expected); - } - else { - skipTest(5); - } - }); }()); /*--------------------------------------------------------------------------*/ @@ -4219,13 +4179,14 @@ test('should work in a lazy chain sequence', 3, function() { if (!isNpm) { - var wrapped = _(array).dropWhile(function(num) { - return num < 3; - }); + var array = _.range(1, LARGE_ARRAY_SIZE + 3), + predicate = function(num) { return num < 3; }, + expected = _.dropWhile(array, predicate), + wrapped = _(array).dropWhile(predicate); - deepEqual(wrapped.value(), [3, 4]); - deepEqual(wrapped.reverse().value(), [4, 3]); - strictEqual(wrapped.last(), 4); + deepEqual(wrapped.value(), expected); + deepEqual(wrapped.reverse().value(), expected.slice().reverse()); + strictEqual(wrapped.last(), _.last(expected)); } else { skipTest(3); @@ -4234,58 +4195,20 @@ test('should work in a lazy chain sequence with `drop`', 1, function() { if (!isNpm) { + var array = _.range(1, LARGE_ARRAY_SIZE + 3); + var actual = _(array) .dropWhile(function(num) { return num == 1; }) .drop() .dropWhile(function(num) { return num == 3; }) .value(); - deepEqual(actual, [4]); + deepEqual(actual, array.slice(3)); } else { skipTest(); } }); - - test('should provide the correct `predicate` arguments in a lazy chain sequence', 5, function() { - if (!isNpm) { - var args, - expected = [1, 0, [1, 4, 9, 16]]; - - _(array).dropWhile(function(value, index, array) { - args = slice.call(arguments); - }).value(); - - deepEqual(args, [1, 0, array]); - - _(array).map(square).dropWhile(function(value, index, array) { - args = slice.call(arguments); - }).value(); - - deepEqual(args, expected); - - _(array).map(square).dropWhile(function(value, index) { - args = slice.call(arguments); - }).value(); - - deepEqual(args, expected); - - _(array).map(square).dropWhile(function(index) { - args = slice.call(arguments); - }).value(); - - deepEqual(args, [1]); - - _(array).map(square).dropWhile(function() { - args = slice.call(arguments); - }).value(); - - deepEqual(args, expected); - } - else { - skipTest(5); - } - }); }()); /*--------------------------------------------------------------------------*/ @@ -4372,29 +4295,56 @@ QUnit.module('lodash.escapeRegExp'); (function() { + var escaped = '\\/\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\n\\r\\u2028\\u2029\\\\', + unescaped = '/^$.*+?()[]{}|\n\r\u2028\u2029\\'; + test('should escape values', 1, function() { - var escaped = '\\.\\*\\+\\?\\^\\$\\{\\}\\(\\)\\|\\[\\]\\/\\\\', - unescaped = '.*+?^${}()|[\]\/\\'; + strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped); + }); + + test('should escape special characters at the start of a string', 1, function() { + var chars = [ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', + 'A', 'B', 'C', 'D', 'E', 'F', + 'n', 'r', 't', 'u', 'v', 'x', + ':', '!', ',' + ]; - escaped += escaped; - unescaped += unescaped; + var expected = _.map(chars, function(chr) { + return ['\\' + (regexpEscapes[chr] || chr) + 'z', 'z' + chr]; + }); + + var actual = _.map(chars, function(chr) { + return [_.escapeRegExp(chr + 'z'), _.escapeRegExp('z' + chr)]; + }); - strictEqual(_.escapeRegExp(unescaped), escaped); + deepEqual(actual, expected); }); test('should handle strings with nothing to escape', 1, function() { - strictEqual(_.escapeRegExp('abc'), 'abc'); + strictEqual(_.escapeRegExp('ghi'), 'ghi'); + }); + + test('should return `"(?:)"` when provided nullish or empty string values', 1, function() { + var values = [, null, undefined, ''], + expected = _.map(values, _.constant('(?:)')); + + var actual = _.map(values, function(value, index) { + return index ? _.escapeRegExp(value) : _.escapeRegExp(); + }); + + deepEqual(actual, expected); }); test('should work with `eval` and `Function`', 2, function() { - var string = '[lodash](https://lodash.com/)', - escaped = _.escapeRegExp(string), - regexp = eval('(/' + escaped + '/)'); + var actual = _.escapeRegExp(unescaped), + regexp = eval('(/' + actual + '/)'); - ok(regexp.test(string)); + ok(regexp.test(unescaped)); - regexp = Function('return /' + escaped + '/')(); - ok(regexp.test(string)); + regexp = Function('return /' + actual + '/')(); + ok(regexp.test(unescaped)); }); }()); @@ -4856,9 +4806,19 @@ } }); + test('should not execute immediately when explicitly chaining', 1, function() { + if (!isNpm) { + var wrapped = _(array).chain().first(); + strictEqual(wrapped.__wrapped__, array); + } + else { + skipTest(); + } + }); + test('should work in a lazy chain sequence', 1, function() { if (!isNpm) { - var array = [1, 2, 3, 4]; + var array = _.range(1, LARGE_ARRAY_SIZE + 1); var wrapped = _(array).filter(function(value) { return value % 2 == 0; @@ -4920,25 +4880,25 @@ test('should work in a lazy chain sequence', 6, function() { if (!isNpm) { - var array = [1, 2, 3, 4, 5, 6, 7, 8, 9 , 10], + var array = _.range(1, LARGE_ARRAY_SIZE + 1), values = [], predicate = function(value) { values.push(value); return value > 2; }, actual = _(array).take(2).take().value(); - deepEqual(actual, [1]); + deepEqual(actual, _.take(_.take(array, 2))); actual = _(array).filter(predicate).take(2).take().value(); - deepEqual(actual, [3]); - deepEqual(values, array.slice(0, 3)); + deepEqual(values, [1, 2, 3]); + deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2))); actual = _(array).take(6).takeRight(4).take(2).takeRight().value(); - deepEqual(actual, [4]); + deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2))); values = []; actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value(); - deepEqual(actual, [6]); - deepEqual(values, array.slice(0, -2)); + deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8]); + deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2))); } else { skipTest(6); @@ -4990,25 +4950,25 @@ test('should work in a lazy chain sequence', 6, function() { if (!isNpm) { - var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + var array = _.range(1, LARGE_ARRAY_SIZE + 1), values = [], predicate = function(value) { values.push(value); return value < 9; }, actual = _(array).takeRight(2).takeRight().value(); - deepEqual(actual, [10]); + deepEqual(actual, _.takeRight(_.takeRight(array))); actual = _(array).filter(predicate).takeRight(2).takeRight().value(); - deepEqual(actual, [8]); deepEqual(values, array); + deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2))); actual = _(array).takeRight(6).take(4).takeRight(2).take().value(); - deepEqual(actual, [7]); + deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2))); values = []; actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value(); - deepEqual(actual, [5]); deepEqual(values, array); + deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2))); } else { skipTest(6); @@ -5069,13 +5029,14 @@ test('should work in a lazy chain sequence', 3, function() { if (!isNpm) { - var wrapped = _(array).takeRightWhile(function(num) { - return num > 2; - }); + var array = _.range(1, LARGE_ARRAY_SIZE + 1), + predicate = function(num) { return num > 2; }, + expected = _.takeRightWhile(array, predicate), + wrapped = _(array).takeRightWhile(predicate); - deepEqual(wrapped.value(), [3, 4]); - deepEqual(wrapped.reverse().value(), [4, 3]); - strictEqual(wrapped.last(), 4); + deepEqual(wrapped.value(), expected); + deepEqual(wrapped.reverse().value(), expected.slice().reverse()); + strictEqual(wrapped.last(), _.last(expected)); } else { skipTest(3); @@ -5085,33 +5046,34 @@ test('should provide the correct `predicate` arguments in a lazy chain sequence', 5, function() { if (!isNpm) { var args, - expected = [16, 3, [1, 4, 9 , 16]]; + array = _.range(0, LARGE_ARRAY_SIZE + 1), + expected = [square(LARGE_ARRAY_SIZE), LARGE_ARRAY_SIZE - 1, _.map(array.slice(1), square)]; - _(array).takeRightWhile(function(value, index, array) { + _(array).slice(1).takeRightWhile(function(value, index, array) { args = slice.call(arguments) }).value(); - deepEqual(args, [4, 3, array]); + deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]); - _(array).map(square).takeRightWhile(function(value, index, array) { + _(array).slice(1).map(square).takeRightWhile(function(value, index, array) { args = slice.call(arguments) }).value(); deepEqual(args, expected); - _(array).map(square).takeRightWhile(function(value, index) { + _(array).slice(1).map(square).takeRightWhile(function(value, index) { args = slice.call(arguments) }).value(); deepEqual(args, expected); - _(array).map(square).takeRightWhile(function(index) { + _(array).slice(1).map(square).takeRightWhile(function(index) { args = slice.call(arguments); }).value(); - deepEqual(args, [16]); + deepEqual(args, [square(LARGE_ARRAY_SIZE)]); - _(array).map(square).takeRightWhile(function() { + _(array).slice(1).map(square).takeRightWhile(function() { args = slice.call(arguments); }).value(); @@ -5175,13 +5137,14 @@ test('should work in a lazy chain sequence', 3, function() { if (!isNpm) { - var wrapped = _(array).takeWhile(function(num) { - return num < 3; - }); + var array = _.range(1, LARGE_ARRAY_SIZE + 1), + predicate = function(num) { return num < 3; }, + expected = _.takeWhile(array, predicate), + wrapped = _(array).takeWhile(predicate); - deepEqual(wrapped.value(), [1, 2]); - deepEqual(wrapped.reverse().value(), [2, 1]); - strictEqual(wrapped.last(), 2); + deepEqual(wrapped.value(), expected); + deepEqual(wrapped.reverse().value(), expected.slice().reverse()); + strictEqual(wrapped.last(), _.last(expected)); } else { skipTest(3); @@ -5190,6 +5153,8 @@ test('should work in a lazy chain sequence with `take`', 1, function() { if (!isNpm) { + var array = _.range(1, LARGE_ARRAY_SIZE + 1); + var actual = _(array) .takeWhile(function(num) { return num < 4; }) .take(2) @@ -5206,33 +5171,34 @@ test('should provide the correct `predicate` arguments in a lazy chain sequence', 5, function() { if (!isNpm) { var args, - expected = [1, 0, [1, 4, 9, 16]]; + array = _.range(0, LARGE_ARRAY_SIZE + 1), + expected = [1, 0, _.map(array.slice(1), square)]; - _(array).takeWhile(function(value, index, array) { + _(array).slice(1).takeWhile(function(value, index, array) { args = slice.call(arguments); }).value(); - deepEqual(args, [1, 0, array]); + deepEqual(args, [1, 0, array.slice(1)]); - _(array).map(square).takeWhile(function(value, index, array) { + _(array).slice(1).map(square).takeWhile(function(value, index, array) { args = slice.call(arguments); }).value(); deepEqual(args, expected); - _(array).map(square).takeWhile(function(value, index) { + _(array).slice(1).map(square).takeWhile(function(value, index) { args = slice.call(arguments); }).value(); deepEqual(args, expected); - _(array).map(square).takeWhile(function(value) { + _(array).slice(1).map(square).takeWhile(function(value) { args = slice.call(arguments); }).value(); deepEqual(args, [1]); - _(array).map(square).takeWhile(function() { + _(array).slice(1).map(square).takeWhile(function() { args = slice.call(arguments); }).value(); @@ -5329,12 +5295,12 @@ }); test('should support flattening of nested arrays', 3, function() { - var array = [1, [2], [3, [4]]], - expected = [1, 2, 3, [4]]; + var array = [1, [2, 3], 4, [[5]]], + expected = [1, 2, 3, 4, [5]]; deepEqual(_.flatten(array), expected); - expected = [1, 2, 3, 4]; + expected = [1, 2, 3, 4, 5]; deepEqual(_.flatten(array, true), expected); deepEqual(_.flattenDeep(array), expected); }); @@ -5417,7 +5383,7 @@ _.each(['forOwn', 'forOwnRight'], function(methodName) { var func = _[methodName]; - test('iterates over the `length` property', 1, function() { + test('should iterate over `length` properties', 1, function() { var object = { '0': 'zero', '1': 'one', 'length': 2 }, props = []; @@ -6216,12 +6182,16 @@ test('should work in a lazy chain sequence', 1, function() { if (!isNpm) { - var array = [1, 2, 1, 3], - iteratee = function(value) { value.push(value[0]); return value; }, + var array = _.range(LARGE_ARRAY_SIZE).concat( + _.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE), + _.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE) + ); + + var iteratee = function(value) { value.push(value[0]); return value; }, predicate = function(value) { return value[0] > 1; }, - actual = _(array).groupBy(_.identity).map(iteratee).filter(predicate).take().value(); + actual = _(array).groupBy().map(iteratee).filter(predicate).take().value(); - deepEqual(actual, [[2, 2]]); + deepEqual(actual, _.take(_.filter(_.map(_.groupBy(array), iteratee), predicate))); } else { skipTest(); @@ -6409,7 +6379,9 @@ 'a string': '1234' }, function(collection, key) { - var values = _.toArray(collection); + var isStr = typeof collection == 'string', + values = _.toArray(collection), + length = values.length; test('should work with ' + key + ' and return `true` for matched values', 1, function() { strictEqual(_.includes(collection, 3), true); @@ -6428,7 +6400,7 @@ _.each([4, 6, Math.pow(2, 32), Infinity], function(fromIndex) { strictEqual(_.includes(collection, 1, fromIndex), false); strictEqual(_.includes(collection, undefined, fromIndex), false); - strictEqual(_.includes(collection, '', fromIndex), false); + strictEqual(_.includes(collection, '', fromIndex), (isStr && fromIndex == length)); }); }); @@ -6585,11 +6557,15 @@ test('should work in a lazy chain sequence', 1, function() { if (!isNpm) { - var array = [1, 2, 1, 3], - predicate = function(value) { return value > 2; }, - actual = _(array).indexBy(_.identity).map(square).filter(predicate).take().value(); + var array = _.range(LARGE_ARRAY_SIZE).concat( + _.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE), + _.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE) + ); + + var predicate = function(value) { return value > 2; }, + actual = _(array).indexBy().map(square).filter(predicate).take().value(); - deepEqual(actual, [4]); + deepEqual(actual, _.take(_.filter(_.map(_.indexBy(array), square), predicate))); } else { skipTest(); @@ -6779,7 +6755,7 @@ test('should work in a lazy chain sequence', 4, function() { if (!isNpm) { - var array = [1, 2, 3], + var array = _.range(1, LARGE_ARRAY_SIZE + 1), values = []; var actual = _(array).initial().filter(function(value) { @@ -6789,7 +6765,7 @@ .value(); deepEqual(actual, []); - deepEqual(values, [1, 2]); + deepEqual(values, _.initial(array)); values = []; @@ -7240,7 +7216,7 @@ this.nodeType = 1; } - test('should use robust check', 7, function() { + test('should return `false` for plain objects', 7, function() { var element = body || new Element; strictEqual(_.isElement(element), true); @@ -7252,20 +7228,6 @@ strictEqual(_.isElement({ 'nodeType': '001' }), false); }); - test('should use a stronger check in browsers', 2, function() { - var expected = !_.support.dom; - - strictEqual(_.isElement(new Element), expected); - - if (lodashBizarro) { - expected = !lodashBizarro.support.dom; - strictEqual(lodashBizarro.isElement(new Element), expected); - } - else { - skipTest(); - } - }); - test('should return `false` for non DOM elements', 13, function() { var expected = _.map(falsey, _.constant(false)); @@ -7362,11 +7324,11 @@ strictEqual(_.isEmpty({ 'length': '0' }), false); }); - test('fixes the JScript `[[DontEnum]]` bug (test in IE < 9)', 1, function() { + test('should fix the JScript `[[DontEnum]]` bug (test in IE < 9)', 1, function() { strictEqual(_.isEmpty(shadowObject), false); }); - test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', 2, function() { + test('should skip the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', 2, function() { function Foo() {} Foo.prototype.a = 1; @@ -7784,7 +7746,7 @@ strictEqual(_.isEqual(36, '36'), false); }); - test('fixes the JScript `[[DontEnum]]` bug (test in IE < 9)', 1, function() { + test('should fix the JScript `[[DontEnum]]` bug (test in IE < 9)', 1, function() { strictEqual(_.isEqual(shadowObject, {}), false); }); @@ -8176,48 +8138,6 @@ strictEqual(_.isFunction('a'), false); }); - test('should work using its fallback', 3, function() { - if (!isModularize) { - // Simulate native `Uint8Array` constructor with a `toStringTag` of - // 'Function' and a `typeof` result of 'object'. - var lodash = _.runInContext({ - 'Function': { - 'prototype': { - 'toString': function() { - return _.has(this, 'toString') ? this.toString() : fnToString.call(this); - } - } - }, - 'Object': _.assign(function(value) { - return Object(value); - }, { - 'prototype': { - 'toString': _.assign(function() { - return _.has(this, '@@toStringTag') ? this['@@toStringTag'] : objToString.call(this); - }, { - 'toString': function() { - return String(toString); - } - }) - } - }), - 'Uint8Array': { - '@@toStringTag': funcTag, - 'toString': function() { - return String(Uint8Array || Array); - } - } - }); - - strictEqual(lodash.isFunction(slice), true); - strictEqual(lodash.isFunction(/x/), false); - strictEqual(lodash.isFunction(Uint8Array), objToString.call(Uint8Array) == funcTag); - } - else { - skipTest(3); - } - }); - test('should work with host objects in IE 8 document mode (test in IE 11)', 2, function() { // Trigger a Chakra JIT bug. // See https://github.com/jashkenas/underscore/issues/1621. @@ -9361,15 +9281,23 @@ } }); - test('should work in a lazy chain sequence', 1, function() { + test('should not execute immediately when explicitly chaining', 1, function() { if (!isNpm) { - var array = [1, 2, 3, 4]; + var wrapped = _(array).chain().last(); + strictEqual(wrapped.__wrapped__, array); + } + else { + skipTest(); + } + }); - var wrapped = _(array).filter(function(value) { - return value % 2; - }); + test('should work in a lazy chain sequence', 1, function() { + if (!isNpm) { + var array = _.range(1, LARGE_ARRAY_SIZE + 1), + predicate = function(value) { return value % 2; }, + wrapped = _(array).filter(predicate); - strictEqual(wrapped.last(), 3); + strictEqual(wrapped.last(), _.last(_.filter(array, predicate))); } else { skipTest(); @@ -9503,12 +9431,13 @@ deepEqual(actual, expected); }); - test('`_.' + methodName + '` should return `-1` for an unmatched value', 4, function() { + test('`_.' + methodName + '` should return `-1` for an unmatched value', 5, function() { var array = [1, 2, 3], empty = []; strictEqual(func(array, 4), -1); strictEqual(func(array, 4, true), -1); + strictEqual(func(array, undefined, true), -1); strictEqual(func(empty, undefined), -1); strictEqual(func(empty, undefined, true), -1); @@ -9637,37 +9566,38 @@ test('should provide the correct `predicate` arguments in a lazy chain sequence', 5, function() { if (!isNpm) { var args, - expected = [1, 0, [1, 4, 9]]; + array = _.range(0, LARGE_ARRAY_SIZE), + expected = [1, 0, _.map(array.slice(1), square)]; - _(array).map(function(value, index, array) { + _(array).slice(1).map(function(value, index, array) { args || (args = slice.call(arguments)); }).value(); - deepEqual(args, [1, 0, array]); + deepEqual(args, [1, 0, array.slice(1)]); args = null; - _(array).map(square).map(function(value, index, array) { + _(array).slice(1).map(square).map(function(value, index, array) { args || (args = slice.call(arguments)); }).value(); deepEqual(args, expected); args = null; - _(array).map(square).map(function(value, index) { + _(array).slice(1).map(square).map(function(value, index) { args || (args = slice.call(arguments)); }).value(); deepEqual(args, expected); args = null; - _(array).map(square).map(function(value) { + _(array).slice(1).map(square).map(function(value) { args || (args = slice.call(arguments)); }).value(); deepEqual(args, [1]); args = null; - _(array).map(square).map(function() { + _(array).slice(1).map(square).map(function() { args || (args = slice.call(arguments)); }).value(); @@ -10432,16 +10362,6 @@ strictEqual(memoized(1, 3, 5), 9); }); - test('should not set a `this` binding', 2, function() { - var memoized = _.memoize(function(a, b, c) { - return a + this.b + this.c; - }); - - var object = { 'b': 2, 'c': 3, 'memoized': memoized }; - strictEqual(object.memoized(1), 6); - strictEqual(object.memoized(2), 7); - }); - test('should throw a TypeError if `resolve` is truthy and not a function', function() { raises(function() { _.memoize(_.noop, {}); }, TypeError); }); @@ -10458,6 +10378,16 @@ deepEqual(actual, expected); }); + test('should not set a `this` binding', 2, function() { + var memoized = _.memoize(function(a, b, c) { + return a + this.b + this.c; + }); + + var object = { 'b': 2, 'c': 3, 'memoized': memoized }; + strictEqual(object.memoized(1), 6); + strictEqual(object.memoized(2), 7); + }); + test('should check cache for own properties', 1, function() { var memoized = _.memoize(_.identity); @@ -11009,7 +10939,7 @@ QUnit.module('lodash.methodOf'); (function() { - test('hould create a function that calls a method of a given key', 4, function() { + test('should create a function that calls a method of a given key', 4, function() { var object = { 'a': _.constant(1) }; _.each(['a', ['a']], function(path) { @@ -11389,11 +11319,11 @@ delete Wrapper.prototype.b; }); - test('should not assign inherited `source` properties', 1, function() { + test('should not assign inherited `source` methods', 1, function() { function Foo() {} Foo.prototype.a = _.noop; - deepEqual(_.mixin({}, new Foo, {}), {}); + deepEqual(_.mixin({}, new Foo), {}); }); test('should accept an `options` argument', 16, function() { @@ -11491,10 +11421,11 @@ if (!isNpm) { _.mixin({ 'a': _.countBy, 'b': _.filter }); - var predicate = function(value) { return value > 2; }, - actual = _([1, 2, 1, 3]).a(_.identity).map(square).b(predicate).take().value(); + var array = _.range(1, LARGE_ARRAY_SIZE + 1), + predicate = function(value) { return value > 2; }, + actual = _(array).a().map(square).b(predicate).take().value(); - deepEqual(actual, [4]); + deepEqual(actual, _.take(_.b(_.map(_.a(array), square), predicate))); delete _.a; delete _.prototype.a; @@ -11509,6 +11440,52 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.modArgs'); + + (function() { + function fn() { + return slice.call(arguments); + } + + test('should transform each argument', 1, function() { + var modded = _.modArgs(fn, doubled, square); + deepEqual(modded(5, 10), [10, 100]); + }); + + test('should flatten `transforms`', 1, function() { + var modded = _.modArgs(fn, [doubled, square], String); + deepEqual(modded(5, 10, 15), [10, 100, '15']); + }); + + test('should not transform any argument greater than the number of transforms', 1, function() { + var modded = _.modArgs(fn, doubled, square); + deepEqual(modded(5, 10, 18), [10, 100, 18]); + }); + + test('should not transform any arguments if no transforms are provided', 1, function() { + var modded = _.modArgs(fn); + deepEqual(modded(5, 10, 18), [5, 10, 18]); + }); + + test('should not pass `undefined` if there are more `transforms` than `arguments`', 1, function() { + var modded = _.modArgs(fn, doubled, _.identity); + deepEqual(modded(5), [10]); + }); + + test('should not set a `this` binding', 1, function() { + var modded = _.modArgs(function(x) { + return this[x]; + }, function(x) { + return this === x; + }); + + var object = { 'modded': modded, 'false': 1 }; + strictEqual(object.modded(object), 1); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.negate'); (function() { @@ -11544,14 +11521,39 @@ QUnit.module('lodash.noConflict'); (function() { - test('should return the `lodash` function', 1, function() { + test('should return the `lodash` function', 2, function() { if (!isModularize) { var oldDash = root._; - strictEqual(_.noConflict(), _); + strictEqual(_.noConflict(), oldDash); + + if (!(isRhino && typeof require == 'function')) { + notStrictEqual(root._, oldDash); + } + else { + skipTest(); + } root._ = oldDash; } else { - skipTest(); + skipTest(2); + } + }); + + test('should work with a `root` of `this`', 2, function() { + if (!isModularize && !document && _._object) { + var fs = require('fs'), + vm = require('vm'), + expected = {}, + context = vm.createContext({ '_': expected, 'console': console }), + source = fs.readFileSync(filePath); + + vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context); + + strictEqual(context._, expected); + ok(!!context.lodash); + } + else { + skipTest(2); } }); }()); @@ -11586,20 +11588,16 @@ (function() { var args = arguments, - object = { 'a': 1, 'b': 2, 'c': 3 }, - expected = { 'b': 2 }; + object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, + expected = { 'b': 2, 'd': 4 }; test('should create an object with omitted properties', 2, function() { - deepEqual(_.omit(object, 'a'), { 'b': 2, 'c': 3 }); + deepEqual(_.omit(object, 'a'), { 'b': 2, 'c': 3, 'd': 4 }); deepEqual(_.omit(object, 'a', 'c'), expected); }); - test('should support picking an array of properties', 1, function() { - deepEqual(_.omit(object, ['a', 'c']), expected); - }); - - test('should support picking an array of properties and individual properties', 1, function() { - deepEqual(_.omit(object, ['a'], 'c'), expected); + test('should flatten `props`', 1, function() { + deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 }); }); test('should iterate over inherited properties', 1, function() { @@ -11635,15 +11633,15 @@ delete stringProto.b; }); - test('should work with a `predicate` argument', 1, function() { + test('should work with a predicate argument', 1, function() { var actual = _.omit(object, function(num) { - return num != 2; + return num != 2 && num != 4; }); deepEqual(actual, expected); }); - test('should provide the correct `predicate` arguments', 1, function() { + test('should provide the correct predicate arguments', 1, function() { var args, object = { 'a': 1, 'b': 2 }, lastKey = _.keys(object).pop(); @@ -11661,8 +11659,8 @@ test('should set the `this` binding', 1, function() { var actual = _.omit(object, function(num) { - return num != this.b; - }, { 'b': 2 }); + return num != this.b && num != this.d; + }, { 'b': 2, 'd': 4 }); deepEqual(actual, expected); }); @@ -12069,16 +12067,16 @@ QUnit.module('methods using `createWrapper`'); (function() { + function fn() { + return slice.call(arguments); + } + var ph1 = _.bind.placeholder, ph2 = _.bindKey.placeholder, ph3 = _.partial.placeholder, ph4 = _.partialRight.placeholder; - test('combinations of partial functions should work', 1, function() { - function fn() { - return slice.call(arguments); - } - + test('should work with combinations of partial functions', 1, function() { var a = _.partial(fn), b = _.partialRight(a, 3), c = _.partial(b, 1); @@ -12086,12 +12084,12 @@ deepEqual(c(2), [1, 2, 3]); }); - test('combinations of bound and partial functions should work', 3, function() { - function fn() { + test('should work with combinations of bound and partial functions', 3, function() { + var fn = function() { var result = [this.a]; push.apply(result, arguments); return result; - } + }; var expected = [1, 2, 3, 4], object = { 'a': 1, 'fn': fn }; @@ -12115,11 +12113,7 @@ deepEqual(c(3), expected); }); - test('combinations of functions with placeholders should work', 3, function() { - function fn() { - return slice.call(arguments); - } - + test('should work with combinations of functions with placeholders', 3, function() { var expected = [1, 2, 3, 4, 5, 6], object = { 'fn': fn }; @@ -12142,11 +12136,7 @@ deepEqual(c(3, 5), expected); }); - test('combinations of functions with overlaping placeholders should work', 3, function() { - function fn() { - return slice.call(arguments); - } - + test('should work with combinations of functions with overlaping placeholders', 3, function() { var expected = [1, 2, 3, 4], object = { 'fn': fn }; @@ -12169,10 +12159,10 @@ deepEqual(c(1), expected); }); - test('recursively bound functions should work', 1, function() { - function fn() { + test('should work with recursively bound functions', 1, function() { + var fn = function() { return this.a; - } + }; var a = _.bind(fn, { 'a': 1 }), b = _.bind(a, { 'a': 2 }), @@ -12329,7 +12319,7 @@ (function() { var args = arguments, - object = { 'a': 1, 'b': 2, 'c': 3 }, + object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, expected = { 'a': 1, 'c': 3 }; test('should create an object of picked properties', 2, function() { @@ -12337,12 +12327,8 @@ deepEqual(_.pick(object, 'a', 'c'), expected); }); - test('should support picking an array of properties', 1, function() { - deepEqual(_.pick(object, ['a', 'c']), expected); - }); - - test('should support picking an array of properties and individual properties', 1, function() { - deepEqual(_.pick(object, ['a'], 'c'), expected); + test('should flatten `props`', 1, function() { + deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 }); }); test('should iterate over inherited properties', 1, function() { @@ -12370,15 +12356,15 @@ deepEqual(_.pick('', 'slice'), { 'slice': ''.slice }); }); - test('should work with a `predicate` argument', 1, function() { + test('should work with a predicate argument', 1, function() { var actual = _.pick(object, function(num) { - return num != 2; + return num == 1 || num == 3; }); deepEqual(actual, expected); }); - test('should provide the correct `predicate` arguments', 1, function() { + test('should provide the correct predicate arguments', 1, function() { var args, object = { 'a': 1, 'b': 2 }, lastKey = _.keys(object).pop(); @@ -12396,8 +12382,8 @@ test('should set the `this` binding', 1, function() { var actual = _.pick(object, function(num) { - return num != this.b; - }, { 'b': 2 }); + return num == this.a || num == this.c; + }, { 'a': 1, 'c': 3 }); deepEqual(actual, expected); }); @@ -12457,13 +12443,15 @@ test('should work in a lazy chain sequence', 2, function() { if (!isNpm) { - var array = [{ 'a': 1 }, null, { 'a': 3 }, { 'a': 4 }], - actual = _(array).pluck('a').value(); + var array = _.times(LARGE_ARRAY_SIZE + 1, function(index) { + return index ? { 'a': index } : null; + }); - deepEqual(actual, [1, undefined, 3, 4]); + var actual = _(array).slice(1).pluck('a').value(); + deepEqual(actual, _.pluck(array.slice(1), 'a')); - actual = _(array).filter(Boolean).pluck('a').value(); - deepEqual(actual, [1, 3, 4]); + actual = _(array).slice(1).filter().pluck('a').value(); + deepEqual(actual, _.pluck(_.filter(array.slice(1)), 'a')); } else { skipTest(2); @@ -13366,16 +13354,18 @@ test('`_.' + methodName + '` should work in a lazy chain sequence', 2, function() { if (!isNpm) { - var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, - predicate = function(value) { return isFilter ? (value > 6) : (value < 6); }; + var array = _.range(0, LARGE_ARRAY_SIZE + 1), + predicate = function(value) { return isFilter ? (value > 6) : (value < 6); }, + actual = _(array).slice(1).map(square)[methodName](predicate).value(); - var expected = [9, 16], - actual = _(array).map(square)[methodName](predicate).value(); + deepEqual(actual, _[methodName](_.map(array.slice(1), square), predicate)); - deepEqual(actual, expected); + var object = _.zipObject(_.times(LARGE_ARRAY_SIZE, function(index) { + return ['key' + index, index]; + })); actual = _(object).mapValues(square)[methodName](predicate).value(); - deepEqual(actual, expected); + deepEqual(actual, _[methodName](_.mapValues(object, square), predicate)); } else { skipTest(2); @@ -13385,37 +13375,38 @@ test('`_.' + methodName + '` should provide the correct `predicate` arguments in a lazy chain sequence', 5, function() { if (!isNpm) { var args, - expected = [1, 0, [1, 4, 9, 16]]; + array = _.range(0, LARGE_ARRAY_SIZE + 1), + expected = [1, 0, _.map(array.slice(1), square)]; - _(array)[methodName](function(value, index, array) { + _(array).slice(1)[methodName](function(value, index, array) { args || (args = slice.call(arguments)); }).value(); - deepEqual(args, [1, 0, array]); + deepEqual(args, [1, 0, array.slice(1)]); args = null; - _(array).map(square)[methodName](function(value, index, array) { + _(array).slice(1).map(square)[methodName](function(value, index, array) { args || (args = slice.call(arguments)); }).value(); deepEqual(args, expected); args = null; - _(array).map(square)[methodName](function(value, index) { + _(array).slice(1).map(square)[methodName](function(value, index) { args || (args = slice.call(arguments)); }).value(); deepEqual(args, expected); args = null; - _(array).map(square)[methodName](function(value) { + _(array).slice(1).map(square)[methodName](function(value) { args || (args = slice.call(arguments)); }).value(); deepEqual(args, [1]); args = null; - _(array).map(square)[methodName](function() { + _(array).slice(1).map(square)[methodName](function() { args || (args = slice.call(arguments)); }).value(); @@ -13754,7 +13745,7 @@ test('should work in a lazy chain sequence', 4, function() { if (!isNpm) { - var array = [1, 2, 3], + var array = _.range(1, LARGE_ARRAY_SIZE + 1), values = []; var actual = _(array).rest().filter(function(value) { @@ -13764,7 +13755,7 @@ .value(); deepEqual(actual, []); - deepEqual(values, [2, 3]); + deepEqual(values, array.slice(1)); values = []; @@ -13775,7 +13766,7 @@ .rest() .value(); - deepEqual(actual, [3]); + deepEqual(actual, array.slice(2)); deepEqual(values, array); } else { @@ -13785,16 +13776,16 @@ test('should not execute subsequent iteratees on an empty array in a lazy chain sequence', 4, function() { if (!isNpm) { - var array = [1], + var array = _.range(1, LARGE_ARRAY_SIZE + 1), iteratee = function() { pass = false }, pass = true, - actual = _(array).rest().map(iteratee).value(); + actual = _(array).slice(0, 1).rest().map(iteratee).value(); ok(pass); deepEqual(actual, []); pass = true; - actual = _(array).filter(_.identity).rest().map(iteratee).value(); + actual = _(array).filter().slice(0, 1).rest().map(iteratee).value(); ok(pass); deepEqual(actual, []); @@ -13845,7 +13836,7 @@ deepEqual(rp(1), [1, undefined, []]); }); - test('should work on functions with more than 3 params', 1, function() { + test('should work on functions with more than three params', 1, function() { var rp = _.restParam(function(a, b, c, d) { return slice.call(arguments); }); @@ -13865,6 +13856,44 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('round methods'); + + _.each(['ceil', 'floor', 'round'], function(methodName) { + var func = _[methodName], + isCeil = methodName == 'ceil', + isFloor = methodName == 'floor'; + + test('`_.' + methodName + '` should return a rounded number without a precision', 1, function() { + var actual = func(4.006); + strictEqual(actual, isCeil ? 5 : 4); + }); + + test('`_.' + methodName + '` should return a rounded number with a precision of `0`', 1, function() { + var actual = func(4.006, 0); + strictEqual(actual, isCeil ? 5 : 4); + }); + + test('`_.' + methodName + '` should coerce `precision` values to numbers and `NaN` to `0`', 2, function() { + var actual = func(4.006, NaN); + strictEqual(actual, isCeil ? 5 : 4); + + actual = func(4.016, '+2'); + strictEqual(actual, isFloor ? 4.01 : 4.02); + }); + + test('`_.' + methodName + '` should return a rounded number with a positive precision', 1, function() { + var actual = func(4.016, 2); + strictEqual(actual, isFloor ? 4.01 : 4.02); + }); + + test('`_.' + methodName + '` should return a rounded number with a negative precision', 1, function() { + var actual = func(4160, -2); + strictEqual(actual, isFloor ? 4100 : 4200); + }); + }); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.runInContext'); (function() { @@ -14292,7 +14321,7 @@ strictEqual(_.size({ 'length': '0' }), 1); }); - test('fixes the JScript `[[DontEnum]]` bug (test in IE < 9)', 1, function() { + test('should fix the JScript `[[DontEnum]]` bug (test in IE < 9)', 1, function() { strictEqual(_.size(shadowObject), 7); }); @@ -14409,32 +14438,34 @@ test('should work in a lazy chain sequence', 38, function() { if (!isNpm) { - var wrapped = _(array); + var array = _.range(1, LARGE_ARRAY_SIZE + 1), + length = array.length, + wrapped = _(array); _.each(['map', 'filter'], function(methodName) { - deepEqual(wrapped[methodName]().slice(0, -1).value(), [1, 2]); - deepEqual(wrapped[methodName]().slice(1).value(), [2, 3]); - deepEqual(wrapped[methodName]().slice(1, 3).value(), [2, 3]); - deepEqual(wrapped[methodName]().slice(-1).value(), [3]); - - deepEqual(wrapped[methodName]().slice(4).value(), []); - deepEqual(wrapped[methodName]().slice(3, 2).value(), []); - deepEqual(wrapped[methodName]().slice(0, -4).value(), []); - deepEqual(wrapped[methodName]().slice(0, null).value(), []); - - deepEqual(wrapped[methodName]().slice(0, 4).value(), array); - deepEqual(wrapped[methodName]().slice(-4).value(), array); - deepEqual(wrapped[methodName]().slice(null).value(), array); - - deepEqual(wrapped[methodName]().slice(0, 1).value(), [1]); - deepEqual(wrapped[methodName]().slice(NaN, '1').value(), [1]); - - deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), [1]); - deepEqual(wrapped[methodName]().slice('0', 1).value(), [1]); - deepEqual(wrapped[methodName]().slice(0, '1').value(), [1]); - deepEqual(wrapped[methodName]().slice('1').value(), [2, 3]); - deepEqual(wrapped[methodName]().slice(NaN, 1).value(), [1]); - deepEqual(wrapped[methodName]().slice(1, NaN).value(), []); + deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1)); + deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1)); + deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3)); + deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1)); + + deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length)); + deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2)); + deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length)); + deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null)); + + deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length)); + deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length)); + deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null)); + + deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1)); + deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1')); + + deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1)); + deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1)); + deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1')); + deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1')); + deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1)); + deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN)); }); } else { @@ -14650,14 +14681,18 @@ { 'a': 'y', 'b': 2 } ]; - test('should sort multiple properties by specified orders', 1, function() { - var actual = _.sortByOrder(objects, ['a', 'b'], [false, true]); - deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]); + test('should sort multiple properties by specified orders', 2, function() { + _.each([[false, true], ['desc', 'asc']], function(orders) { + var actual = _.sortByOrder(objects, ['a', 'b'], orders); + deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]); + }); }); - test('should sort a property in ascending order when its order is not specified', 1, function() { - var actual = _.sortByOrder(objects, ['a', 'b'], [false]); - deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]); + test('should sort a property in ascending order when its order is not specified', 2, function() { + _.each([[false], ['desc']], function(orders) { + var actual = _.sortByOrder(objects, ['a', 'b'], orders); + deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]); + }); }); }()); @@ -15062,19 +15097,9 @@ test('should not contain minified properties (test production builds)', 1, function() { var props = [ - 'argsTag', - 'argsObject', - 'dom', 'enumErrorProps', 'enumPrototypes', - 'fastBind', - 'funcDecomp', - 'funcNames', - 'hostObject', - 'nodeTag', - 'nonEnumArgs', 'nonEnumShadows', - 'nonEnumStrings', 'ownLast', 'spliceObjects', 'unindexedChars' @@ -15764,7 +15789,7 @@ setTimeout(function() { strictEqual(callCount, 2); QUnit.start(); - }, 256); + }, 128); } else { skipTest(3); @@ -15924,8 +15949,7 @@ if (!(isRhino && isModularize)) { var actual = [], args = _.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }), - length = isDebounce ? 1 : 2, - expected = args.slice(0, length), + expected = args.slice(), queue = args.slice(); var funced = func(function() { @@ -15937,16 +15961,16 @@ if (next) { funced.call(next[0], next[1]); } - }, 64); + }, 32); var next = queue.shift(); funced.call(next[0], next[1]); - deepEqual(actual, expected.slice(0, length - 1)); + deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1)); setTimeout(function() { - deepEqual(actual, expected); + deepEqual(actual, expected.slice(0, actual.length)); QUnit.start(); - }, 96); + }, 256); } else { skipTest(2); @@ -16008,6 +16032,29 @@ QUnit.start(); } }); + + asyncTest('_.' + methodName + ' should reset `lastCalled` after cancelling', 3, function() { + if (!(isRhino && isModularize)) { + var callCount = 0; + + var funced = func(function() { + return ++callCount; + }, 32, { 'leading': true }); + + strictEqual(funced(), 1); + funced.cancel(); + strictEqual(funced(), 2); + + setTimeout(function() { + strictEqual(callCount, 2); + QUnit.start(); + }, 64); + } + else { + skipTest(3); + QUnit.start(); + } + }); }); /*--------------------------------------------------------------------------*/ @@ -16103,11 +16150,17 @@ test('should work in a lazy chain sequence', 2, function() { if (!isNpm) { - var actual = _([1, 2]).map(String).toArray().value(); - deepEqual(actual, ['1', '2']); + var array = _.range(0, LARGE_ARRAY_SIZE + 1), + actual = _(array).slice(1).map(String).toArray().value(); + + deepEqual(actual, _.map(array.slice(1), String)); + + var object = _.zipObject(_.times(LARGE_ARRAY_SIZE, function(index) { + return ['key' + index, index]; + })); - actual = _({ 'a': 1, 'b': 2 }).toArray().map(String).value(); - deepEqual(actual, ['1', '2']); + actual = _(object).toArray().slice(1).map(String).value(); + deepEqual(actual, _.map(_.toArray(object).slice(1), String)); } else { skipTest(2); @@ -16840,14 +16893,12 @@ test('should work in a lazy chain sequence', 1, function() { if (!isNpm) { - var array = [ - { 'a': 1 }, - { 'a': 3 }, - { 'a': 1, 'b': 2 } - ]; + var array = _.times(LARGE_ARRAY_SIZE + 1, function(index) { + return index ? { 'a': 1, 'b': index } : { 'a': 3 }; + }); - var actual = _(array).where({ 'a': 1 }).value(); - deepEqual(actual, [array[0], array[2]]); + var actual = _(array).slice(1).where({ 'a': 1 }).value(); + deepEqual(actual, _.where(array.slice(1), { 'a': 1 })); } else { skipTest(); @@ -16947,15 +16998,6 @@ deepEqual(args, [_.noop, 1, 2, 3]); }); - test('should not set a `this` binding', 1, function() { - var p = _.wrap(_.escape, function(func) { - return '

' + func(this.text) + '

'; - }); - - var object = { 'p': p, 'text': 'fred, barney, & pebbles' }; - strictEqual(object.p(), '

fred, barney, & pebbles

'); - }); - test('should use `_.identity` when `wrapper` is nullish', 1, function() { var values = [, null, undefined], expected = _.map(values, _.constant('a')); @@ -16967,6 +17009,15 @@ deepEqual(actual, expected); }); + + test('should not set a `this` binding', 1, function() { + var p = _.wrap(_.escape, function(func) { + return '

' + func(this.text) + '

'; + }); + + var object = { 'p': p, 'text': 'fred, barney, & pebbles' }; + strictEqual(object.p(), '

fred, barney, & pebbles

'); + }); }()); /*--------------------------------------------------------------------------*/ @@ -17019,13 +17070,14 @@ test('should work when in a lazy chain sequence before `first` or `last`', 1, function() { if (!isNpm) { - var wrapped = _([1, 2]).slice().xor([2, 3]); + var array = _.range(0, LARGE_ARRAY_SIZE), + wrapped = _(array).slice(1).xor([LARGE_ARRAY_SIZE - 1, LARGE_ARRAY_SIZE]); var actual = _.map(['first', 'last'], function(methodName) { return wrapped[methodName](); }); - deepEqual(actual, [1, 3]); + deepEqual(actual, [1, LARGE_ARRAY_SIZE]); } else { skipTest(); @@ -17083,11 +17135,14 @@ test('should work in a lazy chain sequence', 1, function() { if (!isNpm) { - var array = [['a', 1], ['b', 2]], - predicate = function(value) { return value > 2; }, + var array = _.times(LARGE_ARRAY_SIZE, function(index) { + return ['key' + index, index]; + }); + + var predicate = function(value) { return value > 2; }, actual = _(array).zipObject().map(square).filter(predicate).take().value(); - deepEqual(actual, [4]); + deepEqual(actual, _.take(_.filter(_.map(_.zipObject(array), square), predicate))); } else { skipTest(); @@ -17239,9 +17294,9 @@ test('should track the `__chain__` value of a wrapper', 2, function() { if (!isNpm) { - var wrapper = _([1]).chain().commit().first(); - ok(wrapper instanceof _); - strictEqual(wrapper.value(), 1); + var wrapped = _([1]).chain().commit().first(); + ok(wrapped instanceof _); + strictEqual(wrapped.value(), 1); } else { skipTest(2); @@ -17254,6 +17309,36 @@ QUnit.module('lodash(...).concat'); (function() { + test('should concat arrays and values', 2, function() { + if (!isNpm) { + var array = [1], + wrapped = _(array).concat(2, [3], [[4]]); + + deepEqual(wrapped.value(), [1, 2, 3, [4]]); + deepEqual(array, [1]); + } + else { + skipTest(2); + } + }); + + test('should treat sparse arrays as dense', 3, function() { + if (!isNpm) { + var expected = [], + wrapped = _(Array(1)).concat(Array(1)), + actual = wrapped.value(); + + expected.push(undefined, undefined); + + ok('0'in actual); + ok('1' in actual); + deepEqual(actual, expected); + } + else { + skipTest(3); + } + }); + test('should return a new wrapped array', 3, function() { if (!isNpm) { var array = [1], @@ -17411,8 +17496,10 @@ test('should work in a lazy chain sequence', 1, function() { if (!isNpm) { - var actual = _([1, 2, 3, null]).map(_.identity).reverse().value(); - deepEqual(actual, [null, 3, 2, 1]); + var array = _.range(0, LARGE_ARRAY_SIZE).concat(null), + actual = _(array).slice(1).reverse().value(); + + deepEqual(actual, array.slice(1).reverse()); } else { skipTest(); @@ -17428,12 +17515,13 @@ }; try { - var wrapped = _(['a', spy]).map(String).reverse(), + var array = _.range(0, LARGE_ARRAY_SIZE).concat(spy), + wrapped = _(array).slice(1).map(String).reverse(), actual = wrapped.last(); } catch(e) {} ok(wrapped instanceof _); - strictEqual(actual, 'a'); + strictEqual(actual, '1'); } else { skipTest(2); @@ -17459,9 +17547,9 @@ test('should track the `__chain__` value of a wrapper', 2, function() { if (!isNpm) { - var wrapper = _([1, 2, 3]).chain().reverse().first(); - ok(wrapper instanceof _); - strictEqual(wrapper.value(), 3); + var wrapped = _([1, 2, 3]).chain().reverse().first(); + ok(wrapped instanceof _); + strictEqual(wrapped.value(), 3); } else { skipTest(2); @@ -17832,7 +17920,7 @@ var args = arguments, array = [1, 2, 3, 4, 5, 6]; - test('should work with `arguments` objects', 29, function() { + test('should work with `arguments` objects', 27, function() { function message(methodName) { return '`_.' + methodName + '` should work with `arguments` objects'; } @@ -17866,17 +17954,6 @@ deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq')); deepEqual(_.without(args, null), [1, [3], 5], message('without')); deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip')); - - if (_.support.argsTag && _.support.argsObject && !_.support.nonEnumArgs) { - _.pull(args, null); - deepEqual([args[0], args[1], args[2]], [1, [3], 5], message('pull')); - - _.remove(args, function(value) { return typeof value == 'number'; }); - ok(args.length === 1 && _.isEqual(args[0], [3]), message('remove')); - } - else { - skipTest(2); - } }); test('should accept falsey primary arguments', 4, function() { @@ -17910,7 +17987,6 @@ 'camelCase', 'capitalize', 'escape', - 'escapeRegExp', 'kebabCase', 'pad', 'padLeft', @@ -17955,6 +18031,7 @@ 'defer', 'delay', 'memoize', + 'modArgs', 'negate', 'once', 'partial', @@ -18015,9 +18092,8 @@ var acceptFalsey = _.difference(allMethods, rejectFalsey); - test('should accept falsey arguments', 225, function() { + test('should accept falsey arguments', 229, function() { var emptyArrays = _.map(falsey, _.constant([])), - isExposed = '_' in root, oldDash = root._; _.each(acceptFalsey, function(methodName) { @@ -18034,11 +18110,7 @@ }); if (methodName == 'noConflict') { - if (isExposed) { - root._ = oldDash; - } else { - delete root._; - } + root._ = oldDash; } else if (methodName == 'pull') { expected = falsey; @@ -18081,7 +18153,7 @@ }); }); - test('should throw an error for falsey arguments', 24, function() { + test('should throw an error for falsey arguments', 25, function() { _.each(rejectFalsey, function(methodName) { var expected = _.map(falsey, _.constant(true)), func = _[methodName]; diff --git a/test/underscore.html b/test/underscore.html index 07f599a2c7..53839884aa 100644 --- a/test/underscore.html +++ b/test/underscore.html @@ -1,242 +1,242 @@ - - - Underscore Test Suite - - - -
- - - - - - - + + + + + + - + - + require(getConfig(), [moduleId], function(lodash) { + if (ui.isModularize) { + window._ = lodash; + } + require(getConfig(), [ + 'test/collections', + 'test/arrays', + 'test/functions', + 'test/objects', + 'test/cross-document', + 'test/utility', + 'test/chaining' + ], function() { + QUnit.start(); + }); + }); + }()); + + diff --git a/vendor/backbone/backbone.js b/vendor/backbone/backbone.js index 8ebdac9304..58800425c7 100644 --- a/vendor/backbone/backbone.js +++ b/vendor/backbone/backbone.js @@ -1,4 +1,4 @@ -// Backbone.js 1.2.0 +// Backbone.js 1.2.1 // (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Backbone may be freely distributed under the MIT license. @@ -40,12 +40,11 @@ // restored later on, if `noConflict` is used. var previousBackbone = root.Backbone; - // Create local references to array methods we'll want to use later. - var array = []; - var slice = array.slice; + // Create a local reference to a common array method we'll want to use later. + var slice = [].slice; // Current version of the library. Keep in sync with `package.json`. - Backbone.VERSION = '1.2.0'; + Backbone.VERSION = '1.2.1'; // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns // the `$` variable. @@ -69,6 +68,35 @@ // form param named `model`. Backbone.emulateJSON = false; + // Proxy Underscore methods to a Backbone class' prototype using a + // particular attribute as the data argument + var addMethod = function(length, method, attribute) { + switch (length) { + case 1: return function() { + return _[method](this[attribute]); + }; + case 2: return function(value) { + return _[method](this[attribute], value); + }; + case 3: return function(iteratee, context) { + return _[method](this[attribute], iteratee, context); + }; + case 4: return function(iteratee, defaultVal, context) { + return _[method](this[attribute], iteratee, defaultVal, context); + }; + default: return function() { + var args = slice.call(arguments); + args.unshift(this[attribute]); + return _[method].apply(_, args); + }; + } + }; + var addUnderscoreMethods = function(Class, methods, attribute) { + _.each(methods, function(length, method) { + if (_[method]) Class.prototype[method] = addMethod(length, method, attribute); + }); + }; + // Backbone.Events // --------------- @@ -96,6 +124,7 @@ var i = 0, names; if (name && typeof name === 'object') { // Handle event maps. + if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback; for (names = _.keys(name); i < names.length ; i++) { memo = iteratee(memo, names[i], name[names[i]], opts); } @@ -205,7 +234,7 @@ // No events to consider. if (!events) return; - var i = 0, length, listening; + var i = 0, listening; var context = options.context, listeners = options.listeners; // Delete all events listeners and "drop" events. @@ -274,7 +303,7 @@ }; // Reduces the event callbacks into a map of `{event: onceWrapper}`. - // `offer` unbinds the `onceWrapper` after it as been called. + // `offer` unbinds the `onceWrapper` after it has been called. var onceMap = function(map, name, callback, offer) { if (callback) { var once = map[name] = _.once(function() { @@ -327,35 +356,6 @@ } }; - // Proxy Underscore methods to a Backbone class' prototype using a - // particular attribute as the data argument - var addMethod = function(length, method, attribute) { - switch (length) { - case 1: return function() { - return _[method](this[attribute]); - }; - case 2: return function(value) { - return _[method](this[attribute], value); - }; - case 3: return function(iteratee, context) { - return _[method](this[attribute], iteratee, context); - }; - case 4: return function(iteratee, defaultVal, context) { - return _[method](this[attribute], iteratee, defaultVal, context); - }; - default: return function() { - var args = slice.call(arguments); - args.unshift(this[attribute]); - return _[method].apply(_, args); - }; - } - }; - var addUnderscoreMethods = function(Class, methods, attribute) { - _.each(methods, function(length, method) { - if (_[method]) Class.prototype[method] = addMethod(length, method, attribute); - }); - }; - // Aliases for backwards compatibility. Events.bind = Events.on; Events.unbind = Events.off; @@ -444,10 +444,10 @@ // the core primitive operation of a model, updating the data and notifying // anyone who needs to know about the change in state. The heart of the beast. set: function(key, val, options) { - var attr, attrs, unset, changes, silent, changing, prev, current; if (key == null) return this; // Handle both `"key", value` and `{key: value}` -style arguments. + var attrs; if (typeof key === 'object') { attrs = key; options = val; @@ -461,29 +461,32 @@ if (!this._validate(attrs, options)) return false; // Extract attributes and options. - unset = options.unset; - silent = options.silent; - changes = []; - changing = this._changing; - this._changing = true; + var unset = options.unset; + var silent = options.silent; + var changes = []; + var changing = this._changing; + this._changing = true; if (!changing) { this._previousAttributes = _.clone(this.attributes); this.changed = {}; } - current = this.attributes, prev = this._previousAttributes; + + var current = this.attributes; + var changed = this.changed; + var prev = this._previousAttributes; // Check for changes of `id`. if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; // For each `set` attribute, update or delete the current value. - for (attr in attrs) { + for (var attr in attrs) { val = attrs[attr]; if (!_.isEqual(current[attr], val)) changes.push(attr); if (!_.isEqual(prev[attr], val)) { - this.changed[attr] = val; + changed[attr] = val; } else { - delete this.changed[attr]; + delete changed[attr]; } unset ? delete current[attr] : current[attr] = val; } @@ -539,13 +542,14 @@ // determining if there *would be* a change. changedAttributes: function(diff) { if (!diff) return this.hasChanged() ? _.clone(this.changed) : false; - var val, changed = false; var old = this._changing ? this._previousAttributes : this.attributes; + var changed = {}; for (var attr in diff) { - if (_.isEqual(old[attr], (val = diff[attr]))) continue; - (changed || (changed = {}))[attr] = val; + var val = diff[attr]; + if (_.isEqual(old[attr], val)) continue; + changed[attr] = val; } - return changed; + return _.size(changed) ? changed : false; }, // Get the previous value of an attribute, recorded at the time the last @@ -564,12 +568,12 @@ // Fetch the model from the server, merging the response with the model's // local attributes. Any changed attributes will trigger a "change" event. fetch: function(options) { - options = options ? _.clone(options) : {}; - if (options.parse === void 0) options.parse = true; + options = _.extend({parse: true}, options); var model = this; var success = options.success; options.success = function(resp) { - if (!model.set(model.parse(resp, options), options)) return false; + var serverAttrs = options.parse ? model.parse(resp, options) : resp; + if (!model.set(serverAttrs, options)) return false; if (success) success.call(options.context, model, resp, options); model.trigger('sync', model, resp, options); }; @@ -581,9 +585,8 @@ // If the server returns an attributes hash that differs, the model's // state will be `set` again. save: function(key, val, options) { - var attrs, method, xhr, attributes = this.attributes, wait; - // Handle both `"key", value` and `{key: value}` -style arguments. + var attrs; if (key == null || typeof key === 'object') { attrs = key; options = val; @@ -591,8 +594,8 @@ (attrs = {})[key] = val; } - options = _.extend({validate: true}, options); - wait = options.wait; + options = _.extend({validate: true, parse: true}, options); + var wait = options.wait; // If we're not waiting and attributes exist, save acts as // `set(attr).save(null, opts)` with validation. Otherwise, check if @@ -603,35 +606,31 @@ if (!this._validate(attrs, options)) return false; } - // Set temporary attributes if `{wait: true}`. - if (attrs && wait) { - this.attributes = _.extend({}, attributes, attrs); - } - // After a successful server-side save, the client is (optionally) // updated with the server-side state. - if (options.parse === void 0) options.parse = true; var model = this; var success = options.success; + var attributes = this.attributes; options.success = function(resp) { // Ensure attributes are restored during synchronous saves. model.attributes = attributes; var serverAttrs = options.parse ? model.parse(resp, options) : resp; - if (wait) serverAttrs = _.extend(attrs || {}, serverAttrs); - if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) { - return false; - } + if (wait) serverAttrs = _.extend({}, attrs, serverAttrs); + if (serverAttrs && !model.set(serverAttrs, options)) return false; if (success) success.call(options.context, model, resp, options); model.trigger('sync', model, resp, options); }; wrapError(this, options); - method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update'); + // Set temporary attributes if `{wait: true}` to properly find new ids. + if (attrs && wait) this.attributes = _.extend({}, attributes, attrs); + + var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update'); if (method === 'patch' && !options.attrs) options.attrs = attrs; - xhr = this.sync(method, this, options); + var xhr = this.sync(method, this, options); // Restore attributes. - if (attrs && wait) this.attributes = attributes; + this.attributes = attributes; return xhr; }, @@ -676,8 +675,8 @@ _.result(this.collection, 'url') || urlError(); if (this.isNew()) return base; - var id = this.id || this.attributes[this.idAttribute]; - return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(id); + var id = this.get(this.idAttribute); + return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id); }, // **parse** converts a response into the hash of attributes to be `set` on @@ -698,7 +697,7 @@ // Check if the model is currently in a valid state. isValid: function(options) { - return this._validate({}, _.extend(options || {}, { validate: true })); + return this._validate({}, _.defaults({validate: true}, options)); }, // Run validation against the next complete set of model attributes, @@ -761,7 +760,7 @@ // The JSON representation of a Collection is an array of the // models' attributes. toJSON: function(options) { - return this.map(function(model){ return model.toJSON(options); }); + return this.map(function(model) { return model.toJSON(options); }); }, // Proxy `Backbone.sync` by default. @@ -776,12 +775,12 @@ // Remove a model, or a list of models from the set. remove: function(models, options) { - var singular = !_.isArray(models), removed; + options = _.extend({}, options); + var singular = !_.isArray(models); models = singular ? [models] : _.clone(models); - options || (options = {}); - removed = this._removeModels(models, options); + var removed = this._removeModels(models, options); if (!options.silent && removed) this.trigger('update', this, options); - return singular ? models[0] : models; + return singular ? removed[0] : removed; }, // Update a collection by `set`-ing a new list of models, adding new ones, @@ -790,7 +789,7 @@ // the core operation for updating the data contained by the collection. set: function(models, options) { options = _.defaults({}, options, setOptions); - if (options.parse) models = this.parse(models, options); + if (options.parse && !this._isModel(models)) models = this.parse(models, options); var singular = !_.isArray(models); models = singular ? (models ? [models] : []) : models.slice(); var id, model, attrs, existing, sort; @@ -910,8 +909,7 @@ // Remove a model from the end of the collection. pop: function(options) { var model = this.at(this.length - 1); - this.remove(model, options); - return model; + return this.remove(model, options); }, // Add a model to the beginning of the collection. @@ -922,8 +920,7 @@ // Remove a model from the beginning of the collection. shift: function(options) { var model = this.at(0); - this.remove(model, options); - return model; + return this.remove(model, options); }, // Slice out a sub-array of models from the collection. @@ -986,8 +983,7 @@ // collection when they arrive. If `reset: true` is passed, the response // data will be passed through the `reset` method instead of `set`. fetch: function(options) { - options = options ? _.clone(options) : {}; - if (options.parse === void 0) options.parse = true; + options = _.extend({parse: true}, options); var success = options.success; var collection = this; options.success = function(resp) { @@ -1006,7 +1002,8 @@ create: function(model, options) { options = options ? _.clone(options) : {}; var wait = options.wait; - if (!(model = this._prepareModel(model, options))) return false; + model = this._prepareModel(model, options); + if (!model) return false; if (!wait) this.add(model, options); var collection = this; var success = options.success; @@ -1060,31 +1057,27 @@ return false; }, - // Internal method called by both remove and set. Does not trigger any - // additional events. Returns true if anything was actually removed. + // Internal method called by both remove and set. + // Returns removed models, or false if nothing is removed. _removeModels: function(models, options) { - var i, l, index, model, removed = false; - for (var i = 0, j = 0; i < models.length; i++) { - var model = models[i] = this.get(models[i]); + var removed = []; + for (var i = 0; i < models.length; i++) { + var model = this.get(models[i]); if (!model) continue; - var id = this.modelId(model.attributes); - if (id != null) delete this._byId[id]; - delete this._byId[model.cid]; + var index = this.indexOf(model); this.models.splice(index, 1); this.length--; + if (!options.silent) { options.index = index; model.trigger('remove', model, this, options); } - models[j++] = model; + + removed.push(model); this._removeReference(model, options); - removed = true; } - // We only need to slice if models array should be smaller, which is - // caused by some models not actually getting removed. - if (models.length !== j) models = models.slice(0, j); - return removed; + return removed.length ? removed : false; }, // Method for checking whether an object should be considered a model for @@ -1103,6 +1096,9 @@ // Internal method to sever a model's ties to a collection. _removeReference: function(model, options) { + delete this._byId[model.cid]; + var id = this.modelId(model.attributes); + if (id != null) delete this._byId[id]; if (this === model.collection) delete model.collection; model.off('all', this._onModelEvent, this); }, @@ -1133,7 +1129,7 @@ var collectionMethods = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 4, foldl: 4, inject: 4, reduceRight: 4, foldr: 4, find: 3, detect: 3, filter: 3, select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 2, - contains: 2, invoke: 2, max: 3, min: 3, toArray: 1, size: 1, first: 3, + contains: 2, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3, head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3, without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3, isEmpty: 1, chain: 1, sample: 3, partition: 3 }; @@ -1170,7 +1166,6 @@ // if an existing element is not provided... var View = Backbone.View = function(options) { this.cid = _.uniqueId('view'); - options || (options = {}); _.extend(this, _.pick(options, viewOptions)); this._ensureElement(); this.initialize.apply(this, arguments); @@ -1253,11 +1248,12 @@ // Uses event delegation for efficiency. // Omitting the selector binds the event to `this.el`. delegateEvents: function(events) { - if (!(events || (events = _.result(this, 'events')))) return this; + events || (events = _.result(this, 'events')); + if (!events) return this; this.undelegateEvents(); for (var key in events) { var method = events[key]; - if (!_.isFunction(method)) method = this[events[key]]; + if (!_.isFunction(method)) method = this[method]; if (!method) continue; var match = key.match(delegateEventSplitter); this.delegate(match[1], match[2], _.bind(method, this)); @@ -1270,6 +1266,7 @@ // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer. delegate: function(eventName, selector, listener) { this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener); + return this; }, // Clears all callbacks previously bound to the view by `delegateEvents`. @@ -1284,6 +1281,7 @@ // `selector` and `listener` are both optional. undelegate: function(eventName, selector, listener) { this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener); + return this; }, // Produces a DOM element to be assigned to your view. Exposed for @@ -1647,15 +1645,16 @@ // support the `hashchange` event, HTML5 history, or the user wants // `hashChange` but not `pushState`. if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) { - var iframe = document.createElement('iframe'); - iframe.src = 'javascript:0'; - iframe.style.display = 'none'; - iframe.tabIndex = -1; + this.iframe = document.createElement('iframe'); + this.iframe.src = 'javascript:0'; + this.iframe.style.display = 'none'; + this.iframe.tabIndex = -1; var body = document.body; // Using `appendChild` will throw on IE < 9 if the document is not ready. - this.iframe = body.insertBefore(iframe, body.firstChild).contentWindow; - this.iframe.document.open().close(); - this.iframe.location.hash = '#' + this.fragment; + var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow; + iWindow.document.open(); + iWindow.document.close(); + iWindow.location.hash = '#' + this.fragment; } // Add a cross-platform `addEventListener` shim for older browsers. @@ -1693,7 +1692,7 @@ // Clean up the iframe if necessary. if (this.iframe) { - document.body.removeChild(this.iframe.frameElement); + document.body.removeChild(this.iframe); this.iframe = null; } @@ -1716,7 +1715,7 @@ // If the user pressed the back button, the iframe's hash will have // changed and we should use that for comparison. if (current === this.fragment && this.iframe) { - current = this.getHash(this.iframe); + current = this.getHash(this.iframe.contentWindow); } if (current === this.fragment) return false; @@ -1774,12 +1773,18 @@ // fragment to store history. } else if (this._wantsHashChange) { this._updateHash(this.location, fragment, options.replace); - if (this.iframe && (fragment !== this.getHash(this.iframe))) { + if (this.iframe && (fragment !== this.getHash(this.iframe.contentWindow))) { + var iWindow = this.iframe.contentWindow; + // Opening and closing the iframe tricks IE7 and earlier to push a // history entry on hash-tag change. When replace is true, we don't // want this. - if (!options.replace) this.iframe.document.open().close(); - this._updateHash(this.iframe.location, fragment, options.replace); + if (!options.replace) { + iWindow.document.open(); + iWindow.document.close(); + } + + this._updateHash(iWindow.location, fragment, options.replace); } // If you've told us that you explicitly don't want fallback hashchange- diff --git a/vendor/backbone/test/collection.js b/vendor/backbone/test/collection.js index 51a9b7befd..fa84818612 100644 --- a/vendor/backbone/test/collection.js +++ b/vendor/backbone/test/collection.js @@ -298,17 +298,13 @@ deepEqual(col.pluck('id'), [1, 2, 3]); }); - test("remove", 7, function() { + test("remove", 10, function() { var removed = null; - var otherRemoved = null; var result = null; col.on('remove', function(model, col, options) { removed = model.get('label'); equal(options.index, 3); }); - otherCol.on('remove', function(model, col, options) { - otherRemoved = true; - }); result = col.remove(d); equal(removed, 'd'); strictEqual(result, d); @@ -317,7 +313,13 @@ strictEqual(result, undefined); equal(col.length, 3); equal(col.first(), a); - equal(otherRemoved, null); + col.off(); + result = col.remove([c, d]); + equal(result.length, 1, 'only returns removed models'); + equal(result[0], c, 'only returns removed models'); + result = col.remove([c, b]); + equal(result.length, 1, 'only returns removed models'); + equal(result[0], b, 'only returns removed models'); }); test("add and remove return values", 13, function() { @@ -559,6 +561,20 @@ }); + test("create with wait:true should not call collection.parse", 0, function() { + var Collection = Backbone.Collection.extend({ + url: '/test', + parse: function () { + ok(false); + } + }); + + var collection = new Collection; + + collection.create({}, {wait: true}); + this.ajaxSettings.success(); + }); + test("a failing create returns model with errors", function() { var ValidatingModel = Backbone.Model.extend({ validate: function(attrs) { @@ -1605,4 +1621,19 @@ collection.set([{id: 1}, {id: 2}]); }); + test("#3610 - invoke collects arguments", 3, function() { + var Model = Backbone.Model.extend({ + method: function(a, b, c) { + equal(a, 1); + equal(b, 2); + equal(c, 3); + } + }); + var Collection = Backbone.Collection.extend({ + model: Model + }); + var collection = new Collection([{id: 1}]); + collection.invoke('method', 1, 2, 3); + }); + })(); diff --git a/vendor/backbone/test/events.js b/vendor/backbone/test/events.js index 017cf47f6b..a2730bc01d 100644 --- a/vendor/backbone/test/events.js +++ b/vendor/backbone/test/events.js @@ -66,6 +66,24 @@ equal(obj.counter, 5); }); + test("binding and trigger with event maps context", 2, function() { + var obj = { counter: 0 }; + var context = {}; + _.extend(obj, Backbone.Events); + + obj.on({ + a: function() { + strictEqual(this, context, 'defaults `context` to `callback` param'); + } + }, context).trigger('a'); + + obj.off().on({ + a: function() { + strictEqual(this, context, 'will not override explicit `context` param'); + } + }, this, context).trigger('a'); + }); + test("listenTo and stopListening", 1, function() { var a = _.extend({}, Backbone.Events); var b = _.extend({}, Backbone.Events); diff --git a/vendor/backbone/test/model.js b/vendor/backbone/test/model.js index 94647bbd03..faaf61dda3 100644 --- a/vendor/backbone/test/model.js +++ b/vendor/backbone/test/model.js @@ -550,6 +550,21 @@ model.destroy(options); }); + test("#3470 - save and fetch with parse false", 2, function() { + var i = 0; + var model = new Backbone.Model(); + model.parse = function() { + ok(false); + }; + model.sync = function(method, model, options) { + options.success({i: ++i}); + }; + model.fetch({parse: false}); + equal(model.get('i'), i); + model.save(null, {parse: false}); + equal(model.get('i'), i); + }); + test("save with PATCH", function() { doc.clear().set({id: 1, a: 1, b: 2, c: 3, d: 4}); doc.save(); diff --git a/vendor/backbone/test/router.js b/vendor/backbone/test/router.js index db2db909c2..acd17cecb0 100644 --- a/vendor/backbone/test/router.js +++ b/vendor/backbone/test/router.js @@ -918,7 +918,7 @@ test('#3358 - pushState to hashChange transition with search params', 1, function() { Backbone.history.stop(); - location.replace('/root?foo=bar'); + location.replace('http://example.com/root?foo=bar'); location.replace = function(url) { strictEqual(url, '/root#?foo=bar'); }; diff --git a/vendor/backbone/test/view.js b/vendor/backbone/test/view.js index 392a50f790..a3e2697490 100644 --- a/vendor/backbone/test/view.js +++ b/vendor/backbone/test/view.js @@ -48,6 +48,11 @@ strictEqual(new View().one, 1); }); + test("render", 1, function() { + var view = new Backbone.View; + equal(view.render(), view, '#render returns the view instance'); + }); + test("delegateEvents", 6, function() { var counter1 = 0, counter2 = 0; @@ -72,7 +77,7 @@ equal(counter2, 3); }); - test("delegate", 2, function() { + test("delegate", 3, function() { var view = new Backbone.View({el: '#testElement'}); view.delegate('click', 'h1', function() { ok(true); @@ -81,6 +86,8 @@ ok(true); }); view.$('h1').trigger('click'); + + equal(view.delegate(), view, '#delegate returns the view instance'); }); test("delegateEvents allows functions for callbacks", 3, function() { @@ -112,7 +119,7 @@ view.$el.trigger('click'); }); - test("undelegateEvents", 6, function() { + test("undelegateEvents", 7, function() { var counter1 = 0, counter2 = 0; var view = new Backbone.View({el: '#testElement'}); @@ -135,9 +142,11 @@ view.$('h1').trigger('click'); equal(counter1, 2); equal(counter2, 3); + + equal(view.undelegateEvents(), view, '#undelegateEvents returns the view instance'); }); - test("undelegate", 0, function() { + test("undelegate", 1, function() { view = new Backbone.View({el: '#testElement'}); view.delegate('click', function() { ok(false); }); view.delegate('click', 'h1', function() { ok(false); }); @@ -146,6 +155,8 @@ view.$('h1').trigger('click'); view.$el.trigger('click'); + + equal(view.undelegate(), view, '#undelegate returns the view instance'); }); test("undelegate with passed handler", 1, function() { @@ -387,14 +398,14 @@ equal(counter, 2); }); - test("remove", 1, function() { + test("remove", 2, function() { var view = new Backbone.View; document.body.appendChild(view.el); view.delegate('click', function() { ok(false); }); view.listenTo(view, 'all x', function() { ok(false); }); - view.remove(); + equal(view.remove(), view, '#remove returns the view instance'); view.$el.trigger('click'); view.trigger('x'); @@ -402,4 +413,25 @@ notEqual(view.el.parentNode, document.body); }); + test("setElement", 3, function() { + var view = new Backbone.View({ + events: { + click: function() { ok(false); } + } + }); + view.events = { + click: function() { ok(true); } + }; + var oldEl = view.el; + var $oldEl = view.$el; + + view.setElement(document.createElement('div')); + + $oldEl.click(); + view.$el.click(); + + notEqual(oldEl, view.el); + notEqual($oldEl, view.$el); + }); + })(); diff --git a/vendor/benchmark.js/LICENSE.txt b/vendor/benchmark.js/LICENSE similarity index 100% rename from vendor/benchmark.js/LICENSE.txt rename to vendor/benchmark.js/LICENSE