Compare commits

...

58 Commits

Author SHA1 Message Date
John-David Dalton
af9bf3e852 Cleanup comments/docs/descriptions. [ci skip]
Former-commit-id: 4d6a0a54abbaa6607cc5897a09e5a7c0fc884a1a
2012-12-04 09:14:59 -08:00
John-David Dalton
ed8746df77 Rebuild update vendors, minified files, and adjust README.md changelog.
Former-commit-id: a01567b3d8e88da0cb20e12c864703e633b86fc6
2012-12-04 01:29:24 -08:00
John-David Dalton
bb187db49d Tweak _.throttle unit test and add _.bind test.
Former-commit-id: b863194c661d97177bbcda9676699e9753f0db22
2012-12-03 22:37:09 -08:00
John-David Dalton
081e72b3ea Fix typo in _.clone documentation. [closes #130]
Former-commit-id: 81e17c992848c5d0ac9d30fb64eef3163bac6598
2012-12-03 22:10:08 -08:00
John-David Dalton
6188c38053 Move bound inheritance hookup inside bound.
Former-commit-id: 7f95fffa14ef42f8f065aad124ac883740baac64
2012-12-03 22:07:45 -08:00
John-David Dalton
12b0186f5a Make _.isEqual work with arguments objects in older versions of Opera.
Former-commit-id: 860a27e7f81e14781eb371cadf24bb812eb31718
2012-12-03 01:54:46 -08:00
John-David Dalton
9bccc9c53c Ensured _.throttle nulls the timeoutId. [closes #129]
Former-commit-id: 24242f513e01adb2827cc3a5af6c8904098a9280
2012-12-03 01:04:54 -08:00
John-David Dalton
351b2b320e Bump to version 1.0.0-rc.1.
Former-commit-id: 8867f4ddfab62435d0c2c685d67e68555d146545
2012-12-02 22:09:56 -08:00
John-David Dalton
94258feb09 Make _#bind return non-wrapped values and cleanup a _.template unit test.
Former-commit-id: 351e4ae8b346a69a795c6d2bfe6a55b306515af6
2012-12-02 21:19:34 -08:00
John-David Dalton
8b0f033a78 Update vendor/underscore.
Former-commit-id: 8bb0b59d367ab2600a85a4442789eb41d9d97cb6
2012-12-02 21:18:46 -08:00
John-David Dalton
f58f255fc8 Make the custom build message work with -rc.1 and fix build.
Former-commit-id: 96f31fff906fa978a0d10fad90d9322c761e1d26
2012-12-02 02:21:55 -08:00
John-David Dalton
e3eabcf648 Fix isBindFast and isKeysFast.
Former-commit-id: 59e6cfa0669f28139a7036a172995d7f7f8a64ef
2012-12-02 00:01:29 -08:00
John-David Dalton
9aa506cbd7 Cleanup build.js.
Former-commit-id: 91bb957cef2efd3aefd3c196374841efbd3ffd1d
2012-12-01 23:32:26 -08:00
John-David Dalton
d8cff7b90f Remove script injection and simplify createFunction.
Former-commit-id: cc466c8ea05210b2238ee72a624628c7454eb1ee
2012-12-01 23:32:02 -08:00
John-David Dalton
07e7bca9eb Merge branch 'master' of github.com:bestiejs/lodash
Former-commit-id: a1f2773afba4c885385e601e656c6ee461a6fb24
2012-12-01 18:49:46 -08:00
John-David Dalton
e1f442be90 Ensure Lo-Dash works in the JS engine embedded in Adobe products.
Former-commit-id: 860665d3735aef1dff75149b49b78c1615f38fa0
2012-12-01 18:47:38 -08:00
John-David Dalton
c5d579e0e3 Update vendors, minified files, and docs.
Former-commit-id: b29e9f8a497153408ba6266bf44412004e63c1af
2012-12-01 17:16:50 -08:00
John-David Dalton
5271c2e08f Update vendors, minified files, and docs.
Former-commit-id: 018dfcade1386aa84492f60c8404ea00c01cbe11
2012-12-01 13:24:40 -08:00
John-David Dalton
9010a7ddbc Fix typo in _.toArray and tweak _.forEach documentation.
Former-commit-id: 6417e50be9381a4ecede54868a9c2c41dabca4f2
2012-12-01 13:23:15 -08:00
John-David Dalton
bb95fb7d07 Reduce _.pluck.
Former-commit-id: 91db56f95d258070a0d25e4e4b74917e52b8cefe
2012-12-01 10:47:00 -08:00
John-David Dalton
2edb11376d Avoid script injection unless the JS engine is inferred to be Firefox's.
Former-commit-id: 1e267374fe85a858197609b35b85670394c0b66d
2012-12-01 01:08:38 -08:00
John-David Dalton
e7f5ebf912 Rebuild minified files and docs.
Former-commit-id: 18a7f085459a08c6440be3e14d3f663fa181032d
2012-11-30 23:17:00 -08:00
John-David Dalton
da9758c2f3 Ensure bound result of _.bind(func, …) is an instance of bound and func.
Former-commit-id: d8176ad5eb45a3d675617676fc1eee4d9cbd6ebc
2012-11-30 23:16:39 -08:00
John-David Dalton
3e11d58d73 Ensure _.toArray returns a dence array.
Former-commit-id: 534091d4d200208b8aa831d86801d5e9d73410fe
2012-11-30 22:51:15 -08:00
John-David Dalton
6b35c097d6 Make deep _.clone copy array properties assigned by RegExp#exec.
Former-commit-id: b465457babfc04e8204048dfaeff6e5d37e5e43c
2012-11-30 00:40:32 -08:00
John-David Dalton
619ba13265 Make _.uniqueId consistently return a string value.
Former-commit-id: 5a5c626df83b0fc78e9bae37510680383f112c0b
2012-11-29 22:38:15 -08:00
John-David Dalton
529c5b8abf Use forIn in _.isEqual instead of forOwn.
Former-commit-id: dd057e421be029d67cd293b733ee1cfee2b7715f
2012-11-29 20:57:13 -08:00
John-David Dalton
3a5ed6e800 Ensure revised _.isEqual works correctly in Underscore build.
Former-commit-id: 24c01405f08f8925bfe473d5d7e9ad0a270382b6
2012-11-29 08:54:33 -08:00
John-David Dalton
52cddc015b Make _.clone follow the structured cloning algorithm's behavior for cloning objects created by constructors other than Object and make _.isEqual equate objects to arguments objects.
Former-commit-id: a387c6444694d8d550ab463ea5290088d3356d8b
2012-11-29 02:04:16 -08:00
John-David Dalton
4a01f4f65f Update vendor/underscore.js
Former-commit-id: d74b9331b5547cfde6c04bd1b915e983187b2ec0
2012-11-27 19:25:55 -08:00
John-David Dalton
f9768cb5a3 Use typeof x == 'undefined' checks instead of x === undefined for consistency with other typeof checks.
Former-commit-id: 8ab7d3efe54aa7017b52295b0598b75c297a6277
2012-11-26 09:24:51 -06:00
John-David Dalton
221e0e550c Optimize _.forEach, _.forIn, and _.forOwn.
Former-commit-id: 5d3b83ec0d5240ee14a86421994de86f311089fd
2012-11-24 23:21:30 -06:00
John-David Dalton
d2d1d42d0f Optimize _.isNumber and _.isString. [closes #126]
Former-commit-id: 633dfe2e9c2c0ff7e54d5bbb4bf95f9adcca83c4
2012-11-24 09:46:20 -06:00
John-David Dalton
faf018a097 Rebuild minified files and docs.
Former-commit-id: b3e87e12dfa55dcaa813d31b2ef0749a83b652aa
2012-11-24 01:49:56 -06:00
John-David Dalton
a2a71a107e Fix onerror typo.
Former-commit-id: 61ba70537963824f396496cc59e7cfac1e9f8c8a
2012-11-24 01:36:18 -06:00
John-David Dalton
fc9c937e67 Simplify iteratorTemplate and support for minifying double quoted strings in source.
Former-commit-id: d18cbd6dc380001fe3617f6891c84a794a13c8d1
2012-11-24 01:34:00 -06:00
John-David Dalton
b4f2e9b442 Fix build.
Former-commit-id: dba1a3fa7526001d0062dc6e0b44f3c6e3d3d8db
2012-11-23 13:26:12 -06:00
John-David Dalton
1672645e73 Avoid engine slow path for primitives in _(…). [closes #123]
Former-commit-id: 32e33b0c0d192915e6d5a83001b85645829ca0ab
2012-11-23 10:19:10 -06:00
John-David Dalton
4a42c44101 Use createFunction in _.template.
Former-commit-id: c996d94c7002bf4a89092b9cf7f4e5e80f70d9fd
2012-11-23 10:05:15 -06:00
John-David Dalton
383b1a5769 Avoid Firefox's unoptimized Function constructor.
Former-commit-id: 7cc5fc63c0cebd1410edde47c88e580c64fa2b98
2012-11-23 01:14:44 -06:00
John-David Dalton
77bac4cf9e Narrow the scope of regexes used in build.js to the functions they relate to.
Former-commit-id: 6d838b24778d5e2107f4f5b25613ae40f363e969
2012-11-20 16:20:06 -06:00
John-David Dalton
e2b8e530c9 Merge pull request #119 from bestiejs/no-chain
Make `_(...)` wrapped values chainable without the need to call `chain`

Former-commit-id: 2e133540c0bedb41440bab592f1bacb75d426687
2012-11-20 07:52:11 -08:00
John-David Dalton
e9f752bd67 Merge /master into /no-chain
Former-commit-id: 59e5a4b13eb8bddd39bd37d917344715d62bf385
2012-11-20 07:47:48 -08:00
John-David Dalton
4b31921eb4 Rebuild minified files and docs.
Former-commit-id: 9565bb8c27577b72cf42d79cc7a1569a496d8bdc
2012-11-20 07:44:25 -08:00
John-David Dalton
3df9fc6225 Ensure _.reduce and _.reduceRight pass the correct number of callback arguments.
Former-commit-id: fec2d28b5a69ceb590e0ef1d8a0792b25b53c7e9
2012-11-20 07:43:09 -08:00
John-David Dalton
b57fe466ce Make _(…) wrapper versions of _.first and _.last capable of returning wrapped and unwrapped values.
Former-commit-id: b30704c1ce359213aa09069b290ee55edfb3e33e
2012-11-20 07:32:51 -08:00
John-David Dalton
bd4bff3b6b Add lodash.prototype methods that return non-wrapped values.
Former-commit-id: b7ecb8c91ec9647827a80a297b966639c6580ef0
2012-11-19 23:02:35 -08:00
John-David Dalton
9d4618a223 Merge /master into /no-chain
Former-commit-id: fcef4ca54be1907762e92ee528b650bea9759c1d
2012-11-19 21:52:25 -08:00
John-David Dalton
93636180df Fallback to the local npm install if there are problems resolving the npm -g root path. [closes #122]
Former-commit-id: 1cbf807877e51198853950e5ebd1b49a6e20d123
2012-11-19 21:42:54 -08:00
John-David Dalton
fcceaa168f Update v0.10.0 changelog in README.md.
Former-commit-id: daf4501ee97420d93bb02d7c1dfd5498d6618bb9
2012-11-19 21:12:57 -08:00
John-David Dalton
2639cc6138 Update vendors.
Former-commit-id: e109c9ffd436610d066493b07bd38293e1ec01a7
2012-11-19 20:54:23 -08:00
John-David Dalton
4a99c2e928 Add support for NodeLists in _.toArray for IE < 9.
Former-commit-id: 67b26fe6fe60d77c0b38c48865bfd2ca56f7b470
2012-11-19 20:47:16 -08:00
John-David Dalton
7d5af3df05 Remove deprecated indicators from _.isFinite, _.isNaN, _.isNull, _.isUndefined, and _.result docs. [ci skip]
Former-commit-id: 39a6e1a4a948469993afb90c6303f1f6faa661fd
2012-11-18 22:37:47 -08:00
John-David Dalton
c88b80d2a0 Add documentation note to _#chain. [ci skip]
Former-commit-id: 90b50a50b6b104cd9e2bbccc4412346dfd6a6bba
2012-11-18 22:35:23 -08:00
John-David Dalton
819d4abaa2 Add _#toString and _#valueOf.
Former-commit-id: adb194b6270fc72f794c69343891a2e891b90051
2012-11-18 21:50:41 -08:00
John-David Dalton
20630aeb47 Remove the need to call chain on _(…) wrapped values.
Former-commit-id: 21861c88e3ec9af955d844c025b50cb32c322809
2012-11-18 21:06:24 -08:00
John-David Dalton
0c0db3babb Remove deprecated indicators from _.isFinite, _.isNaN, _.isNull, _.isUndefined, and _.result docs. [ci skip]
Former-commit-id: 597001cfe5ef71d40b3254344eb5dbbe9905430a
2012-11-18 15:41:07 -08:00
John-David Dalton
e7761f7e57 Minor cleanup to README.md.
Former-commit-id: a4ded5a5b2f41016fad5e4c7491dd96704e9d69a
2012-11-18 14:38:04 -08:00
26 changed files with 5352 additions and 901 deletions

View File

@@ -1,17 +1,25 @@
# Lo-Dash <sup>v0.10.0</sup>
# Lo-Dash <sup>v1.0.0-rc.1</sup>
[![build status](https://secure.travis-ci.org/bestiejs/lodash.png)](http://travis-ci.org/bestiejs/lodash)
A drop-in replacement<sup>[*](https://github.com/bestiejs/lodash/wiki/Drop-in-Disclaimer)</sup> for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), delivering [performance](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#resolved-underscorejs-issues), and [additional features](http://lodash.com/#features).
Lo-Dashs performance is gained by avoiding slower native methods, instead opting for simplified non-ES5 compliant methods optimized for common usage, and by leveraging function compilation to reduce the number of overall function calls.
A utility library, usable as a drop-in replacement for Underscore, delivering [performance](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#resolved-underscorejs-issues), and [additional features](http://lodash.com/#features).
## Download
* [Development build](https://raw.github.com/bestiejs/lodash/v0.10.0/lodash.js)
* [Production build](https://raw.github.com/bestiejs/lodash/v0.10.0/lodash.min.js)
* [Underscore build](https://raw.github.com/bestiejs/lodash/v0.10.0/lodash.underscore.min.js) tailored for projects already using Underscore
* CDN copies of ≤ v0.10.0s [Production](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.10.0/lodash.min.js), [Underscore](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.10.0/lodash.underscore.min.js), and [Development](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.10.0/lodash.js) builds are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/)
* For optimal file size, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
* Lo-Dash builds:<br>
[Development](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.1/lodash.js) and
[Production](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.1/lodash.min.js)
* Underscore builds:<br>
[Development](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.1/lodash.underscore.js) and
[Production](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.1/lodash.underscore.min.js)
* CDN copies of ≤ v1.0.0-rc.1s builds are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/):<br>
[Lo-Dash development](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.1/lodash.js),
[Lo-Dash production](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.1/lodash.min.js),
[Underscore development](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.1/lodash.underscore.js), and
[Underscore production](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.1/lodash.underscore.min.js)
* For optimal file size, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
## Dive in
@@ -35,23 +43,23 @@ For more information check out these screencasts over Lo-Dash:
## Features
* AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
* [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”* defined](http://michaux.ca/articles/lazy-function-definition-pattern) methods
* [_.clone](http://lodash.com/docs#clone) supports *“deep”* cloning
* [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` argument
* [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an objects own and inherited properties
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an objects own properties
* [_.isPlainObject](http://lodash.com/docs#isPlainObject) checks if values are created by the `Object` constructor
* [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”* defined](http://michaux.ca/articles/lazy-function-definition-pattern) methods
* [_.merge](http://lodash.com/docs#merge) for a *“deep”* [_.extend](http://lodash.com/docs#extend)
* [_.partial](http://lodash.com/docs#partial) for partial application without `this` binding
* [_.pick](http://lodash.com/docs#pick) and [_.omit](http://lodash.com/docs#omit) accepts `callback` and `thisArg` arguments
* [_.template](http://lodash.com/docs#template) supports [ES6 delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6) and utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
* [_.template](http://lodash.com/docs#template) supports [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6) and utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
* [_.contains](http://lodash.com/docs#contains), [_.size](http://lodash.com/docs#size), [_.toArray](http://lodash.com/docs#toArray),
[and more…](http://lodash.com/docs "_.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.some, _.sortBy, _.where") accept strings
## Support
Lo-Dash has been tested in at least Chrome 5~23, Firefox 1~16, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.14, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
Lo-Dash has been tested in at least Chrome 5~23, Firefox 1~16, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.15, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
## Custom builds
@@ -185,9 +193,12 @@ In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
```js
var _ = require('lodash');
// or as a drop-in replacement for Underscore
var _ = require('lodash/lodash.underscore');
```
**Note:** If Lo-Dash is installed globally, [run `npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your projects root directory before requiring it.
**Note:** If Lo-Dash is installed globally, run [`npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your projects root directory before requiring it.
In [RingoJS v0.7.0-](http://ringojs.org/):
@@ -216,34 +227,34 @@ require({
## Resolved Underscore.js issues
* Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/bestiejs/lodash/blob/v0.10.0/test/test.js#L590-L596)]
* Fix cross-browser object iteration bugs [[#60](https://github.com/documentcloud/underscore/issues/60), [#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/v0.10.0/test/test.js#L603-L627)]
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [#742](https://github.com/documentcloud/underscore/issues/742), [test](https://github.com/bestiejs/lodash/blob/v0.10.0/test/test.js#L140-L146)]
* `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v0.10.0/test/test.js#L792-L797)]
* `_.isObject` should avoid V8 bug [#2291](http://code.google.com/p/v8/issues/detail?id=2291) [[#605](https://github.com/documentcloud/underscore/issues/605), [test](https://github.com/bestiejs/lodash/blob/v0.10.0/test/test.js#L873-L885)]
* `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/bestiejs/lodash/blob/v0.10.0/test/test.js#L966-L968)]
* `_.range` should coerce arguments to numbers [[#634](https://github.com/documentcloud/underscore/issues/634), [#683](https://github.com/documentcloud/underscore/issues/683), [test](https://github.com/bestiejs/lodash/blob/v0.10.0/test/test.js#L1367-L1370)]
* Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.1/test/test.js#L605-L611)]
* Fix cross-browser object iteration bugs [[#60](https://github.com/documentcloud/underscore/issues/60), [#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.1/test/test.js#L618-L642)]
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [#742](https://github.com/documentcloud/underscore/issues/742), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.1/test/test.js#L140-L146)]
* `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.1/test/test.js#L807-L812)]
* `_.isObject` should avoid V8 bug [#2291](http://code.google.com/p/v8/issues/detail?id=2291) [[#605](https://github.com/documentcloud/underscore/issues/605), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.1/test/test.js#L888-L900)]
* `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.1/test/test.js#L981-L983)]
* `_.range` should coerce arguments to numbers [[#634](https://github.com/documentcloud/underscore/issues/634), [#683](https://github.com/documentcloud/underscore/issues/683), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.1/test/test.js#L1382-L1385)]
## Release Notes
### <sup>v0.10.0</sup>
### <sup>v1.0.0-rc.1</sup>
#### Compatibility Warnings ####
* Aligned `_.defaults` and `_.extend` with ES6 [Object.assign](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.2.3.15)
* Renamed `_.lateBind` to `_.bindKey`
* Made `_(…)` chain automatically without needing to call `_#chain`
* Made `_.isEqual` equate `arguments` objects to similar `Object` objects
* Made `_.clone` copy the enumerable properties of `arguments` objects and objects<br>
created by constructors other than `Object` are cloned to plain `Object` objects
#### Changes ####
* Added the build commands used to custom build copyright/license headers
* Added `_.assign`
* Ensured the `underscore` build of `_.find` returns the first, not last, matched value
* Ensured `_defaults`, `_.extends`, and `_.merge` works with `_.reduce`
* Made Lo-Dashs `npm` package installation work with more system configurations
* Made `_.extend` an alias of `_.assign`
* Optimized `_.contains`, `_.defaults`, `_.extend`, and `_.filter`
* Restricted `_.where` to iterate only own properties of the `source` object
* Updated `backbone` build Lo-Dash method dependencies
* Ensure Lo-Dash runs in the JS engine embedded in Adobe products
* Ensured `_.reduce` and `_.reduceRight` pass the correct number of `callback` arguments
* Ensured `_.throttle` nulls the `timeoutId`
* Made deep `_.clone` more closely follow the structured clone algorithm and copy array properties assigned by `RegExp#exec`
* Optimized compiled templates in Firefox
* Optimized `_.forEach`, `_.forOwn`, `_.isNumber`, and `_.isString`
* Simplified `iteratorTemplate`
The full changelog is available [here](https://github.com/bestiejs/lodash/wiki/Changelog).

581
build.js
View File

@@ -71,7 +71,7 @@
'bindAll': ['bind', 'functions'],
'bindKey': ['isFunction', 'isObject'],
'chain': ['mixin'],
'clone': ['assign', 'forEach', 'forOwn', 'isArguments', 'isObject', 'isPlainObject'],
'clone': ['assign', 'forEach', 'forOwn', 'isArray', 'isObject'],
'compact': [],
'compose': [],
'contains': ['forEach', 'indexOf', 'isString'],
@@ -87,7 +87,7 @@
'find': ['forEach'],
'first': [],
'flatten': ['isArray'],
'forEach': ['identity', 'isString'],
'forEach': ['identity', 'isArguments', 'isString'],
'forIn': ['identity', 'isArguments'],
'forOwn': ['identity', 'isArguments'],
'functions': ['forIn', 'isFunction'],
@@ -105,10 +105,10 @@
'isDate': [],
'isElement': [],
'isEmpty': ['forOwn', 'isArguments', 'isFunction'],
'isEqual': ['isArguments', 'isFunction'],
'isEqual': ['forIn', 'isArguments', 'isFunction'],
'isFinite': [],
'isFunction': [],
'isNaN': [],
'isNaN': ['isNumber'],
'isNull': [],
'isNumber': [],
'isObject': [],
@@ -124,7 +124,7 @@
'memoize': [],
'merge': ['forOwn', 'isArray', 'isPlainObject'],
'min': ['forEach', 'isArray', 'isString'],
'mixin': ['forEach', 'functions'],
'mixin': ['filter', 'forEach', 'functions'],
'noConflict': [],
'object': [],
'omit': ['forIn', 'indexOf'],
@@ -132,7 +132,7 @@
'pairs': ['forOwn'],
'partial': ['isFunction', 'isObject'],
'pick': ['forIn'],
'pluck': ['forEach'],
'pluck': ['map'],
'random': [],
'range': [],
'reduce': ['forEach'],
@@ -149,7 +149,7 @@
'template': ['escape'],
'throttle': [],
'times': [],
'toArray': ['values'],
'toArray': ['isString', 'values'],
'unescape': [],
'union': ['uniq'],
'uniq': ['identity', 'indexOf'],
@@ -263,7 +263,7 @@
* @returns {String} Returns the modified source.
*/
function addCommandsToHeader(source, commands) {
return source.replace(/(\/\*!\n)( \*)?( *Lo-Dash [0-9.]+)(.*)/, function() {
return source.replace(/(\/\*!\n)( \*)?( *Lo-Dash [\w.-]+)(.*)/, function() {
// convert unmatched groups to empty strings
var parts = _.map(slice.call(arguments, 1), function(part) {
return part || '';
@@ -329,7 +329,7 @@
precompiled = getFunctionSource(_.template(text, null, options)),
prop = filename.replace(/\..*$/, '');
source.push(" templates['" + prop.replace(/'/g, "\\'") + "'] = " + precompiled + ';', '');
source.push(" templates['" + prop.replace(/['\n\r\t]/g, '\\$&') + "'] = " + precompiled + ';', '');
}
});
@@ -476,7 +476,7 @@
return [];
}
// recursively accumulate the dependencies of the `methodName` function, and
// the dependencies of its dependencies, and so on.
// the dependencies of its dependencies, and so on
return _.uniq(dependencies.reduce(function(result, otherName) {
result.push.apply(result, getDependencies(otherName).concat(otherName));
return result;
@@ -524,6 +524,17 @@
return (source.match(/(?:\s*\/\/.*)*\n( *)if *\(isFunction\(\/x\/[\s\S]+?};\n\1}/) || [''])[0];
}
/**
* Gets the `iteratorTemplate` from `source`.
*
* @private
* @param {String} source The source to inspect.
* @returns {String} Returns the `iteratorTemplate`.
*/
function getIteratorTemplate(source) {
return (source.match(/^( *)var iteratorTemplate *= *[\s\S]+?\n\1.+?;\n/m) || [''])[0];
}
/**
* Gets the names of methods in `source` belonging to the given `category`.
*
@@ -626,6 +637,20 @@
return _.uniq(_.intersection(allMethods, methodNames));
}
/**
* Removes the `createFunction` function from `source`.
*
* @private
* @param {String} source The source to process.
* @returns {String} Returns the modified source.
*/
function removeCreateFunction(source) {
source = removeVar(source, 'isFirefox');
return removeFunction(source, 'createFunction')
.replace(/createFunction/g, 'Function')
.replace(/(?:\s*\/\/.*)*\s*if *\(isIeOpera[^}]+}\n/, '');
}
/**
* Removes the all references to `refName` from `createIterator` in `source`.
*
@@ -652,13 +677,11 @@
* @private
* @param {String} source The source to process.
* @param {String} funcName The name of the function to remove.
* @returns {String} Returns the source with the function removed.
* @returns {String} Returns the modified source.
*/
function removeFunction(source, funcName) {
var modified,
snippet = matchFunction(source, funcName);
// remove function
var snippet = matchFunction(source, funcName);
if (snippet) {
source = source.replace(snippet, '');
}
@@ -666,7 +689,7 @@
snippet = getMethodAssignments(source);
// remove assignment and aliases
modified = getAliases(funcName).concat(funcName).reduce(function(result, otherName) {
var modified = getAliases(funcName).concat(funcName).reduce(function(result, otherName) {
return result.replace(RegExp('(?:\\n *//.*\\s*)* *lodash\\.' + otherName + ' *= *.+\\n'), '');
}, snippet);
@@ -681,7 +704,7 @@
*
* @private
* @param {String} source The source to process.
* @returns {String} Returns the source with the `isArguments` fallback removed.
* @returns {String} Returns the modified source.
*/
function removeIsArgumentsFallback(source) {
return source.replace(getIsArgumentsFallback(source), '');
@@ -692,7 +715,7 @@
*
* @private
* @param {String} source The source to process.
* @returns {String} Returns the source with the `isFunction` fallback removed.
* @returns {String} Returns the modified source.
*/
function removeIsFunctionFallback(source) {
return source.replace(getIsFunctionFallback(source), '');
@@ -706,11 +729,19 @@
* @returns {String} Returns the modified source.
*/
function removeKeysOptimization(source) {
return removeVar(source, 'isKeysFast')
// remove optimized branch in `iteratorTemplate`
.replace(/(?: *\/\/.*\n)* *'( *)<% *if *\(isKeysFast[\s\S]+?'\1<% *} *else *\{ *%>.+\n([\s\S]+?) *'\1<% *} *%>.+/, "'\\n' +\n$2")
// remove data object property assignment in `createIterator`
.replace(/ *'isKeysFast':.+\n/, '');
source = removeVar(source, 'isKeysFast');
// remove optimized branch in `iteratorTemplate`
source = source.replace(getIteratorTemplate(source), function(match) {
return match.replace(/(?: *\/\/.*\n)* *["']( *)<% *if *\(isKeysFast[\s\S]+?["']\1<% *} *else *\{ *%>.+\n([\s\S]+?) *["']\1<% *} *%>.+/, "'\\n' +\n$2");
});
// remove data object property assignment in `createIterator`
source = source.replace(matchFunction(source, 'createIterator'), function(match) {
return match.replace(/ *'isKeysFast':.+\n/, '');
});
return source;
}
/**
@@ -721,11 +752,19 @@
* @returns {String} Returns the modified source.
*/
function removeNoArgsClass(source) {
return removeVar(source, 'noArgsClass')
// remove `noArgsClass` from `_.clone` and `_.isEqual`
.replace(/ *\|\| *\(noArgsClass *&&[^)]+?\)\)/g, '')
// remove `noArgsClass` from `_.isEqual`
.replace(/if *\(noArgsClass[^}]+?}\n/, '\n');
source = removeVar(source, 'noArgsClass');
// remove `noArgsClass` from `_.isEmpty`
source = source.replace(matchFunction(source, 'isEmpty'), function(match) {
return match.replace(/ *\|\| *\(noArgsClass *&&[^)]+?\)\)/g, '');
});
// remove `noArgsClass` from `_.isEqual`
source = source.replace(matchFunction(source, 'isEqual'), function(match) {
return match.replace(/noArgsClass[^:]+:\s*/g, '');
});
return source;
}
/**
@@ -736,13 +775,25 @@
* @returns {String} Returns the modified source.
*/
function removeNoNodeClass(source) {
return source
// remove `noNodeClass` assignment
.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var noNodeClass[\s\S]+?catch[^}]+}\n/, '')
// remove `noNodeClass` from `isPlainObject`
.replace(/\(!noNodeClass *\|\|[\s\S]+?\)\) *&&/, '')
// remove `noNodeClass` from `_.isEqual`
.replace(/ *\|\| *\(noNodeClass *&&[\s\S]+?\)\)\)/, '');
// remove `noNodeClass` assignment
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var noNodeClass[\s\S]+?catch[^}]+}\n/, '');
// remove `noNodeClass` from `shimIsPlainObject`
source = source.replace(matchFunction(source, 'shimIsPlainObject'), function(match) {
return match.replace(/ *&& *\(!noNodeClass[\s\S]+?\)\)/, '');
});
// remove `noNodeClass` from `_.clone`
source = source.replace(matchFunction(source, 'clone'), function(match) {
return match.replace(/ *\|\| *\(noNodeClass[\s\S]+?\)\)/, '');
});
// remove `noNodeClass` from `_.isEqual`
source = source.replace(matchFunction(source, 'isEqual'), function(match) {
return match.replace(/ *\|\| *\(noNodeClass[\s\S]+?\)\)\)/, '');
});
return source;
}
/**
@@ -751,16 +802,12 @@
* @private
* @param {String} source The source to process.
* @param {String} varName The name of the variable to remove.
* @returns {String} Returns the source with the variable removed.
* @returns {String} Returns the modified source.
*/
function removeVar(source, varName) {
// simplify `cloneableClasses`
if (varName == 'cloneableClasses') {
source = source.replace(/(var cloneableClasses *=)[\s\S]+?(true;\n)/, '$1$2');
}
// simplify `hasObjectSpliceBug`
if (varName == 'hasObjectSpliceBug') {
source = source.replace(/(var hasObjectSpliceBug *=)[^;]+/, '$1false');
// simplify `cloneableClasses`, `ctorByClass`, or `hasObjectSpliceBug`
if (/^(?:cloneableClasses|ctorByClass|hasObjectSpliceBug)$/.test(varName)) {
source = source.replace(RegExp('(var ' + varName + ' *=)[\\s\\S]+?\\n\\n'), '$1=null;\n\n');
}
source = source.replace(RegExp(
// match multi-line comment block
@@ -777,35 +824,57 @@
// remove a variable at the end of a variable declaration list
source = source.replace(RegExp(',\\s*' + varName + ' *=.+?;'), ';');
// remove variable reference from `cloneableClasses` assignments
source = source.replace(RegExp('cloneableClasses\\[' + varName + '\\] *= *(?:false|true)?', 'g'), '');
return removeFromCreateIterator(source, varName);
}
/**
* Searches `source` for a `varName` variable declaration and replaces its
* assigned value with `varValue`.
* Replaces the `funcName` function body in `source` with `funcValue`.
*
* @private
* @param {String} source The source to inspect.
* @param {String} varName The name of the function to replace.
* @returns {String} Returns the modified source.
*/
function replaceFunction(source, funcName, funcValue) {
var match = matchFunction(source, funcName);
if (match) {
// clip snippet after the JSDoc comment block
match = match.replace(/^\s*(?:\/\/.*|\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)\n/, '');
source = source.replace(match, function() {
return funcValue;
});
}
return source;
}
/**
* Replaces the `varName` variable declaration value in `source` with `varValue`.
*
* @private
* @param {String} source The source to inspect.
* @param {String} varName The name of the variable to replace.
* @returns {String} Returns the source with the variable replaced.
* @returns {String} Returns the modified source.
*/
function replaceVar(source, varName, varValue) {
// replace a variable that's not part of a declaration list
var result = source.replace(RegExp(
'(( *)var ' + varName + ' *= *)' +
'(?:.+?;|(?:Function\\(.+?|.*?[^,])\\n[\\s\\S]+?\\n\\2.+?;)\\n'
), '$1' + varValue + ';\n');
), function(match, captured) {
return captured + varValue + ';\n';
});
if (source == result) {
// replace a varaible at the start or middle of a declaration list
result = source.replace(RegExp('((?:var|\\n) +' + varName + ' *=).+?,'), '$1 ' + varValue + ',');
result = source.replace(RegExp('((?:var|\\n) +' + varName + ' *=).+?,'), function(match, captured) {
return captured + ' ' + varValue + ',';
});
}
if (source == result) {
// replace a variable at the end of a variable declaration list
result = source.replace(RegExp('(,\\s*' + varName + ' *=).+?;'), '$1 ' + varValue + ';');
result = source.replace(RegExp('(,\\s*' + varName + ' *=).+?;'), function(match, captured) {
return captured + ' ' + varValue + ';';
});
}
return result;
}
@@ -823,8 +892,12 @@
if (value) {
source = source.replace(/^[\s\S]*?function[^{]+{/, "$&\n 'use strict';");
}
// replace `useStrict` branch in `value` with hard-coded option
return source.replace(/(?: *\/\/.*\n)*(\s*)' *<%.+?useStrict.+/, value ? "$1'\\'use strict\\';\\n' +" : '');
// replace `useStrict` branch in `iteratorTemplate` with hard-coded option
source = source.replace(getIteratorTemplate(source), function(match) {
return match.replace(/(?: *\/\/.*\n)*(\s*)["'] *<%.+?useStrict.+/, value ? '$1"\'use strict\';\\n" +' : '');
});
return source;
}
/*--------------------------------------------------------------------------*/
@@ -855,6 +928,7 @@
'csp',
'legacy',
'mobile',
'modularize',
'strict',
'underscore',
'-c', '--stdout',
@@ -926,6 +1000,9 @@
// flag used to specify a mobile build
var isMobile = !isLegacy && (isCSP || isUnderscore || options.indexOf('mobile') > -1);
// flag used to specify a modularize build
var isModularize = options.indexOf('modularize') > -1;
// flag used to specify writing output to standard output
var isStdOut = options.indexOf('-c') > -1 || options.indexOf('--stdout') > -1;
@@ -1098,58 +1175,14 @@
else if (isUnderscore) {
// remove unneeded variables
source = removeVar(source, 'cloneableClasses');
source = removeVar(source, 'ctorByClass');
// remove large array optimizations
source = removeFunction(source, 'cachedContains');
source = removeVar(source, 'largeArraySize');
// replace `_.clone`
if (useUnderscoreClone) {
source = source.replace(/^( *)function clone[\s\S]+?\n\1}/m, [
' function clone(value) {',
' return value && objectTypes[typeof value]',
' ? (isArray(value) ? slice.call(value) : assign({}, value))',
' : value',
' }'
].join('\n'));
}
// replace `_.contains`
source = source.replace(/^( *)function contains[\s\S]+?\n\1}/m, [
' function contains(collection, target) {',
' var length = collection ? collection.length : 0,',
' result = false;',
" if (typeof length == 'number') {",
' result = indexOf(collection, target) > -1;',
' } else {',
' forEach(collection, function(value) {',
' return (result = value === target) && indicatorObject;',
' });',
' }',
' return result;',
' }'
].join('\n'));
// replace `_.difference`
source = source.replace(/^( *)function difference[\s\S]+?\n\1}/m, [
' function difference(array) {',
' var index = -1,',
' length = array.length,',
' flattened = concat.apply(arrayRef, arguments),',
' result = [];',
'',
' while (++index < length) {',
' var value = array[index]',
' if (indexOf(flattened, value, length) < 0) {',
' result.push(value);',
' }',
' }',
' return result',
' }'
].join('\n'));
// replace `_.assign`
source = source.replace(/^( *)var assign *= *createIterator[\s\S]+?\);/m, [
source = replaceFunction(source, 'assign', [
' function assign(object) {',
' if (!object) {',
' return object;',
@@ -1166,8 +1199,44 @@
' }'
].join('\n'));
// replace `_.chain`
source = replaceFunction(source, 'chain', [
' function chain(value) {',
' value = new lodash(value);',
' value.__chain__ = true;',
' return value;',
' }'
].join('\n'));
// replace `_.clone`
if (useUnderscoreClone) {
source = replaceFunction(source, 'clone', [
' function clone(value) {',
' return value && objectTypes[typeof value]',
' ? (isArray(value) ? slice(value) : assign({}, value))',
' : value',
' }'
].join('\n'));
}
// replace `_.contains`
source = replaceFunction(source, 'contains', [
' function contains(collection, target) {',
' var length = collection ? collection.length : 0,',
' result = false;',
" if (typeof length == 'number') {",
' result = indexOf(collection, target) > -1;',
' } else {',
' forEach(collection, function(value) {',
' return (result = value === target) && indicatorObject;',
' });',
' }',
' return result;',
' }'
].join('\n'));
// replace `_.defaults`
source = source.replace(/^( *)var defaults *= *createIterator[\s\S]+?\);/m, [
source = replaceFunction(source, 'defaults', [
' function defaults(object) {',
' if (!object) {',
' return object;',
@@ -1186,8 +1255,26 @@
' }'
].join('\n'));
// replace `_.difference`
source = replaceFunction(source, 'difference', [
' function difference(array) {',
' var index = -1,',
' length = array.length,',
' flattened = concat.apply(arrayRef, arguments),',
' result = [];',
'',
' while (++index < length) {',
' var value = array[index]',
' if (indexOf(flattened, value, length) < 0) {',
' result.push(value);',
' }',
' }',
' return result',
' }'
].join('\n'));
// replace `_.intersection`
source = source.replace(/^( *)function intersection[\s\S]+?\n\1}/m, [
source = replaceFunction(source, 'intersection', [
' function intersection(array) {',
' var args = arguments,',
' argsLength = args.length,',
@@ -1209,7 +1296,7 @@
].join('\n'));
// replace `_.isEmpty`
source = source.replace(/^( *)function isEmpty[\s\S]+?\n\1}/m, [
source = replaceFunction(source, 'isEmpty', [
' function isEmpty(value) {',
' if (!value) {',
' return true;',
@@ -1227,14 +1314,14 @@
].join('\n'));
// replace `_.isFinite`
source = source.replace(/^( *)function isFinite[\s\S]+?\n\1}/m, [
source = replaceFunction(source, 'isFinite', [
' function isFinite(value) {',
' return nativeIsFinite(value) && toString.call(value) == numberClass;',
' }'
].join('\n'));
// replace `_.omit`
source = source.replace(/^( *)function omit[\s\S]+?\n\1}/m, [
source = replaceFunction(source, 'omit', [
' function omit(object) {',
' var props = concat.apply(arrayRef, arguments),',
' result = {};',
@@ -1249,7 +1336,7 @@
].join('\n'));
// replace `_.pick`
source = source.replace(/^( *)function pick[\s\S]+?\n\1}/m, [
source = replaceFunction(source, 'pick', [
' function pick(object) {',
' var index = 0,',
' props = concat.apply(arrayRef, arguments),',
@@ -1267,60 +1354,58 @@
].join('\n'));
// replace `_.template`
source = source.replace(/^( *)function template[\s\S]+?\n\1}/m, function() {
return [
' function template(text, data, options) {',
" text || (text = '');",
' options = defaults({}, options, lodash.templateSettings);',
'',
' var index = 0,',
' source = "__p += \'",',
' variable = options.variable;',
'',
' var reDelimiters = RegExp(',
" (options.escape || reNoMatch).source + '|' +",
" (options.interpolate || reNoMatch).source + '|' +",
" (options.evaluate || reNoMatch).source + '|$'",
" , 'g');",
'',
' text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) {',
' source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);',
' source +=',
' escapeValue ? "\' +\\n_.escape(" + escapeValue + ") +\\n\'" :',
' evaluateValue ? "\';\\n" + evaluateValue + ";\\n__p += \'" :',
' interpolateValue ? "\' +\\n((__t = (" + interpolateValue + ")) == null ? \'\' : __t) +\\n\'" : \'\';',
'',
' index = offset + match.length;',
' });',
'',
' source += "\';\\n";',
' if (!variable) {',
" variable = 'obj';",
" source = 'with (' + variable + ' || {}) {\\n' + source + '\\n}\\n';",
' }',
" source = 'function(' + variable + ') {\\n' +",
" 'var __t, __p = \\'\\', __j = Array.prototype.join;\\n' +",
" 'function print() { __p += __j.call(arguments, \\'\\') }\\n' +",
' source +',
" 'return __p\\n}';",
'',
' try {',
" var result = Function('_', 'return ' + source)(lodash);",
' } catch(e) {',
' e.source = source;',
' throw e;',
' }',
' if (data) {',
' return result(data);',
' }',
' result.source = source;',
' return result;',
' }'
].join('\n');
});
source = replaceFunction(source, 'template', [
' function template(text, data, options) {',
" text || (text = '');",
' options = defaults({}, options, lodash.templateSettings);',
'',
' var index = 0,',
' source = "__p += \'",',
' variable = options.variable;',
'',
' var reDelimiters = RegExp(',
" (options.escape || reNoMatch).source + '|' +",
" (options.interpolate || reNoMatch).source + '|' +",
" (options.evaluate || reNoMatch).source + '|$'",
" , 'g');",
'',
' text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) {',
' source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);',
' source +=',
' escapeValue ? "\' +\\n_.escape(" + escapeValue + ") +\\n\'" :',
' evaluateValue ? "\';\\n" + evaluateValue + ";\\n__p += \'" :',
' interpolateValue ? "\' +\\n((__t = (" + interpolateValue + ")) == null ? \'\' : __t) +\\n\'" : \'\';',
'',
' index = offset + match.length;',
' });',
'',
' source += "\';\\n";',
' if (!variable) {',
" variable = 'obj';",
" source = 'with (' + variable + ' || {}) {\\n' + source + '\\n}\\n';",
' }',
" source = 'function(' + variable + ') {\\n' +",
' "var __t, __p = \'\', __j = Array.prototype.join;\\n" +',
' "function print() { __p += __j.call(arguments, \'\') }\\n" +',
' source +',
" 'return __p\\n}';",
'',
' try {',
" var result = Function('_', 'return ' + source)(lodash);",
' } catch(e) {',
' e.source = source;',
' throw e;',
' }',
' if (data) {',
' return result(data);',
' }',
' result.source = source;',
' return result;',
' }'
].join('\n'));
// replace `_.uniq`
source = source.replace(/^( *)function uniq[\s\S]+?\n\1}/m, [
source = replaceFunction(source, 'uniq', [
' function uniq(array, isSorted, callback, thisArg) {',
' var index = -1,',
' length = array ? array.length : 0,',
@@ -1349,8 +1434,16 @@
' }'
].join('\n'));
// replace `_.uniqueId`
source = replaceFunction(source, 'uniqueId', [
' function uniqueId(prefix) {',
' var id = idCounter++;',
' return prefix ? prefix + id : id;',
' }'
].join('\n'));
// replace `_.without`
source = source.replace(/^( *)function without[\s\S]+?\n\1}/m, [
source = replaceFunction(source, 'without', [
' function without(array) {',
' var index = -1,',
' length = array.length,',
@@ -1366,21 +1459,47 @@
' }'
].join('\n'));
// remove unneeded template related variables
source = removeVar(source, 'reComplexDelimiter');
source = removeVar(source, 'reEmptyStringLeading');
source = removeVar(source, 'reEmptyStringMiddle');
source = removeVar(source, 'reEmptyStringTrailing');
source = removeVar(source, 'reInsertVariable');
// replace `wrapperChain`
source = replaceFunction(source, 'wrapperChain', [
' function wrapperChain() {',
' this.__chain__ = true;',
' return this;',
' }'
].join('\n'));
// add `__chain__` checks to `_.mixin` and Array function wrappers
source = source.replace(/^( *)forEach\([\s\S]+?\n\1}.+/gm, function(match) {
return match.replace(/^( *)return new lodash\(([^)]+)\).+/m, function(submatch, indent, varName) {
return indent + [
'if (this.__chain__) {',
' varName = new lodash(varName);',
' varName.__chain__ = true;',
'}',
'return varName;'
].join('\n' + indent)
.replace(/varName/g, varName);
});
});
// remove `arguments` object check from `_.isEqual`
source = source.replace(/ *\|\| *className *== *argsClass/, '');
// simplify DOM node check from `_.isEqual`
source = source.replace(/(if *\(className *!= *objectClass).+?noNodeClass[\s\S]+?{/, '$1) {');
source = source.replace(matchFunction(source, 'isEqual'), function(match) {
return match.replace(/^ *if *\(.+== argsClass[^}]+}\n/gm, '')
});
// remove conditional `charCodeCallback` use from `_.max` and `_.min`
source = source.replace(/!callback *&& *isString\(collection\)[\s\S]+?: */g, '');
_.each(['max', 'min'], function(methodName) {
source = source.replace(matchFunction(source, methodName), function(match) {
return match.replace(/!callback *&& *isString\(collection\)[\s\S]+?: */g, '');
});
});
// remove `lodash.prototype.toString` and `lodash.prototype.valueOf` assignments
source = source.replace(/ *lodash\.prototype\.(?:toString|valueOf) *=.+\n/g, '');
// remove `lodash.prototype` batch method assignments
source = source
.replace(/(?:\s*\/\/.*)*\n( *)forEach\(\['first'[\s\S]+?\n\1}.+/, '')
.replace(/(?:\s*\/\/.*)*\n( *)forEach\(filter[\s\S]+?lodash\.[\s\S]+?\n\1}.+/, '');
// remove unused features from `createBound`
if (buildMethods.indexOf('partial') == -1) {
@@ -1394,14 +1513,19 @@
if (isMobile) {
source = replaceVar(source, 'isKeysFast', 'false');
source = removeKeysOptimization(source);
source = removeNoNodeClass(source);
// remove `prototype` [[Enumerable]] fix from `_.keys`
source = source.replace(/(?:\s*\/\/.*)*(\s*return *).+?propertyIsEnumerable[\s\S]+?: */, '$1');
source = source.replace(matchFunction(source, 'keys'), function(match) {
return match.replace(/(?:\s*\/\/.*)*(\s*return *).+?propertyIsEnumerable[\s\S]+?: */, '$1');
});
// remove `prototype` [[Enumerable]] fix from `iteratorTemplate`
source = source
.replace(/(?: *\/\/.*\n)* *' *(?:<% *)?if *\(!hasDontEnumBug *(?:&&|\))[\s\S]+?<% *} *(?:%>|').+/g, '')
.replace(/!hasDontEnumBug *\|\|/g, '');
source = source.replace(getIteratorTemplate(source), function(match) {
return match
.replace(/(?: *\/\/.*\n)* *["'] *(?:<% *)?if *\(!hasDontEnumBug *(?:&&|\))[\s\S]+?<% *} *(?:%>|["']).+/g, '')
.replace(/!hasDontEnumBug *\|\|/g, '');
});
}
vm.runInContext(source, context);
return context._;
@@ -1438,23 +1562,18 @@
/*----------------------------------------------------------------------*/
if (isLegacy) {
_.each(['isBindFast', 'nativeBind', 'nativeIsArray', 'nativeKeys'], function(varName) {
_.each(['isBindFast', 'isV8', 'nativeBind', 'nativeIsArray', 'nativeKeys', 'reNative'], function(varName) {
source = removeVar(source, varName);
});
_.each(['bind', 'isArray'], function(methodName) {
var snippet = matchFunction(source, methodName),
modified = snippet;
// remove native `Function#bind` branch in `_.bind`
source = source.replace(matchFunction(source, 'bind'), function(match) {
return match.replace(/(?:\s*\/\/.*)*\s*return isBindFast[^:]+:\s*/, 'return ');
});
// remove native `Function#bind` branch in `_.bind`
if (methodName == 'bind') {
modified = modified.replace(/(?:\s*\/\/.*)*\s*return isBindFast[^:]+:\s*/, 'return ');
}
// remove native `Array.isArray` branch in `_.isArray`
else {
modified = modified.replace(/nativeIsArray * \|\|/, '');
}
source = source.replace(snippet, modified);
// remove native `Array.isArray` branch in `_.isArray`
source = source.replace(matchFunction(source, 'isArray'), function(match) {
return match.replace(/nativeIsArray * \|\|/, '');
});
// replace `_.keys` with `shimKeys`
@@ -1475,9 +1594,8 @@
source = removeIsArgumentsFallback(source);
}
source = removeVar(source, 'reNative');
source = removeFromCreateIterator(source, 'nativeKeys');
source = removeCreateFunction(source);
}
/*----------------------------------------------------------------------*/
@@ -1486,13 +1604,12 @@
// inline all functions defined with `createIterator`
_.functions(lodash).forEach(function(methodName) {
var reFunc = RegExp('(\\bvar ' + methodName + ' *= *)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n');
// skip if not defined with `createIterator`
if (!reFunc.test(source)) {
return;
if (reFunc.test(source)) {
// extract, format, and inject the compiled function's source code
source = source.replace(reFunc, function(match, captured) {
return captured + getFunctionSource(lodash[methodName]) + ';\n';
});
}
// extract, format, and inject the compiled function's source code
source = source.replace(reFunc, '$1' + getFunctionSource(lodash[methodName]) + ';\n');
});
if (isUnderscore) {
@@ -1518,15 +1635,14 @@
// replace `isArguments` and its fallback
(function() {
var snippet = matchFunction(source, 'isArguments')
.replace(/function isArguments/, 'lodash.isArguments = function');
var snippet = matchFunction(source, 'isArguments');
snippet = snippet.replace(/function isArguments/, 'lodash.isArguments = function');
source = removeFunction(source, 'isArguments');
source = source.replace(getIsArgumentsFallback(source), function(match) {
return snippet + '\n' + match
.replace(/\bisArguments\b/g, 'lodash.$&')
.replace(/\bnoArgsClass\b/g, '!lodash.isArguments(arguments)');
.replace(/isArguments/g, 'lodash.$&')
.replace(/noArgsClass/g, '!lodash.isArguments(arguments)');
});
}());
@@ -1542,9 +1658,11 @@
});
});
// modify `_.every`, `_.find`, and `_.some` to use the private `indicatorObject`
source = source.replace(matchFunction(source, 'every'), function(match) {
return match.replace(/\(result *= *(.+?)\);/, '!(result = $1) && indicatorObject;');
// modify `_.every`, `_.find`, `_.isEqual`, and `_.some` to use the private `indicatorObject`
_.each(['every', 'isEqual'], function(methodName) {
source = source.replace(matchFunction(source, methodName), function(match) {
return match.replace(/\(result *= *(.+?)\);/g, '!(result = $1) && indicatorObject;');
});
});
source = source.replace(matchFunction(source, 'find'), function(match) {
@@ -1557,7 +1675,6 @@
}
else {
source = removeIsArgumentsFallback(source);
source = removeVar(source, 'hasObjectSpliceBug');
// remove `hasObjectSpliceBug` fix from the mutator Array functions mixin
source = source.replace(/(?:\s*\/\/.*)*\n( *)if *\(hasObjectSpliceBug[\s\S]+?\n\1}/, '');
@@ -1570,38 +1687,41 @@
], function(data) {
if (!data.flag) {
source = source.replace(matchFunction(source, data.methodName), function(match) {
return match.replace(/(callback), *thisArg/g, '$1');
return match
.replace(/(callback), *thisArg/g, '$1')
.replace(/^( *)callback *=.+/m, '$1callback || (callback = identity);')
});
}
});
// remove `hasDontEnumBug`, `iteratesOwnLast`, and `noArgsEnum` declarations and assignments
source = source
.replace(/ *\(function\(\) *{[\s\S]+?}\(1\)\);\n/, '')
.replace(/^ *\(function\(\) *{[\s\S]+?}\(1\)\);\n/m, '')
.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var (?:hasDontEnumBug|iteratesOwnLast|noArgsEnum).+\n/g, '');
// remove `iteratesOwnLast` from `isPlainObject`
source = source.replace(/(?:\s*\/\/.*)*\n( *)if *\(iteratesOwnLast[\s\S]+?\n\1}/, '');
// remove JScript [[DontEnum]] fix from `_.isEqual`
source = source.replace(/(?:\s*\/\/.*)*\n( *)if *\(hasDontEnumBug[\s\S]+?\n\1}/, '');
// remove `noArraySliceOnStrings` from `_.toArray`
source = source.replace(/noArraySliceOnStrings *\?[^:]+: *([^)]+)/g, '$1');
// remove `iteratesOwnLast` from `shimIsPlainObject`
source = source.replace(matchFunction(source, 'shimIsPlainObject'), function(match) {
return match.replace(/(?:\s*\/\/.*)*\n( *)if *\(iteratesOwnLast[\s\S]+?\n\1}/, '');
});
// remove `noCharByIndex` from `_.reduceRight`
source = source.replace(/}\s*else if *\(noCharByIndex[^}]+/, '');
source = source.replace(matchFunction(source, 'reduceRight'), function(match) {
return match.replace(/}\s*else if *\(noCharByIndex[^}]+/, '');
});
// remove `noCharByIndex` from `_.toArray`
source = source.replace(matchFunction(source, 'toArray'), function(match) {
return match.replace(/noCharByIndex[^:]+:/, '');
});
source = removeVar(source, 'extendIteratorOptions');
source = removeVar(source, 'iteratorTemplate');
source = removeVar(source, 'noArraySliceOnStrings');
source = removeVar(source, 'noCharByIndex');
source = removeCreateFunction(source);
source = removeNoArgsClass(source);
source = removeNoNodeClass(source);
}
else {
// inline `iteratorTemplate` template
source = source.replace(/(( *)var iteratorTemplate *= *)[\s\S]+?\n\2.+?;\n/, (function() {
source = source.replace(getIteratorTemplate(source), function() {
var snippet = getFunctionSource(lodash._iteratorTemplate);
// prepend data object references to property names to avoid having to
@@ -1631,8 +1751,8 @@
// remove comments, including sourceURLs
snippet = snippet.replace(/\s*\/\/.*(?:\n|$)/g, '');
return '$1' + snippet + ';\n';
}()));
return ' var iteratorTemplate = ' + snippet + ';\n';
});
}
}
@@ -1701,6 +1821,13 @@
source = removeIsFunctionFallback(source);
}
if (isRemoved(source, 'mixin')) {
// simplify the `lodash` function
source = replaceFunction(source, 'lodash', [
' function lodash() {',
' // no operation performed',
' }'
].join('\n'));
// remove `lodash.prototype` additions
source = source.replace(/(?:\s*\/\/.*)*\s*mixin\(lodash\)[\s\S]+?\/\*-+\*\//, '');
source = removeVar(source, 'hasObjectSpliceBug');
@@ -1716,6 +1843,7 @@
// remove associated functions, variables, and code snippets that the minifier may miss
if (isRemoved(source, 'clone')) {
source = removeVar(source, 'cloneableClasses');
source = removeVar(source, 'ctorByClass');
}
if (isRemoved(source, 'isArray')) {
source = removeVar(source, 'nativeIsArray');
@@ -1730,24 +1858,21 @@
// remove `templateSettings` assignment
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *lodash\.templateSettings[\s\S]+?};\n/, '');
}
if (isRemoved(source, 'toArray')) {
source = removeVar(source, 'noArraySliceOnStrings');
}
if (isRemoved(source, 'clone', 'isArguments', 'isEmpty', 'isEqual')) {
if (isRemoved(source, 'isArguments', 'isEmpty')) {
source = removeNoArgsClass(source);
}
if (isRemoved(source, 'isEqual', 'isPlainObject')) {
if (isRemoved(source, 'clone', 'isEqual', 'isPlainObject')) {
source = removeNoNodeClass(source);
}
if ((source.match(/\bcreateIterator\b/g) || []).length < 2) {
source = removeFunction(source, 'createIterator');
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var noArgsEnum;|.+?noArgsEnum *=.+/g, '');
}
if (isRemoved(source, 'createIterator', 'bind')) {
if (isRemoved(source, 'createIterator', 'bind', 'keys', 'template')) {
source = removeVar(source, 'isBindFast');
source = removeVar(source, 'nativeBind');
}
if (isRemoved(source, 'createIterator', 'bind', 'isArray', 'isPlainObject', 'keys')) {
if (isRemoved(source, 'createIterator', 'bind', 'isArray', 'isPlainObject', 'keys', 'template')) {
source = removeVar(source, 'reNative');
}
if (isRemoved(source, 'createIterator', 'isEqual')) {
@@ -1804,7 +1929,7 @@
'onComplete': function(source) {
// inject "use strict" directive
if (isStrict) {
source = source.replace(/^([\s\S]*?function[^{]+{)([^'"])/, '$1"use strict";$2');
source = source.replace(/^([\s\S]*?function[^{]+{)([^"'])/, '$1"use strict";$2');
}
if (isCustom) {
source = addCommandsToHeader(source, options);

View File

@@ -99,22 +99,28 @@
/*--------------------------------------------------------------------------*/
exec('npm -g root', function(exception, stdout) {
if (!exception) {
try {
var isGlobal = path.resolve(basePath, '..') == fs.realpathSync(stdout.trim());
} catch(e) {
exception = e;
}
}
if (exception) {
console.error([
'There was a problem loading the npm registry. If youre installing the Lo-Dash',
'command-line executable (via `npm install -g lodash`), youll need to manually',
'install UglifyJS and the Closure Compiler by running:',
'Oops! There was a problem detecting the install mode. If youre installing the',
'Lo-Dash command-line executable (via `npm install -g lodash`), youll need to',
'manually install UglifyJS and the Closure Compiler by running:',
'',
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + closureId + " | tar xvz -C '" + vendorPath + "'",
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + uglifyId + " | tar xvz -C '" + vendorPath + "'",
'',
'Please submit an issue on the GitHub issue tracker: ' + process.env.npm_package_bugs_url + '.'
'Please submit an issue on the GitHub issue tracker: ' + process.env.npm_package_bugs_url
].join('\n'));
console.error(exception);
process.exit();
}
// exit early if not a global install
if (path.resolve(basePath, '..') != fs.realpathSync(stdout.trim())) {
if (!isGlobal) {
return;
}
// download the Closure Compiler

View File

@@ -29,8 +29,7 @@
'result',
'skipProto',
'source',
'thisArg',
'value'
'thisArg'
];
/** Used to minify `compileIterator` option properties */
@@ -59,7 +58,6 @@
/** Used to protect the specified properties from getting minified */
var propWhitelist = [
'_',
'__chain__',
'__wrapped__',
'after',
'all',
@@ -190,6 +188,9 @@
'wrap',
'zip',
// property used by the `lodash underscore` build
'__chain__',
// properties used by underscore.js
'_chain',
'_wrapped'
@@ -214,13 +215,14 @@
if (options.isTemplate) {
return source;
}
// remove copyright/license header to add later in post-compile.js
source = source.replace(/\/\*![\s\S]+?\*\//, '');
// add brackets to whitelisted properties so the Closure Compiler won't mung them
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
source = source.replace(RegExp('\\.(' + propWhitelist.join('|') + ')\\b', 'g'), "['$1']");
source = source.replace(RegExp('\\.(' + propWhitelist.join('|') + ')\\b', 'g'), function(match, prop) {
return "['" + prop.replace(/['\n\r\t]/g, '\\$&') + "']";
});
// remove brackets from `_.escape()` in `_.template`
source = source.replace(/__e *= *_\['escape']/g, '__e=_.escape');
@@ -235,16 +237,25 @@
source = source.replace("result[length]['value']", 'result[length].value');
// remove whitespace from string literals
source = source.replace(/'(?:(?=(\\?))\1.)*?'/g, function(string) {
source = source.replace(/^([ "'\w]+:)? *"(?:(?=(\\?))\2.)*?"|'(?:(?=(\\?))\3.)*?'/gm, function(string, captured) {
// remove object literal property name
if (/:$/.test(captured)) {
string = string.slice(captured.length);
}
// avoids removing the '\n' of the `stringEscapes` object
return string.replace(/\[object |delete |else |function | in |return\s+[\w']|throw |typeof |use strict|var |@ |'\\n'|\\\\n|\\n|\s+/g, function(match) {
string = string.replace(/\[object |delete |else |function | in |return\s+[\w"']|throw |typeof |use strict|var |@ |(["'])\\n\1|\\\\n|\\n|\s+/g, function(match) {
return match == false || match == '\\n' ? '' : match;
});
// prepend object literal property name
return (captured || '') + string;
});
// add newline to `+"__p+='"` in underscore.js `_.template`
source = source.replace(/\+"__p\+='"/g, '+"\\n__p+=\'"');
// add newline to `body + '}'` in `createFunction`
source = source.replace(/body *\+ *'}'/, 'body+"\\n}"');
// remove whitespace from `_.template` related regexes
source = source.replace(/(?:reEmptyString\w+|reInsertVariable) *=.+/g, function(match) {
return match.replace(/ |\\n/g, '');
@@ -252,11 +263,8 @@
// remove newline from double-quoted strings in `_.template`
source = source
.replace('"\';\\n__with ("', '"\';__with("')
.replace('"\\n}__\\n__p += \'"', '"}____p+=\'"')
.replace('"__p = \'"', '"__p=\'"')
.replace('"\';\\n"', '"\';"')
.replace("') {\\n'", "'){'")
.replace('"__p += \'"', '"__p+=\'"')
.replace('"\';\n"', '"\';"')
// remove `useSourceURL` variable
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var useSourceURL[\s\S]+?catch[^}]+}\n/, '');
@@ -316,8 +324,10 @@
isIteratorTemplate = /var iteratorTemplate\b/.test(snippet),
modified = snippet;
// add brackets to whitelisted properties so the Closure Compiler won't mung them
modified = modified.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), "['$1']");
// add brackets to iterator option properties so the Closure Compiler won't mung them
modified = modified.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), function(match, prop) {
return "['" + prop.replace(/['\n\r\t]/g, '\\$&') + "']";
});
if (isCreateIterator) {
// replace with modified snippet early and clip snippet to the `factory`
@@ -331,9 +341,9 @@
// ensure properties in compiled strings aren't minified
modified = modified.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minNames[index]);
// correct `typeof x == 'object'`
if (variable == 'object') {
modified = modified.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), "$1object'");
// correct `typeof` values
if (/^(?:boolean|function|object|number|string|undefined)$/.test(variable)) {
modified = modified.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), '$1' + variable + "'");
}
});

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@
// generate Markdown
$markdown = docdown(array(
'path' => '../' . $file,
'title' => 'Lo-Dash <sup>v0.10.0</sup>',
'title' => 'Lo-Dash <sup>v1.0.0-rc.1</sup>',
'toc' => 'categories',
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
));

509
lodash.js

File diff suppressed because it is too large Load Diff

75
lodash.min.js vendored
View File

@@ -1,40 +1,41 @@
/*!
Lo-Dash 0.10.0 lodash.com/license
Lo-Dash 1.0.0-rc.1 lodash.com/license
Underscore.js 1.4.2 underscorejs.org/LICENSE
*/
;(function(e,t){function s(e){if(e&&e.__wrapped__)return e;if(!(this instanceof s))return new s(e);this.__wrapped__=e}function o(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||Z);if(i)for(var s={},n=t-1;++n<r;){var o=e[n]+"";(bt.call(s,o)?s[o]:s[o]=[]).push(e[n])}return function(n){if(i){var r=n+"";return bt.call(s,r)&&-1<q(s[r],n)}return-1<q(e,n,t)}}function u(e){return e.charCodeAt(0)}function a(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1;if(e<n||n===t)return-1}return r<i?-1:1}function f
(e,t,n){function r(){var u=arguments,a=s?this:t;return i||(e=t[o]),n.length&&(u=u.length?n.concat(St.call(u)):n),this instanceof r?(d.prototype=e.prototype,a=new d,u=e.apply(a,u),T(u)?u:a):e.apply(a,u)}var i=x(e),s=!n,o=t;return s&&(n=t),i||(t=e),r}function l(e,n){return e?"function"!=typeof e?function(t){return t[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:X}function c(){for(var e={b:"",c:"",e:qt,f:Qt,g:"",h:zt,i:Vt,j:dt,k:"",l:n},t,r=0;t=arguments[r];r++)for(var i in t)e[i]=t[i];t=e.a,e
.d=/^[^,]+/.exec(t)[0],r="var i,x,l="+e.d+",t="+e.d+";if(!"+e.d+")return t;"+e.k+";",e.b?(r+="var m=l.length;i=-1;if(typeof m=='number'){",e.i&&(r+="if(k(l)){l=l.split('')}"),r+="while(++i<m){x=l[i];"+e.b+"}}else {"):e.h&&(r+="var m=l.length;i=-1;if(m&&j(l)){while(++i<m){x=l[i+=''];"+e.g+"}}else {"),e.e||(r+="var u=typeof l=='function'&&s.call(l,'prototype');");if(e.f&&e.l)r+="var q=-1,r=p[typeof l]?n(l):[],m=r.length;while(++q<m){i=r[q];",e.e||(r+="if(!(u&&i=='prototype')){"),r+="x=l[i];"+e.g+""
,e.e||(r+="}");else{r+="for(i in l){";if(!e.e||e.l)r+="if(",e.e||(r+="!(u&&i=='prototype')"),!e.e&&e.l&&(r+="&&"),e.l&&(r+="h.call(l,i)"),r+="){";r+="x=l[i];"+e.g+";";if(!e.e||e.l)r+="}"}r+="}";if(e.e){r+="var f=l.constructor;";for(i=0;7>i;i++)r+="i='"+e.j[i]+"';if(","constructor"==e.j[i]&&(r+="!(f&&f.prototype===l)&&"),r+="h.call(l,i)){x=l[i];"+e.g+"}"}if(e.b||e.h)r+="}";return r+=e.c+";return t",Function("e,h,j,k,p,n,s","return function("+t+"){"+r+"}")(l,bt,m,N,Yt,Lt,Et)}function h(e){return"\\"+
Zt[e]}function p(e){return un[e]}function d(){}function v(e){return an[e]}function m(e){return xt.call(e)==_t}function g(e){var t=i;if(!e||"object"!=typeof e||m(e))return t;var n=e.constructor;return(!$t||"function"==typeof e.toString||"string"!=typeof (e+""))&&(!x(n)||n instanceof n)?Rt?(sn(e,function(e,n,r){return t=!bt.call(r,n),i}),t===i):(sn(e,function(e,n){t=n}),t===i||bt.call(e,t)):t}function y(e){var t=[];return on(e,function(e,n){t.push(n)}),t}function b(e,t,n,s,o){if(e==r)return e;n&&(t=
i);if(n=T(e)){var u=xt.call(e);if(!Gt[u]||Wt&&m(e))return e;var a=u==Dt,n=a||(u==jt?cn(e):n)}if(!n||!t)return n?a?St.call(e):rn({},e):e;n=e.constructor;switch(u){case Pt:case Ht:return new n(+e);case Bt:case It:return new n(e);case Ft:return n(e.source,ot.exec(e))}s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u];var f=a?n(e.length):{};return s.push(e),o.push(f),(a?pn:on)(e,function(e,n){f[n]=b(e,t,r,s,o)}),f}function w(e){var t=[];return sn(e,function(e,n){x(e)&&t.push(n)}),t.sort()
}function E(e){var t={};return on(e,function(e,n){t[e]=n}),t}function S(e,t,s,o){if(e===t)return 0!==e||1/e==1/t;if(e==r||t==r)return e===t;var u=xt.call(e);if(u!=xt.call(t))return i;switch(u){case Pt:case Ht:return+e==+t;case Bt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case Ft:case It:return e==t+""}var a=u==Dt||u==_t;if(Wt&&!a&&(a=m(e))&&!m(t))return i;if(!a){if(e.__wrapped__||t.__wrapped__)return S(e.__wrapped__||e,t.__wrapped__||t);if(u!=jt||$t&&("function"!=typeof e.toString&&"string"==typeof
(e+"")||"function"!=typeof t.toString&&"string"==typeof (t+"")))return i;var u=e.constructor,f=t.constructor;if(u!=f&&(!x(u)||!(u instanceof u&&x(f)&&f instanceof f)))return i}s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var u=-1,f=n,l=0;s.push(e),o.push(t);if(a){l=e.length;if(f=l==t.length)for(;l--&&(f=S(e[l],t[l],s,o)););return f}for(var c in e)if(bt.call(e,c)&&(l++,!bt.call(t,c)||!S(e[c],t[c],s,o)))return i;for(c in t)if(bt.call(t,c)&&!(l--))return i;if(qt)for(;7>++u;)if(c=
dt[u],bt.call(e,c)&&(!bt.call(t,c)||!S(e[c],t[c],s,o)))return i;return n}function x(e){return"function"==typeof e}function T(e){return e?Yt[typeof e]:i}function N(e){return xt.call(e)==It}function C(e,t,n){var i=arguments,s=0,o=2,u=i[3],a=i[4];n!==Y&&(u=[],a=[],"number"!=typeof n&&(o=i.length));for(;++s<o;)on(i[s],function(t,n){var i,s,o;if(t&&((s=ln(t))||cn(t))){for(var f=u.length;f--;)if(i=u[f]==t)break;i?e[n]=a[f]:(u.push(t),a.push(o=(o=e[n],s)?ln(o)?o:[]:cn(o)?o:{}),e[n]=C(o,t,Y,u,a))}else t!=
r&&(e[n]=t)});return e}function k(e){var t=[];return on(e,function(e){t.push(e)}),t}function L(e,t,n){var r=-1,s=e?e.length:0,o=i,n=(0>n?At(0,s+n):n)||0;return"number"==typeof s?o=-1<(N(e)?e.indexOf(t,n):q(e,t,n)):pn(e,function(e){if(++r>=n)return!(o=e===t)}),o}function A(e,t,r){var i=n,t=l(t,r);if(ln(e))for(var r=-1,s=e.length;++r<s&&(i=!!t(e[r],r,e)););else pn(e,function(e,n,r){return i=!!t(e,n,r)});return i}function O(e,t,n){var r=[],t=l(t,n);if(ln(e))for(var n=-1,i=e.length;++n<i;){var s=e[n]
;t(s,n,e)&&r.push(s)}else pn(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function M(e,t,n){var r,t=l(t,n);return pn(e,function(e,n,s){if(t(e,n,s))return r=e,i}),r}function _(e,t,n){var r=-1,i=e?e.length:0,s=Array("number"==typeof i?i:0),t=l(t,n);if(ln(e))for(;++r<i;)s[r]=t(e[r],r,e);else pn(e,function(e,n,i){s[++r]=t(e,n,i)});return s}function D(e,t,n){var r=-Infinity,i=-1,s=e?e.length:0,o=r;if(t||!ln(e))t=!t&&N(e)?u:l(t,n),pn(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,o=e)});else for(;++i<s;)e[
i]>o&&(o=e[i]);return o}function P(e,t){var n=[];return pn(e,function(e){n.push(e[t])}),n}function H(e,t,n,r){var s=3>arguments.length,t=l(t,r);return pn(e,function(e,r,o){n=s?(s=i,e):t(n,e,r,o)}),n}function B(e,t,n,r){var s=e,o=e?e.length:0,u=3>arguments.length;if("number"!=typeof o)var a=hn(e),o=a.length;else Vt&&N(e)&&(s=e.split(""));return pn(e,function(e,f,l){f=a?a[--o]:--o,n=u?(u=i,s[f]):t.call(r,n,s[f],f,l)}),n}function j(e,t,n){var r,t=l(t,n);if(ln(e))for(var n=-1,i=e.length;++n<i&&!(r=t(
e[n],n,e)););else pn(e,function(e,n,i){return!(r=t(e,n,i))});return!!r}function F(e,t,n){if(e)return t==r||n?e[0]:St.call(e,0,t)}function I(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];ln(s)?wt.apply(i,t?s:I(s)):i.push(s)}return i}function q(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof n)r=(0>n?At(0,i+n):n||0)-1;else if(n)return r=U(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function R(e,t,n){return e?St.call(e,t==r||n?1:t):[]}function U(e,t,n,r){for(var i=0,s=
e?e.length:i,n=n?l(n,r):X,t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r;return i}function z(e,t,n,r){var s=-1,o=e?e.length:0,u=[],a=u;"function"==typeof t&&(r=n,n=t,t=i);var f=!t&&74<o;if(f)var c={};n&&(a=[],n=l(n,r));for(;++s<o;){var r=e[s],h=n?n(r,s,e):r;f&&(a=bt.call(c,h+"")?c[h]:c[h]=[]);if(t?!s||a[a.length-1]!==h:0>q(a,h))(n||f)&&a.push(h),u.push(r)}return u}function W(e,t){return Kt||Tt&&2<arguments.length?Tt.call.apply(Tt,arguments):f(e,t,St.call(arguments,2))}function X(e){return e}function V
(e){pn(w(e),function(t){var r=s[t]=e[t];s.prototype[t]=function(){var e=[this.__wrapped__];return wt.apply(e,arguments),e=r.apply(s,e),this.__chain__&&(e=new s(e),e.__chain__=n),e}})}var n=!0,r=null,i=!1,$="object"==typeof exports&&exports,J="object"==typeof global&&global;J.global===J&&(e=J);var K=[],Q=new function(){},G=0,Y=Q,Z=30,et=e._,tt=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,nt=/&(?:amp|lt|gt|quot|#x27);/g,rt=/\b__p\+='';/g,it=/\b(__p\+=)''\+/g,st=/(__e\(.*?\)|\b__t\))\+'';/g
,ot=/\w*$/,ut=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,at=RegExp("^"+(Q.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),ft=/\$\{((?:(?=\\?)\\?[\s\S])*?)}/g,lt=/<%=([\s\S]+?)%>/g,ct=/($^)/,ht=/[&<>"']/g,pt=/['\n\r\t\u2028\u2029\\]/g,dt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),vt=Math.ceil,mt=K.concat,gt=Math.floor,yt=at.test(yt=Object.getPrototypeOf)&&yt,bt=Q.hasOwnProperty,wt=K.push,Et=
Q.propertyIsEnumerable,St=K.slice,xt=Q.toString,Tt=at.test(Tt=St.bind)&&Tt,Nt=at.test(Nt=Array.isArray)&&Nt,Ct=e.isFinite,kt=e.isNaN,Lt=at.test(Lt=Object.keys)&&Lt,At=Math.max,Ot=Math.min,Mt=Math.random,_t="[object Arguments]",Dt="[object Array]",Pt="[object Boolean]",Ht="[object Date]",Bt="[object Number]",jt="[object Object]",Ft="[object RegExp]",It="[object String]",qt,Rt,Ut=(Ut={0:1,length:1},K.splice.call(Ut,0,1),Ut[0]),zt=n;(function(){function e(){this.x=1}var t=[];e.prototype={valueOf:1,y
:1};for(var n in new e)t.push(n);for(n in arguments)zt=!n;qt=!/valueOf/.test(t),Rt="x"!=t[0]})(1);var Wt=!m(arguments),Xt="x"!=St.call("x")[0],Vt="xx"!="x"[0]+Object("x")[0];try{var $t=("[object Object]",xt.call(e.document||0)==jt)}catch(Jt){}var Kt=Tt&&/\n|Opera/.test(Tt+xt.call(e.opera)),Qt=Lt&&/^.+$|true/.test(Lt+!!e.attachEvent),Gt={};Gt[_t]=Gt["[object Function]"]=i,Gt[Dt]=Gt[Pt]=Gt[Ht]=Gt[Bt]=Gt[jt]=Gt[Ft]=Gt[It]=n;var Yt={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i},Zt=
{"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:lt,variable:""};var en={a:"o,v,g",k:"for(var a=1,b=typeof g=='number'?2:arguments.length;a<b;a++){if((l=arguments[a])){",g:"t[i]=x",c:"}}"},tn={a:"d,c,w",k:"c=e(c,w)",b:"if(c(x,i,d)===false)return t",g:"if(c(x,i,d)===false)return t"},nn={b:r},rn=c(en);Wt&&(m=function(e){return e?bt.call(e,"callee"):i});var sn=c(tn,nn,{l:i}),on=c(tn,nn
),un={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},an=E(un),fn=c(en,{g:"if(t[i]==null)"+en.g}),ln=Nt||function(e){return xt.call(e)==Dt};x(/x/)&&(x=function(e){return"[object Function]"==xt.call(e)});var cn=yt?function(e){if(!e||"object"!=typeof e)return i;var t=e.valueOf,n="function"==typeof t&&(n=yt(t))&&yt(n);return n?e==n||yt(e)==n&&!m(e):g(e)}:g,hn=Lt?function(e){return"function"==typeof e&&Et.call(e,"prototype")?y(e):T(e)?Lt(e):[]}:y,pn=c(tn);s.VERSION="0.10.0",s.assign=rn,s
.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=W,s.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=w(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=W(e[i],e)}return e},s.bindKey=function(e,t){return f(e,t,St.call(arguments,2))},s.chain=function(e){return e=new s(e),e.__chain__=n,e},s.clone=b,s.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},s.compose=function(){var e=arguments;return function(){for(
var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},s.contains=L,s.countBy=function(e,t,n){var r={},t=l(t,n);return pn(e,function(e,n,i){n=t(e,n,i),bt.call(r,n)?r[n]++:r[n]=1}),r},s.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,clearTimeout(a),a=setTimeout(i,t),r&&(o=e.apply(u,s)),o}},s.defaults=fn,s.defer=function(e){var n=St.call(arguments,1);return setTimeout(function(){e.apply(t,n)},1)},s.delay=
function(e,n){var r=St.call(arguments,2);return setTimeout(function(){e.apply(t,r)},n)},s.difference=function(e){for(var t=-1,n=e?e.length:0,r=mt.apply(K,arguments),r=o(r,n),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.escape=function(e){return e==r?"":(e+"").replace(ht,p)},s.every=A,s.filter=O,s.find=M,s.first=F,s.flatten=I,s.forEach=pn,s.forIn=sn,s.forOwn=on,s.functions=w,s.groupBy=function(e,t,n){var r={},t=l(t,n);return pn(e,function(e,n,i){n=t(e,n,i),(bt.call(r,n)?r[n]:r[n]=[]).push(e
)}),r},s.has=function(e,t){return e?bt.call(e,t):i},s.identity=X,s.indexOf=q,s.initial=function(e,t,n){return e?St.call(e,0,-(t==r||n?1:t)):[]},s.intersection=function(e){var t=arguments,n=t.length,r={},i=[];return pn(e,function(e){if(0>q(i,e)){for(var s=n;--s;)if(!(r[s]||(r[s]=o(t[s])))(e))return;i.push(e)}}),i},s.invert=E,s.invoke=function(e,t){var n=St.call(arguments,2),r="function"==typeof t,i=[];return pn(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},s.isArguments=m,s.isArray=ln,s.isBoolean=
function(e){return e===n||e===i||xt.call(e)==Pt},s.isDate=function(e){return xt.call(e)==Ht},s.isElement=function(e){return e?1===e.nodeType:i},s.isEmpty=function(e){var t=n;if(!e)return t;var r=xt.call(e),s=e.length;return r==Dt||r==It||r==_t||Wt&&m(e)||r==jt&&"number"==typeof s&&x(e.splice)?!s:(on(e,function(){return t=i}),t)},s.isEqual=S,s.isFinite=function(e){return Ct(e)&&!kt(parseFloat(e))},s.isFunction=x,s.isNaN=function(e){return xt.call(e)==Bt&&e!=+e},s.isNull=function(e){return e===r},s
.isNumber=function(e){return xt.call(e)==Bt},s.isObject=T,s.isPlainObject=cn,s.isRegExp=function(e){return xt.call(e)==Ft},s.isString=N,s.isUndefined=function(e){return e===t},s.keys=hn,s.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:St.call(e,-t||i)}},s.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?At(0,r+n):Ot(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},s.map=_,s.max=D,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments
):arguments[0];return bt.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=C,s.min=function(e,t,n){var r=Infinity,i=-1,s=e?e.length:0,o=r;if(t||!ln(e))t=!t&&N(e)?u:l(t,n),pn(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,o=e)});else for(;++i<s;)e[i]<o&&(o=e[i]);return o},s.mixin=V,s.noConflict=function(){return e._=et,this},s.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},s.omit=function(e,t,n){var r="function"==typeof t,i={};if(r)t=l(t,n);
else var s=mt.apply(K,arguments);return sn(e,function(e,n,o){if(r?!t(e,n,o):0>q(s,n,1))i[n]=e}),i},s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.pairs=function(e){var t=[];return on(e,function(e,n){t.push([n,e])}),t},s.partial=function(e){return f(e,St.call(arguments,1))},s.pick=function(e,t,n){var r={};if("function"!=typeof t)for(var i=0,s=mt.apply(K,arguments),o=s.length;++i<o;){var u=s[i];u in e&&(r[u]=e[u])}else t=l(t,n),sn(e,function(e,n,
i){t(e,n,i)&&(r[n]=e)});return r},s.pluck=P,s.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+gt(Mt()*((+t||0)-e+1))},s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=At(0,vt((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reduce=H,s.reduceRight=B,s.reject=function(e,t,n){return t=l(t,n),O(e,function(e,n,r){return!t(e,n,r)})},s.rest=R,s.result=function(e,t){var n=e?e[t]:r;return x(n)?e[t]():n},s.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return pn
(e,function(e){var r=gt(Mt()*(++t+1));n[t]=n[r],n[r]=e}),n},s.size=function(e){var t=e?e.length:0;return"number"==typeof t?t:hn(e).length},s.some=j,s.sortBy=function(e,t,n){var r=[],t=l(t,n);pn(e,function(e,n,i){r.push({a:t(e,n,i),b:n,c:e})}),e=r.length;for(r.sort(a);e--;)r[e]=r[e].c;return r},s.sortedIndex=U,s.tap=function(e,t){return t(e),e},s.template=function(e,t,n){e||(e=""),n||(n={});var r,i,o=s.templateSettings,u=0,a=n.interpolate||o.interpolate||ct,f="__p += '",l=n.variable||o.variable,c=
l;e.replace(RegExp((n.escape||o.escape||ct).source+"|"+a.source+"|"+(a===lt?ft:ct).source+"|"+(n.evaluate||o.evaluate||ct).source+"|$","g"),function(t,n,i,s,o,a){i||(i=s),f+=e.slice(u,a).replace(pt,h),f+=n?"'+__e("+n+")+'":o?"';"+o+";__p+='":i?"'+((__t=("+i+"))==null?'':__t)+'":"",r||(r=o||tt.test(n||i)),u=a+t.length}),f+="';",c||(l="obj",r?f="with("+l+"){"+f+"}":(n=RegExp("(\\(\\s*)"+l+"\\."+l+"\\b","g"),f=f.replace(ut,"$&"+l+".").replace(n,"$1__d"))),f=(r?f.replace(rt,""):f).replace(it,"$1").replace
(st,"$1;"),f="function("+l+"){"+(c?"":l+"||("+l+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(c?"":",__d="+l+"."+l+"||"+l)+";")+f+"return __p}";try{i=Function("_","return "+f)(s)}catch(p){throw p.source=f,p}return t?i(t):(i.source=f,i)},s.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(){var r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(clearTimeout(u),a=r,s=e.apply(o,i)
):u||(u=setTimeout(n,f)),s}},s.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},s.toArray=function(e){return e&&"number"==typeof e.length?(Xt?N(e):"string"==typeof e)?e.split(""):St.call(e):k(e)},s.unescape=function(e){return e==r?"":(e+"").replace(nt,v)},s.union=function(){return z(mt.apply(K,arguments))},s.uniq=z,s.uniqueId=function(e){var t=G++;return e?e+t:t},s.values=k,s.where=function(e,t){var n=hn(t);return O(e,function(e){for(var r=n.length;r--;){var i=
e[n[r]]===t[n[r]];if(!i)break}return!!i})},s.without=function(e){for(var t=-1,n=e?e.length:0,r=o(arguments,1,20),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.wrap=function(e,t){return function(){var n=[e];return wt.apply(n,arguments),t.apply(this,n)}},s.zip=function(e){for(var t=-1,n=e?D(P(arguments,"length")):0,r=Array(n);++t<n;)r[t]=P(arguments,t);return r},s.all=A,s.any=j,s.collect=_,s.detect=M,s.drop=R,s.each=pn,s.extend=rn,s.foldl=H,s.foldr=B,s.head=F,s.include=L,s.inject=H,s.methods=
w,s.select=O,s.tail=R,s.take=F,s.unique=z,V(s),s.prototype.chain=function(){return this.__chain__=n,this},s.prototype.value=function(){return this.__wrapped__},pn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=K[e];s.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),Ut&&e.length===0&&delete e[0],this.__chain__&&(e=new s(e),e.__chain__=n),e}}),pn(["concat","join","slice"],function(e){var t=K[e];s.prototype[e]=function(){var e=t.apply(this.__wrapped__
,arguments);return this.__chain__&&(e=new s(e),e.__chain__=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):$?"object"==typeof module&&module&&module.exports==$?(module.exports=s)._=s:$._=s:e._=s})(this);
;(function(e,t){function s(e){if(e&&"object"==typeof e&&e.__wrapped__)return e;if(!(this instanceof s))return new s(e);this.__wrapped__=e}function o(t,n){return e.eval("(function("+t+"){"+n+"})")}function u(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||it);if(i)for(var s={},n=t-1;++n<r;){var o=e[n]+"";(Tt.call(s,o)?s[o]:s[o]=[]).push(e[n])}return function(n){if(i){var r=n+"";return Tt.call(s,r)&&-1<W(s[r],n)}return-1<W(e,n,t)}}function a(e){return e.charCodeAt(0)}function f(e,t){var n=e.b,r=t.b,e=e.a,
t=t.a;if(e!==t){if(e>t||"undefined"==typeof e)return 1;if(e<t||"undefined"==typeof t)return-1}return n<r?-1:1}function l(e,t,n){function i(){var a=arguments,f=o?this:t;return s||(e=t[u]),n.length&&(a=a.length?n.concat(g(a)):n),this instanceof i?(m.prototype=e.prototype,f=new m,m.prototype=r,a=e.apply(f,a),k(a)?a:f):e.apply(f,a)}var s=C(e),o=!n,u=t;return o&&(n=t),s||(t=e),i}function c(e,t){return e?"function"!=typeof e?function(t){return t[e]}:"undefined"!=typeof t?function(n,r,i){return e.call(t
,n,r,i)}:e:K}function h(){for(var e={b:"",c:"",e:Kt,f:Jt,g:"",h:Yt,i:en,j:bt,k:"",l:n},t,r=0;t=arguments[r];r++)for(var i in t)e[i]=t[i];t=e.a,e.d=/^[^,]+/.exec(t)[0],r="var i,l="+e.d+",t="+e.d+";if(!"+e.d+")return t;"+e.k+";",e.b?(r+="var m=l.length;i=-1;if(typeof m=='number'){",e.i&&(r+="if(k(l)){l=l.split('')}"),r+="while(++i<m){"+e.b+"}}else {"):e.h&&(r+="var m=l.length;i=-1;if(m&&j(l)){while(++i<m){i+='';"+e.g+"}}else {"),e.e||(r+="var u=typeof l=='function'&&s.call(l,'prototype');");if(e.f&&
e.l)r+="var q=-1,r=p[typeof l]?n(l):[],m=r.length;while(++q<m){i=r[q];",e.e||(r+="if(!(u&&i=='prototype')){"),r+=e.g+"",e.e||(r+="}");else{r+="for(i in l){";if(!e.e||e.l)r+="if(",e.e||(r+="!(u&&i=='prototype')"),!e.e&&e.l&&(r+="&&"),e.l&&(r+="h.call(l,i)"),r+="){";r+=e.g+";";if(!e.e||e.l)r+="}"}r+="}";if(e.e){r+="var f=l.constructor;";for(i=0;7>i;i++)r+="i='"+e.j[i]+"';if(","constructor"==e.j[i]&&(r+="!(f&&f.prototype===l)&&"),r+="h.call(l,i)){"+e.g+"}"}if(e.b||e.h)r+="}";return r+=e.c+";return t"
,o("e,h,j,k,p,n,s","return function("+t+"){"+r+"}")(c,Tt,b,A,on,_t,Ct)}function p(e){return"\\"+un[e]}function d(e){return dn[e]}function v(e){return"function"!=typeof e.toString&&"string"==typeof (e+"")}function m(){}function g(e,t,n){t||(t=0),"undefined"==typeof n&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++r<n;)i[r]=e[t+r];return i}function y(e){return vn[e]}function b(e){return kt.call(e)==Bt}function w(e){var t=i;if(!e||"object"!=typeof e||b(e))return t;var n=e.constructor;return!
C(n)&&(!tn||!v(e))||n instanceof n?Qt?(hn(e,function(e,n,r){return t=!Tt.call(r,n),i}),t===i):(hn(e,function(e,n){t=n}),t===i||Tt.call(e,t)):t}function E(e){var t=[];return pn(e,function(e,n){t.push(n)}),t}function S(e,t,n,s,o){if(e==r)return e;n&&(t=i);if(n=k(e)){var u=kt.call(e);if(!rn[u]||tn&&v(e))return e;var a=gn(e)}if(!n||!t)return n?a?g(e):cn({},e):e;n=sn[u];switch(u){case Ft:case It:return new n(+e);case qt:case zt:return new n(e);case Ut:return n(e.source,ct.exec(e))}s||(s=[]),o||(o=[]);
for(u=s.length;u--;)if(s[u]==e)return o[u];var f=a?n(e.length):{};return s.push(e),o.push(f),(a?wn:pn)(e,function(e,n){f[n]=S(e,t,r,s,o)}),a&&(Tt.call(e,"index")&&(f.index=e.index),Tt.call(e,"input")&&(f.input=e.input)),f}function x(e){var t=[];return hn(e,function(e,n){C(e)&&t.push(n)}),t.sort()}function T(e){var t={};return pn(e,function(e,n){t[e]=n}),t}function N(e,t,s,o){if(e===t)return 0!==e||1/e==1/t;if(e==r||t==r)return e===t;var u=kt.call(e),a=kt.call(t);u==Bt&&(u=Rt),a==Bt&&(a=Rt);if(u!=
a)return i;switch(u){case Ft:case It:return+e==+t;case qt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case Ut:case zt:return e==t+""}a=u==jt;if(!a){if(e.__wrapped__||t.__wrapped__)return N(e.__wrapped__||e,t.__wrapped__||t);if(u!=Rt||tn&&(v(e)||v(t)))return i;var u=Zt&&b(e)?Object:e.constructor,f=Zt&&b(t)?Object:t.constructor;if(u!=f&&(!C(u)||!(u instanceof u&&C(f)&&f instanceof f)))return i}s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var l=n,c=0;s.push(e),o.push(t);if(a){c=e.length
;if(l=c==t.length)for(;c--&&(l=N(e[c],t[c],s,o)););return l}return hn(e,function(e,n,r){if(Tt.call(r,n))return c++,l=Tt.call(t,n)&&N(e,t[n],s,o)}),l&&hn(t,function(e,t,n){if(Tt.call(n,t))return l=-1<--c}),l}function C(e){return"function"==typeof e}function k(e){return e?on[typeof e]:i}function L(e){return"number"==typeof e||kt.call(e)==qt}function A(e){return"string"==typeof e||kt.call(e)==zt}function O(e,t,n){var i=arguments,s=0,o=2,u=i[3],a=i[4];n!==rt&&(u=[],a=[],"number"!=typeof n&&(o=i.length
));for(;++s<o;)pn(i[s],function(t,n){var i,s,o;if(t&&((s=gn(t))||yn(t))){for(var f=u.length;f--;)if(i=u[f]==t)break;i?e[n]=a[f]:(u.push(t),a.push(o=(o=e[n],s)?gn(o)?o:[]:yn(o)?o:{}),e[n]=O(o,t,rt,u,a))}else t!=r&&(e[n]=t)});return e}function M(e){var t=[];return pn(e,function(e){t.push(e)}),t}function _(e,t,n){var r=-1,s=e?e.length:0,o=i,n=(0>n?Dt(0,s+n):n)||0;return"number"==typeof s?o=-1<(A(e)?e.indexOf(t,n):W(e,t,n)):wn(e,function(e){if(++r>=n)return!(o=e===t)}),o}function D(e,t,r){var i=n,t=c
(t,r);if(gn(e))for(var r=-1,s=e.length;++r<s&&(i=!!t(e[r],r,e)););else wn(e,function(e,n,r){return i=!!t(e,n,r)});return i}function P(e,t,n){var r=[],t=c(t,n);if(gn(e))for(var n=-1,i=e.length;++n<i;){var s=e[n];t(s,n,e)&&r.push(s)}else wn(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function H(e,t,n){var r,t=c(t,n);return wn(e,function(e,n,s){if(t(e,n,s))return r=e,i}),r}function B(e,t,n){var r=-1,i=e?e.length:0,s=Array("number"==typeof i?i:0),t=c(t,n);if(gn(e))for(;++r<i;)s[r]=t(e[r],r,e);else wn
(e,function(e,n,i){s[++r]=t(e,n,i)});return s}function j(e,t,n){var r=-Infinity,i=-1,s=e?e.length:0,o=r;if(t||!gn(e))t=!t&&A(e)?a:c(t,n),wn(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,o=e)});else for(;++i<s;)e[i]>o&&(o=e[i]);return o}function F(e,t){return B(e,t+"")}function I(e,t,n,r){var s=3>arguments.length;return t||(t=K),wn(e,function(e,o,u){n=s?(s=i,e):t.call(r,n,e,o,u)}),n}function q(e,t,n,r){var s=e,o=e?e.length:0,u=3>arguments.length;if("number"!=typeof o)var a=bn(e),o=a.length;else en&&A(e)&&
(s=e.split(""));return t||(t=K),wn(e,function(e,f,l){f=a?a[--o]:--o,n=u?(u=i,s[f]):t.call(r,n,s[f],f,l)}),n}function R(e,t,n){var r,t=c(t,n);if(gn(e))for(var n=-1,i=e.length;++n<i&&!(r=t(e[n],n,e)););else wn(e,function(e,n,i){return!(r=t(e,n,i))});return!!r}function U(e,t,n){if(e){var i=e.length;return t==r||n?e[0]:g(e,0,Pt(Dt(0,t),i))}}function z(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];gn(s)?Nt.apply(i,t?s:z(s)):i.push(s)}return i}function W(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof
n)r=(0>n?Dt(0,i+n):n||0)-1;else if(n)return r=V(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function X(e,t,n){return g(e,t==r||n?1:Dt(0,t))}function V(e,t,n,r){for(var i=0,s=e?e.length:i,n=n?c(n,r):K,t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r;return i}function $(e,t,n,r){var s=-1,o=e?e.length:0,u=[],a=u;"function"==typeof t&&(r=n,n=t,t=i);var f=!t&&74<o;if(f)var l={};n&&(a=[],n=c(n,r));for(;++s<o;){var r=e[s],h=n?n(r,s,e):r;f&&(a=Tt.call(l,h+"")?l[h]:l[h]=[]);if(t?!s||a[a.length-1
]!==h:0>W(a,h))(n||f)&&a.push(h),u.push(r)}return u}function J(e,t){return $t||Lt&&2<arguments.length?Lt.call.apply(Lt,arguments):l(e,t,g(arguments,2))}function K(e){return e}function Q(e){wn(x(e),function(t){var n=s[t]=e[t];s.prototype[t]=function(){var e=[this.__wrapped__];return Nt.apply(e,arguments),e=n.apply(s,e),new s(e)}})}function G(){return this.__wrapped__}var n=!0,r=null,i=!1,Y="object"==typeof exports&&exports,Z="object"==typeof global&&global;Z.global===Z&&(e=Z);var et=[],tt=new function(
){},nt=0,rt=tt,it=30,st=e._,ot=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,ut=/&(?:amp|lt|gt|quot|#x27);/g,at=/\b__p\+='';/g,ft=/\b(__p\+=)''\+/g,lt=/(__e\(.*?\)|\b__t\))\+'';/g,ct=/\w*$/,ht=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,pt=RegExp("^"+(tt.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),dt=/\$\{((?:(?=\\?)\\?[\s\S])*?)}/g,vt=/<%=([\s\S]+?)%>/g,mt=/($^)/,gt=/[&<>"']/g,yt=/['\n\r\t\u2028\u2029\\]/g,bt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf"
.split(" "),wt=Math.ceil,Et=et.concat,St=Math.floor,xt=pt.test(xt=Object.getPrototypeOf)&&xt,Tt=tt.hasOwnProperty,Nt=et.push,Ct=tt.propertyIsEnumerable,kt=tt.toString,Lt=pt.test(Lt=g.bind)&&Lt,At=pt.test(At=Array.isArray)&&At,Ot=e.isFinite,Mt=e.isNaN,_t=pt.test(_t=Object.keys)&&_t,Dt=Math.max,Pt=Math.min,Ht=Math.random,Bt="[object Arguments]",jt="[object Array]",Ft="[object Boolean]",It="[object Date]",qt="[object Number]",Rt="[object Object]",Ut="[object RegExp]",zt="[object String]",Wt=!/1/.test
(Function("1")),Xt=!!e.attachEvent,Vt=Lt&&!/\n|true/.test(Lt+Xt),$t=Lt&&!Vt,Jt=_t&&(Xt||Vt),Kt,Qt,Gt=(Gt={0:1,length:1},et.splice.call(Gt,0,1),Gt[0]),Yt=n;(function(){function e(){this.x=1}var t=[];e.prototype={valueOf:1,y:1};for(var n in new e)t.push(n);for(n in arguments)Yt=!n;Kt=!/valueOf/.test(t),Qt="x"!=t[0]})(1);var Zt=!b(arguments),en="xx"!="x"[0]+Object("x")[0];try{var tn=("[object Object]",kt.call(document)==Rt)}catch(nn){}var rn={"[object Function]":i};rn[Bt]=rn[jt]=rn[Ft]=rn[It]=rn[qt]=
rn[Rt]=rn[Ut]=rn[zt]=n;var sn={};sn[jt]=Array,sn[Ft]=Boolean,sn[It]=Date,sn[Rt]=Object,sn[qt]=Number,sn[Ut]=RegExp,sn[zt]=String;var on={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i},un={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:vt,variable:""};if(Xt||Vt||!Wt)o=Function;var an={a:"o,v,g",k:"for(var a=1,b=typeof g=='number'?2:arguments.length;a<b;a++){if((l=arguments[a])){"
,g:"t[i]=l[i]",c:"}}"},fn={a:"d,c,w",k:"c=c&&typeof w=='undefined'?c:e(c,w)",b:"if(c(l[i],i,d)===false)return t",g:"if(c(l[i],i,d)===false)return t"},ln={b:r},cn=h(an);Zt&&(b=function(e){return e?Tt.call(e,"callee"):i});var hn=h(fn,ln,{l:i}),pn=h(fn,ln),dn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},vn=T(dn),mn=h(an,{g:"if(t[i]==null)"+an.g}),gn=At||function(e){return kt.call(e)==jt};C(/x/)&&(C=function(e){return"[object Function]"==kt.call(e)});var yn=xt?function(e){if(!e||"object"!=typeof
e)return i;var t=e.valueOf,n="function"==typeof t&&(n=xt(t))&&xt(n);return n?e==n||xt(e)==n&&!b(e):w(e)}:w,bn=_t?function(e){return"function"==typeof e&&Ct.call(e,"prototype")?E(e):k(e)?_t(e):[]}:E,wn=h(fn);s.VERSION="1.0.0-rc.1",s.assign=cn,s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=J,s.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=x(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=J(e[i],e)}return e},s.bindKey=function(e,t){return l(e,t
,g(arguments,2))},s.chain=function(e){return new s(e)},s.clone=S,s.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},s.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},s.contains=_,s.countBy=function(e,t,n){var r={},t=c(t,n);return wn(e,function(e,n,i){n=t(e,n,i),Tt.call(r,n)?r[n]++:r[n]=1}),r},s.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(
){var r=n&&!a;return s=arguments,u=this,clearTimeout(a),a=setTimeout(i,t),r&&(o=e.apply(u,s)),o}},s.defaults=mn,s.defer=function(e){var n=g(arguments,1);return setTimeout(function(){e.apply(t,n)},1)},s.delay=function(e,n){var r=g(arguments,2);return setTimeout(function(){e.apply(t,r)},n)},s.difference=function(e){for(var t=-1,n=e?e.length:0,r=Et.apply(et,arguments),r=u(r,n),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.escape=function(e){return e==r?"":(e+"").replace(gt,d)},s.every=D,s.filter=
P,s.find=H,s.first=U,s.flatten=z,s.forEach=wn,s.forIn=hn,s.forOwn=pn,s.functions=x,s.groupBy=function(e,t,n){var r={},t=c(t,n);return wn(e,function(e,n,i){n=t(e,n,i),(Tt.call(r,n)?r[n]:r[n]=[]).push(e)}),r},s.has=function(e,t){return e?Tt.call(e,t):i},s.identity=K,s.indexOf=W,s.initial=function(e,t,n){if(!e)return[];var i=e.length;return g(e,0,Pt(Dt(0,i-(t==r||n?1:t||0)),i))},s.intersection=function(e){var t=arguments,n=t.length,r={},i=[];return wn(e,function(e){if(0>W(i,e)){for(var s=n;--s;)if(!
(r[s]||(r[s]=u(t[s])))(e))return;i.push(e)}}),i},s.invert=T,s.invoke=function(e,t){var n=g(arguments,2),r="function"==typeof t,i=[];return wn(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},s.isArguments=b,s.isArray=gn,s.isBoolean=function(e){return e===n||e===i||kt.call(e)==Ft},s.isDate=function(e){return kt.call(e)==It},s.isElement=function(e){return e?1===e.nodeType:i},s.isEmpty=function(e){var t=n;if(!e)return t;var r=kt.call(e),s=e.length;return r==jt||r==zt||r==Bt||Zt&&b(e)||r==Rt&&"number"==typeof
s&&C(e.splice)?!s:(pn(e,function(){return t=i}),t)},s.isEqual=N,s.isFinite=function(e){return Ot(e)&&!Mt(parseFloat(e))},s.isFunction=C,s.isNaN=function(e){return L(e)&&e!=+e},s.isNull=function(e){return e===r},s.isNumber=L,s.isObject=k,s.isPlainObject=yn,s.isRegExp=function(e){return kt.call(e)==Ut},s.isString=A,s.isUndefined=function(e){return"undefined"==typeof e},s.keys=bn,s.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:g(e,Dt(0,i-t))}},s.lastIndexOf=function(e,t,n){var r=e?
e.length:0;for("number"==typeof n&&(r=(0>n?Dt(0,r+n):Pt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},s.map=B,s.max=j,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Tt.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=O,s.min=function(e,t,n){var r=Infinity,i=-1,s=e?e.length:0,o=r;if(t||!gn(e))t=!t&&A(e)?a:c(t,n),wn(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,o=e)});else for(;++i<s;)e[i]<o&&(o=e[i]);return o},s.mixin=Q,s.noConflict=function()
{return e._=st,this},s.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},s.omit=function(e,t,n){var r="function"==typeof t,i={};if(r)t=c(t,n);else var s=Et.apply(et,arguments);return hn(e,function(e,n,o){if(r?!t(e,n,o):0>W(s,n,1))i[n]=e}),i},s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.pairs=function(e){var t=[];return pn(e,function(e,n){t.push([n,e])}),t},s.partial=function(e){return l
(e,g(arguments,1))},s.pick=function(e,t,n){var r={};if("function"!=typeof t)for(var i=0,s=Et.apply(et,arguments),o=s.length;++i<o;){var u=s[i];u in e&&(r[u]=e[u])}else t=c(t,n),hn(e,function(e,n,i){t(e,n,i)&&(r[n]=e)});return r},s.pluck=F,s.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+St(Ht()*((+t||0)-e+1))},s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=Dt(0,wt((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reduce=I,s.reduceRight=q,s.reject=
function(e,t,n){return t=c(t,n),P(e,function(e,n,r){return!t(e,n,r)})},s.rest=X,s.result=function(e,t){var n=e?e[t]:r;return C(n)?e[t]():n},s.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return wn(e,function(e){var r=St(Ht()*(++t+1));n[t]=n[r],n[r]=e}),n},s.size=function(e){var t=e?e.length:0;return"number"==typeof t?t:bn(e).length},s.some=R,s.sortBy=function(e,t,n){var r=[],t=c(t,n);wn(e,function(e,n,i){r.push({a:t(e,n,i),b:n,c:e})}),e=r.length;for(r.sort(f);e--;)r[e]=r[e].c;return r},s.sortedIndex=
V,s.tap=function(e,t){return t(e),e},s.template=function(e,t,n){e||(e=""),n||(n={});var r,i,u=s.templateSettings,a=0,f=n.interpolate||u.interpolate||mt,l="__p+='",c=n.variable||u.variable,h=c;e.replace(RegExp((n.escape||u.escape||mt).source+"|"+f.source+"|"+(f===vt?dt:mt).source+"|"+(n.evaluate||u.evaluate||mt).source+"|$","g"),function(t,n,i,s,o,u){return i||(i=s),l+=e.slice(a,u).replace(yt,p),n&&(l+="'+__e("+n+")+'"),o&&(l+="';"+o+";__p+='"),i&&(l+="'+((__t=("+i+"))==null?'':__t)+'"),r||(r=o||ot
.test(n||i)),a=u+t.length,t}),l+="';\n",h||(c="obj",r?l="with("+c+"){"+l+"}":(n=RegExp("(\\(\\s*)"+c+"\\."+c+"\\b","g"),l=l.replace(ht,"$&"+c+".").replace(n,"$1__d"))),l=(r?l.replace(at,""):l).replace(ft,"$1").replace(lt,"$1;"),l="function("+c+"){"+(h?"":c+"||("+c+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(h?"":",__d="+c+"."+c+"||"+c)+";")+l+"return __p}";try{i=o("_","return "+l)(s)}catch(d){throw d.source=l,d}return t?i(t)
:(i.source=l,i)},s.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(){var f=new Date,l=t-(f-a);return i=arguments,o=this,0>=l?(clearTimeout(u),u=r,a=f,s=e.apply(o,i)):u||(u=setTimeout(n,l)),s}},s.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},s.toArray=function(e){return"number"==typeof (e?e.length:0)?en&&A(e)?e.split(""):g(e):M(e)},s.unescape=function(e){return e==r?"":(e+"").replace(ut,y)},s.union=function(
){return $(Et.apply(et,arguments))},s.uniq=$,s.uniqueId=function(e){return(e==r?"":e+"")+ ++nt},s.values=M,s.where=function(e,t){var n=bn(t);return P(e,function(e){for(var r=n.length;r--;){var i=e[n[r]]===t[n[r]];if(!i)break}return!!i})},s.without=function(e){for(var t=-1,n=e?e.length:0,r=u(arguments,1,20),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.wrap=function(e,t){return function(){var n=[e];return Nt.apply(n,arguments),t.apply(this,n)}},s.zip=function(e){for(var t=-1,n=e?j(F(arguments
,"length")):0,r=Array(n);++t<n;)r[t]=F(arguments,t);return r},s.all=D,s.any=R,s.collect=B,s.detect=H,s.drop=X,s.each=wn,s.extend=cn,s.foldl=I,s.foldr=q,s.head=U,s.include=_,s.inject=I,s.methods=x,s.select=P,s.tail=X,s.take=U,s.unique=$,Q(s),s.prototype.chain=function(){return this},s.prototype.toString=function(){return""+this.__wrapped__},s.prototype.value=G,s.prototype.valueOf=G,wn(["first","last"],function(e){var t=s[e];t&&(s.prototype[e]=function(e,n){var i=t(this.__wrapped__,e,n);return e==r||
n?i:new s(i)})}),wn(P(x(s),function(e){return/^(?:bind|contains|every|find|has|is[A-Z].+|reduce.*|some)$/.test(e)}),function(e){var t=s[e];s.prototype[e]=function(){var e=[this.__wrapped__];return Nt.apply(e,arguments),t.apply(s,e)}}),wn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=et[e];s.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),Gt&&e.length===0&&delete e[0],this}}),wn(["concat","join","slice"],function(e){var t=et[e];s.prototype[e]=
function(){var e=t.apply(this.__wrapped__,arguments);return new s(e)}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):Y?"object"==typeof module&&module&&module.exports==Y?(module.exports=s)._=s:Y._=s:e._=s})(this);

3772
lodash.underscore.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +1,33 @@
/*!
Lo-Dash 0.10.0 (Custom Build) lodash.com/license
Lo-Dash 1.0.0-rc.1 (Custom Build) lodash.com/license
Build: `lodash underscore -m -o ./lodash.underscore.min.js`
Underscore.js 1.4.2 underscorejs.org/LICENSE
*/
;(function(e,t){function n(e){if(e&&e.__wrapped__)return e;if(!(this instanceof n))return new n(e);this.__wrapped__=e}function r(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1;if(e<n||n===t)return-1}return r<i?-1:1}function i(e,t,n){function r(){var i=arguments,s=t;return n.length&&(i=i.length?n.concat(tt.call(i)):n),this instanceof r?(a.prototype=e.prototype,s=new a,i=e.apply(s,i),g(i)?i:s):e.apply(s,i)}return r}function s(e,n){return e?"function"!=typeof e?function(t){return t
[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:j}function o(e){return"\\"+wt[e]}function u(e){return xt[e]}function a(){}function f(e){return Tt[e]}function l(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)for(var i in r)e[i]=r[i]}return e}function c(e){var t=[];return St(e,function(e,n){t.push(n)}),t}function h(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)for(var i in r)null==e[i]&&(e[i]=r[i])}return e}function p(e){var t=
[];return Et(e,function(e,n){m(e)&&t.push(n)}),t.sort()}function d(e){var t={};return St(e,function(e,n){t[e]=n}),t}function v(e,t,n,r){if(e===t)return 0!==e||1/e==1/t;if(null==e||null==t)return e===t;var i=nt.call(e);if(i!=nt.call(t))return!1;switch(i){case ct:case ht:return+e==+t;case pt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case vt:case mt:return e==t+""}var s=i==lt;if(!s){if(e.__wrapped__||t.__wrapped__)return v(e.__wrapped__||e,t.__wrapped__||t);if(i!=dt)return!1;var i=e.constructor,o=t.constructor
;if(i!=o&&(!m(i)||!(i instanceof i&&m(o)&&o instanceof o)))return!1}n||(n=[]),r||(r=[]);for(i=n.length;i--;)if(n[i]==e)return r[i]==t;i=!0,o=0,n.push(e),r.push(t);if(s){o=e.length;if(i=o==t.length)for(;o--&&(i=v(e[o],t[o],n,r)););return i}for(var u in e)if(Z.call(e,u)&&(o++,!Z.call(t,u)||!v(e[u],t[u],n,r)))return!1;for(u in t)if(Z.call(t,u)&&!(o--))return!1;return!0}function m(e){return"function"==typeof e}function g(e){return e?bt[typeof e]:!1}function y(e){return nt.call(e)==mt}function b(e){var t=
[];return St(e,function(e){t.push(e)}),t}function w(e,t){var n=!1;return"number"==typeof (e?e.length:0)?n=-1<_(e,t):kt(e,function(e){return(n=e===t)&&z}),n}function E(e,t,n){var r=!0,t=s(t,n);if(Nt(e))for(var n=-1,i=e.length;++n<i&&(r=!!t(e[n],n,e)););else kt(e,function(e,n,i){return!(r=!!t(e,n,i))&&z});return r}function S(e,t,n){var r=[],t=s(t,n);if(Nt(e))for(var n=-1,i=e.length;++n<i;){var o=e[n];t(o,n,e)&&r.push(o)}else kt(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function x(e,t,n){var r
,t=s(t,n);return kt(e,function(e,n,i){if(t(e,n,i))return r=e,z}),r}function T(e,t,n){var r=-1,i=e?e.length:0,o=Array("number"==typeof i?i:0),t=s(t,n);if(Nt(e))for(;++r<i;)o[r]=t(e[r],r,e);else kt(e,function(e,n,i){o[++r]=t(e,n,i)});return o}function N(e,t,n){var r=-Infinity,i=-1,o=e?e.length:0,u=r;if(t||!Nt(e))t=s(t,n),kt(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,u=e)});else for(;++i<o;)e[i]>u&&(u=e[i]);return u}function C(e,t){var n=[];return kt(e,function(e){n.push(e[t])}),n}function k(e,t,n,r){var i=3>
arguments.length,t=s(t,r);return kt(e,function(e,r,s){n=i?(i=!1,e):t(n,e,r,s)}),n}function L(e,t,n,r){var i=e?e.length:0,s=3>arguments.length;if("number"!=typeof i)var o=Ct(e),i=o.length;return kt(e,function(u,a,f){a=o?o[--i]:--i,n=s?(s=!1,e[a]):t.call(r,n,e[a],a,f)}),n}function A(e,t,n){var r,t=s(t,n);if(Nt(e))for(var n=-1,i=e.length;++n<i&&!(r=t(e[n],n,e)););else kt(e,function(e,n,i){return(r=t(e,n,i))&&z});return!!r}function O(e,t,n){if(e)return null==t||n?e[0]:tt.call(e,0,t)}function M(e,t){for(
var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];Nt(s)?et.apply(i,t?s:M(s)):i.push(s)}return i}function _(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof n)r=(0>n?ut(0,i+n):n||0)-1;else if(n)return r=P(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function D(e,t,n){return e?tt.call(e,null==t||n?1:t):[]}function P(e,t,n,r){for(var i=0,o=e?e.length:i,n=n?s(n,r):j,t=n(t);i<o;)r=i+o>>>1,n(e[r])<t?i=r+1:o=r;return i}function H(e,t,n,r){var i=-1,o=e?e.length:0,u=[],a=u;n&&(a=[],n=s(n,r
));for(;++i<o;){var r=e[i],f=n?n(r,i,e):r;if(t?!i||a[a.length-1]!==f:0>_(a,f))n&&a.push(f),u.push(r)}return u}function B(e,t){return yt||rt&&2<arguments.length?rt.call.apply(rt,arguments):i(e,t,tt.call(arguments,2))}function j(e){return e}function F(e){kt(p(e),function(t){var r=n[t]=e[t];n.prototype[t]=function(){var e=[this.__wrapped__];return et.apply(e,arguments),e=r.apply(n,e),this.__chain__&&(e=new n(e),e.__chain__=!0),e}})}var I="object"==typeof exports&&exports,q="object"==typeof global&&global
;q.global===q&&(e=q);var R=[],q=new function(){},U=0,z=q,W=e._,X=/&(?:amp|lt|gt|quot|#x27);/g,V=RegExp("^"+(q.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),$=/($^)/,J=/[&<>"']/g,K=/['\n\r\t\u2028\u2029\\]/g,Q=Math.ceil,G=R.concat,Y=Math.floor,Z=q.hasOwnProperty,et=R.push,tt=R.slice,nt=q.toString,rt=V.test(rt=tt.bind)&&rt,it=V.test(it=Array.isArray)&&it,st=e.isFinite,ot=V.test(ot=Object.keys)&&ot,ut=Math.max,at=Math.min,ft=Math.random,lt="[object Array]"
,ct="[object Boolean]",ht="[object Date]",pt="[object Number]",dt="[object Object]",vt="[object RegExp]",mt="[object String]",gt=(gt={0:1,length:1},R.splice.call(gt,0,1),gt[0]),yt=rt&&/\n|Opera/.test(rt+nt.call(e.opera)),bt={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,"undefined":!1},wt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};n.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},n.isArguments=
function(e){return"[object Arguments]"==nt.call(e)},n.isArguments(arguments)||(n.isArguments=function(e){return e?Z.call(e,"callee"):!1});var Et=function(e,t){var n,r;if(!e)return e;t=s(t);for(n in e)if(r=e[n],t(r,n,e)===z)break;return e},St=function(e,t){var n,r;if(!e)return e;t=s(t);for(n in e)if(Z.call(e,n)&&(r=e[n],t(r,n,e)===z))break;return e},xt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},Tt=d(xt),Nt=it||function(e){return nt.call(e)==lt};m(/x/)&&(m=function(e){return"[object Function]"==
nt.call(e)});var Ct=ot?function(e){return g(e)?ot(e):[]}:c,kt=function(e,t,n){var r;if(!e)return e;var t=s(t,n),i=e.length,n=-1;if("number"==typeof i){for(;++n<i;)if(r=e[n],t(r,n,e)===z)return e}else for(n in e)if(Z.call(e,n)&&(r=e[n],t(r,n,e)===z))return e};n.VERSION="0.10.0",n.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},n.bind=B,n.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=p(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=B(e[i],e)}return e},
n.chain=function(e){return e=new n(e),e.__chain__=!0,e},n.clone=function(e){return e&&bt[typeof e]?Nt(e)?tt.call(e):l({},e):e},n.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},n.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},n.contains=w,n.countBy=function(e,t,n){var r={},t=s(t,n);return kt(e,function(e,n,i){n=t(e,n,i),Z.call(r,n)?r[n]++:r[n]=1}),r},n.debounce=function(e,
t,n){function r(){u=null,n||(s=e.apply(o,i))}var i,s,o,u;return function(){var a=n&&!u;return i=arguments,o=this,clearTimeout(u),u=setTimeout(r,t),a&&(s=e.apply(o,i)),s}},n.defaults=h,n.defer=function(e){var n=tt.call(arguments,1);return setTimeout(function(){e.apply(t,n)},1)},n.delay=function(e,n){var r=tt.call(arguments,2);return setTimeout(function(){e.apply(t,r)},n)},n.difference=function(e){for(var t=-1,n=e.length,r=G.apply(R,arguments),i=[];++t<n;){var s=e[t];0>_(r,s,n)&&i.push(s)}return i}
,n.escape=function(e){return null==e?"":(e+"").replace(J,u)},n.every=E,n.filter=S,n.find=x,n.first=O,n.flatten=M,n.forEach=kt,n.functions=p,n.groupBy=function(e,t,n){var r={},t=s(t,n);return kt(e,function(e,n,i){n=t(e,n,i),(Z.call(r,n)?r[n]:r[n]=[]).push(e)}),r},n.has=function(e,t){return e?Z.call(e,t):!1},n.identity=j,n.indexOf=_,n.initial=function(e,t,n){return e?tt.call(e,0,-(null==t||n?1:t)):[]},n.intersection=function(e){var t=arguments,n=t.length,r=[];return kt(e,function(e){if(0>_(r,e)){for(
var i=n;--i;)if(0>_(t[i],e))return;r.push(e)}}),r},n.invert=d,n.invoke=function(e,t){var n=tt.call(arguments,2),r="function"==typeof t,i=[];return kt(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},n.isArray=Nt,n.isBoolean=function(e){return!0===e||!1===e||nt.call(e)==ct},n.isDate=function(e){return nt.call(e)==ht},n.isElement=function(e){return e?1===e.nodeType:!1},n.isEmpty=function(e){if(!e)return!0;if(Nt(e)||y(e))return!e.length;for(var t in e)if(Z.call(e,t))return!1;return!0},n.isEqual=v,n.
isFinite=function(e){return st(e)&&nt.call(e)==pt},n.isFunction=m,n.isNaN=function(e){return nt.call(e)==pt&&e!=+e},n.isNull=function(e){return null===e},n.isNumber=function(e){return nt.call(e)==pt},n.isObject=g,n.isRegExp=function(e){return nt.call(e)==vt},n.isString=y,n.isUndefined=function(e){return e===t},n.keys=Ct,n.last=function(e,t,n){if(e){var r=e.length;return null==t||n?e[r-1]:tt.call(e,-t||r)}},n.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?ut(0,r+n):
at(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},n.map=T,n.max=N,n.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Z.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},n.min=function(e,t,n){var r=Infinity,i=-1,o=e?e.length:0,u=r;if(t||!Nt(e))t=s(t,n),kt(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,u=e)});else for(;++i<o;)e[i]<u&&(u=e[i]);return u},n.mixin=F,n.noConflict=function(){return e._=W,this},n.object=function(e,t){for(var n=-1,r=e?e.length:0,i={}
;++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},n.omit=function(e){var t=G.apply(R,arguments),n={};return Et(e,function(e,r){0>_(t,r,1)&&(n[r]=e)}),n},n.once=function(e){var t,n=!1;return function(){return n?t:(n=!0,t=e.apply(this,arguments),e=null,t)}},n.pairs=function(e){var t=[];return St(e,function(e,n){t.push([n,e])}),t},n.pick=function(e){for(var t=0,n=G.apply(R,arguments),r=n.length,i={};++t<r;){var s=n[t];s in e&&(i[s]=e[s])}return i},n.pluck=C,n.random=function(e,t){return null==e&&
null==t&&(t=1),e=+e||0,null==t&&(t=e,e=0),e+Y(ft()*((+t||0)-e+1))},n.range=function(e,t,n){e=+e||0,n=+n||1,null==t&&(t=e,e=0);for(var r=-1,t=ut(0,Q((t-e)/n)),i=Array(t);++r<t;)i[r]=e,e+=n;return i},n.reduce=k,n.reduceRight=L,n.reject=function(e,t,n){return t=s(t,n),S(e,function(e,n,r){return!t(e,n,r)})},n.rest=D,n.result=function(e,t){var n=e?e[t]:null;return m(n)?e[t]():n},n.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return kt(e,function(e){var r=Y(ft()*(++t+1));n[t]=n[r],n[r]=e}),n},n.size=
function(e){var t=e?e.length:0;return"number"==typeof t?t:Ct(e).length},n.some=A,n.sortBy=function(e,t,n){var i=[],t=s(t,n);kt(e,function(e,n,r){i.push({a:t(e,n,r),b:n,c:e})}),e=i.length;for(i.sort(r);e--;)i[e]=i[e].c;return i},n.sortedIndex=P,n.tap=function(e,t){return t(e),e},n.template=function(e,t,r){e||(e="");var r=h({},r,n.templateSettings),i=0,s="__p += '",u=r.variable;e.replace(RegExp((r.escape||$).source+"|"+(r.interpolate||$).source+"|"+(r.evaluate||$).source+"|$","g"),function(t,n,r,u,
a){s+=e.slice(i,a).replace(K,o),s+=n?"'+_['escape']("+n+")+'":u?"';"+u+";__p+='":r?"'+((__t=("+r+"))==null?'':__t)+'":"",i=a+t.length}),s+="';",u||(u="obj",s="with("+u+"||{}){"+s+"}"),s="function("+u+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+s+"return __p}";try{var a=Function("_","return "+s)(n)}catch(f){throw f.source=s,f}return t?a(t):(a.source=s,a)},n.throttle=function(e,t){function n(){u=new Date,o=null,i=e.apply(s,r)}var r,i,s,o,u=0;return function(
){var a=new Date,f=t-(a-u);return r=arguments,s=this,0>=f?(clearTimeout(o),u=a,i=e.apply(s,r)):o||(o=setTimeout(n,f)),i}},n.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},n.toArray=function(e){return e&&"number"==typeof e.length?"string"==typeof e?e.split(""):tt.call(e):b(e)},n.unescape=function(e){return null==e?"":(e+"").replace(X,f)},n.union=function(){return H(G.apply(R,arguments))},n.uniq=H,n.uniqueId=function(e){var t=U++;return e?e+t:t},n.values=b,n
.where=function(e,t){var n=Ct(t);return S(e,function(e){for(var r=n.length;r--;){var i=e[n[r]]===t[n[r]];if(!i)break}return!!i})},n.without=function(e){for(var t=-1,n=e.length,r=[];++t<n;){var i=e[t];0>_(arguments,i,1)&&r.push(i)}return r},n.wrap=function(e,t){return function(){var n=[e];return et.apply(n,arguments),t.apply(this,n)}},n.zip=function(e){for(var t=-1,n=e?N(C(arguments,"length")):0,r=Array(n);++t<n;)r[t]=C(arguments,t);return r},n.all=E,n.any=A,n.collect=T,n.detect=x,n.drop=D,n.each=
kt,n.extend=l,n.foldl=k,n.foldr=L,n.head=O,n.include=w,n.inject=k,n.methods=p,n.select=S,n.tail=D,n.take=O,n.unique=H,F(n),n.prototype.chain=function(){return this.__chain__=!0,this},n.prototype.value=function(){return this.__wrapped__},kt("pop push reverse shift sort splice unshift".split(" "),function(e){var t=R[e];n.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),gt&&e.length===0&&delete e[0],this.__chain__&&(e=new n(e),e.__chain__=!0),e}}),kt(["concat","join","slice"
],function(e){var t=R[e];n.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new n(e),e.__chain__=!0),e}}),I?"object"==typeof module&&module&&module.exports==I?(module.exports=n)._=n:I._=n:e._=n})(this);
;(function(e,t){function n(e){if(e&&"object"==typeof e&&e.__wrapped__)return e;if(!(this instanceof n))return new n(e);this.__wrapped__=e}function r(e,t){var n=e.b,r=t.b,e=e.a,t=t.a;if(e!==t){if(e>t||"undefined"==typeof e)return 1;if(e<t||"undefined"==typeof t)return-1}return n<r?-1:1}function i(e,t,n){function r(){var i=arguments,s=t;return n.length&&(i=i.length?n.concat(f(i)):n),this instanceof r?(a.prototype=e.prototype,s=new a,a.prototype=null,i=e.apply(s,i),y(i)?i:s):e.apply(s,i)}return r}function s
(e,t){return e?"function"!=typeof e?function(t){return t[e]}:"undefined"!=typeof t?function(n,r,i){return e.call(t,n,r,i)}:e:I}function o(e){return"\\"+Et[e]}function u(e){return Tt[e]}function a(){}function f(e,t,n){t||(t=0),"undefined"==typeof n&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++r<n;)i[r]=e[t+r];return i}function l(e){return Nt[e]}function c(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)for(var i in r)e[i]=r[i]}return e}function h(e){
var t=[];return xt(e,function(e,n){t.push(n)}),t}function p(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)for(var i in r)null==e[i]&&(e[i]=r[i])}return e}function d(e){var t=[];return St(e,function(e,n){g(e)&&t.push(n)}),t.sort()}function v(e){var t={};return xt(e,function(e,n){t[e]=n}),t}function m(e,t,n,r){if(e===t)return 0!==e||1/e==1/t;if(null==e||null==t)return e===t;var i=rt.call(e),s=rt.call(t);if(i!=s)return!1;switch(i){case ht:case pt:return+e==+t;case dt
:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case mt:case gt:return e==t+""}s=i==ct;if(!s){if(e.__wrapped__||t.__wrapped__)return m(e.__wrapped__||e,t.__wrapped__||t);if(i!=vt)return!1;var i=e.constructor,o=t.constructor;if(i!=o&&(!g(i)||!(i instanceof i&&g(o)&&o instanceof o)))return!1}n||(n=[]),r||(r=[]);for(i=n.length;i--;)if(n[i]==e)return r[i]==t;var u=!0,a=0;n.push(e),r.push(t);if(s){a=e.length;if(u=a==t.length)for(;a--&&(u=m(e[a],t[a],n,r)););return u}return St(e,function(e,i,s){if(tt.call(s,i)
)return a++,!(u=tt.call(t,i)&&m(e,t[i],n,r))&&X}),u&&St(t,function(e,t,n){if(tt.call(n,t))return!(u=-1<--a)&&X}),u}function g(e){return"function"==typeof e}function y(e){return e?wt[typeof e]:!1}function b(e){return"number"==typeof e||rt.call(e)==dt}function w(e){return"string"==typeof e||rt.call(e)==gt}function E(e){var t=[];return xt(e,function(e){t.push(e)}),t}function S(e,t){var n=!1;return"number"==typeof (e?e.length:0)?n=-1<P(e,t):Lt(e,function(e){return(n=e===t)&&X}),n}function x(e,t,n){var r=!0
,t=s(t,n);if(Ct(e))for(var n=-1,i=e.length;++n<i&&(r=!!t(e[n],n,e)););else Lt(e,function(e,n,i){return!(r=!!t(e,n,i))&&X});return r}function T(e,t,n){var r=[],t=s(t,n);if(Ct(e))for(var n=-1,i=e.length;++n<i;){var o=e[n];t(o,n,e)&&r.push(o)}else Lt(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function N(e,t,n){var r,t=s(t,n);return Lt(e,function(e,n,i){if(t(e,n,i))return r=e,X}),r}function C(e,t,n){var r=-1,i=e?e.length:0,o=Array("number"==typeof i?i:0),t=s(t,n);if(Ct(e))for(;++r<i;)o[r]=t(e[r
],r,e);else Lt(e,function(e,n,i){o[++r]=t(e,n,i)});return o}function k(e,t,n){var r=-Infinity,i=-1,o=e?e.length:0,u=r;if(t||!Ct(e))t=s(t,n),Lt(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,u=e)});else for(;++i<o;)e[i]>u&&(u=e[i]);return u}function L(e,t){return C(e,t+"")}function A(e,t,n,r){var i=3>arguments.length;return t||(t=I),Lt(e,function(e,s,o){n=i?(i=!1,e):t.call(r,n,e,s,o)}),n}function O(e,t,n,r){var i=e?e.length:0,s=3>arguments.length;if("number"!=typeof i)var o=kt(e),i=o.length;return t||(t=I
),Lt(e,function(u,a,f){a=o?o[--i]:--i,n=s?(s=!1,e[a]):t.call(r,n,e[a],a,f)}),n}function M(e,t,n){var r,t=s(t,n);if(Ct(e))for(var n=-1,i=e.length;++n<i&&!(r=t(e[n],n,e)););else Lt(e,function(e,n,i){return(r=t(e,n,i))&&X});return!!r}function _(e,t,n){if(e){var r=e.length;return null==t||n?e[0]:f(e,0,ft(at(0,t),r))}}function D(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];Ct(s)?nt.apply(i,t?s:D(s)):i.push(s)}return i}function P(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof n)r=(0>n?at
(0,i+n):n||0)-1;else if(n)return r=B(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function H(e,t,n){return f(e,null==t||n?1:at(0,t))}function B(e,t,n,r){for(var i=0,o=e?e.length:i,n=n?s(n,r):I,t=n(t);i<o;)r=i+o>>>1,n(e[r])<t?i=r+1:o=r;return i}function j(e,t,n,r){var i=-1,o=e?e.length:0,u=[],a=u;n&&(a=[],n=s(n,r));for(;++i<o;){var r=e[i],f=n?n(r,i,e):r;if(t?!i||a[a.length-1]!==f:0>P(a,f))n&&a.push(f),u.push(r)}return u}function F(e,t){return yt||it&&2<arguments.length?it.call.apply
(it,arguments):i(e,t,f(arguments,2))}function I(e){return e}function q(e){Lt(d(e),function(t){var r=n[t]=e[t];n.prototype[t]=function(){var e=[this.__wrapped__];return nt.apply(e,arguments),e=r.apply(n,e),this.__chain__&&(e=new n(e),e.__chain__=!0),e}})}var R="object"==typeof exports&&exports,U="object"==typeof global&&global;U.global===U&&(e=U);var z=[],U=new function(){},W=0,X=U,V=e._,$=/&(?:amp|lt|gt|quot|#x27);/g,J=RegExp("^"+(U.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g
,".+?")+"$"),K=/($^)/,Q=/[&<>"']/g,G=/['\n\r\t\u2028\u2029\\]/g,Y=Math.ceil,Z=z.concat,et=Math.floor,tt=U.hasOwnProperty,nt=z.push,rt=U.toString,it=J.test(it=f.bind)&&it,st=J.test(st=Array.isArray)&&st,ot=e.isFinite,ut=J.test(ut=Object.keys)&&ut,at=Math.max,ft=Math.min,lt=Math.random,ct="[object Array]",ht="[object Boolean]",pt="[object Date]",dt="[object Number]",vt="[object Object]",mt="[object RegExp]",gt="[object String]",U=!!e.attachEvent,U=it&&!/\n|true/.test(it+U),yt=it&&!U,bt=(bt={0:1,length
:1},z.splice.call(bt,0,1),bt[0]),wt={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,"undefined":!1},Et={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};n.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},n.isArguments=function(e){return"[object Arguments]"==rt.call(e)},n.isArguments(arguments)||(n.isArguments=function(e){return e?tt.call(e,"callee"):!1});var St=function(e,t){var n;if(!e)return e
;t||(t=I);for(n in e)if(t(e[n],n,e)===X)break;return e},xt=function(e,t){var n;if(!e)return e;t||(t=I);for(n in e)if(tt.call(e,n)&&t(e[n],n,e)===X)break;return e},Tt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},Nt=v(Tt),Ct=st||function(e){return rt.call(e)==ct};g(/x/)&&(g=function(e){return"[object Function]"==rt.call(e)});var kt=ut?function(e){return y(e)?ut(e):[]}:h,Lt=function(e,t,n){if(!e)return e;var t=t&&"undefined"==typeof n?t:s(t,n),r=e.length,n=-1;if("number"==typeof r){
for(;++n<r;)if(t(e[n],n,e)===X)return e}else for(n in e)if(tt.call(e,n)&&t(e[n],n,e)===X)return e};n.VERSION="1.0.0-rc.1",n.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},n.bind=F,n.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=d(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=F(e[i],e)}return e},n.chain=function(e){return e=new n(e),e.__chain__=!0,e},n.clone=function(e){return e&&wt[typeof e]?Ct(e)?f(e):c({},e):e},n.compact=function(e){for(var t=-1,
n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},n.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},n.contains=S,n.countBy=function(e,t,n){var r={},t=s(t,n);return Lt(e,function(e,n,i){n=t(e,n,i),tt.call(r,n)?r[n]++:r[n]=1}),r},n.debounce=function(e,t,n){function r(){u=null,n||(s=e.apply(o,i))}var i,s,o,u;return function(){var a=n&&!u;return i=arguments,o=this,clearTimeout(u),u=setTimeout(r,t),a&&(s=e.apply(
o,i)),s}},n.defaults=p,n.defer=function(e){var n=f(arguments,1);return setTimeout(function(){e.apply(t,n)},1)},n.delay=function(e,n){var r=f(arguments,2);return setTimeout(function(){e.apply(t,r)},n)},n.difference=function(e){for(var t=-1,n=e.length,r=Z.apply(z,arguments),i=[];++t<n;){var s=e[t];0>P(r,s,n)&&i.push(s)}return i},n.escape=function(e){return null==e?"":(e+"").replace(Q,u)},n.every=x,n.filter=T,n.find=N,n.first=_,n.flatten=D,n.forEach=Lt,n.functions=d,n.groupBy=function(e,t,n){var r={
},t=s(t,n);return Lt(e,function(e,n,i){n=t(e,n,i),(tt.call(r,n)?r[n]:r[n]=[]).push(e)}),r},n.has=function(e,t){return e?tt.call(e,t):!1},n.identity=I,n.indexOf=P,n.initial=function(e,t,n){if(!e)return[];var r=e.length;return f(e,0,ft(at(0,r-(null==t||n?1:t||0)),r))},n.intersection=function(e){var t=arguments,n=t.length,r=[];return Lt(e,function(e){if(0>P(r,e)){for(var i=n;--i;)if(0>P(t[i],e))return;r.push(e)}}),r},n.invert=v,n.invoke=function(e,t){var n=f(arguments,2),r="function"==typeof t,i=[];
return Lt(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},n.isArray=Ct,n.isBoolean=function(e){return!0===e||!1===e||rt.call(e)==ht},n.isDate=function(e){return rt.call(e)==pt},n.isElement=function(e){return e?1===e.nodeType:!1},n.isEmpty=function(e){if(!e)return!0;if(Ct(e)||w(e))return!e.length;for(var t in e)if(tt.call(e,t))return!1;return!0},n.isEqual=m,n.isFinite=function(e){return ot(e)&&rt.call(e)==dt},n.isFunction=g,n.isNaN=function(e){return b(e)&&e!=+e},n.isNull=function(e){return null===
e},n.isNumber=b,n.isObject=y,n.isRegExp=function(e){return rt.call(e)==mt},n.isString=w,n.isUndefined=function(e){return"undefined"==typeof e},n.keys=kt,n.last=function(e,t,n){if(e){var r=e.length;return null==t||n?e[r-1]:f(e,at(0,r-t))}},n.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?at(0,r+n):ft(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},n.map=C,n.max=k,n.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return tt
.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},n.min=function(e,t,n){var r=Infinity,i=-1,o=e?e.length:0,u=r;if(t||!Ct(e))t=s(t,n),Lt(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,u=e)});else for(;++i<o;)e[i]<u&&(u=e[i]);return u},n.mixin=q,n.noConflict=function(){return e._=V,this},n.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},n.omit=function(e){var t=Z.apply(z,arguments),n={};return St(e,function(e,r){0>P(t,r,1)&&(n[r]=e)}),n},n.once=function(
e){var t,n=!1;return function(){return n?t:(n=!0,t=e.apply(this,arguments),e=null,t)}},n.pairs=function(e){var t=[];return xt(e,function(e,n){t.push([n,e])}),t},n.pick=function(e){for(var t=0,n=Z.apply(z,arguments),r=n.length,i={};++t<r;){var s=n[t];s in e&&(i[s]=e[s])}return i},n.pluck=L,n.random=function(e,t){return null==e&&null==t&&(t=1),e=+e||0,null==t&&(t=e,e=0),e+et(lt()*((+t||0)-e+1))},n.range=function(e,t,n){e=+e||0,n=+n||1,null==t&&(t=e,e=0);for(var r=-1,t=at(0,Y((t-e)/n)),i=Array(t);++
r<t;)i[r]=e,e+=n;return i},n.reduce=A,n.reduceRight=O,n.reject=function(e,t,n){return t=s(t,n),T(e,function(e,n,r){return!t(e,n,r)})},n.rest=H,n.result=function(e,t){var n=e?e[t]:null;return g(n)?e[t]():n},n.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return Lt(e,function(e){var r=et(lt()*(++t+1));n[t]=n[r],n[r]=e}),n},n.size=function(e){var t=e?e.length:0;return"number"==typeof t?t:kt(e).length},n.some=M,n.sortBy=function(e,t,n){var i=[],t=s(t,n);Lt(e,function(e,n,r){i.push({a:t(e,n,r),b:
n,c:e})}),e=i.length;for(i.sort(r);e--;)i[e]=i[e].c;return i},n.sortedIndex=B,n.tap=function(e,t){return t(e),e},n.template=function(e,t,r){e||(e="");var r=p({},r,n.templateSettings),i=0,s="__p+='",u=r.variable;e.replace(RegExp((r.escape||K).source+"|"+(r.interpolate||K).source+"|"+(r.evaluate||K).source+"|$","g"),function(t,n,r,u,a){s+=e.slice(i,a).replace(G,o),s+=n?"'+_['escape']("+n+")+'":u?"';"+u+";__p+='":r?"'+((__t=("+r+"))==null?'':__t)+'":"",i=a+t.length}),s+="';\n",u||(u="obj",s="with("+
u+"||{}){"+s+"}"),s="function("+u+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+s+"return __p}";try{var a=Function("_","return "+s)(n)}catch(f){throw f.source=s,f}return t?a(t):(a.source=s,a)},n.throttle=function(e,t){function n(){u=new Date,o=null,i=e.apply(s,r)}var r,i,s,o,u=0;return function(){var a=new Date,f=t-(a-u);return r=arguments,s=this,0>=f?(clearTimeout(o),o=null,u=a,i=e.apply(s,r)):o||(o=setTimeout(n,f)),i}},n.times=function(e,t,n){for(var e=+
e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},n.toArray=function(e){return"number"==typeof (e?e.length:0)?f(e):E(e)},n.unescape=function(e){return null==e?"":(e+"").replace($,l)},n.union=function(){return j(Z.apply(z,arguments))},n.uniq=j,n.uniqueId=function(e){var t=W++;return e?e+t:t},n.values=E,n.where=function(e,t){var n=kt(t);return T(e,function(e){for(var r=n.length;r--;){var i=e[n[r]]===t[n[r]];if(!i)break}return!!i})},n.without=function(e){for(var t=-1,n=e.length,r=[];++t<n;){var i=
e[t];0>P(arguments,i,1)&&r.push(i)}return r},n.wrap=function(e,t){return function(){var n=[e];return nt.apply(n,arguments),t.apply(this,n)}},n.zip=function(e){for(var t=-1,n=e?k(L(arguments,"length")):0,r=Array(n);++t<n;)r[t]=L(arguments,t);return r},n.all=x,n.any=M,n.collect=C,n.detect=N,n.drop=H,n.each=Lt,n.extend=c,n.foldl=A,n.foldr=O,n.head=_,n.include=S,n.inject=A,n.methods=d,n.select=T,n.tail=H,n.take=_,n.unique=j,q(n),n.prototype.chain=function(){return this.__chain__=!0,this},n.prototype.
value=function(){return this.__wrapped__},Lt("pop push reverse shift sort splice unshift".split(" "),function(e){var t=z[e];n.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),bt&&e.length===0&&delete e[0],this}}),Lt(["concat","join","slice"],function(e){var t=z[e];n.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new n(e),e.__chain__=!0),e}}),R?"object"==typeof module&&module&&module.exports==R?(module.exports=n)._=n:R._=n:e._=
n})(this);

