Compare commits

..

36 Commits
0.2.2 ... 0.3.0

Author SHA1 Message Date
John-David Dalton
51a459fe48 Simplify function checks and cleanup documentation.
Former-commit-id: 460f34725e212ced27831b9aad1e9e7e2fc02cf1
2012-06-06 15:56:40 -04:00
John-David Dalton
03c07abbc3 Update README.md.
Former-commit-id: 64ce8f122be084fd93fd711a6ca207fc4ae6b870
2012-06-06 15:05:52 -04:00
John-David Dalton
5eabe1a172 Add sourceURL support to _.template.
Former-commit-id: 31d40d57f903098fe1678777aa7921e72d1dca9e
2012-06-06 15:05:41 -04:00
John-David Dalton
5b6ea7afb2 Bump to v0.3.0.
Former-commit-id: 2b713b3d926e3dbba80eab6e1e14d080f169bf39
2012-06-06 00:52:57 -04:00
John-David Dalton
7c1c5e70ca Update Backbone and RequireJS submodules.
Former-commit-id: 145455767d22eb1b03a751024e69826e2387fd04
2012-06-06 00:50:31 -04:00
John-David Dalton
d475f8f965 Fix documentation typo.
Former-commit-id: 85e89c893d358d196a3f0f04b95acb10bbca2771
2012-06-05 01:44:50 -04:00
John-David Dalton
fd239076dd Fix minified build for _.forIn.
Former-commit-id: 1d5d41fe63a10ccae8fcf4a91e7e77526a7c0d9c
2012-06-05 01:07:46 -04:00
John-David Dalton
5f786bbe47 Add category build option.
Former-commit-id: 4adea9367949985a1218cff58ff856184fd11db7
2012-06-05 00:41:20 -04:00
John-David Dalton
f66dc6bed8 Fix typo in iteratorTemplate.
Former-commit-id: b787391db088e672c55ca56ca246147557b3694f
2012-06-04 22:49:33 -04:00
John-David Dalton
52c36ac445 Fix documentation typo.
Former-commit-id: defc89d6a8267a4a6626ca6ac7345db1d55cb9b6
2012-06-04 16:54:47 -04:00
John-David Dalton
8f6a78cba5 Update documentation and package.json.
Former-commit-id: 4ab7d954b7abc5f73269eb7c74a39b02fa04970d
2012-06-04 16:38:37 -04:00
John-David Dalton
7053e9113f Add unit test for _.sortedIndex to ensure it supports arrays with high length values.
Former-commit-id: 8956495dfa40c75dcb3c0585e78913607bf92e99
2012-06-04 16:18:23 -04:00
John-David Dalton
89f9ab9940 Bump to v0.3.0-pre.
Former-commit-id: 1e7958b4b1cdffd962a51edf3e3695cea960d8c9
2012-06-04 15:44:54 -04:00
John-David Dalton
240bc40b39 Ensure collection methods treat array-like objects with invalid length properties as regular objects.
Former-commit-id: dd8b382635bc30dc6e417cd9b47c36abfdf5ddcb
2012-06-04 15:36:27 -04:00
John-David Dalton
74649b5f28 Add _.forOwn and _.forIn.
Former-commit-id: f4e94a0fd15318063eec16c464435b07f419fa6a
2012-06-04 14:45:06 -04:00
John-David Dalton
b484d4b2dc Update minified build and documentation.
Former-commit-id: 592319b69487858794529d789383af1b38d55632
2012-06-04 02:23:16 -04:00
John-David Dalton
da1124dd37 Switch to an htmlEscapes object for use in _.escape.
Former-commit-id: bc449b5d6868c846d599840e5c0d90d0314fe4b8
2012-06-04 02:12:41 -04:00
John-David Dalton
210485d0be Update Benchmark.js and UglifyJS submodules.
Former-commit-id: 78611de2f992dc4d6cc4d336bfb761b98b22ce79
2012-06-04 00:08:26 -04:00
John-David Dalton
d9aee5ae60 Update minified build, documentation, and Backbone submodule.
Former-commit-id: cca2cf2f55e2750486d1d32b8da26fbc5576a65b
2012-06-03 21:58:35 -04:00
John-David Dalton
9ac64623fc Added thisArg argument to _.sortedIndex and _.uniq, benchmarks, unit tests, and adjusted related dependencies in build.js.
Former-commit-id: a97aa769d760c7cc4d0df6307cebc860345a0da0
2012-06-03 21:56:36 -04:00
John-David Dalton
6ea4226680 Remove unneeded Closure Compiler export around the template string _.escape(__t) in pre-compile.js.
Former-commit-id: 812bd220cd3baca30a100f07e1d47cd6745a3602
2012-06-03 20:36:31 -04:00
John-David Dalton
c1416bba39 Cleanup console messages in perf.js.
Former-commit-id: b3e669d46f21d39f96873167557b4ede80458beb
2012-06-03 20:35:22 -04:00
John-David Dalton
ddb3ab3238 Tweak indexOf isSorted benchmark.
Former-commit-id: 0183b35929a2c1f7113747a67f55abbc797fab8c
2012-06-03 01:06:12 -04:00
John-David Dalton
5e7c9698c7 Use typeof == 'number' more, and default callback values to docs.
Former-commit-id: 02786903a510d0cc837eeeb7e9f42db2ecd634a4
2012-06-03 01:05:40 -04:00
John-David Dalton
4c66b95516 Make Firebug Lite console fullscreen in more browsers.
Former-commit-id: a42e7d187a582a1caea721860cf3ed4bd0f94368
2012-06-01 07:41:29 -06:00
John-David Dalton
2d03060a0d Make previous build.js regexp simplification non-greedy.
Former-commit-id: e58cfb5e5143e12721bb08445dfd4a6fec119cd1
2012-05-31 23:18:44 -06:00
John-David Dalton
3313b0aa42 Update minified build and docs.
Former-commit-id: 3c0463d77c9091c1e66c7d68240de8b7ab2e499f
2012-05-31 22:54:50 -06:00
John-David Dalton
5d2928d2b3 Simplify regexps in build.js.
Former-commit-id: 7640f90b6aeca0438579c15c9eef270904c2c523
2012-05-31 22:54:37 -06:00
John-David Dalton
f6e2ae41d6 Add more benchmarks.
Former-commit-id: bddb4a26073ecd5aaf622f9726be940b6340cc07
2012-05-31 22:11:07 -06:00
John-David Dalton
7ccb038b6d Add _.isEmpty unit test.
Former-commit-id: 066961a929da280421083d3f9d66b838d3d29dfd
2012-05-31 17:40:47 -06:00
John-David Dalton
7d62bbf74f Optimize _.times.
Former-commit-id: beae48853d0e9be1c3016c11bee86a272964dfa2
2012-05-31 17:37:01 -06:00
John-David Dalton
3d8cc32302 Add fromIndex to _.indexOf and _.lastIndexOf. [closes #20]
Former-commit-id: 3ab67c318a5a7fc2e521a9a2573b694e6920b14d
2012-05-31 17:26:45 -06:00
John-David Dalton
861eea5148 Fix "prototype" iteration bug with _.keys.
Former-commit-id: 1e072b2639e21a5c0a920db0ac27693ade34b009
2012-05-31 10:29:33 -05:00
John-David Dalton
b432721fe5 Optimize this binding in iterator methods and remove _.bind as a dependency for several methods.
Former-commit-id: 60af002cd80758fea81fbff9c2b20b1ccf3ccffd
2012-05-31 10:21:38 -05:00
John-David Dalton
f13a0cc7e0 Format numbers and scroll down results panel in perf.js.
Former-commit-id: 9f80b5534e3b46be7ad9c84ebb7e9ed5afdc35b8
2012-05-30 09:19:58 -04:00
John-David Dalton
1f7e37a1a3 Change performance link in README.md to lodash.com benchmarks.
Former-commit-id: 5c851961fd1b8e46599c28967d782551722a03d4
2012-05-30 04:03:14 -04:00
15 changed files with 1333 additions and 538 deletions

View File

@@ -1,9 +1,15 @@
# Lo-Dash <sup>v0.2.2</sup>
# Lo-Dash <sup>v0.3.0</sup>
A drop-in replacement for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), that delivers [performance improvements](http://jsperf.com/lodash-underscore#filterby=family), [bug fixes](https://github.com/bestiejs/lodash#closed-underscorejs-issues), and [additional features](https://github.com/bestiejs/lodash#features).
A drop-in replacement for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), that delivers [performance improvements](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#closed-underscorejs-issues), and [additional features](https://github.com/bestiejs/lodash#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.
## Download
* [Development source](https://raw.github.com/bestiejs/lodash/v0.3.0/lodash.js)
* [Production source](https://raw.github.com/bestiejs/lodash/v0.3.0/lodash.min.js)
* For optimal performance, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
## Dive in
Weve got [API docs](http://lodash.com/docs), [benchmarks](http://lodash.com/benchmarks), and [unit tests](http://lodash.com/tests).
@@ -19,17 +25,21 @@ For more information check out these screencasts over Lo-Dash:
## Features
* AMD loader support
* AMD loader support (RequireJS, curl.js, etc.)
* [_.bind](http://lodash.com/docs#bind) supports *"lazy"* binding
* [_.debounce](http://lodash.com/docs#debounce)ed functions match [_.throttle](http://lodash.com/docs#throttle)ed functions return value behavior
* [_.forEach](http://lodash.com/docs#forEach) is chainable
* [_.groupBy](http://lodash.com/docs#groupBy) accepts a third, `thisArg`, argument
* [_.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
* [_.groupBy](http://lodash.com/docs#groupBy), [_.sortedIndex](http://lodash.com/docs#sortedIndex), and [_.uniq](http://lodash.com/docs#uniq) accept a `thisArg` argument
* [_.indexOf](http://lodash.com/docs#indexOf) and [_.lastIndexOf](http://lodash.com/docs#lastIndexOf) accept a `fromIndex` argument
* [_.partial](http://lodash.com/docs#partial) for more functional fun
* [_.size](http://lodash.com/docs#size) supports returning the `length` of string values
* [_.template](http://lodash.com/docs#template) utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
## Support
Lo-Dash has been tested in at least Chrome 5-19, Firefox 1.5-12, IE 6-9, Opera 9.25-11.64, Safari 3.0.4-5.1.3, Node.js 0.4.8-0.6.18, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC3.
Lo-Dash has been tested in at least Chrome 5-19, Firefox 1.5-13, IE 6-9, Opera 9.25-11.64, Safari 3.0.4-5.1.3, Node.js 0.4.8-0.6.18, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC3.
## Custom builds
@@ -42,20 +52,28 @@ Mobile builds, with IE bug fixes and method compilation removed, may be created
node build mobile
~~~
Custom builds may be created in two ways:
Custom builds may be created in three ways:
1. Use the`include` argument to pass the names of the methods to include in the build.
1. Use the `category` argument to pass the categories of methods to include in the build.<br>
Valid categories are *"arrays"*, *"chaining"*, *"collections"*, *"functions"*, *"objects"*, and *"utilities"*.
~~~ bash
node build include=each,filter,map,noConflict
node build include="each, filter, map, noConflict"
node build mobile include=each,filter,map,noConflict
node build category=collections,functions
node build category="collections, functions"
node build mobile category=collections,functions
~~~
2. Use the `exclude` argument to pass the names of the methods to exclude from the build.
2. Use the `include` argument to pass the names of the methods to include in the build.
~~~ bash
node build exclude=isNaN,isUndefined,union,zip
node build exclude="isNaN, isUndefined, union, zip"
node build mobile exclude=isNaN,isUndefined,union,zip
node build include=each,filter,map
node build include="each, filter, map"
node build mobile include=each,filter,map
~~~
3. Use the `exclude` argument to pass the names of the methods to exclude from the build.
~~~ bash
node build exclude=union,uniq,zip
node build exclude="union, uniq, zip"
node build mobile exclude=union,uniq,zip
~~~
Custom builds are saved to `lodash.custom.js` and `lodash.custom.min.js`.
@@ -124,17 +142,20 @@ git submodule update --init
## Closed Underscore.js issues
* Ensure `_(...)` returns passed wrapper instances [[test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L95-98)]
* Ensure `_.groupBy` adds values to own, not inherited, properties [[test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L229-236)]
* Ensure `_.throttle` works when called in tight loops [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L436-446)]
* Fix Firefox, IE, Opera, and Safari object iteration bugs [[#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L152-172), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L206-213), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L255-257), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L265-267), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L285-292), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L386-388)]
* Allow iteration of objects with a `length` property [[#148](https://github.com/documentcloud/underscore/issues/148), [#154](https://github.com/documentcloud/underscore/issues/154), [#252](https://github.com/documentcloud/underscore/issues/252), [#448](https://github.com/documentcloud/underscore/issues/448), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L266-272)]
* Ensure array-like objects with invalid `length` properties are treated like regular objects [[test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L237-243), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L533-542), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L661-664)]
* Ensure `_(...)` returns passed wrapper instances [[test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L106-109)]
* Ensure `_.groupBy` adds values to own, not inherited, properties [[test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L317-324)]
* Ensure `_.sortedIndex` supports arrays with high `length` values [[test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L586-595)]
* Ensure `_.throttle` works when called in tight loops [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L629-639)]
* Fix Firefox, IE, Opera, and Safari object iteration bugs [[#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L175-187), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L277-302), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L379-390), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L398-400), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L418-438), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L554-556)]
* Handle arrays with `undefined` values correctly in IE < 9 [[#601](https://github.com/documentcloud/underscore/issues/601)]
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L77-83)]
* Register as AMD module, but still export to global [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L61-75)]
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L74-77)]
* `_isNaN(new Number(NaN))` should return `true` [[test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L95-99)]
* `_.reduceRight` should pass correct callback arguments when iterating objects [[test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L106-116)]
* `_.size` should return the `length` of string values [[test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L121-127)]
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L88-94)]
* Register as AMD module, but still export to global [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L72-86)]
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L232-235)]
* `_isNaN(new Number(NaN))` should return `true` [[test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L408-410)]
* `_.reduceRight` should pass correct callback arguments when iterating objects [[test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L521-531)]
* `_.size` should return the `length` of string values [[test](https://github.com/bestiejs/lodash/blob/c07e1567a7a12cff2c5ee6cda81306c8bcf126f0/test/test.js#L550-552)]
## Optimized methods <sup>(50+)</sup>
@@ -182,6 +203,7 @@ git submodule update --init
* `_.sortedIndex`
* `_.template`
* `_.throttle`
* `_.times`
* `_.toArray`
* `_.union`
* `_.uniq`, `_.unique`
@@ -193,9 +215,21 @@ git submodule update --init
## Changelog
### <sup>v0.3.0</sup>
* Added `category` build option
* Added `fromIndex` argument to `_.indexOf` and `_.lastIndexOf`
* Added `//@ sourceURL` support to `_.template`
* Added `thisArg` argument to `_.sortedIndex` and `_.uniq`
* Added `_.forIn` and `_.forOwn` methods
* Ensured array-like objects with invalid `length` properties are treated like regular objects
* Ensured `_.sortedIndex` supports arrays with high `length` values
* Fixed `prototype` property iteration bug in `_.keys` for Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
* Optimized `_.times` and `this` bindings in iterator methods
### <sup>v0.2.2</sup>
* Added mobile build option
* Added `mobile` build option
* Ensured `_.find` returns `undefined` for unmatched values
* Ensured `_.templateSettings.variable` is compatible with Underscore.js
* Optimized `_.escape`
@@ -223,7 +257,7 @@ git submodule update --init
* Ensured `_(...)` returns passed wrapper instances
* Ensured `_.max` and `_.min` support extremely large arrays
* Ensured `_.throttle` works in tight loops
* Fixed IE < 9 `[DontEnum]` bug and Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1s prototype property iteration bug
* Fixed IE < 9 `[DontEnum]` bug and Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1s `prototype` property iteration bug
* Inlined `_.isFunction` calls.
* Made `_.debounce`ed functions match `_.throttle`ed functions return value behavior
* Made `_.escape` no longer translate the *">"* character

109
build.js
View File

@@ -60,7 +60,7 @@
'after': [],
'bind': [],
'bindAll': ['bind'],
'chain': [],
'chain': ['mixin'],
'clone': ['extend', 'isArray'],
'compact': [],
'compose': [],
@@ -72,15 +72,17 @@
'delay': [],
'difference': ['indexOf'],
'escape': [],
'every': ['bind', 'createIterator', 'identity'],
'every': ['createIterator', 'identity'],
'extend': ['createIterator'],
'filter': ['bind', 'createIterator', 'identity'],
'find': ['bind', 'createIterator'],
'filter': ['createIterator', 'identity'],
'find': ['createIterator'],
'first': [],
'flatten': ['isArray'],
'forEach': ['bind', 'createIterator'],
'forEach': ['createIterator'],
'forIn': ['createIterator'],
'forOwn': ['createIterator'],
'functions': ['createIterator'],
'groupBy': ['bind', 'createIterator'],
'groupBy': ['createIterator'],
'has': [],
'identity': [],
'indexOf': ['sortedIndex'],
@@ -106,10 +108,10 @@
'keys': ['createIterator'],
'last': [],
'lastIndexOf': [],
'map': ['bind', 'createIterator', 'identity'],
'max': ['bind'],
'map': ['createIterator', 'identity'],
'max': [],
'memoize': [],
'min': ['bind'],
'min': [],
'mixin': ['forEach'],
'noConflict': [],
'once': [],
@@ -117,23 +119,23 @@
'pick': [],
'pluck': ['createIterator'],
'range': [],
'reduce': ['bind', 'createIterator'],
'reduceRight': ['bind', 'keys'],
'reject': ['bind', 'createIterator', 'identity'],
'reduce': ['createIterator'],
'reduceRight': ['keys'],
'reject': ['createIterator', 'identity'],
'rest': [],
'result': [],
'shuffle': [],
'size': ['keys'],
'some': ['bind', 'createIterator', 'identity'],
'sortBy': ['bind', 'map', 'pluck'],
'sortedIndex': [],
'some': ['createIterator', 'identity'],
'sortBy': ['map', 'pluck'],
'sortedIndex': ['identity'],
'tap': [],
'template': ['escape'],
'throttle': [],
'times': ['bind'],
'times': [],
'toArray': ['values'],
'union': ['indexOf'],
'uniq': ['indexOf'],
'uniq': ['identity', 'indexOf'],
'uniqueId': [],
'values': ['createIterator'],
'without': ['indexOf'],
@@ -141,18 +143,38 @@
'zip': ['max', 'pluck']
};
/** Names of methods to filter for the build */
var filterMethods = Object.keys(dependencyMap);
/** Names of all methods */
var allMethods = Object.keys(dependencyMap);
/** Used to specify if `filterMethods` should be used for exclusion or inclusion */
/** Names of methods to filter for the build */
var filterMethods = allMethods;
/** Used to specify whether `filterMethods` is used for exclusion or inclusion */
var filterType = process.argv.reduce(function(result, value) {
if (!result) {
var pair = value.match(/^(exclude|include)=(.*)$/);
if (pair) {
filterMethods = lodash.intersection(filterMethods, pair[2].split(/, */).map(getRealName));
return pair[1];
}
if (result) {
return result;
}
var pair = value.match(/^(category|exclude|include)=(.*)$/);
if (!pair) {
return result;
}
result = pair[1];
filterMethods = pair[2].split(/, */).map(getRealName);
if (result == 'category') {
// resolve method names belonging to each category
filterMethods = filterMethods.reduce(function(result, category) {
return result.concat(allMethods.filter(function(funcName) {
return RegExp('@category ' + category + '\\b', 'i').test(matchFunction(source, funcName));
}));
}, []);
}
else {
// remove nonexistent method names
filterMethods = lodash.intersection(allMethods, filterMethods);
}
return result;
}, '');
/*--------------------------------------------------------------------------*/
@@ -251,9 +273,9 @@
// match a function declaration
'( +)function ' + funcName + '\\b[\\s\\S]+?\\n\\1}|' +
// match a variable declaration with `createIterator`
' +var ' + funcName + ' *= *(?:[a-zA-Z]+ *\\|\\| *)?createIterator\\((?:{|[a-zA-Z])[\\s\\S]+?\\);|' +
' +var ' + funcName + ' *=.*?createIterator\\((?:{|[a-zA-Z])[\\s\\S]+?\\);|' +
// match a variable declaration with function expression
'( +)var ' + funcName + ' *= *(?:[a-zA-Z]+ *\\|\\| *)?function[\\s\\S]+?\\n\\2};' +
'( +)var ' + funcName + ' *=.*?function[\\s\\S]+?\\n\\2};' +
// end non-capturing group
')\\n'
));
@@ -293,7 +315,6 @@
if (!snippet) {
return source;
}
// remove function
source = source.replace(matchFunction(source, funcName), '');
@@ -350,7 +371,7 @@
* @returns {String} Returns the source with whitespace removed.
*/
function removeWhitespace(source) {
return source.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |var |\\\\n|\\n|\s+/g, function(match) {
return source.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |var |@ |\\\\n|\\n|\s+/g, function(match) {
return match == false || match == '\\n' ? '' : match;
});
}
@@ -359,25 +380,26 @@
// custom build
(function() {
// exit early if "exclude" or "include" options aren't specified
// exit early if "category", "exclude", or "include" options aren't specified
if (!filterType) {
return;
}
// remove the specified functions and their dependants
if (filterType == 'exclude') {
// remove methods that are named in `filterMethods` and their dependants
filterMethods.forEach(function(funcName) {
getDependants(funcName).concat(funcName).forEach(function(otherName) {
source = removeFunction(source, otherName);
});
});
}
// else remove all but the specified functions and their dependencies
else {
// add dependencies to `filterMethods`
filterMethods = lodash.uniq(filterMethods.reduce(function(result, funcName) {
result.push.apply(result, getDependencies(funcName).concat(funcName));
return result;
}, []));
// remove methods that aren't named in `filterMethods`
lodash.each(dependencyMap, function(dependencies, otherName) {
if (filterMethods.indexOf(otherName) < 0) {
source = removeFunction(source, otherName);
@@ -439,25 +461,20 @@
if (isMobile) {
// inline functions defined with `createIterator`
lodash.functions(lodash).forEach(function(funcName) {
var reFunc = RegExp('( +var ' + funcName + ' *= *)((?:[a-zA-Z]+ *\\|\\| *)?)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n'),
parts = source.match(reFunc);
// match `funcName` with pseudo private `_` prefixes removed to allow matching `shimKeys`
var reFunc = RegExp('(\\bvar ' + funcName.replace(/^_/, '') + ' *= *)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n');
// skip if not defined with `createIterator`
if (!parts) {
if (!reFunc.test(source)) {
return;
}
// extract function's code
var code = funcName == 'keys'
? '$1$2' + lodash._createIterator(Function('return ' + parts[3])())
: '$1' + lodash[funcName];
// format code
code = code.replace(/\n(?:.*)/g, function(match) {
// extract and format the function's code
var code = (lodash[funcName] + '').replace(/\n(?:.*)/g, function(match) {
match = match.slice(1);
return (match == '}' ? '\n ' : '\n ') + match;
}) + ';\n';
});
source = source.replace(reFunc, code);
source = source.replace(reFunc, '$1' + code + ';\n');
});
// remove `iteratorTemplate`
@@ -490,7 +507,7 @@
}
// remove pseudo private properties
source = source.replace(/(?:\s*\/\/.*)*\s*lodash\._(?:createIterator|iteratorTemplate)\b.+\n/g, '\n');
source = source.replace(/(?:(?:\s*\/\/.*)*\s*lodash\._[^=]+=.+\n)+/g, '\n');
/*--------------------------------------------------------------------------*/

View File

@@ -9,7 +9,6 @@
var compiledVars = [
'accumulator',
'arrayClass',
'bind',
'callback',
'className',
'collection',
@@ -19,6 +18,7 @@
'hasOwnProperty',
'identity',
'index',
'iteratorBind',
'length',
'object',
'objectTypes',
@@ -101,6 +101,8 @@
'foldl',
'foldr',
'forEach',
'forIn',
'forOwn',
'functions',
'groupBy',
'has',
@@ -193,21 +195,30 @@
// remove copyright to add later in post-compile.js
source = source.replace(/\/\*![\s\S]+?\*\//, '');
// correct JSDoc tags for Closure Compiler
// remove unrecognized JSDoc tags so Closure Compiler won't complain
source = source.replace(/@(?:alias|category)\b.*/g, '');
// add brackets to whitelisted properties so 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']");
// remove brackets from `_.escape(__t)` in `tokenizeEscape`
source = source.replace("_['escape'](__t)", '_.escape(__t)');
// remove whitespace from string literals
source = source.replace(/'(?:(?=(\\?))\1.)*?'/g, function(string) {
// avoids removing the '\n' of the `escapes` object
return string.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |use strict|var |'\\n'|\\\\n|\\n|\s+/g, function(match) {
// avoids removing the '\n' of the `stringEscapes` object
return string.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |use strict|var |@ |'\\n'|\\\\n|\\n|\s+/g, function(match) {
return match == false || match == '\\n' ? '' : match;
});
});
// remove newline from double-quoted string in `_.template`
source = source.replace('"\';\\n"', '"\';"');
// remove debug sourceURL in `_.template`
source = source.replace(/\+(?:\s*\/\/.*)*\s*'\/\/@ sourceURL=[^;]+/, '');
// minify `_.sortBy` internal properties
(function() {
var properties = ['criteria', 'value'],
@@ -276,7 +287,7 @@
// correct external boolean literals
else if (variable == 'true' || variable == 'false') {
result = result
.replace(RegExp(': *' + minNames[index] + ',', 'g'), ':' + variable + ',')
.replace(RegExp(': *' + minNames[index] + '([,\\n])', 'g'), ':' + variable + '$1')
.replace(RegExp('\\b' + minNames[index] + ';', 'g'), variable + ';');
}
});

File diff suppressed because it is too large Load Diff

View File

@@ -21,8 +21,8 @@
// generate Markdown
$markdown = docdown(array(
'path' => '../' . $file,
'title' => 'Lo-Dash <sup>v0.2.2</sup>',
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
'title' => 'Lo-Dash <sup>v0.3.0</sup>',
'url' => 'https://github.com/bestiejs/lodash/blob/v0.3.0/lodash.js'
));
// save to a .md file

567
lodash.js

File diff suppressed because it is too large Load Diff

56
lodash.min.js vendored
View File

@@ -1,30 +1,32 @@
/*!
Lo-Dash 0.2.2 lodash.com/license
Lo-Dash 0.3.0 lodash.com/license
Underscore.js 1.3.3 github.com/documentcloud/underscore/blob/master/LICENSE
*/
;(function(u,n){"use strict";function S(a){return"[object Arguments]"==i.call(a)}function b(a){return new p(a)}function p(a){if(a&&a._wrapped)return a;this._wrapped=a}function k(){for(var a,c,d,j=-1,b=arguments.length,e={e:"",f:"",k:"",q:"",c:{d:"",m:"++l<m"},o:{d:""}};++j<b;)for(c in a=arguments[j],a)d=(d=a[c])==o?"":d,/d|m|j/.test(c)?("string"==typeof d&&(d={b:d,n:d}),e.c[c]=d.b,e.o[c]=d.n):e[c]=d;a=e.a,c=e.c,d=e.o;var j=/^[^,]+/.exec(a)[0],b=d.m,g=/\S+$/.exec(b||j)[0];e.g=j,e.i=H,e.h="j.call("+
g+",l)",e.l=g,e.p=ca,e.r=e.r!==q,e.f||(e.f="if(!"+j+")return r");if("n"==j||!c.j)e.c=o;return b||(d.m="l in "+g),Function("b,c,i,j,k,o,v,y,z,h,A",'"use strict";return function('+a+"){"+sa(e)+"}")(I,v,r,s,da,J,K,i,m,q)}function ta(a,c){return w[c]}function ua(a){return"\\"+va[a]}function ea(){}function wa(a,c){var d=w.length;return w[d]="'+((__t=("+c+"))==null?'':_['escape'](__t))+'",T+d}function xa(a,c){var d=w.length;return w[d]="'+((__t=("+c+"))==null?'':__t)+'",T+d}function ya(a,c){var d=w.length
;return w[d]="';"+c+";__p+='",T+d}function fa(a,c,d,j){if(!a)return d;var b=a.length,e=3>arguments.length;j&&(c=v(c,j));if(b===+b){for(b&&e&&(d=a[--b]);b--;)d=c(d,a[b],b,a);return d}var g=U(a);for((b=g.length)&&e&&(d=a[g[--b]]);b--;)e=g[b],d=c(d,a[e],e,a);return d}function V(a,c,d){return c==n||d?a[0]:l.call(a,0,c)}function ga(a,c){for(var d,b=-1,f=a.length,e=[];++b<f;)d=a[b],W(d)?L.apply(e,c?d:ga(d)):e.push(d);return e}function x(a,c,d){var b;if(!a)return-1;if(d)return d=ha(a,c),a[d]===c?d:-1;d=0
;for(b=a.length;d<b;d++)if(a[d]===c)return d;return-1}function ia(a,c,d){var b=-Infinity,f=-1,e=a.length,g=b;if(!c){for(;++f<e;)a[f]>g&&(g=a[f]);return g}for(d&&(c=v(c,d));++f<e;)d=c(a[f],f,a),d>b&&(b=d,g=a[f]);return g}function ja(a,c,d){return l.call(a,c==n||d?1:c)}function ha(a,c,d){var b,f=0,e=a.length;for(d&&(c=d(c));f<e;)b=f+e>>1,(d?d(a[b]):a[b])<c?f=b+1:e=b;return f}function ka(a,c,d){for(var b,f=-1,e=a.length,g=[],h=[];++f<e;)if(b=d?d(a[f]):a[f],c?!f||h[h.length-1]!==b:0>x(h,b))h.push(b),
g.push(a[f]);return g}function v(a,c){function d(){var g=arguments,h=c;return f||(a=c[b]),e.length&&(g=g.length?M.apply(e,g):e),this instanceof d?(ea.prototype=a.prototype,h=new ea,g=a.apply(h,g),J[typeof g]&&g!==o?g:h):a.apply(h,g)}var b,f=i.call(a)==r;if(f){if(y)return y.call.apply(y,arguments)}else b=c,c=a;var e=l.call(arguments,2);return d}function N(a,c,d){d||(d=[]);if(a===c)return 0!==a||1/a==1/c;if(a==n||c==n)return a===c;a._chain&&(a=a._wrapped),c._chain&&(c=c._wrapped);if(a.isEqual&&i.call
(a.isEqual)==r)return a.isEqual(c);if(c.isEqual&&i.call(c.isEqual)==r)return c.isEqual(a);var b=i.call(a);if(b!=i.call(c))return q;switch(b){case K:return a==""+c;case O:return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case la:case ma:return+a==+c;case na:return a.source==c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return q;for(var f=d.length;f--;)if(d[f]==a)return m;var f=-1,e=m,g=0;d.push(a);if(b==I){if(g=a.length,e=g==c.length
)for(;g--&&(e=N(a[g],c[g],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return q;for(var h in a)if(s.call(a,h)&&(g++,!(e=s.call(c,h)&&N(a[h],c[h],d))))break;if(e){for(h in c)if(s.call(c,h)&&!(g--))break;e=!g}if(e&&H)for(;7>++f&&(h=ca[f],!s.call(a,h)||!!(e=s.call(c,h)&&N(a[h],c[h],d))););}return d.pop(),e}function da(a){return a}function oa(a){C(P(a),function(c){var d=b[c]=a[c];p.prototype[c]=function(){var a=[this._wrapped];return arguments.length&&L.apply(a,arguments
),a=1==a.length?d.call(b,a[0]):d.apply(b,a),this._chain&&(a=new p(a),a._chain=m),a}})}var m=!0,o=null,q=!1,X="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(u=global),exports),va={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},H=!{valueOf:0}.propertyIsEnumerable("valueOf"),za=0,J={"boolean":q,"function":m,object:m,number:q,string:q,"undefined":q},Aa=u._,z=RegExp("^"+({}.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&"
).replace(/valueOf|for [^\]]+/g,".+?")+"$"),Ba=/__token__(\d+)/g,Ca=/['\n\r\t\u2028\u2029\\]/g,ca="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),T="__token__",w=[],I="[object Array]",la="[object Boolean]",ma="[object Date]",r="[object Function]",O="[object Number]",na="[object RegExp]",K="[object String]",A=Array.prototype,D=Object.prototype,M=A.concat,s=D.hasOwnProperty,L=A.push,l=A.slice,i=D.toString,y=z.test(y=l.bind)&&/\n|Opera/.test
(y+i.call(u.opera))&&y,E=z.test(E=Array.isArray)&&E,Da=u.isFinite,Y=z.test(Y=Object.keys)&&Y,Ea=u.clearTimeout,Q=u.setTimeout;b.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:"obj"};var sa=Function("obj","var __p;with(obj){__p='var l,r';if(k){__p+='='+k};__p+=';'+f+';'+q+';';if(c){__p+='var m='+g+'.length;l=-1;';if(o){__p+='if(m===+m){'};__p+=''+c['d']+';while('+c['m']+'){'+c['j']+'}';if(o){__p+='}'}}if(o){if(c){__p+='else{'}if(!i){__p+='var s=typeof '+l+'==\\'function\\';'};__p+=''+o['d']+';for('+o['m']+'){';if(i){if(r){__p+='if('+h+'){'};__p+=''+o['j']+';';if(r){__p+='}'}}else{__p+='if(!(s&&l==\\'prototype\\')';if(r){__p+='&&'+h};__p+='){'+o['j']+'}'};__p+='}';if(i){__p+='var g='+l+'.constructor;';for(var k=0;k<7;k++){__p+='l=\\''+p[k]+'\\';if(';if(p[k]=='constructor'){__p+='!(g&&g.prototype==='+l+')&&'};__p+=''+h+'){'+o['j']+'}'}}if(c){__p+='}'}};__p+=''+e+';return r'}return __p"
),t={a:"f,d,x",k:"f",q:"if(!d){d=k}else if(x){d=c(d,x)}",j:"d(f[l],l,f)"},Z={k:"z",j:"if(!d(f[l],l,f))return!r"},$={a:"n",k:"n",q:"for(var t,u=1,m=arguments.length;u<m;u++){t=arguments[u];"+(H?"if(t){":""),m:"l in t",r:q,j:"n[l]=t[l]",e:(H?"}":"")+"}"},F={k:"[]",j:"d(f[l],l,f)&&r.push(f[l])"},B={q:"if(x)d=c(d,x)"},G={k:"",f:"if(!f)return[]",d:{b:"r=Array(m)",n:"r=[]"},j:{b:"r[l]=d(f[l],l,f)",n:"r.push(d(f[l],l,f))"}},z=k({a:"f,w",k:"h",j:"if(f[l]===w)return z"}),aa=k(t,Z),D=k(t,F),pa=k(t,B,{k:"",
j:"if(d(f[l],l,f))return f[l]"}),C=k(t,B),ba=k(t,G),R=k(G,{a:"f,q",j:{b:"r[l]=f[l][q]",n:"r.push(f[l][q])"}}),B=k({a:"f,d,a,x",k:"a",q:"var p=arguments.length<3;if(x)d=c(d,x)",d:{b:"if(p)r=f[++l]"},j:{b:"r=d(r,f[l],l,f)",n:"r=p?(p=h,f[l]):d(r,f[l],l,f)"}}),F=k(t,F,{j:"!"+F.j}),t=k(t,Z,{k:"h",j:Z.j.replace("!","")}),qa=k(G,{a:"f",j:{b:"r[l]=f[l]",n:"r.push(f[l])"}}),G=k($,{j:"if(n[l]==A)"+$.j}),ra=k($),P=k({a:"n",k:"[]",r:q,j:"if(y.call(n[l])==i)r.push(l)",e:"r.sort()"});S(arguments)||(S=function(
a){return!!a&&!!s.call(a,"callee")});var W=E||function(a){return i.call(a)==I},E=k({a:"B",k:"z",q:"var e=y.call(B);if(e==b||e==v)return!B.length",j:{n:"return h"}}),U=Y||k({a:"n",f:"if(!o[typeof n]||n===null)throw TypeError()",k:"[]",j:"r.push(l)"});b.VERSION="0.2.2",b.after=function(a,c){return 1>a?c():function(){if(1>--a)return c.apply(this,arguments)}},b.bind=v,b.bindAll=function(a){var c=arguments,d=1;1==c.length&&(d=0,c=P(a));for(var b=c.length;d<b;d++)a[c[d]]=v(a[c[d]],a);return a},b.chain=
function(a){return a=new p(a),a._chain=m,a},b.clone=function(a){return J[typeof a]&&a!==o?W(a)?a.slice():ra({},a):a},b.compact=function(a){for(var c=-1,d=a.length,b=[];++c<d;)a[c]&&b.push(a[c]);return b},b.compose=function(){var a=arguments;return function(){for(var c=arguments,d=a.length;d--;)c=[a[d].apply(this,c)];return c[0]}},b.contains=z,b.debounce=function(a,c,d){function b(){h=n,d||a.apply(g,f)}var f,e,g,h;return function(){var i=d&&!h;return f=arguments,g=this,Ea(h),h=Q(b,c),i&&(e=a.apply
(g,f)),e}},b.defaults=G,b.defer=function(a){var c=l.call(arguments,1);return Q(function(){return a.apply(n,c)},1)},b.delay=function(a,c){var d=l.call(arguments,2);return Q(function(){return a.apply(n,d)},c)},b.difference=function(a){for(var c=-1,d=a.length,b=[],f=M.apply(b,l.call(arguments,1));++c<d;)0>x(f,a[c])&&b.push(a[c]);return b},b.escape=function(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")},b.every=aa,b.extend=ra,b.filter=D,b.find=
pa,b.first=V,b.flatten=ga,b.forEach=C,b.functions=P,b.groupBy=function(a,c,d){var b,f=-1,e=i.call(c)==r,g=a.length,h={};for(e&&d&&(c=v(c,d));++f<g;)b=a[f],d=e?c(b,f,a):b[c],(s.call(h,d)?h[d]:h[d]=[]).push(b);return h},b.has=function(a,c){return s.call(a,c)},b.identity=da,b.indexOf=x,b.initial=function(a,c,d){return l.call(a,0,-(c==n||d?1:c))},b.intersection=function(a){for(var c,d=-1,b=a.length,f=l.call(arguments,1),e=[];++d<b;)c=a[d],0>x(e,c)&&aa(f,function(a){return-1<x(a,c)})&&e.push(c);return e
},b.invoke=function(a,c){for(var d=l.call(arguments,2),b=-1,f=a.length,e=i.call(c)==r,g=[];++b<f;)g[b]=(e?c:a[b][c]).apply(a[b],d);return g},b.isArguments=S,b.isArray=W,b.isBoolean=function(a){return a===m||a===q||i.call(a)==la},b.isDate=function(a){return i.call(a)==ma},b.isElement=function(a){return!!a&&1==a.nodeType},b.isEmpty=E,b.isEqual=N,b.isFinite=function(a){return Da(a)&&i.call(a)==O},b.isFunction=function(a){return i.call(a)==r},b.isNaN=function(a){return i.call(a)==O&&a!=+a},b.isNull=function(
a){return a===o},b.isNumber=function(a){return i.call(a)==O},b.isObject=function(a){return J[typeof a]&&a!==o},b.isRegExp=function(a){return i.call(a)==na},b.isString=function(a){return i.call(a)==K},b.isUndefined=function(a){return a===n},b.keys=U,b.last=function(a,c,d){var b=a.length;return c==n||d?a[b-1]:l.call(a,-c||b)},b.lastIndexOf=function(a,c){if(!a)return-1;for(var d=a.length;d--;)if(a[d]===c)return d;return-1},b.map=ba,b.max=ia,b.memoize=function(a,c){var d={};return function(){var b=c?
c.apply(this,arguments):arguments[0];return s.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}},b.min=function(a,c,d){var b=Infinity,f=-1,e=a.length,g=b;if(!c){for(;++f<e;)a[f]<g&&(g=a[f]);return g}for(d&&(c=v(c,d));++f<e;)d=c(a[f],f,a),d<b&&(b=d,g=a[f]);return g},b.mixin=oa,b.noConflict=function(){return u._=Aa,this},b.once=function(a){var c,d=q;return function(){return d?c:(d=m,c=a.apply(this,arguments))}},b.partial=function(a){var c=l.call(arguments,1),d=c.length;return function(){var b;return b=arguments
,b.length&&(c.length=d,L.apply(c,b)),b=1==c.length?a.call(this,c[0]):a.apply(this,c),c.length=d,b}},b.pick=function(a){for(var c,d=0,b=M.apply(A,arguments),f=b.length,e={};++d<f;)c=b[d],c in a&&(e[c]=a[c]);return e},b.pluck=R,b.range=function(a,c,d){d||(d=1),2>arguments.length&&(c=a||0,a=0);for(var b=-1,f=Math.max(Math.ceil((c-a)/d),0),e=Array(f);++b<f;)e[b]=a,a+=d;return e},b.reduce=B,b.reduceRight=fa,b.reject=F,b.rest=ja,b.result=function(a,c){if(!a)return o;var d=a[c];return i.call(d)==r?a[c](
):d},b.shuffle=function(a){for(var c,d=-1,b=a.length,f=Array(b);++d<b;)c=Math.floor(Math.random()*(d+1)),f[d]=f[c],f[c]=a[d];return f},b.size=function(a){var c=i.call(a);return c==I||c==K?a.length:U(a).length},b.some=t,b.sortBy=function(a,c,d){if(i.call(c)!=r)var b=c,c=function(a){return a[b]};else d&&(c=v(c,d));return R(ba(a,function(b,d){return{a:c(b,d,a),b:b}}).sort(function(a,c){var b=a.a,d=c.a;return b===n?1:d===n?-1:b<d?-1:b>d?1:0}),"b")},b.sortedIndex=ha,b.tap=function(a,c){return c(a),a},
b.template=function(a,c,d){d||(d={});var j;j=b.templateSettings;var f=d.escape,e=d.evaluate,g=d.interpolate,d=d.variable;return f==o&&(f=j.escape),e==o&&(e=j.evaluate),g==o&&(g=j.interpolate),f&&(a=a.replace(f,wa)),g&&(a=a.replace(g,xa)),e&&(a=a.replace(e,ya)),a="__p='"+a.replace(Ca,ua).replace(Ba,ta)+"';\n",w.length=0,d||(d=j.variable,a="with("+d+"||{}){"+a+"}"),a="function("+d+"){var __p,__t,__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+a+"return __p}",j=Function("_","return "+
a)(b),c?j(c):(j.source=a,j)},b.throttle=function(a,c){function b(){h=new Date,g=n,a.apply(e,j)}var j,f,e,g,h=0;return function(){var i=new Date,k=c-(i-h);return j=arguments,e=this,0>=k?(h=i,f=a.apply(e,j)):g||(g=Q(b,k)),f}},b.times=function(a,c,b){b&&(c=v(c,b));for(b=0;b<a;b++)c(b)},b.toArray=function(a){if(!a)return[];if(i.call(a.toArray)==r)return a.toArray();var b=a.length;return b===+b?l.call(a):qa(a)},b.union=function(){for(var a=-1,b=[],d=M.apply(b,arguments),i=d.length;++a<i;)0>x(b,d[a])&&
b.push(d[a]);return b},b.uniq=ka,b.uniqueId=function(a){var b=za++;return a?a+b:b},b.values=qa,b.without=function(a){for(var b=l.call(arguments,1),d=-1,i=a.length,f=[];++d<i;)0>x(b,a[d])&&f.push(a[d]);return f},b.wrap=function(a,b){return function(){var d=[a];return arguments.length&&L.apply(d,arguments),b.apply(this,d)}},b.zip=function(){for(var a=-1,b=ia(R(arguments,"length")),d=Array(b);++a<b;)d[a]=R(arguments,a);return d},b.all=aa,b.any=t,b.collect=ba,b.detect=pa,b.each=C,b.foldl=B,b.foldr=fa
,b.head=V,b.include=z,b.inject=B,b.methods=P,b.select=D,b.tail=ja,b.take=V,b.unique=ka,p.prototype=b.prototype,oa(b),p.prototype.chain=function(){return this._chain=m,this},p.prototype.value=function(){return this._wrapped},C("pop push reverse shift sort splice unshift".split(" "),function(a){var b=A[a];p.prototype[a]=function(){var a=this._wrapped;return arguments.length?b.apply(a,arguments):b.call(a),a.length===0&&delete a[0],this._chain&&(a=new p(a),a._chain=m),a}}),C(["concat","join","slice"]
,function(a){var b=A[a];p.prototype[a]=function(){var a=this._wrapped,a=arguments.length?b.apply(a,arguments):b.call(a);return this._chain&&(a=new p(a),a._chain=m),a}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(u._=b,define(function(){return b})):X?"object"==typeof module&&module&&module.s==X?(module.s=b)._=b:X._=b:u._=b})(this);
;(function(e,t){"use strict";function s(e){return"[object Arguments]"==nt.call(e)}function o(e){return new u(e)}function u(e){if(e&&e._wrapped)return e;this._wrapped=e}function a(){for(var e,t,s,o=-1,u=arguments.length,a={e:"",f:"",k:"",q:"",c:{d:"",m:"++k<m"},o:{d:""}};++o<u;)for(t in e=arguments[o],e)s=(s=e[t])==r?"":s,/d|m|j/.test(t)?("string"==typeof s&&(s={b:s,n:s}),a.c[t]=s.b,a.o[t]=s.n):a[t]=s;e=a.a,t=a.c,s=a.o;var o=/^[^,]+/.exec(e)[0],u=s.m,f=/\S+$/.exec(u||o)[0];a.g=o,a.i=O,a.h="i.call("+
f+",k)",a.l=f,a.p=j,a.r=a.r!==i,a.f||(a.f="if(!"+o+")return r");if("n"==o||!t.j)a.c=r;return u||(s.m="k in "+f),Function("b,h,i,j,l,o,v,y,z,g,A",'"use strict";return function('+e+"){"+ft(a)+"}")(z,V,Z,k,h,R,K,nt,n,i)}function f(e,t){return I[t]}function l(e){return"\\"+U[e]}function c(e){return q[e]}function h(e,t){return function(n,r,i){return e.call(t,n,r,i)}}function p(){}function d(e,t){var n=I.length;return I[n]="'+((__t=("+t+"))==null?'':_.escape(__t))+'",F+n}function v(e,t){var n=I.length;
return I[n]="'+((__t=("+t+"))==null?'':__t)+'",F+n}function m(e,t){var n=I.length;return I[n]="';"+t+";__p+='",F+n}function g(e,t,n,r){if(!e)return n;var i=e.length,s=3>arguments.length;r&&(t=h(t,r));if(i===i>>>0){for(i&&s&&(n=e[--i]);i--;)n=t(n,e[i],i,e);return n}var o=Lt(e);for((i=o.length)&&s&&(n=e[o[--i]]);i--;)s=o[i],n=t(n,e[s],s,e);return n}function y(e,n,r){return n==t||r?e[0]:tt.call(e,0,n)}function b(e,t){for(var n,r=-1,i=e.length,s=[];++r<i;)n=e[r],kt(n)?et.apply(s,t?n:b(n)):s.push(n);return s
}function w(e,t,n){var r=-1,i=e.length;if(n){if("number"!=typeof n)return r=x(e,t),e[r]===t?r:-1;r=(0>n?Math.max(0,i+n):n)-1}for(;++r<i;)if(e[r]===t)return r;return-1}function E(e,t,n){var r=-Infinity,i=-1,s=e.length,o=r;if(!t){for(;++i<s;)e[i]>o&&(o=e[i]);return o}for(n&&(t=h(t,n));++i<s;)n=t(e[i],i,e),n>r&&(r=n,o=e[i]);return o}function S(e,n,r){return tt.call(e,n==t||r?1:n)}function x(e,t,n,r){var i,s=0,o=e.length;if(n)for(t=n.call(r,t);s<o;)i=s+o>>>1,n.call(r,e[i])<t?s=i+1:o=i;else for(;s<o;)
i=s+o>>>1,e[i]<t?s=i+1:o=i;return s}function T(e,t,n,r){var s=-1,o=e.length,u=[],a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n?r&&(n=h(n,r)):n=k;++s<o;)if(r=n(e[s],s,e),t?!s||a[a.length-1]!==r:0>w(a,r))a.push(r),u.push(e[s]);return u}function N(e,t){function n(){var u=arguments,a=t;return s||(e=t[i]),o.length&&(u=u.length?Y.apply(o,u):o),this instanceof n?(p.prototype=e.prototype,a=new p,u=e.apply(a,u),R[typeof u]&&u!==r?u:a):e.apply(a,u)}var i,s=nt.call(e)==V;if(s){if(rt)return rt.call.apply(rt
,arguments)}else i=t,t=e;var o=tt.call(arguments,2);return n}function C(e,r,s){s||(s=[]);if(e===r)return 0!==e||1/e==1/r;if(e==t||r==t)return e===r;e._chain&&(e=e._wrapped),r._chain&&(r=r._wrapped);if(e.isEqual&&nt.call(e.isEqual)==V)return e.isEqual(r);if(r.isEqual&&nt.call(r.isEqual)==V)return r.isEqual(e);var o=nt.call(e);if(o!=nt.call(r))return i;switch(o){case K:return e==""+r;case $:return e!=+e?r!=+r:0==e?1/e==1/r:e==+r;case W:case X:return+e==+r;case J:return e.source==r.source&&e.global==
r.global&&e.multiline==r.multiline&&e.ignoreCase==r.ignoreCase}if("object"!=typeof e||"object"!=typeof r)return i;for(var u=s.length;u--;)if(s[u]==e)return n;var u=-1,a=n,f=0;s.push(e);if(o==z){if(f=e.length,a=f==r.length)for(;f--&&(a=C(e[f],r[f],s)););}else{if("constructor"in e!="constructor"in r||e.constructor!=r.constructor)return i;for(var l in e)if(Z.call(e,l)&&(f++,!(a=Z.call(r,l)&&C(e[l],r[l],s))))break;if(a){for(l in r)if(Z.call(r,l)&&!(f--))break;a=!f}if(a&&O)for(;7>++u&&(l=j[u],!Z.call(
e,l)||!!(a=Z.call(r,l)&&C(e[l],r[l],s))););}return s.pop(),a}function k(e){return e}function L(e){wt(Ct(e),function(t){var r=o[t]=e[t];u.prototype[t]=function(){var e=[this._wrapped];return arguments.length&&et.apply(e,arguments),e=1==e.length?r.call(o,e[0]):r.apply(o,e),this._chain&&(e=new u(e),e._chain=n),e}})}var n=!0,r=null,i=!1,A="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),O=!{valueOf:0}.propertyIsEnumerable("valueOf"),M=0,_=
e._,D=RegExp("^"+({}.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),P=/__token__(\d+)/g,H=/[&<"']/g,B=/['\n\r\t\u2028\u2029\\]/g,j="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),F="__token__",I=[],q={"&":"&amp;","<":"&lt;",'"':"&quot;","'":"&#x27;"},R={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i},U={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029"
:"u2029"},z="[object Array]",W="[object Boolean]",X="[object Date]",V="[object Function]",$="[object Number]",J="[object RegExp]",K="[object String]",Q=Array.prototype,G=Object.prototype,Y=Q.concat,Z=G.hasOwnProperty,et=Q.push,tt=Q.slice,nt=G.toString,rt=D.test(rt=tt.bind)&&/\n|Opera/.test(rt+nt.call(e.opera))&&rt,it=D.test(it=Array.isArray)&&it,st=e.isFinite,ot=D.test(ot=Object.keys)&&ot,ut=e.clearTimeout,at=e.setTimeout;o.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate
:/<%=([\s\S]+?)%>/g,variable:"obj"};var ft=Function("obj","var __p;with(obj){__p='var k,r';if(k){__p+='='+k};__p+=';'+f+';'+q+';';if(c){__p+='var m='+g+'.length;k=-1;';if(o){__p+='if(m===m>>>0){'};__p+=''+c['d']+';while('+c['m']+'){'+c['j']+'}';if(o){__p+='}'}}if(o){if(c){__p+='else{'}if(!i){__p+='var s=typeof '+l+'==\\'function\\';'};__p+=''+o['d']+';for('+o['m']+'){';if(i){if(r){__p+='if('+h+'){'};__p+=''+o['j']+';';if(r){__p+='}'}}else{__p+='if(!(s&&k==\\'prototype\\')';if(r){__p+='&&'+h};__p+='){'+o['j']+'}'};__p+='}';if(i){__p+='var f='+l+'.constructor;';for(var k=0;k<7;k++){__p+='k=\\''+p[k]+'\\';if(';if(p[k]=='constructor'){__p+='!(f&&f.prototype==='+l+')&&'};__p+=''+h+'){'+o['j']+'}'}}if(c){__p+='}'}};__p+=''+e+';return r'}return __p"
),lt={a:"e,c,x",k:"e",q:"if(!c){c=j}else if(x){c=l(c,x)}",j:"c(e[k],k,e)"},ct={k:"z",j:"if(!c(e[k],k,e))return!r"},ht={a:"n",k:"n",q:"for(var t,u=1,m=arguments.length;u<m;u++){t=arguments[u];"+(O?"if(t){":""),m:"k in t",r:i,j:"n[k]=t[k]",e:(O?"}":"")+"}"},pt={k:"[]",j:"c(e[k],k,e)&&r.push(e[k])"},dt={q:"if(x)c=l(c,x)"},vt={j:{n:lt.j}},mt={k:"",f:"if(!e)return[]",d:{b:"r=Array(m)",n:"r=[]"},j:{b:"r[k]=c(e[k],k,e)",n:"r.push(c(e[k],k,e))"}},gt=a({a:"n",f:"if(!o[typeof n]||n===null)throw TypeError()"
,k:"[]",j:"r.push(k)"}),D=a({a:"e,w",k:"g",j:"if(e[k]===w)return z"}),yt=a(lt,ct),G=a(lt,pt),bt=a(lt,dt,{k:"",j:"if(c(e[k],k,e))return e[k]"}),wt=a(lt,dt),Et=a(lt,mt),St=a(mt,{a:"e,q",j:{b:"r[k]=e[k][q]",n:"r.push(e[k][q])"}}),xt=a({a:"e,c,a,x",k:"a",q:"var p=arguments.length<3;if(x)c=l(c,x)",d:{b:"if(p)r=e[++k]"},j:{b:"r=c(r,e[k],k,e)",n:"r=p?(p=g,e[k]):c(r,e[k],k,e)"}}),pt=a(lt,pt,{j:"!"+pt.j}),ct=a(lt,ct,{k:"g",j:ct.j.replace("!","")}),Tt=a(mt,{a:"e",j:{b:"r[k]=e[k]",n:"r.push(e[k])"}}),mt=a(ht
,{j:"if(n[k]==A)"+ht.j}),Nt=a(ht),ht=a(lt,dt,vt,{r:i}),lt=a(lt,dt,vt),Ct=a({a:"n",k:"[]",r:i,j:"if(y.call(n[k])==h)r.push(k)",e:"r.sort()"});s(arguments)||(s=function(e){return!!e&&!!Z.call(e,"callee")});var kt=it||function(e){return nt.call(e)==z},it=a({a:"B",k:"z",q:"var d=y.call(B);if(d==b||d==v)return!B.length",j:{n:"return g"}}),Lt=ot?function(e){return"function"==typeof e?gt(e):ot(e)}:gt;o.VERSION="0.3.0",o.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments
)}},o.bind=N,o.bindAll=function(e){var t=arguments,n=1;1==t.length&&(n=0,t=Ct(e));for(var r=t.length;n<r;n++)e[t[n]]=N(e[t[n]],e);return e},o.chain=function(e){return e=new u(e),e._chain=n,e},o.clone=function(e){return R[typeof e]&&e!==r?kt(e)?e.slice():Nt({},e):e},o.compact=function(e){for(var t=-1,n=e.length,r=[];++t<n;)e[t]&&r.push(e[t]);return r},o.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},o.contains=D,o.debounce=
function(e,n,r){function i(){a=t,r||e.apply(u,s)}var s,o,u,a;return function(){var t=r&&!a;return s=arguments,u=this,ut(a),a=at(i,n),t&&(o=e.apply(u,s)),o}},o.defaults=mt,o.defer=function(e){var n=tt.call(arguments,1);return at(function(){return e.apply(t,n)},1)},o.delay=function(e,n){var r=tt.call(arguments,2);return at(function(){return e.apply(t,r)},n)},o.difference=function(e){for(var t=-1,n=e.length,r=[],i=Y.apply(r,tt.call(arguments,1));++t<n;)0>w(i,e[t])&&r.push(e[t]);return r},o.escape=function(
e){return(e+"").replace(H,c)},o.every=yt,o.extend=Nt,o.filter=G,o.find=bt,o.first=y,o.flatten=b,o.forEach=wt,o.forIn=ht,o.forOwn=lt,o.functions=Ct,o.groupBy=function(e,t,n){var r,i=-1,s="function"==typeof t,o=e.length,u={};for(s&&n&&(t=h(t,n));++i<o;)r=e[i],n=s?t(r,i,e):r[t],(Z.call(u,n)?u[n]:u[n]=[]).push(r);return u},o.has=function(e,t){return Z.call(e,t)},o.identity=k,o.indexOf=w,o.initial=function(e,n,r){return tt.call(e,0,-(n==t||r?1:n))},o.intersection=function(e){for(var t,n=-1,r=e.length,
i=tt.call(arguments,1),s=[];++n<r;)t=e[n],0>w(s,t)&&yt(i,function(e){return-1<w(e,t)})&&s.push(t);return s},o.invoke=function(e,t){for(var n=tt.call(arguments,2),r=-1,i=e.length,s="function"==typeof t,o=[];++r<i;)o[r]=(s?t:e[r][t]).apply(e[r],n);return o},o.isArguments=s,o.isArray=kt,o.isBoolean=function(e){return e===n||e===i||nt.call(e)==W},o.isDate=function(e){return nt.call(e)==X},o.isElement=function(e){return!!e&&1==e.nodeType},o.isEmpty=it,o.isEqual=C,o.isFinite=function(e){return st(e)&&nt
.call(e)==$},o.isFunction=function(e){return nt.call(e)==V},o.isNaN=function(e){return nt.call(e)==$&&e!=+e},o.isNull=function(e){return e===r},o.isNumber=function(e){return nt.call(e)==$},o.isObject=function(e){return R[typeof e]&&e!==r},o.isRegExp=function(e){return nt.call(e)==J},o.isString=function(e){return nt.call(e)==K},o.isUndefined=function(e){return e===t},o.keys=Lt,o.last=function(e,n,r){var i=e.length;return n==t||r?e[i-1]:tt.call(e,-n||i)},o.lastIndexOf=function(e,t,n){var r=e.length
;for(n&&"number"==typeof n&&(r=(0>n?Math.max(0,r+n):Math.min(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},o.map=Et,o.max=E,o.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)}},o.min=function(e,t,n){var r=Infinity,i=-1,s=e.length,o=r;if(!t){for(;++i<s;)e[i]<o&&(o=e[i]);return o}for(n&&(t=h(t,n));++i<s;)n=t(e[i],i,e),n<r&&(r=n,o=e[i]);return o},o.mixin=L,o.noConflict=function(){return e._=_,this},o.once=
function(e){var t,r=i;return function(){return r?t:(r=n,t=e.apply(this,arguments))}},o.partial=function(e){var t=tt.call(arguments,1),n=t.length;return function(){var r;return r=arguments,r.length&&(t.length=n,et.apply(t,r)),r=1==t.length?e.call(this,t[0]):e.apply(this,t),t.length=n,r}},o.pick=function(e){for(var t,n=0,r=Y.apply(Q,arguments),i=r.length,s={};++n<i;)t=r[n],t in e&&(s[t]=e[t]);return s},o.pluck=St,o.range=function(e,t,n){n||(n=1),2>arguments.length&&(t=e||0,e=0);for(var r=-1,i=Math.
max(Math.ceil((t-e)/n),0),s=Array(i);++r<i;)s[r]=e,e+=n;return s},o.reduce=xt,o.reduceRight=g,o.reject=pt,o.rest=S,o.result=function(e,t){if(!e)return r;var n=e[t];return nt.call(n)==V?e[t]():n},o.shuffle=function(e){for(var t,n=-1,r=e.length,i=Array(r);++n<r;)t=Math.floor(Math.random()*(n+1)),i[n]=i[t],i[t]=e[n];return i},o.size=function(e){var t=nt.call(e);return t==z||t==K?e.length:Lt(e).length},o.some=ct,o.sortBy=function(e,n,r){if("string"==typeof n)var i=n,n=function(e){return e[i]};else r&&
(n=h(n,r));return St(Et(e,function(t,r){return{a:n(t,r,e),b:t}}).sort(function(e,n){var r=e.a,i=n.a;return r===t?1:i===t?-1:r<i?-1:r>i?1:0}),"b")},o.sortedIndex=x,o.tap=function(e,t){return t(e),e},o.template=function(e,t,n){n||(n={});var i;i=o.templateSettings;var s=n.escape,u=n.evaluate,a=n.interpolate,n=n.variable;return s==r&&(s=i.escape),u==r&&(u=i.evaluate),a==r&&(a=i.interpolate),s&&(e=e.replace(s,d)),a&&(e=e.replace(a,v)),u&&(e=e.replace(u,m)),e="__p='"+e.replace(B,l).replace(P,f)+"';",I.
length=0,n||(n=i.variable,e="with("+n+"||{}){"+e+"}"),e="function("+n+"){var __p,__t,__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+e+"return __p}",i=Function("_","return "+e)(o),t?i(t):(i.source=e,i)},o.throttle=function(e,n){function r(){a=new Date,u=t,e.apply(o,i)}var i,s,o,u,a=0;return function(){var t=new Date,f=n-(t-a);return i=arguments,o=this,0>=f?(a=t,s=e.apply(o,i)):u||(u=at(r,f)),s}},o.times=function(e,t,n){var r=-1;if(n)for(;++r<e;)t.call(n,r);else for(;++r<e;
)t(r)},o.toArray=function(e){if(!e)return[];if(nt.call(e.toArray)==V)return e.toArray();var t=e.length;return t===t>>>0?tt.call(e):Tt(e)},o.union=function(){for(var e=-1,t=[],n=Y.apply(t,arguments),r=n.length;++e<r;)0>w(t,n[e])&&t.push(n[e]);return t},o.uniq=T,o.uniqueId=function(e){var t=M++;return e?e+t:t},o.values=Tt,o.without=function(e){for(var t=tt.call(arguments,1),n=-1,r=e.length,i=[];++n<r;)0>w(t,e[n])&&i.push(e[n]);return i},o.wrap=function(e,t){return function(){var n=[e];return arguments
.length&&et.apply(n,arguments),t.apply(this,n)}},o.zip=function(){for(var e=-1,t=E(St(arguments,"length")),n=Array(t);++e<t;)n[e]=St(arguments,e);return n},o.all=yt,o.any=ct,o.collect=Et,o.detect=bt,o.each=wt,o.foldl=xt,o.foldr=g,o.head=y,o.include=D,o.inject=xt,o.methods=Ct,o.select=G,o.tail=S,o.take=y,o.unique=T,u.prototype=o.prototype,L(o),u.prototype.chain=function(){return this._chain=n,this},u.prototype.value=function(){return this._wrapped},wt("pop push reverse shift sort splice unshift".split
(" "),function(e){var t=Q[e];u.prototype[e]=function(){var e=this._wrapped;return arguments.length?t.apply(e,arguments):t.call(e),e.length===0&&delete e[0],this._chain&&(e=new u(e),e._chain=n),e}}),wt(["concat","join","slice"],function(e){var t=Q[e];u.prototype[e]=function(){var e=this._wrapped,e=arguments.length?t.apply(e,arguments):t.call(e);return this._chain&&(e=new u(e),e._chain=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=o,define(function(){return o})):A?"object"==typeof
module&&module&&module.s==A?(module.s=o)._=o:A._=o:e._=o})(this);

View File

@@ -1,6 +1,6 @@
{
"name": "lodash",
"version": "0.2.2",
"version": "0.3.0",
"description": "A drop-in replacement for Underscore.js that delivers performance improvements, bug fixes, and additional features.",
"homepage": "http://lodash.com",
"main": "lodash",

View File

@@ -34,11 +34,13 @@
}());
window.onload = function() {
var sibling = document.getElementsByTagName('script')[0],
var fbUI = document.getElementById('FirebugUI'),
fbDoc = (fbDoc = fbUI.contentWindow || fbUI.contentDocument).document || fbDoc,
sibling = document.getElementsByTagName('script')[0],
script = document.createElement('script');
document.getElementById('FirebugUI').style.height = '100%';
script.src = 'perf.js';
fbUI.style.height = fbDoc.body.style.height = fbDoc.documentElement.style.height = '100%';
script.src = 'perf.js?t=' + (+new Date);
sibling.parentNode.insertBefore(script, sibling);
};
</script>

View File

@@ -25,6 +25,11 @@
_._ || _
);
/** Used to access the Firebug Lite panel */
var fbPanel = (fbPanel = window.document && document.getElementById('FirebugUI')) &&
(fbPanel = (fbPanel = fbPanel.contentWindow || fbPanel.contentDocument).document || fbPanel) &&
fbPanel.getElementById('fbPanel1');
/** Used to score Lo-Dash and Underscore performance */
var score = { 'lodash': 0, 'underscore': 0 };
@@ -41,6 +46,22 @@
/*--------------------------------------------------------------------------*/
/**
* Logs text to the console.
*
* @private
* @param {String} text The text to log.
*/
function log(text) {
console.log(text);
if (fbPanel) {
// scroll the Firebug Lite panel down
fbPanel.scrollTop = fbPanel.scrollHeight;
}
}
/*--------------------------------------------------------------------------*/
lodash.extend(Benchmark.options, {
'async': true,
'setup': function() {
@@ -48,16 +69,12 @@
_ = window._,
lodash = window.lodash;
var numbers = [],
var length = 20,
numbers = [],
object = {},
fourNumbers = [5, 25, 10, 30],
nestedNumbers = [1, [2], [3, [[4]]]],
twoNumbers = [12, 21],
words = [
'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',
'seventeen', 'eighteen', 'nineteen', 'twenty'
];
twoNumbers = [12, 21];
var ctor = function() { },
func = function(greeting) { return greeting + ': ' + this.name; };
@@ -70,40 +87,71 @@
_boundCtor = _.bind(ctor, { 'name': 'moe' }),
_boundPartial = _.bind(func, { 'name': 'moe' }, 'hi');
for (var index = 0; index < 20; index++) {
var wordToNumber = {
'one': 1,
'two': 2,
'three': 3,
'four': 4,
'five': 5,
'six': 6,
'seven': 7,
'eight': 8,
'nine': 9,
'ten': 10,
'eleven': 11,
'twelve': 12,
'thirteen': 13,
'fourteen': 14,
'fifteen': 15,
'sixteen': 16,
'seventeen': 17,
'eighteen': 18,
'nineteen': 19,
'twenty': 20,
'twenty-one': 21,
'twenty-two': 22,
'twenty-three': 23,
'twenty-four': 24,
'twenty-five': 25
};
var words = _.keys(wordToNumber).slice(0, length);
for (var index = 0; index < length; index++) {
numbers[index] = index;
object['key' + index] = index;
}
var objects = lodash.map(numbers, function(n) {
return { 'num': n };
var objects = lodash.map(numbers, function(num) {
return { 'num': num };
});
}
});
lodash.extend(Benchmark.Suite.options, {
'onStart': function() {
console.log('\n' + this.name + ':');
log('\n' + this.name + ':');
},
'onCycle': function(event) {
console.log(event.target + '');
log(event.target + '');
},
'onComplete': function() {
var fastest = this.filter('fastest'),
var formatNumber = Benchmark.formatNumber,
fastest = this.filter('fastest'),
slowest = this.filter('slowest'),
lodashHz = 1 / (this[0].stats.mean + this[0].stats.moe),
underscoreHz = 1 / (this[1].stats.mean + this[1].stats.moe);
if (fastest.length > 1) {
console.log('It\'s too close to call.');
log('It\'s too close to call.');
lodashHz = underscoreHz = Math.min(lodashHz, underscoreHz);
}
else {
var fastestHz = fastest[0] == this[0] ? lodashHz : underscoreHz,
slowestHz = slowest[0] == this[0] ? lodashHz : underscoreHz,
percent = Math.round(((fastestHz / slowestHz) - 1) * 100);
percent = formatNumber(Math.round(((fastestHz / slowestHz) - 1) * 100));
console.log(fastest[0].name + ' is ' + percent + '% faster.');
log(fastest[0].name + ' is ' + percent + '% faster.');
}
// add score adjusted for margin of error
score.lodash += lodashHz;
@@ -119,15 +167,15 @@
else {
var fastestTotalHz = Math.max(score.lodash, score.underscore),
slowestTotalHz = Math.min(score.lodash, score.underscore),
totalPercent = Math.round(((fastestTotalHz / slowestTotalHz) - 1) * 100),
totalX = (fastestTotalHz / slowestTotalHz).toFixed(2),
message = ' is ' + totalPercent + '% (' + totalX + 'x) faster than ';
totalPercent = formatNumber(Math.round(((fastestTotalHz / slowestTotalHz) - 1) * 100)),
totalX = fastestTotalHz / slowestTotalHz,
message = ' is ' + totalPercent + '% ' + (totalX == 1 ? '' : '(' + formatNumber(totalX.toFixed(2)) + 'x) ') + 'faster than ';
// report results
if (score.lodash >= score.underscore) {
console.log('\nLo-Dash' + message + 'Underscore.');
log('\nLo-Dash' + message + 'Underscore.');
} else {
console.log('\nUnderscore' + message + 'Lo-Dash.');
log('\nUnderscore' + message + 'Lo-Dash.');
}
}
}
@@ -146,7 +194,7 @@
);
suites.push(
Benchmark.Suite('bound normal')
Benchmark.Suite('bound')
.add('Lo-Dash', function() {
lodashBoundNormal();
})
@@ -180,31 +228,43 @@
suites.push(
Benchmark.Suite('each array')
.add('Lo-Dash', function() {
var timesTwo = [];
lodash.each(numbers, function(num) {
timesTwo.push(num * 2);
});
var result = [];
lodash.each(numbers, function(num) { result.push(num * 2); });
})
.add('Underscore', function() {
var timesTwo = [];
_.each(numbers, function(num) {
timesTwo.push(num * 2);
});
var result = [];
_.each(numbers, function(num) { result.push(num * 2); });
})
);
suites.push(
Benchmark.Suite('each array thisArg')
.add('Lo-Dash', function() {
var result = [];
lodash.each(numbers, function(num, index) {
result.push(num + this['key' + index]);
}, object);
})
.add('Underscore', function() {
var result = [];
_.each(numbers, function(num, index) {
result.push(num + this['key' + index]);
}, object);
})
);
suites.push(
Benchmark.Suite('each object')
.add('Lo-Dash', function() {
var timesTwo = [];
var result = [];
lodash.each(object, function(num) {
timesTwo.push(num * 2);
result.push(num * 2);
});
})
.add('Underscore', function() {
var timesTwo = [];
var result = [];
_.each(object, function(num) {
timesTwo.push(num * 2);
result.push(num * 2);
});
})
);
@@ -264,10 +324,10 @@
suites.push(
Benchmark.Suite('groupBy callback')
.add('Lo-Dash', function() {
lodash.groupBy(numbers, function(num) { return Math.floor(num); });
lodash.groupBy(numbers, function(num) { return num >> 1; });
})
.add('Underscore', function() {
_.groupBy(numbers, function(num) { return Math.floor(num); });
_.groupBy(numbers, function(num) { return num >> 1; });
})
);
@@ -283,6 +343,28 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('indexOf')
.add('Lo-Dash', function() {
lodash.indexOf(numbers, 9);
})
.add('Underscore', function() {
_.indexOf(numbers, 9);
})
);
suites.push(
Benchmark.Suite('indexOf isSorted')
.add('Lo-Dash', function() {
lodash.indexOf(numbers, 19, true);
})
.add('Underscore', function() {
_.indexOf(numbers, 19, true);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('intersection')
.add('Lo-Dash', function() {
@@ -307,20 +389,46 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('lastIndexOf')
.add('Lo-Dash', function() {
lodash.lastIndexOf(numbers, 9);
})
.add('Underscore', function() {
_.lastIndexOf(numbers, 9);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('map')
.add('Lo-Dash', function() {
lodash.map(objects, function(obj) {
return obj.num;
lodash.map(objects, function(value) {
return value.num;
});
})
.add('Underscore', function() {
_.map(objects, function(obj) {
return obj.num;
_.map(objects, function(value) {
return value.num;
});
})
);
suites.push(
Benchmark.Suite('map thisArg')
.add('Lo-Dash', function() {
lodash.map(objects, function(value, index) {
return this['key' + index] + value.num;
}, object);
})
.add('Underscore', function() {
_.map(objects, function(value, index) {
return this['key' + index] + value.num;
}, object);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
@@ -371,6 +479,90 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('sortBy callback')
.add('Lo-Dash', function() {
lodash.sortBy(numbers, function(num) { return Math.sin(num); });
})
.add('Underscore', function() {
_.sortBy(numbers, function(num) { return Math.sin(num); });
})
);
suites.push(
Benchmark.Suite('sortBy callback thisArg')
.add('Lo-Dash', function() {
lodash.sortBy(numbers, function(num) { return this.sin(num); }, Math);
})
.add('Underscore', function() {
_.sortBy(numbers, function(num) { return this.sin(num); }, Math);
})
);
suites.push(
Benchmark.Suite('sortBy property name')
.add('Lo-Dash', function() {
lodash.sortBy(words, 'length');
})
.add('Underscore', function() {
_.sortBy(words, 'length');
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('sortedIndex')
.add('Lo-Dash', function() {
lodash.sortedIndex(numbers, 25);
})
.add('Underscore', function() {
_.sortedIndex(numbers, 25);
})
);
suites.push(
Benchmark.Suite('sortedIndex callback')
.add('Lo-Dash', function() {
lodash.sortedIndex(words, 'twenty-five', function(value) {
return wordToNumber[value];
});
})
.add('Underscore', function() {
_.sortedIndex(words, 'twenty-five', function(value) {
return wordToNumber[value];
});
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('times')
.add('Lo-Dash', function() {
var result = [];
lodash.times(length, function(n) { result.push(n); });
})
.add('Underscore', function() {
var result = [];
_.times(length, function(n) { result.push(n); });
})
);
suites.push(
Benchmark.Suite('times thisArg')
.add('Lo-Dash', function() {
var result = [];
lodash.times(length, function(n) { result.push(this.sin(n)); }, Math);
})
.add('Underscore', function() {
var result = [];
_.times(length, function(n) { result.push(this.sin(n)); }, Math);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('union')
.add('Lo-Dash', function() {
@@ -383,6 +575,32 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('uniq')
.add('Lo-Dash', function() {
lodash.uniq(numbers.concat(fourNumbers, twoNumbers));
})
.add('Underscore', function() {
_.uniq(numbers.concat(fourNumbers, twoNumbers));
})
);
suites.push(
Benchmark.Suite('uniq callback')
.add('Lo-Dash', function() {
lodash.uniq(numbers.concat(fourNumbers, twoNumbers), function(num) {
return num % 2;
});
})
.add('Underscore', function() {
_.uniq(numbers.concat(fourNumbers, twoNumbers), function(num) {
return num % 2;
});
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('values')
.add('Lo-Dash', function() {
@@ -396,9 +614,10 @@
/*--------------------------------------------------------------------------*/
if (Benchmark.platform + '') {
console.log(Benchmark.platform + '');
log(Benchmark.platform + '');
}
// start suites
log('\nSit back and relax, this may take a while.');
suites[0].run();
}(typeof global == 'object' && global || this));

View File

@@ -37,6 +37,17 @@
'valueOf': 7
};
/** Used to check problem JScript properties too */
var shadowedKeys = [
'constructor',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'toLocaleString',
'toString',
'valueOf'
];
/*--------------------------------------------------------------------------*/
/**
@@ -142,6 +153,10 @@
test('should not escape the ">" character', function() {
equal(_.escape('>'), '>');
});
test('should not escape the "/" character', function() {
equal(_.escape('/'), '/');
});
}());
/*--------------------------------------------------------------------------*/
@@ -177,14 +192,14 @@
QUnit.module('lodash.find');
(function() {
var array = [1, 2, 3, 4];
var array = [1, 2, 3];
test('should return found `value`', function() {
equal(_.find(array, function(n) { return n > 2; }), 3);
});
test('should return `undefined` if `value` is not found', function() {
equal(_.find(array, function(n) { return n == 5; }), undefined);
equal(_.find(array, function(n) { return n == 4; }), undefined);
});
}());
@@ -215,22 +230,79 @@
(function() {
test('returns the collection', function() {
var collection = [1, 2, 3, 4];
var collection = [1, 2, 3];
equal(_.forEach(collection, Boolean), collection);
});
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
var object = {};
_.forEach(shadowed, function(value, key) {
object[key] = value;
});
test('should treat array-like object with invalid `length` as a regular object', function() {
var keys = [],
object = { 'length': -1 };
deepEqual(object, shadowed);
_.forEach(object, function(value, key) { keys.push(key); });
deepEqual(keys, ['length']);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.forIn');
(function() {
test('iterates over inherited properties', function() {
function Dog(name) { this.name = name; }
Dog.prototype.bark = function() { /* Woof, woof! */ };
var keys = [];
_.forIn(new Dog('Dagny'), function(value, key) { keys.push(key); });
deepEqual(keys.sort(), ['bark', 'name']);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.forOwn');
(function() {
test('iterates over the `length` property', function() {
var keys = [],
object = { '0': 'zero', '1': 'one', 'length': 2 };
_.forOwn(object, function(value, key) { keys.push(key); });
deepEqual(keys.sort(), ['0', '1', 'length']);
});
}());
/*--------------------------------------------------------------------------*/
_.each(['forEach', 'forIn', 'forOwn'], function(methodName) {
var func = _[methodName];
QUnit.module('lodash.' + methodName + ' iteration bugs');
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
var keys = [];
func(shadowed, function(value, key) { keys.push(key); });
deepEqual(keys.sort(), shadowedKeys);
});
test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
function Foo() {}
Foo.prototype.a = 1;
var keys = [];
function callback(value, key) { keys.push(key); }
func(Foo, callback);
deepEqual(keys, []);
keys.length = 0;
Foo.prototype = { 'a': 1 };
func(Foo, callback);
deepEqual(keys, []);
});
});
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.groupBy');
(function() {
@@ -254,11 +326,47 @@
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.indexOf');
(function() {
var array = [1, 2, 3, 1, 2, 3];
test('should work with a positive `fromIndex`', function() {
equal(_.indexOf(array, 1, 2), 3);
});
test('should work with `fromIndex` >= `array.length`', function() {
equal(_.indexOf(array, 1, 6), -1);
equal(_.indexOf(array, undefined, 6), -1);
equal(_.indexOf(array, 1, 8), -1);
equal(_.indexOf(array, undefined, 8), -1);
});
test('should work with a negative `fromIndex`', function() {
equal(_.indexOf(array, 2, -3), 4);
});
test('should work with a negative `fromIndex` <= `-array.length`', function() {
equal(_.indexOf(array, 1, -6), 0);
equal(_.indexOf(array, 2, -8), 1);
});
test('should ignore non-number `fromIndex` values', function() {
equal(_.indexOf([1, 2, 3], 1, '1'), 0);
});
test('should work with `isSorted`', function() {
equal(_.indexOf([1, 2, 3], 1, true), 0);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.initial');
(function() {
test('returns an empty collection for `n` of `0`', function() {
var array = [1, 2, 3, 4];
var array = [1, 2, 3];
deepEqual(_.initial(array, 0), []);
});
}());
@@ -271,6 +379,15 @@
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
equal(_.isEmpty(shadowed), false);
});
test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
function Foo() {}
Foo.prototype.a = 1;
equal(_.isEmpty(Foo), true);
Foo.prototype = { 'a': 1 };
equal(_.isEmpty(Foo), true);
});
}());
/*--------------------------------------------------------------------------*/
@@ -303,8 +420,54 @@
Foo.prototype.a = 1;
deepEqual(_.keys(Foo.prototype), ['a']);
deepEqual(_.keys(shadowed).sort(),
'constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf'.split(' '));
deepEqual(_.keys(shadowed).sort(), shadowedKeys);
});
test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
function Foo() {}
Foo.prototype.c = 3;
Foo.a = 1;
Foo.b = 2;
var expected = ['a', 'b'];
deepEqual(_.keys(Foo), expected);
Foo.prototype = { 'c': 3 };
deepEqual(_.keys(Foo), expected);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.lastIndexOf');
(function() {
var array = [1, 2, 3, 1, 2, 3];
test('should work with a positive `fromIndex`', function() {
equal(_.lastIndexOf(array, 1, 2), 0);
});
test('should work with `fromIndex` >= `array.length`', function() {
equal(_.lastIndexOf(array, undefined, 6), -1);
equal(_.lastIndexOf(array, 1, 6), 3);
equal(_.lastIndexOf(array, undefined, 8), -1);
equal(_.lastIndexOf(array, 1, 8), 3);
});
test('should work with a negative `fromIndex`', function() {
equal(_.lastIndexOf(array, 2, -3), 1);
});
test('should work with a negative `fromIndex` <= `-array.length`', function() {
equal(_.lastIndexOf(array, 1, -6), 0);
equal(_.lastIndexOf(array, 2, -8), -1);
});
test('should ignore non-number `fromIndex` values', function() {
equal(_.lastIndexOf([1, 2, 3], 3, '1'), 2);
equal(_.lastIndexOf([1, 2, 3], 3, true), 2);
});
}());
@@ -366,6 +529,17 @@
deepEqual(args, ['C', 'B', 'b', object]);
});
test('should treat array-like object with invalid `length` as a regular object', function() {
var args,
object = { 'a': 'A', 'length': -1 };
_.reduceRight(object, function() {
args || (args = slice.call(arguments));
});
deepEqual(args, [-1, 'A', 'a', object]);
});
}());
/*--------------------------------------------------------------------------*/
@@ -388,11 +562,36 @@
(function() {
test('supports the `thisArg` argument', function() {
var actual = _.sortBy([1, 2, 3, 4], function(num) {
var actual = _.sortBy([1, 2, 3], function(num) {
return this.sin(num);
}, Math);
deepEqual(actual, [4, 3, 1, 2]);
deepEqual(actual, [3, 1, 2]);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.sortedIndex');
(function() {
test('supports the `thisArg` argument', function() {
var actual = _.sortedIndex([1, 2, 3], 4, function(num) {
return this.sin(num);
}, Math);
equal(actual, 0);
});
test('supports arrays with lengths larger than `Math.pow(2, 31) - 1`', function() {
var length = Math.pow(2, 32) - 1,
index = length - 1,
array = Array(length),
steps = 0;
array[index] = index;
_.sortedIndex(array, index, function() { steps++; });
equal(steps, 33);
});
}());
@@ -453,15 +652,34 @@
deepEqual(_.toArray(array), [3, 2, 1]);
});
test('should treat array-like-objects like arrays', function() {
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']);
deepEqual(_.toArray(args), [1, 2, 3]);
});
test('should treat array-like object with invalid `length` as a regular object', function() {
var object = { 'length': -1 };
deepEqual(_.toArray(object), [-1]);
});
}(1, 2, 3));
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.uniq');
(function() {
test('supports the `thisArg` argument', function() {
var actual = _.uniq([1, 2, 1.5, 3, 2.5], function(num) {
return this.floor(num);
}, Math);
deepEqual(actual, [1, 2, 3]);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash(...).shift');
(function() {