View File

@@ -1,7 +1,7 @@
{
"name": "lodash",
"version": "0.10.0",
"description": "A drop-in replacement for Underscore.js delivering performance, bug fixes, and additional features.",
"version": "1.0.0-rc.1",
"description": "A utility library, usable as a drop-in replacement for Underscore, delivering performance, bug fixes, and additional features.",
"homepage": "http://lodash.com",
"main": "./lodash",
"keywords": [

View File

@@ -1600,7 +1600,7 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.toArray` with an array')
Benchmark.Suite('`_.toArray` with an array (edge case)')
.add(buildName, '\
lodash.toArray(numbers)'
)

View File

@@ -679,8 +679,11 @@
object = { 'length': 0, 'splice': Array.prototype.splice };
equal(lodash.isEmpty(object), false, '_.isEmpty should return `false` for jQuery/MooTools DOM query collections: ' + basename);
equal(lodash.isFinite('2'), false, '_.isFinite should return `false` for numeric string values: ' + basename);
object = { 'a': 1, 'b': 2, 'c': 3 };
equal(lodash.isEqual(object, { 'a': 1, 'b': 0, 'c': 3 }), false, '_.isEqual: ' + basename);
equal(lodash.max('abc'), -Infinity, '_.max should return `-Infinity` for strings: ' + basename);
equal(lodash.min('abc'), Infinity, '_.min should return `Infinity` for strings: ' + basename);
@@ -695,6 +698,18 @@
equal(lodash.some([false, true, false]), true, '_.some: ' + basename);
equal(lodash.template('${a}', object), '${a}', '_.template should ignore ES6 delimiters: ' + basename);
actual = [lodash.uniqueId(3), lodash.uniqueId(2), lodash.uniqueId(1)];
equal(actual.join(','), '3,3,3', '_.uniqueId should not coerce the prefix argument to a string: ' + basename);
equal(typeof lodash.uniqueId(), 'number', '_.uniqueId should return a number value when not passing a prefix argument: ' + basename);
var wrapped = lodash(1);
equal(wrapped.clone() instanceof lodash, false, '_(...) wrapped values are not chainable by default: ' + basename);
equal(String(wrapped) === '1', false, '_#toString should not be implemented: ' + basename);
equal(Number(wrapped) === 1 , false, '_#valueOf should not be implemented: ' + basename);
wrapped.chain();
equal(wrapped.has('x') instanceof lodash, true, '_#has returns wrapped values when chaining: ' + basename);
start();
});
});

View File

@@ -209,6 +209,13 @@
bound(['b'], 'c');
deepEqual(args, ['a', ['b'], 'c']);
});
test('ensure `new bound` is an instance of `func`', function() {
var func = function() {},
bound = _.bind(func, {});
ok(new bound instanceof func);
});
}());
/*--------------------------------------------------------------------------*/
@@ -243,17 +250,17 @@
Klass.prototype = { 'b': 1 };
var nonCloneable = {
'an arguments object': arguments,
'an element': window.document && document.body,
'a function': Klass,
'a Klass instance': new Klass
'a function': Klass
};
var objects = {
'an arguments object': arguments,
'an array': ['a', 'b', 'c', ''],
'an array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 },
'boolean': false,
'boolean object': Object(false),
'a Klass instance': new Klass,
'an object': { 'a': 0, 'b': 1, 'c': 3 },
'an object with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
'an object from another document': _._object || {},
@@ -295,6 +302,14 @@
ok(actual != expected && actual.a == expected.a && actual.b == expected.b);
});
test('should deep clone `index` and `input` array properties', function() {
var array = /x/.exec('x'),
actual = _.clone(array, true);
equal(actual.index, 0);
equal(actual.input, 'x');
});
test('should deep clone objects with circular references', function() {
var object = {
'foo': { 'b': { 'foo': { 'c': { } } } },
@@ -530,10 +545,10 @@
expected.push(undefined, undefined, undefined);
deepEqual(actual1, expected);
ok('4' in actual1);
ok(4 in actual1);
deepEqual(actual2, expected);
ok('4' in actual2);
ok(4 in actual2);
});
}());
@@ -722,9 +737,9 @@
QUnit.module('lodash.initial');
(function() {
test('returns an empty collection for `n` of `0`', function() {
test('returns a full collection for `n` of `0`', function() {
var array = [1, 2, 3];
deepEqual(_.initial(array, 0), []);
deepEqual(_.initial(array, 0), [1, 2, 3]);
});
test('should allow a falsey `array` argument', function() {
@@ -1375,6 +1390,17 @@
QUnit.module('lodash.reduce');
(function() {
test('should pass the correct `callback` arguments', function() {
var args,
array = [1, 2, 3];
_.reduce(array, function() {
args || (args = slice.call(arguments));
});
deepEqual(args, [1, 2, 1, array]);
});
_.each({
'literal': 'abc',
'object': Object('abc')
@@ -1399,6 +1425,17 @@
QUnit.module('lodash.reduceRight');
(function() {
test('should pass the correct `callback` arguments when iterating an array', function() {
var args,
array = [1, 2, 3];
_.reduceRight(array, function() {
args || (args = slice.call(arguments));
});
deepEqual(args, [3, 2, 1, array]);
});
test('should pass the correct `callback` arguments when iterating an object', function() {
var args,
object = { 'a': 1, 'b': 2 },
@@ -1603,7 +1640,7 @@
} catch(e) {
var source = e.source;
}
ok((source + '').indexOf('__p') > -1);
ok(/__p/.test(source));
});
test('should work with complex "interpolate" delimiters', function() {
@@ -1704,24 +1741,12 @@
(function() {
test('subsequent calls should return the result of the first call', function() {
var throttled = _.throttle(function(value) { return value; }, 90),
var throttled = _.throttle(function(value) { return value; }, 32),
result = [throttled('x'), throttled('y')];
deepEqual(result, ['x', 'x']);
});
test('supports calls in a loop', function() {
var counter = 0,
throttled = _.throttle(function() { counter++; }, 90),
start = new Date,
limit = 180;
while ((new Date - start) < limit) {
throttled();
}
ok(counter > 1);
});
asyncTest('supports recursive calls', function() {
var counter = 0;
var throttled = _.throttle(function() {
@@ -1763,6 +1788,43 @@
QUnit.start();
}, 260);
});
asyncTest('should not trigger a trailing call when invoked once', function() {
var counter = 0,
throttled = _.throttle(function() { counter++; }, 32);
throttled();
equal(counter, 1);
setTimeout(function() {
equal(counter, 1);
QUnit.start();
}, 64);
});
asyncTest('should trigger trailing call when invoked repeatedly', function() {
var actual,
counter = 0,
limit = 80,
throttled = _.throttle(function() { counter++; }, 32),
start = new Date;
while ((new Date - start) < limit) {
throttled();
}
setTimeout(function() {
actual = counter + 2;
throttled();
throttled();
}, 64);
setTimeout(function() {
equal(counter, actual);
QUnit.start();
}, 128);
ok(counter > 1);
});
}());
/*--------------------------------------------------------------------------*/
@@ -1772,6 +1834,17 @@
(function() {
var args = arguments;
test('should return a dense array', function() {
var array = Array(3);
array[1] = 2;
var actual = _.toArray(array);
ok(0 in actual);
ok(2 in actual);
deepEqual(actual, array);
});
test('should treat array-like objects like arrays', function() {
var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
deepEqual(_.toArray(object), ['a', 'b', 'c']);
@@ -1782,6 +1855,19 @@
deepEqual(_.toArray('abc'), ['a', 'b', 'c']);
deepEqual(_.toArray(Object('abc')), ['a', 'b', 'c']);
});
test('should work with a node list for `collection` (test in IE < 9)', function() {
if (window.document) {
try {
var nodeList = document.getElementsByTagName('body'),
body = nodeList[0],
actual = _.toArray(nodeList);
} catch(e) { }
deepEqual(actual, [body]);
} else {
skipTest();
}
});
}(1, 2, 3));
/*--------------------------------------------------------------------------*/
@@ -1843,6 +1929,21 @@
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.uniqueId');
(function() {
test('should return a string value when not passing a prefix argument', function() {
equal(typeof _.uniqueId(), 'string');
});
test('should coerce the prefix argument to a string', function() {
var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
equal(/3\d+,2\d+,1\d+/.test(actual), true);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.where');
(function() {
@@ -1901,7 +2002,7 @@
var wrapped = _({ '0': 1, 'length': 1 });
wrapped.shift();
deepEqual(wrapped.keys(), ['length']);
deepEqual(wrapped.keys().value(), ['length']);
equal(wrapped.first(), undefined);
});
}());
@@ -1915,13 +2016,107 @@
var wrapped = _({ '0': 1, 'length': 1 });
wrapped.splice(0, 1);
deepEqual(wrapped.keys(), ['length']);
deepEqual(wrapped.keys().value(), ['length']);
equal(wrapped.first(), undefined);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash(...).toString');
(function() {
test('should return the `toString` result of the wrapped value', function() {
var wrapped = _([1, 2, 3]);
equal(String(wrapped), '1,2,3');
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash(...).valueOf');
(function() {
test('should return the `valueOf` result of the wrapped value', function() {
var wrapped = _(123);
equal(Number(wrapped), 123);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash(...) methods capable of returning wrapped and unwrapped values');
(function() {
var array = [1, 2, 3],
wrapped = _(array);
var funcs = [
'first',
'last'
];
_.each(funcs, function(methodName) {
test('_.' + methodName + ' should return an unwrapped value', function() {
equal(typeof wrapped[methodName](), 'number');
});
test('_.' + methodName + ' should return a wrapped value', function() {
ok(wrapped[methodName](1) instanceof _);
});
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash(...) methods that return unwrapped values');
(function() {
var array = [1, 2, 3],
wrapped = _(array);
var funcs = [
'contains',
'every',
'find',
'first',
'has',
'isArguments',
'isArray',
'isBoolean',
'isDate',
'isElement',
'isEmpty',
'isEqual',
'isFinite',
'isFunction',
'isNaN',
'isNull',
'isNumber',
'isObject',
'isPlainObject',
'isRegExp',
'isString',
'isUndefined',
'last',
'reduce',
'reduceRight',
'some'
];
_.each(funcs, function(methodName) {
test('_.' + methodName + ' should return unwrapped values', function() {
var result = methodName == 'reduceRight'
? wrapped[methodName](_.identity)
: wrapped[methodName];
notEqual(typeof result, 'object', '_.' + methodName + ' returns unwrapped values');
});
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash methods');
(function() {

View File

@@ -184,22 +184,20 @@
var Model = Backbone.Model = function(attributes, options) {
var defaults;
var attrs = attributes || {};
if (options && options.collection) this.collection = options.collection;
this.attributes = {};
this._escapedAttributes = {};
this.cid = _.uniqueId('c');
this.changed = {};
this._changes = {};
this._pending = {};
this.attributes = {};
this._escapedAttributes = {};
this._modelState = [];
if (options && options.collection) this.collection = options.collection;
if (options && options.parse) attrs = this.parse(attrs);
if (defaults = _.result(this, 'defaults')) {
attrs = _.extend({}, defaults, attrs);
}
this.set(attrs, {silent: true});
// Reset change tracking.
this.changed = {};
this._changes = {};
this._pending = {};
this._cleanChange = true;
this._modelState = [];
this._currentState = _.clone(this.attributes);
this._previousAttributes = _.clone(this.attributes);
this.initialize.apply(this, arguments);
};
@@ -210,17 +208,26 @@
// A hash of attributes whose current and previous value differ.
changed: null,
// A hash of attributes that have changed since the last time `change`
// was called.
_changes: null,
// Whether there is a pending request to fire in the final `change` loop.
_pending: false,
// A hash of attributes that have changed since the last `change` event
// began.
_pending: null,
// Whether the model is in the midst of a change cycle.
_changing: false,
// A hash of attributes with the current model state to determine if
// a `change` should be recorded within a nested `change` block.
_changing : null,
// Whether there has been a `set` call since the last
// calculation of the changed hash, for efficiency.
_cleanChange: true,
// The model state used for comparison in determining if a
// change should be fired.
_currentState: null,
// An array queue of all changes attributed to a model
// on the next non-silent change event.
_modelState: null,
// A hash of the model's attributes when the last `change` occured.
_previousAttributes: null,
// The default name for the JSON `id` attribute is `"id"`. MongoDB and
// CouchDB users may want to set this to `"_id"`.
@@ -276,6 +283,7 @@
// Extract attributes and options.
var silent = options && options.silent;
var unset = options && options.unset;
if (attrs instanceof Model) attrs = attrs.attributes;
if (unset) for (attr in attrs) attrs[attr] = void 0;
@@ -285,38 +293,26 @@
// Check for changes of `id`.
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
var changing = this._changing;
var now = this.attributes;
var escaped = this._escapedAttributes;
var prev = this._previousAttributes || {};
var esc = this._escapedAttributes;
// For each `set` attribute...
for (attr in attrs) {
val = attrs[attr];
// If the new and current value differ, record the change.
if (!_.isEqual(now[attr], val) || (unset && _.has(now, attr))) {
delete escaped[attr];
this._changes[attr] = true;
}
// If an escaped attr exists, and the new and current value differ, remove the escaped attr.
if (esc[attr] && !_.isEqual(now[attr], val) || (unset && _.has(now, attr))) delete esc[attr];
// Update or delete the current value.
unset ? delete now[attr] : now[attr] = val;
// If the new and previous value differ, record the change. If not,
// then remove changes for this attribute.
if (!_.isEqual(prev[attr], val) || (_.has(now, attr) !== _.has(prev, attr))) {
this.changed[attr] = val;
if (!silent) this._pending[attr] = true;
} else {
delete this.changed[attr];
delete this._pending[attr];
if (!changing) delete this._changes[attr];
}
if (changing && _.isEqual(now[attr], changing[attr])) delete this._changes[attr];
// Track any action on the attribute.
this._modelState.push(attr, val, unset);
}
// Signal that the model's state has potentially changed.
this._cleanChange = false;
// Fire the `"change"` events.
if (!silent) this.change(options);
return this;
@@ -341,6 +337,7 @@
// triggering a `"change"` event.
fetch: function(options) {
options = options ? _.clone(options) : {};
if (options.parse === void 0) options.parse = true;
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
@@ -367,7 +364,7 @@
// If we're "wait"-ing to set changed attributes, validate early.
if (options.wait) {
if (!this._validate(attrs, options)) return false;
if (attrs && !this._validate(attrs, options)) return false;
current = _.clone(this.attributes);
}
@@ -461,37 +458,23 @@
// a `"change:attribute"` event for each changed attribute.
// Calling this will cause all objects observing the model to update.
change: function(options) {
var changing = this._changing;
var current = this._changing = {};
var i, changing = this._changing;
this._changing = true;
// Silent changes become pending changes.
for (var attr in this._changes) this._pending[attr] = true;
// Generate the changes to be triggered on the model.
var triggers = this._changeCenter(true);
this._pending = triggers.length;
// Trigger 'change:attr' for any new or silent changes.
var changes = this._changes;
this._changes = {};
// Set the correct state for this._changing values
var triggers = [];
for (var attr in changes) {
current[attr] = this.get(attr);
triggers.push(attr);
for (i = triggers.length - 2; i >= 0; i -= 2) {
this.trigger('change:' + triggers[i], this, triggers[i + 1], options);
}
for (var i=0, l=triggers.length; i < l; i++) {
this.trigger('change:' + triggers[i], this, current[triggers[i]], options);
}
if (changing) return this;
// Continue firing `"change"` events while there are pending changes.
while (!_.isEmpty(this._pending)) {
this._pending = {};
// Trigger a `change` while there have been changes.
while (this._pending) {
this._pending = false;
this.trigger('change', this, options);
// Pending and silent changes still remain.
for (var attr in this.changed) {
if (this._pending[attr] || this._changes[attr]) continue;
delete this.changed[attr];
}
this._previousAttributes = _.clone(this.attributes);
}
@@ -502,6 +485,7 @@
// Determine if the model has changed since the last `"change"` event.
// If you specify an attribute name, determine if that attribute has changed.
hasChanged: function(attr) {
if (!this._cleanChange) this._changeCenter();
if (attr == null) return !_.isEmpty(this.changed);
return _.has(this.changed, attr);
},
@@ -522,6 +506,42 @@
return changed;
},
// Calculates and handles any changes in `this._modelState`,
// checking against `this._currentState` to determine current changes.
_changeCenter: function (change) {
this.changed = {};
var local = {};
var triggers = [];
var modelState = this._modelState;
var currentState = this._currentState;
// Loop through the current queue of potential model changes.
for (var i = modelState.length - 3; i >= 0; i -= 3) {
var key = modelState[i], val = modelState[i + 1], unset = modelState[i + 2];
// If the item hasn't been set locally this round, proceed.
if (!local[key]) {
local[key] = val;
// Check if the attribute has been modified since the last change,
// and update `this.changed` accordingly.
if (currentState[key] !== val || (_.has(currentState, key) && unset)) {
this.changed[key] = val;
// Triggers & modifications are only created inside a `change` call.
if (!change) continue;
triggers.push(key, val);
(!unset) ? currentState[key] = val : delete currentState[key];
}
}
modelState.splice(i,3);
}
// Signals `this.changed` is current to prevent duplicate calls from `this.hasChanged`.
this._cleanChange = true;
return triggers;
},
// Get the previous value of an attribute, recorded at the time the last
// `"change"` event was fired.
previous: function(attr) {
@@ -599,26 +619,27 @@
// Add a model, or list of models to the set. Pass **silent** to avoid
// firing the `add` event for every new model.
add: function(models, options) {
var i, args, length, model, existing;
var i, args, length, model, existing, sort;
var at = options && options.at;
models = _.isArray(models) ? models.slice() : [models];
// Begin by turning bare objects into model references, and preventing
// invalid models from being added.
for (i = 0, length = models.length; i < length; i++) {
if (models[i] = this._prepareModel(models[i], options)) continue;
throw new Error("Can't add an invalid model to a collection");
}
// Turn bare objects into model references, and prevent invalid models
// from being added.
for (i = models.length - 1; i >= 0; i--) {
model = models[i];
existing = model.id != null && this._byId[model.id];
if(!(model = this._prepareModel(models[i], options))) {
this.trigger("error", this, models[i], options);
models.splice(i, 1);
continue;
}
models[i] = model;
// If a duplicate is found, splice it out and optionally merge it into
// the existing model.
existing = model.id != null && this._byId[model.id];
// If a duplicate is found, prevent it from being added and
// optionally merge it into the existing model.
if (existing || this._byCid[model.cid]) {
if (options && options.merge && existing) {
existing.set(model, options);
sort = true;
}
models.splice(i, 1);
continue;
@@ -631,14 +652,15 @@
if (model.id != null) this._byId[model.id] = model;
}
// Update `length` and splice in new models.
// See if sorting is needed, update `length` and splice in new models.
if (models.length) sort = true;
this.length += models.length;
args = [at != null ? at : this.models.length, 0];
push.apply(args, models);
splice.apply(this.models, args);
// Sort the collection if appropriate.
if (this.comparator && at == null) this.sort({silent: true});
if (sort && this.comparator && at == null) this.sort({silent: true});
if (options && options.silent) return this;
@@ -821,7 +843,7 @@
},
// Reset all internal state. Called when the collection is reset.
_reset: function(options) {
_reset: function() {
this.length = 0;
this.models = [];
this._byId = {};
@@ -1204,7 +1226,7 @@
var delegateEventSplitter = /^(\S+)\s*(.*)$/;
// List of view options to be merged as properties.
var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];
var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
// Set up all inheritable **Backbone.View** properties and methods.
_.extend(View.prototype, Events, {
@@ -1313,7 +1335,7 @@
// Keys with special meaning *(model, collection, id, className)*, are
// attached directly to the view.
_configure: function(options) {
if (this.options) options = _.extend({}, this.options, options);
if (this.options) options = _.extend({}, _.result(this, 'options'), options);
_.extend(this, _.pick(options, viewOptions));
this.options = options;
},
@@ -1381,7 +1403,7 @@
// Ensure that we have the appropriate request data.
if (!options.data && model && (method === 'create' || method === 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model);
params.data = JSON.stringify(model.toJSON(options));
}
// For older servers, emulate JSON by encoding the request into an HTML-form.

View File

@@ -542,8 +542,7 @@ $(document).ready(function() {
equal(col.length, 0);
});
test("#861, adding models to a collection which do not pass validation", 1, function() {
raises(function() {
test("#861, adding models to a collection which do not pass validation", 2, function() {
var Model = Backbone.Model.extend({
validate: function(attrs) {
if (attrs.id == 3) return "id can't be 3";
@@ -554,26 +553,26 @@ $(document).ready(function() {
model: Model
});
var col = new Collection;
var collection = new Collection;
collection.on("error", function() { ok(true); });
col.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}]);
}, function(e) {
return e.message === "Can't add an invalid model to a collection";
});
collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}]);
deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);
});
test("throwing during add leaves consistent state", 4, function() {
var col = new Backbone.Collection();
col.on('test', function() { ok(false); });
col.model = Backbone.Model.extend({
test("Invalid models are discarded.", 5, function() {
var collection = new Backbone.Collection;
collection.on('test', function() { ok(true); });
collection.model = Backbone.Model.extend({
validate: function(attrs){ if (!attrs.valid) return 'invalid'; }
});
var model = new col.model({id: 1, valid: true});
raises(function() { col.add([model, {id: 2}]); });
var model = new collection.model({id: 1, valid: true});
collection.add([model, {id: 2}]);;
model.trigger('test');
ok(!col.getByCid(model.cid));
ok(!col.get(1));
equal(col.length, 0);
ok(collection.getByCid(model.cid));
ok(collection.get(1));
ok(!collection.get(2));
equal(collection.length, 1);
});
test("multiple copies of the same model", 3, function() {
@@ -716,4 +715,15 @@ $(document).ready(function() {
this.ajaxSettings.success([model]);
});
test("`sort` shouldn't always fire on `add`", 1, function() {
var c = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}], {
comparator: 'id'
});
c.sort = function(){ ok(true); };
c.add([]);
c.add({id: 1});
c.add([{id: 2}, {id: 3}]);
c.add({id: 4});
});
});

View File

@@ -99,7 +99,7 @@ $(document).ready(function() {
equal(model.url(), '/nested/1/collection/2');
});
test("clone", 8, function() {
test("clone", 10, function() {
var a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3});
var b = a.clone();
equal(a.get('foo'), 1);
@@ -111,6 +111,12 @@ $(document).ready(function() {
a.set({foo : 100});
equal(a.get('foo'), 100);
equal(b.get('foo'), 1, "Changing a parent attribute does not change the clone.");
var foo = new Backbone.Model({p: 1});
var bar = new Backbone.Model({p: 2});
bar.set(foo.clone(), {unset: true});
equal(foo.get('p'), 1);
equal(bar.get('p'), undefined);
});
test("isNew", 6, function() {
@@ -897,4 +903,18 @@ $(document).ready(function() {
expect(0);
});
test("silent changes in last `change` event back to original does not trigger change", 2, function() {
var changes = [];
var model = new Backbone.Model();
model.on('change:a change:b change:c', function(model, val) { changes.push(val); });
model.on('change', function() {
model.set({a:'c'}, {silent:true});
});
model.set({a:'a'});
deepEqual(changes, ['a']);
model.set({a:'a'}, {silent:true});
model.change();
deepEqual(changes, ['a']);
});
});

View File

@@ -165,6 +165,30 @@ $(document).ready(function() {
strictEqual(new View().el.id, 'id');
});
test("with options function", 3, function() {
var View1 = Backbone.View.extend({
options: function() {
return {
title: 'title1',
acceptText: 'confirm'
}
}
});
var View2 = View1.extend({
options: function() {
return _.extend(View1.prototype.options.call(this), {
title: 'title2',
fixed: true
});
}
});
strictEqual(new View2().options.title, 'title2');
strictEqual(new View2().options.acceptText, 'confirm');
strictEqual(new View2().options.fixed, true);
});
test("with attributes", 2, function() {
var View = Backbone.View.extend({
attributes: {
@@ -331,4 +355,28 @@ $(document).ready(function() {
ok(view.$el.is('p:has(a)'));
});
test("events passed in options", 2, function() {
var counter = 0;
var View = Backbone.View.extend({
el: '<p><a id="test"></a></p>',
increment: function() {
counter++;
}
});
var view = new View({events:{'click #test':'increment'}});
var view2 = new View({events:function(){
return {'click #test':'increment'};
}});
view.$('#test').trigger('click');
view2.$('#test').trigger('click');
equal(counter, 2);
view.$('#test').trigger('click');
view2.$('#test').trigger('click');
equal(counter, 4);
});
});

View File

@@ -1,5 +1,5 @@
/** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.1.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
* @license RequireJS 2.1.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details
*/
@@ -12,7 +12,7 @@ var requirejs, require, define;
(function (global) {
var req, s, head, baseElement, dataMain, src,
interactiveScript, currentlyAddingScript, mainScript, subPath,
version = '2.1.1',
version = '2.1.2',
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
jsSuffixRegExp = /\.js$/,
@@ -81,6 +81,10 @@ var requirejs, require, define;
return hasOwn.call(obj, prop);
}
function getOwn(obj, prop) {
return hasProp(obj, prop) && obj[prop];
}
/**
* Cycles over properties in an object and calls a function for each
* property value. If the function returns a truthy value, then the
@@ -89,7 +93,7 @@ var requirejs, require, define;
function eachProp(obj, func) {
var prop;
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (hasProp(obj, prop)) {
if (func(obj[prop], prop)) {
break;
}
@@ -261,7 +265,7 @@ var requirejs, require, define;
//otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end.
if (baseName) {
if (config.pkgs[baseName]) {
if (getOwn(config.pkgs, baseName)) {
//If the baseName is a package name, then just treat it as one
//name to concat the name with.
normalizedBaseParts = baseParts = [baseName];
@@ -279,7 +283,7 @@ var requirejs, require, define;
//Some use of packages may use a . path to reference the
//'main' module name, so normalize for that.
pkgConfig = config.pkgs[(pkgName = name[0])];
pkgConfig = getOwn(config.pkgs, (pkgName = name[0]));
name = name.join('/');
if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {
name = pkgName;
@@ -302,12 +306,12 @@ var requirejs, require, define;
//Find the longest baseName segment match in the config.
//So, do joins on the biggest to smallest lengths of baseParts.
for (j = baseParts.length; j > 0; j -= 1) {
mapValue = map[baseParts.slice(0, j).join('/')];
mapValue = getOwn(map, baseParts.slice(0, j).join('/'));
//baseName segment has config, find if it has one for
//this name.
if (mapValue) {
mapValue = mapValue[nameSegment];
mapValue = getOwn(mapValue, nameSegment);
if (mapValue) {
//Match, update name to the new value.
foundMap = mapValue;
@@ -325,8 +329,8 @@ var requirejs, require, define;
//Check for a star map match, but just hold on to it,
//if there is a shorter segment match later in a matching
//config, then favor over this star map.
if (!foundStarMap && starMap && starMap[nameSegment]) {
foundStarMap = starMap[nameSegment];
if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {
foundStarMap = getOwn(starMap, nameSegment);
starI = i;
}
}
@@ -358,7 +362,7 @@ var requirejs, require, define;
}
function hasPathFallback(id) {
var pathConfig = config.paths[id];
var pathConfig = getOwn(config.paths, id);
if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
removeScript(id);
//Pop off the first array value, since it failed, and
@@ -419,7 +423,7 @@ var requirejs, require, define;
if (prefix) {
prefix = normalize(prefix, parentName, applyMap);
pluginModule = defined[prefix];
pluginModule = getOwn(defined, prefix);
}
//Account for relative paths if there is a base name.
@@ -472,7 +476,7 @@ var requirejs, require, define;
function getModule(depMap) {
var id = depMap.id,
mod = registry[id];
mod = getOwn(registry, id);
if (!mod) {
mod = registry[id] = new context.Module(depMap);
@@ -483,7 +487,7 @@ var requirejs, require, define;
function on(depMap, name, fn) {
var id = depMap.id,
mod = registry[id];
mod = getOwn(registry, id);
if (hasProp(defined, id) &&
(!mod || mod.defineEmitComplete)) {
@@ -503,7 +507,7 @@ var requirejs, require, define;
errback(err);
} else {
each(ids, function (id) {
var mod = registry[id];
var mod = getOwn(registry, id);
if (mod) {
//Set error on module, so it skips timeout checks.
mod.error = err;
@@ -562,7 +566,7 @@ var requirejs, require, define;
id: mod.map.id,
uri: mod.map.url,
config: function () {
return (config.config && config.config[mod.map.id]) || {};
return (config.config && getOwn(config.config, mod.map.id)) || {};
},
exports: defined[mod.map.id]
});
@@ -584,14 +588,14 @@ var requirejs, require, define;
traced[id] = true;
each(mod.depMaps, function (depMap, i) {
var depId = depMap.id,
dep = registry[depId];
dep = getOwn(registry, depId);
//Only force things that have not completed
//being defined, so still in the registry,
//and only if it has not been matched up
//in the module already.
if (dep && !mod.depMatched[i] && !processed[depId]) {
if (traced[depId]) {
if (getOwn(traced, depId)) {
mod.defineDep(i, defined[depId]);
mod.check(); //pass false?
} else {
@@ -691,9 +695,9 @@ var requirejs, require, define;
}
Module = function (map) {
this.events = undefEvents[map.id] || {};
this.events = getOwn(undefEvents, map.id) || {};
this.map = map;
this.shim = config.shim[map.id];
this.shim = getOwn(config.shim, map.id);
this.depExports = [];
this.depMaps = [];
this.depMatched = [];
@@ -940,7 +944,7 @@ var requirejs, require, define;
});
}));
normalizedMod = registry[normalizedMap.id];
normalizedMod = getOwn(registry, normalizedMap.id);
if (normalizedMod) {
//Mark this as a dependency for this plugin, so it
//can be traced for cycles.
@@ -1005,6 +1009,11 @@ var requirejs, require, define;
//it.
getModule(moduleMap);
//Transfer any config to this other module.
if (hasProp(config.config, id)) {
config.config[moduleName] = config.config[id];
}
try {
req.exec(text);
} catch (e) {
@@ -1060,7 +1069,7 @@ var requirejs, require, define;
!this.skipMap);
this.depMaps[i] = depMap;
handler = handlers[depMap.id];
handler = getOwn(handlers, depMap.id);
if (handler) {
this.depExports[i] = handler(this);
@@ -1085,7 +1094,7 @@ var requirejs, require, define;
//Skip special modules like 'require', 'exports', 'module'
//Also, don't call enable if it is already enabled,
//important in circular dependency cases.
if (!handlers[id] && mod && !mod.enabled) {
if (!hasProp(handlers, id) && mod && !mod.enabled) {
context.enable(depMap, this);
}
}));
@@ -1093,7 +1102,7 @@ var requirejs, require, define;
//Enable each plugin that is used in
//a dependency
eachProp(this.pluginMaps, bind(this, function (pluginMap) {
var mod = registry[pluginMap.id];
var mod = getOwn(registry, pluginMap.id);
if (mod && !mod.enabled) {
context.enable(pluginMap, this);
}
@@ -1126,7 +1135,10 @@ var requirejs, require, define;
};
function callGetModule(args) {
getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
//Skip modules already defined.
if (!hasProp(defined, args[0])) {
getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
}
}
function removeListener(node, func, name, ieName) {
@@ -1239,7 +1251,7 @@ var requirejs, require, define;
deps: value
};
}
if (value.exports && !value.exportsFn) {
if ((value.exports || value.init) && !value.exportsFn) {
value.exportsFn = context.makeShimExports(value);
}
shim[id] = value;
@@ -1301,7 +1313,7 @@ var requirejs, require, define;
if (value.init) {
ret = value.init.apply(global, arguments);
}
return ret || getGlobal(value.exports);
return ret || (value.exports && getGlobal(value.exports));
}
return fn;
},
@@ -1325,7 +1337,7 @@ var requirejs, require, define;
//If require|exports|module are requested, get the
//value for them from the special handlers. Caveat:
//this only works while module is being defined.
if (relMap && handlers[deps]) {
if (relMap && hasProp(handlers, deps)) {
return handlers[deps](registry[relMap.id]);
}
@@ -1413,7 +1425,7 @@ var requirejs, require, define;
takeGlobalQueue();
var map = makeModuleMap(id, relMap, true),
mod = registry[id];
mod = getOwn(registry, id);
delete defined[id];
delete urlFetched[map.url];
@@ -1441,7 +1453,7 @@ var requirejs, require, define;
* used by the optimizer.
*/
enable: function (depMap, parent) {
var mod = registry[depMap.id];
var mod = getOwn(registry, depMap.id);
if (mod) {
getModule(depMap).enable();
}
@@ -1455,7 +1467,7 @@ var requirejs, require, define;
*/
completeLoad: function (moduleName) {
var found, args, mod,
shim = config.shim[moduleName] || {},
shim = getOwn(config.shim, moduleName) || {},
shExports = shim.exports;
takeGlobalQueue();
@@ -1481,9 +1493,9 @@ var requirejs, require, define;
//Do this after the cycle of callGetModule in case the result
//of those calls/init calls changes the registry.
mod = registry[moduleName];
mod = getOwn(registry, moduleName);
if (!found && !defined[moduleName] && mod && !mod.inited) {
if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {
if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
if (hasPathFallback(moduleName)) {
return;
@@ -1534,8 +1546,8 @@ var requirejs, require, define;
//and work up from it.
for (i = syms.length; i > 0; i -= 1) {
parentModule = syms.slice(0, i).join('/');
pkg = pkgs[parentModule];
parentPath = paths[parentModule];
pkg = getOwn(pkgs, parentModule);
parentPath = getOwn(paths, parentModule);
if (parentPath) {
//If an array, it means there are a few choices,
//Choose the one that is desired
@@ -1660,7 +1672,7 @@ var requirejs, require, define;
contextName = config.context;
}
context = contexts[contextName];
context = getOwn(contexts, contextName);
if (!context) {
context = contexts[contextName] = req.s.newContext(contextName);
}

View File

@@ -55,18 +55,16 @@ $(document).ready(function() {
test("compact", function() {
equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values');
var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3);
var result = (function(){ return _.compact(arguments).length; })(0, 1, false, 2, false, 3);
equal(result, 3, 'works on an arguments object');
});
test("flatten", function() {
if (window.JSON) {
var list = [1, [2], [3, [[[4]]]]];
equal(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays');
equal(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays');
var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
equal(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object');
}
var list = [1, [2], [3, [[[4]]]]];
deepEqual(_.flatten(list), [1,2,3,4], 'can flatten nested arrays');
deepEqual(_.flatten(list, true), [1,2,3,[[[4]]]], 'can shallowly flatten nested arrays');
var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
deepEqual(result, [1,2,3,4], 'works on an arguments object');
});
test("without", function() {

View File

@@ -348,6 +348,11 @@ $(document).ready(function() {
var array = [{}];
_.groupBy(array, function(value, index, obj){ ok(obj === array); });
var array = [1, 2, 1, 2, 3];
var grouped = _.groupBy(array);
equal(grouped['1'].length, 2);
equal(grouped['3'].length, 1);
});
test('countBy', function() {
@@ -372,6 +377,11 @@ $(document).ready(function() {
var array = [{}];
_.countBy(array, function(value, index, obj){ ok(obj === array); });
var array = [1, 2, 1, 2, 3];
var grouped = _.countBy(array);
equal(grouped['1'], 2);
equal(grouped['3'], 1);
});
test('sortedIndex', function() {
@@ -408,6 +418,13 @@ $(document).ready(function() {
var numbers = _.toArray({one : 1, two : 2, three : 3});
equal(numbers.join(', '), '1, 2, 3', 'object flattened into array');
// test in IE < 9
try {
var actual = _.toArray(document.childNodes);
} catch(ex) { }
ok(_.isArray(actual), 'should not throw converting a node list');
});
test('size', function() {

View File

@@ -34,8 +34,10 @@ $(document).ready(function() {
// To test this with a modern browser, set underscore's nativeBind to undefined
var F = function () { return this; };
var Boundf = _.bind(F, {hello: "moe curly"});
equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5");
var newBoundf = new Boundf();
equal(newBoundf.hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5");
equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context");
ok(newBoundf instanceof F, "a bound instance is an instance of the original function");
});
test("bindAll", function() {
@@ -163,6 +165,31 @@ $(document).ready(function() {
}, 400);
});
asyncTest("throttle triggers trailing call after repeatedly invoked", 2, function() {
var actual;
var counter = 0;
var limit = 80;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 32);
var stamp = new Date;
while ((new Date - stamp) < limit) {
throttledIncr();
}
_.delay(function() {
actual = counter + 2;
throttledIncr();
throttledIncr();
}, 64);
_.delay(function() {
equal(counter, actual);
start();
}, 128);
ok(counter > 1);
});
asyncTest("debounce", 1, function() {
var counter = 0;
var incr = function(){ counter++; };

View File

@@ -53,6 +53,13 @@ $(document).ready(function() {
ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps');
result = _.extend({}, {a: void 0, b: null});
equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values');
try {
result = {};
_.extend(result, null, undefined, {a:1});
} catch(ex) {}
equal(result.a, 1, 'should not error on `null` or `undefined` sources');
});
test("pick", function() {
@@ -96,6 +103,13 @@ $(document).ready(function() {
equal(options.empty, "", 'value exists');
ok(_.isNaN(options.nan), "NaN isn't overridden");
equal(options.word, "word", 'new value is added, first one wins');
try {
options = {};
_.defaults(options, null, undefined, {a:1});
} catch(ex) {}
equal(options.a, 1, 'should not error on `null` or `undefined` sources');
});
test("clone", function() {
@@ -337,16 +351,10 @@ $(document).ready(function() {
// Chaining.
ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal');
equal(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained');
// Custom `isEqual` methods.
var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}};
var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}};
ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods');
ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods');
ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal');
ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods');
a = _({x: 1, y: 2}).chain();
b = _({x: 1, y: 2}).chain();
equal(_.isEqual(a.isEqual(b), _(true)), true, '`isEqual` can be chained');
// Objects from another frame.
ok(_.isEqual({}, iObject));

View File

@@ -37,8 +37,10 @@ $(document).ready(function() {
ok(_.isEqual(vals, [0,1,2]), "is 0 indexed");
//
vals = [];
_(3).times(function (i) { vals.push(i); });
_(3).times(function(i) { vals.push(i); });
ok(_.isEqual(vals, [0,1,2]), "works as a wrapper");
// collects return values
ok(_.isEqual([0, 1, 2], _.times(3, function(i) { return i; })), "collects return values");
});
test("mixin", function() {
@@ -173,10 +175,11 @@ $(document).ready(function() {
test('_.template provides the generated function source, when a SyntaxError occurs', function() {
try {
_.template('<b><%= if %></b>');
} catch (e) {
ok(e.source.indexOf('( if )') > 0);
_.template('<b><%= if x %></b>');
} catch (ex) {
var source = ex.source;
}
ok(/__p/.test(source));
});
test('_.template handles \\u2028 & \\u2029', function() {

File diff suppressed because one or more lines are too long

View File

@@ -316,7 +316,7 @@
// An internal function used for aggregate "group by" operations.
var group = function(obj, value, context, behavior) {
var result = {};
var iterator = lookupIterator(value);
var iterator = lookupIterator(value || _.identity);
each(obj, function(value, index) {
var key = iterator.call(context, value, index, obj);
behavior(result, key, value);
@@ -358,7 +358,8 @@
// Safely convert anything iterable into a real, live array.
_.toArray = function(obj) {
if (!obj) return [];
if (obj.length === +obj.length) return slice.call(obj);
if (_.isArray(obj)) return slice.call(obj);
if (obj.length === +obj.length) return _.map(obj, _.identity);
return _.values(obj);
};
@@ -408,7 +409,7 @@
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.filter(array, function(value){ return !!value; });
return _.filter(array, _.identity);
};
// Internal implementation of a recursive `flatten` function.
@@ -572,8 +573,8 @@
// optionally). Binding with arguments is also known as `curry`.
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
// We check for `func.bind` first, to fail fast when `func` is undefined.
_.bind = function bind(func, context) {
var bound, args;
_.bind = function(func, context) {
var args, bound;
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
@@ -581,6 +582,7 @@
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
ctor.prototype = null;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
@@ -636,6 +638,7 @@
args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
} else if (!timeout) {
@@ -758,8 +761,10 @@
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
obj[prop] = source[prop];
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
}
}
});
return obj;
@@ -788,8 +793,10 @@
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
if (obj[prop] == null) obj[prop] = source[prop];
if (source) {
for (var prop in source) {
if (obj[prop] == null) obj[prop] = source[prop];
}
}
});
return obj;
@@ -1000,7 +1007,9 @@
// Run a function **n** times.
_.times = function(n, iterator, context) {
for (var i = 0; i < n; i++) iterator.call(context, i);
var accum = Array(n);
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
return accum;
};
// Return a random integer between min and max (inclusive).
@@ -1065,7 +1074,7 @@
// Useful for temporary DOM ids.
var idCounter = 0;
_.uniqueId = function(prefix) {
var id = idCounter++;
var id = '' + ++idCounter;
return prefix ? prefix + id : id;
};
@@ -1115,11 +1124,18 @@
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
source +=
escape ? "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'" :
interpolate ? "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" :
evaluate ? "';\n" + evaluate + "\n__p+='" : '';
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
return match;
});
source += "';\n";