mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-30 06:57:49 +00:00
Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15b14e12e2 | ||
|
|
b328972c4d | ||
|
|
da3156047f | ||
|
|
f9f08ba54f | ||
|
|
b43684262f | ||
|
|
2120f78bd7 | ||
|
|
2d896f22d6 | ||
|
|
9fa0aebfe9 | ||
|
|
2ddc3af5ff | ||
|
|
fd80e096ea | ||
|
|
fab2d69fce | ||
|
|
83d08e3aba | ||
|
|
bfea6bcacf | ||
|
|
feff34b021 | ||
|
|
79fbade92a | ||
|
|
bf508e453e | ||
|
|
47b51c22fa | ||
|
|
ebd16105f2 | ||
|
|
01fb1a5775 | ||
|
|
b8c2a05db9 | ||
|
|
4087dc5fe4 | ||
|
|
408029e6e0 | ||
|
|
23ff403529 | ||
|
|
be4f81f584 | ||
|
|
361c91e610 | ||
|
|
2aa2ea9675 | ||
|
|
e084225edf | ||
|
|
9ce342205b | ||
|
|
0edf50e00e | ||
|
|
1ea19daad9 | ||
|
|
32b302314e | ||
|
|
ee197e02a2 | ||
|
|
7cd6ffec2a | ||
|
|
0077580838 | ||
|
|
4d85a79fd1 | ||
|
|
a35139bb61 | ||
|
|
f72b833724 | ||
|
|
0e16bac6e2 | ||
|
|
e17564b362 | ||
|
|
90b66eddf5 | ||
|
|
2862a5849f | ||
|
|
7e839231ed | ||
|
|
fa56a4bb73 | ||
|
|
dff950748c | ||
|
|
b7374e3f8e | ||
|
|
4244b92b08 | ||
|
|
4f688028ad | ||
|
|
5a9a18501d | ||
|
|
896b8f7cf1 | ||
|
|
95bd1b014f | ||
|
|
dbdf8642bb | ||
|
|
c3cd9007d2 | ||
|
|
8079fb5bc5 | ||
|
|
80d0b5d4ed | ||
|
|
86bd847bf9 | ||
|
|
943004844a | ||
|
|
4ff12e0426 | ||
|
|
0d7bdb6fa8 | ||
|
|
6d488b6a81 | ||
|
|
f1d0263ffa | ||
|
|
24035caadb | ||
|
|
ed89a3e0f8 | ||
|
|
7088ab89f1 | ||
|
|
d4688bd76b | ||
|
|
befe0fccaf | ||
|
|
a192410498 | ||
|
|
d43ede3a11 | ||
|
|
9848ffb77f | ||
|
|
7487497d1f | ||
|
|
be11c848f4 | ||
|
|
9836b274b9 | ||
|
|
a96d14566f | ||
|
|
1c8cd8c168 | ||
|
|
5f5806a98e | ||
|
|
624b045ac0 | ||
|
|
0f8bae950e | ||
|
|
fcede42903 |
7
.jamignore
Normal file
7
.jamignore
Normal file
@@ -0,0 +1,7 @@
|
||||
*.custom.*
|
||||
.*
|
||||
dist/
|
||||
doc/*.php
|
||||
node_modules/
|
||||
perf/*.sh
|
||||
test/*.sh
|
||||
@@ -1,5 +1,4 @@
|
||||
*.custom.*
|
||||
*.min.*
|
||||
.*
|
||||
dist/
|
||||
doc/*.php
|
||||
@@ -11,7 +10,7 @@ test/*-ui.js
|
||||
test/*.sh
|
||||
vendor/backbone/
|
||||
vendor/docdown/
|
||||
vendor/qunit/qunit/*.css
|
||||
vendor/underscore/
|
||||
vendor/requirejs/
|
||||
vendor/firebug-lite/
|
||||
vendor/qunit/qunit/*.css
|
||||
vendor/requirejs/
|
||||
vendor/underscore/test/
|
||||
|
||||
197
README.md
197
README.md
@@ -1,14 +1,14 @@
|
||||
# Lo-Dash <sup>v0.4.2</sup>
|
||||
# Lo-Dash <sup>v0.5.0</sup>
|
||||
|
||||
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), 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).
|
||||
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-20), and [additional features](https://github.com/bestiejs/lodash#features).
|
||||
|
||||
Lo-Dash’s 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.4.2/lodash.js)
|
||||
* [Production source](https://raw.github.com/bestiejs/lodash/v0.4.2/lodash.min.js)
|
||||
* CDN copies of ≤ [v0.4.1](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.4.1/lodash.min.js) are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/)
|
||||
* [Development source](https://raw.github.com/bestiejs/lodash/v0.5.0/lodash.js)
|
||||
* [Production source](https://raw.github.com/bestiejs/lodash/v0.5.0/lodash.min.js)
|
||||
* CDN copies of ≤ [v0.4.2](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.4.2/lodash.min.js) are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/)
|
||||
* For optimal performance, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
|
||||
|
||||
## Dive in
|
||||
@@ -24,27 +24,34 @@ For a list of upcoming features, check out our [roadmap](https://github.com/best
|
||||
For more information check out these screencasts over Lo-Dash:
|
||||
|
||||
* [Introducing Lo-Dash](https://vimeo.com/44154599)
|
||||
* [Optimizations and custom builds](https://vimeo.com/44154601)
|
||||
* [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601)
|
||||
* [Lo-Dash’s origin and why it’s a better utility belt](https://vimeo.com/44154600)
|
||||
* [Unit testing in Lo-Dash](https://vimeo.com/45865290)
|
||||
|
||||
## Features
|
||||
|
||||
* AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
|
||||
* [_.bind](http://lodash.com/docs#bind) supports *"lazy"* binding
|
||||
* [_.clone](http://lodash.com/docs#clone) supports *"deep"* cloning
|
||||
* [_.countBy](http://lodash.com/docs#countBy) as a compainion function for [_.groupBy](http://lodash.com/docs#groupBy) and [_.sortBy](http://lodash.com/docs#sortBy)
|
||||
* [_.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
|
||||
* [_.drop](http://lodash.com/docs#drop) for the inverse functionality of [_.pick](http://lodash.com/docs#pick)
|
||||
* [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early
|
||||
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an object’s own and inherited properties
|
||||
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an object’s 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
|
||||
* [_.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
|
||||
* [_.template](http://lodash.com/docs#template) utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
|
||||
* [_.where](http://lodash.com/docs#where) for filtering collections by contained properties
|
||||
* [_.zipObject](http://lodash.com/docs#zipObject) for composing objects
|
||||
* [_.contains](http://lodash.com/docs#contains), [_.size](http://lodash.com/docs#size), [_.toArray](http://lodash.com/docs#toArray),
|
||||
[and more…](http://lodash.com/docs "_.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.pluck, _.reduce, _.reduceRight, _.reject, _.some, _sortBy") accept strings
|
||||
|
||||
## Support
|
||||
|
||||
Lo-Dash has been tested in at least Chrome 5-20, Firefox 1.5-13, IE 6-9, Opera 9.25-12, Safari 3.0.4-5.1.7, Node.js 0.4.8-0.8.2, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC3.
|
||||
Lo-Dash has been tested in at least Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.4.8-0.8.7, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
||||
|
||||
## Custom builds
|
||||
|
||||
@@ -52,52 +59,62 @@ Custom builds make it easy to create lightweight versions of Lo-Dash containing
|
||||
We handle all the method dependency and alias mapping for you.
|
||||
|
||||
* Backbone builds, containing all methods required by Backbone, may be created using the `backbone` modifier argument.
|
||||
~~~ bash
|
||||
```bash
|
||||
lodash backbone
|
||||
~~~
|
||||
```
|
||||
|
||||
* CSP builds, supporting default Content Security Policy restrictions, may be created using the `csp` modifier argument.
|
||||
```bash
|
||||
lodash csp
|
||||
```
|
||||
|
||||
* Legacy builds, tailored for older browsers without [ES5 support](http://es5.github.com/), may be created using the `legacy` modifier argument.
|
||||
~~~ bash
|
||||
```bash
|
||||
lodash legacy
|
||||
~~~
|
||||
```
|
||||
|
||||
* Mobile builds, with IE < 9 bug fixes and method compilation removed, may be created using the `mobile` modifier argument.
|
||||
~~~ bash
|
||||
```bash
|
||||
lodash mobile
|
||||
~~~
|
||||
```
|
||||
|
||||
* Strict builds, with `_.bindAll`, `_.extend`, and `_.defaults` in [strict mode](http://es5.github.com/#C), may be created using the `strict` modifier argument.
|
||||
~~~ bash
|
||||
* Strict builds, with `_.bindAll`, `_.defaults`, and `_.extend` in [strict mode](http://es5.github.com/#C), may be created using the `strict` modifier argument.
|
||||
```bash
|
||||
lodash strict
|
||||
~~~
|
||||
```
|
||||
|
||||
* Underscore builds, containing only methods included in Underscore, may be created using the `underscore` modifier argument.
|
||||
```bash
|
||||
lodash underscore
|
||||
```
|
||||
|
||||
Custom builds may be created in three ways:
|
||||
|
||||
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
|
||||
```bash
|
||||
lodash category=collections,functions
|
||||
lodash category="collections, functions"
|
||||
~~~
|
||||
```
|
||||
|
||||
2. Use the `exclude` argument to pass the names of methods to exclude from the build.
|
||||
~~~ bash
|
||||
```bash
|
||||
lodash exclude=union,uniq,zip
|
||||
lodash exclude="union, uniq, zip"
|
||||
~~~
|
||||
```
|
||||
|
||||
3. Use the `include` argument to pass the names of methods to include in the build.
|
||||
~~~ bash
|
||||
```bash
|
||||
lodash include=each,filter,map
|
||||
lodash include="each, filter, map"
|
||||
~~~
|
||||
```
|
||||
|
||||
All arguments, except `exclude` with `include` and `legacy` with `mobile`, may be combined.
|
||||
All arguments, except `backbone` with `underscore`, `exclude` with `include`, and `legacy` with `csp`/`mobile`, may be combined.
|
||||
|
||||
~~~ bash
|
||||
```bash
|
||||
lodash backbone legacy category=utilities exclude=first,last
|
||||
lodash backbone mobile strict category=functions include=pick,uniq
|
||||
~~~
|
||||
lodash underscore mobile strict category=functions include=pick,uniq
|
||||
```
|
||||
|
||||
The `lodash` command-line utility is available when Lo-Dash is installed as a global package (i.e. `npm install -g lodash`).
|
||||
|
||||
@@ -107,38 +124,38 @@ Custom builds are saved to `lodash.custom.js` and `lodash.custom.min.js`.
|
||||
|
||||
In browsers:
|
||||
|
||||
~~~ html
|
||||
```html
|
||||
<script src="lodash.js"></script>
|
||||
~~~
|
||||
```
|
||||
|
||||
Using [npm](http://npmjs.org/):
|
||||
|
||||
~~~ bash
|
||||
```bash
|
||||
npm install lodash
|
||||
npm install -g lodash
|
||||
~~~
|
||||
```
|
||||
|
||||
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
var _ = require('lodash');
|
||||
~~~
|
||||
```
|
||||
|
||||
In [Narwhal](http://narwhaljs.org/) and [RingoJS v0.7.0-](http://ringojs.org/):
|
||||
In [RingoJS v0.7.0-](http://ringojs.org/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
var _ = require('lodash')._;
|
||||
~~~
|
||||
```
|
||||
|
||||
In [Rhino](http://www.mozilla.org/rhino/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
load('lodash.js');
|
||||
~~~
|
||||
```
|
||||
|
||||
In an AMD loader like [RequireJS](http://requirejs.org/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
require({
|
||||
'paths': {
|
||||
'underscore': 'path/to/lodash'
|
||||
@@ -147,33 +164,41 @@ require({
|
||||
['underscore'], function(_) {
|
||||
console.log(_.VERSION);
|
||||
});
|
||||
~~~
|
||||
```
|
||||
|
||||
## Closed Underscore.js issues <sup>(20+)</sup>
|
||||
## Resolved Underscore.js issues <sup>(20+)</sup>
|
||||
|
||||
* 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), [#659](https://github.com/documentcloud/underscore/issues/659), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L364-370)]
|
||||
* Ensure array-like objects with invalid `length` properties are treated like regular objects [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L315-321), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L665-679), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L921-924)]
|
||||
* Ensure *"Arrays"* methods allow falsey `array` arguments [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L989-1027)]
|
||||
* Ensure *"Collections"* methods allow string `collection` arguments [[#247](https://github.com/documentcloud/underscore/issues/247), [#276](https://github.com/documentcloud/underscore/issues/276), [#561](https://github.com/documentcloud/underscore/pull/561), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L148-157), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L323-341), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L681-698), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L926-929)]
|
||||
* Ensure templates compiled with errors are inspectable [[#666](https://github.com/documentcloud/underscore/issues/666), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L795-802)]
|
||||
* Fix cross-browser object iteration bugs [[#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L224-236), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L375-400), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L496-507), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L515-517), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L535-555), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L725-727)]
|
||||
* 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), [#659](https://github.com/documentcloud/underscore/issues/659), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L544-550)]
|
||||
* Ensure array-like objects with invalid `length` properties are treated like regular objects [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L491-501)]
|
||||
* Ensure *"Arrays"* methods allow falsey `array` arguments [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1487-1525)]
|
||||
* Ensure *"Collections"* methods allow string `collection` arguments [[#247](https://github.com/documentcloud/underscore/issues/247), [#276](https://github.com/documentcloud/underscore/issues/276), [#561](https://github.com/documentcloud/underscore/pull/561), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L503-521)]
|
||||
* Ensure templates compiled with errors are inspectable [[#666](https://github.com/documentcloud/underscore/issues/666), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1232-1235)]
|
||||
* 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.5.0/test/test.js#L555-580)]
|
||||
* 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/v0.4.2/test/test.js#L96-102)]
|
||||
* Register as an AMD module, but still export to global [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L80-94)]
|
||||
* `_(…)` should return passed wrapper instances [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L114-117)]
|
||||
* `_.contains` should work with strings [[#667](https://github.com/documentcloud/underscore/pull/667), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L148-157)]
|
||||
* `_.escape` should return an empty string when passed `null` or `undefined` [[#407](https://github.com/documentcloud/underscore/issues/427), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L205-208)]
|
||||
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L310-313)]
|
||||
* `_.groupBy` should add values to own, not inherited, properties [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L415-422)]
|
||||
* `_isNaN(new Number(NaN))` should return `true` [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L525-527)]
|
||||
* `_.reduceRight` should pass correct callback arguments when iterating objects [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L649-663)]
|
||||
* `_.size` should return the `length` of string values [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L708-710)]
|
||||
* `_.size` shouldn't error on falsey values [[#650](https://github.com/documentcloud/underscore/pull/650), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L712-719)]
|
||||
* `_.size` should work with `arguments` objects cross-browser [[#653](https://github.com/documentcloud/underscore/issues/653), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L721-723)]
|
||||
* `_.sortedIndex` should support arrays with high `length` values [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L765-774)]
|
||||
* `_.template` should not augment the `options` object [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L789-793)]
|
||||
* `_.throttle` should work when called in a loop [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L872-882)]
|
||||
* `_.zipObject` should accept less than two arguments [[test](https://github.com/bestiejs/lodash/blob/v0.4.2/test/test.js#L951-953)]
|
||||
* 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/v0.5.0/test/test.js#L117-123)]
|
||||
* Register as an AMD module, but still export to global [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L101-115)]
|
||||
* `_(…)` should return passed wrapper instances [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L135-138)]
|
||||
* `_.clone` should allow `deep` cloning [[#595](https://github.com/documentcloud/underscore/pull/595), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L197-212)]
|
||||
* `_.contains` should work with strings [[#667](https://github.com/documentcloud/underscore/pull/667), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L267-276)]
|
||||
* `_.escape` should return an empty string when passed `null` or `undefined` [[#427](https://github.com/documentcloud/underscore/issues/427), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L367-370)]
|
||||
* `_.extend` should recursively extend objects [[#379](https://github.com/documentcloud/underscore/pull/379), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L882-955)]
|
||||
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L486-489)]
|
||||
* `_.forEach` should allow exiting iteration early [[#211](https://github.com/documentcloud/underscore/issues/211), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L582-601)]
|
||||
* `_.groupBy` should add values to own, not inherited, properties [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L616-623)]
|
||||
* `_.isEmpty` and `_.size` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L716-721)]
|
||||
* `_.isEqual` should return `true` for like-objects from different documents [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L757-777)]
|
||||
* `_.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.5.0/test/test.js#L785-797)]
|
||||
* `_.isNaN(new Number(NaN))` should return `true` [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L805-807)]
|
||||
* `_.keys` and `_.size` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [#653](https://github.com/documentcloud/underscore/issues/653), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L817-819)]
|
||||
* `_.once` should free the given function for garbage collection [[#693](https://github.com/documentcloud/underscore/pull/693)]
|
||||
* `_.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.5.0/test/test.js#L1042-1045)]
|
||||
* `_.reduceRight` should pass correct callback arguments when iterating objects [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1053-1067)]
|
||||
* `_.size` should return the `length` of string values [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1112-1114)]
|
||||
* `_.size` shouldn’t error on falsey values [[#650](https://github.com/documentcloud/underscore/pull/650), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1116-1123)]
|
||||
* `_.sortedIndex` should support arrays with high `length` values [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1202-1211)]
|
||||
* `_.template` should not augment the `options` object [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1226-1230)]
|
||||
* `_.throttle` should work when called in a loop [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1322-1332)]
|
||||
* `_.zipObject` should accept less than two arguments [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1449-1451)]
|
||||
|
||||
## Optimized methods <sup>(50+)</sup>
|
||||
|
||||
@@ -201,7 +226,6 @@ require({
|
||||
* `_.isArguments`
|
||||
* `_.isDate`
|
||||
* `_.isEmpty`
|
||||
* `_.isEqual`
|
||||
* `_.isFinite`
|
||||
* `_.isFunction`
|
||||
* `_.isObject`
|
||||
@@ -238,33 +262,24 @@ require({
|
||||
|
||||
## Release Notes
|
||||
|
||||
### <sup>v0.4.2</sup>
|
||||
### <sup>v0.5.0</sup>
|
||||
|
||||
* Added `strict` build
|
||||
* Ensured `_.bindAll`, `_.extend`, and `_.defaults` avoid strict mode errors when attempting to augment read-only properties
|
||||
* Optimized the iteration of large arrays in `_.difference`, `_.intersection`, and `_.without`
|
||||
* Fixed build bugs related to removing variables
|
||||
|
||||
### <sup>v0.4.1</sup>
|
||||
|
||||
* Fixed `_.template` regression
|
||||
* Optimized build process to detect and remove more unused variables
|
||||
|
||||
### <sup>v0.4.0</sup>
|
||||
|
||||
* Added `bin` and `scripts` entries to package.json
|
||||
* Added `legacy` build option
|
||||
* Added cross-browser support for passing strings to *"Collections"* methods
|
||||
* Added `_.zipObject`
|
||||
* Leveraged `_.indexOf`'s `fromIndex` in `_.difference` and `_.without`
|
||||
* Optimized compiled templates
|
||||
* Optimized inlining the `iteratorTemplate` for builds
|
||||
* Optimized object iteration for *"Collections"* methods
|
||||
* Optimized partially applied `_.bind` in V8
|
||||
* Made compiled templates more debuggable
|
||||
* Made `_.size` work with falsey values and consistent cross-browser with `arguments` objects
|
||||
* Moved `_.groupBy` and `_.sortBy` back to the *"Collections"* category
|
||||
* Removed `arguments` object from `_.range`
|
||||
* Added [_.countBy](http://lodash.com/docs#countBy), [_.drop](http://lodash.com/docs#drop), [_.merge](http://lodash.com/docs#merge), and [_.where](http://lodash.com/docs#where)
|
||||
* Added `csp` *(Content Security Policy)* and `underscore` build options
|
||||
* Added `deep` cloning support to `_.clone`
|
||||
* Added [Jam](http://jamjs.org/) package support
|
||||
* Added support for exiting `_.forEach`, `_.forIn`, and `_.forOwn` early by returning `false` in the `callback`
|
||||
* Added support for jQuery/MooTools DOM query collections to `_.isEmpty` and `_.size`
|
||||
* Ensured development build works with IE conditional compilation enabled
|
||||
* Ensured `_.clone` doesn't clone functions, DOM nodes, `arguments` objects, and objects created by constructors other than `Object`
|
||||
* Ensured `_.filter`’s `callback` can't modify result values
|
||||
* Ensured `_.isEmpty`, `_.isEquals`, and `_.size` support `arguments` objects
|
||||
* Ensured `_.isEqual` doesn't inspect DOM nodes, works with objects from other documents, and calls custom `isEqual` methods before checking strict equality
|
||||
* Ensured `_.once` frees the given function for garbage collection
|
||||
* Ensured `_.sortBy` performs a stable sort
|
||||
* Ensured `reEvaluateDelimiter` is assigned when `_.templateSettings.evaluate` is undefined
|
||||
* Made `_.range` coerce arguments to numbers
|
||||
* Optimized `_.isFunction`
|
||||
|
||||
The full changelog is available [here](https://github.com/bestiejs/lodash/wiki/Changelog).
|
||||
|
||||
|
||||
275
build.js
275
build.js
@@ -11,14 +11,17 @@
|
||||
/** The current working directory */
|
||||
var cwd = process.cwd();
|
||||
|
||||
/** Flag used to specify a backbone build */
|
||||
/** Flag used to specify a Backbone build */
|
||||
var isBackbone = process.argv.indexOf('backbone') > -1;
|
||||
|
||||
/** Flag used to specify a Content Security Policy build */
|
||||
var isCSP = process.argv.indexOf('csp') > -1 || process.argv.indexOf('CSP') > -1;
|
||||
|
||||
/** Flag used to specify a legacy build */
|
||||
var isLegacy = process.argv.indexOf('legacy') > -1;
|
||||
|
||||
/** Flag used to specify a mobile build */
|
||||
var isMobile = !isLegacy && process.argv.indexOf('mobile') > -1;
|
||||
var isMobile = !isLegacy && (isCSP || process.argv.indexOf('mobile') > -1);
|
||||
|
||||
/**
|
||||
* Flag used to specify `_.bindAll`, `_.extend`, and `_.defaults` are
|
||||
@@ -26,6 +29,9 @@
|
||||
*/
|
||||
var isStrict = process.argv.indexOf('strict') > -1;
|
||||
|
||||
/** Flag used to specify an Underscore build */
|
||||
var isUnderscore = process.argv.indexOf('underscore') > -1;
|
||||
|
||||
/** Flag used to specify if the build should include the "use strict" directive */
|
||||
var useStrict = isStrict || !(isLegacy || isMobile);
|
||||
|
||||
@@ -48,6 +54,7 @@
|
||||
}
|
||||
|
||||
if (isLegacy) {
|
||||
source = replaceVar(source, 'noArgsClass', 'true');
|
||||
['isBindFast', 'isKeysFast', 'nativeBind', 'nativeIsArray', 'nativeKeys'].forEach(function(varName) {
|
||||
source = replaceVar(source, varName, 'false');
|
||||
});
|
||||
@@ -146,15 +153,17 @@
|
||||
'bind': [],
|
||||
'bindAll': ['bind', 'functions'],
|
||||
'chain': ['mixin'],
|
||||
'clone': ['extend', 'isArray'],
|
||||
'clone': ['extend', 'forIn', 'forOwn', 'isArguments'],
|
||||
'compact': [],
|
||||
'compose': [],
|
||||
'contains': [],
|
||||
'countBy': [],
|
||||
'debounce': [],
|
||||
'defaults': [],
|
||||
'defer': [],
|
||||
'delay': [],
|
||||
'difference': ['indexOf'],
|
||||
'drop': ['indexOf'],
|
||||
'escape': [],
|
||||
'every': ['identity'],
|
||||
'extend': [],
|
||||
@@ -178,8 +187,8 @@
|
||||
'isBoolean': [],
|
||||
'isDate': [],
|
||||
'isElement': [],
|
||||
'isEmpty': [],
|
||||
'isEqual': [],
|
||||
'isEmpty': ['isArguments'],
|
||||
'isEqual': ['isArguments'],
|
||||
'isFinite': [],
|
||||
'isFunction': [],
|
||||
'isNaN': [],
|
||||
@@ -195,6 +204,7 @@
|
||||
'map': ['identity'],
|
||||
'max': [],
|
||||
'memoize': [],
|
||||
'merge': ['isArray', 'forIn'],
|
||||
'min': [],
|
||||
'mixin': ['forEach', 'functions'],
|
||||
'noConflict': [],
|
||||
@@ -209,7 +219,7 @@
|
||||
'rest': [],
|
||||
'result': [],
|
||||
'shuffle': [],
|
||||
'size': ['keys'],
|
||||
'size': ['isArguments', 'keys'],
|
||||
'some': ['identity'],
|
||||
'sortBy': [],
|
||||
'sortedIndex': ['bind'],
|
||||
@@ -222,6 +232,7 @@
|
||||
'uniq': ['identity', 'indexOf'],
|
||||
'uniqueId': [],
|
||||
'values': [],
|
||||
'where': ['forIn'],
|
||||
'without': ['indexOf'],
|
||||
'wrap': [],
|
||||
'zip': ['max', 'pluck'],
|
||||
@@ -243,6 +254,7 @@
|
||||
'isKeysFast',
|
||||
'object',
|
||||
'objectBranch',
|
||||
'noArgsEnum',
|
||||
'noCharByIndex',
|
||||
'shadowed',
|
||||
'top',
|
||||
@@ -251,10 +263,21 @@
|
||||
];
|
||||
|
||||
/** Collections of method names */
|
||||
var excludeMethods,
|
||||
includeMethods,
|
||||
var excludeMethods = [],
|
||||
includeMethods = [],
|
||||
allMethods = Object.keys(dependencyMap);
|
||||
|
||||
var underscoreMethods = lodash.without.apply(lodash, [allMethods].concat([
|
||||
'countBy',
|
||||
'drop',
|
||||
'forIn',
|
||||
'forOwn',
|
||||
'merge',
|
||||
'partial',
|
||||
'where',
|
||||
'zipObject'
|
||||
]));
|
||||
|
||||
/** Used to specify whether filtering is for exclusion or inclusion */
|
||||
var filterType = process.argv.reduce(function(result, value) {
|
||||
if (result) {
|
||||
@@ -289,14 +312,17 @@
|
||||
' Commands:',
|
||||
'',
|
||||
' lodash backbone Build containing all methods required by Backbone',
|
||||
' lodash csp Build supporting default Content Security Policy restrictions',
|
||||
' lodash legacy Build tailored for older browsers without ES5 support',
|
||||
' lodash mobile Build with IE < 9 bug fixes and method compilation removed',
|
||||
' lodash strict Build with `_.bindAll`, `_.extend`, and `_.defaults` in strict mode',
|
||||
' lodash strict Build with `_.bindAll`, `_.defaults`, and `_.extend` in strict mode',
|
||||
' lodash underscore Build containing only methods included in Underscore',
|
||||
' lodash category=... Comma separated categories of methods to include in the build',
|
||||
' lodash exclude=... Comma separated names of methods to exclude from the build',
|
||||
' lodash include=... Comma separated names of methods to include in the build',
|
||||
'',
|
||||
' All arguments, except `exclude` with `include` and `legacy` with `mobile`, may be combined.',
|
||||
' All arguments, except `backbone` with `underscore`, `exclude` with `include`,',
|
||||
' and `legacy` with `csp`/`mobile`, may be combined.',
|
||||
'',
|
||||
' Options:',
|
||||
'',
|
||||
@@ -317,6 +343,17 @@
|
||||
return realToAliasMap[funcName] || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Lo-Dash method assignments snippet from `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to inspect.
|
||||
* @returns {String} Returns the method assignments snippet.
|
||||
*/
|
||||
function getMethodAssignments(source) {
|
||||
return (source.match(/lodash\.VERSION *= *[\s\S]+?\/\*-+\*\/\n/) || [''])[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of depenants for a function by a given name.
|
||||
*
|
||||
@@ -385,7 +422,7 @@
|
||||
* @returns {String} Returns the `isArguments` fallback snippet.
|
||||
*/
|
||||
function getIsArgumentsFallback(source) {
|
||||
return (source.match(/(?:\s*\/\/.*)*\s*if *\(!(?:lodash\.)?isArguments[^)]+\)[\s\S]+?};\s*}/) || [''])[0];
|
||||
return (source.match(/(?:\s*\/\/.*)*\s*if *\(noArgsClass[\s\S]+?};\s*}/) || [''])[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,7 +489,7 @@
|
||||
function removeFromCreateIterator(source, refName) {
|
||||
var snippet = matchFunction(source, 'createIterator');
|
||||
if (snippet) {
|
||||
// clip the snippet the `factory` assignment
|
||||
// clip the snippet at the `factory` assignment
|
||||
snippet = snippet.match(/Function\([\s\S]+$/)[0];
|
||||
var modified = snippet.replace(RegExp('\\b' + refName + '\\b,? *', 'g'), '');
|
||||
source = source.replace(snippet, modified);
|
||||
@@ -481,7 +518,7 @@
|
||||
source = source.replace(matchFunction(source, funcName), '');
|
||||
|
||||
// grab the method assignments snippet
|
||||
snippet = source.match(/lodash\.VERSION *= *[\s\S]+?\/\*-+\*\/\n/)[0];
|
||||
snippet = getMethodAssignments(source);
|
||||
|
||||
// remove assignment and aliases
|
||||
modified = getAliases(funcName).concat(funcName).reduce(function(result, otherName) {
|
||||
@@ -524,6 +561,38 @@
|
||||
.replace(/\s*.+?\.isKeysFast *=.+/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all `noArgsClass` references from `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to process.
|
||||
* @returns {String} Returns the modified source.
|
||||
*/
|
||||
function removeNoArgsClass(source) {
|
||||
return removeVar(source, 'noArgsClass')
|
||||
// remove `noArgsClass` from `_.clone`, `_.isEqual`, and `_.size`
|
||||
.replace(/ *\|\| *\(noArgsClass *&&[^)]+?\)\)/g, '')
|
||||
// remove `noArgsClass` from `_.isEqual`
|
||||
.replace(/if *\(noArgsClass[^}]+?}\n/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all `noNodeClass` references from `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to process.
|
||||
* @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]+?\)\)\)/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the "use strict" directive from `source`.
|
||||
*
|
||||
@@ -563,6 +632,9 @@
|
||||
// remove a variable at the end of a variable declaration list
|
||||
source = source.replace(RegExp(',\\s*' + varName + ' *=.+?;'), ';');
|
||||
|
||||
// remove variable reference from `arrayLikeClasses` and `cloneableClasses` assignments
|
||||
source = source.replace(RegExp('(?:arrayLikeClasses|cloneableClasses)\\[' + varName + '\\] *= *(?:false|true)?', 'g'), '');
|
||||
|
||||
return removeFromCreateIterator(source, varName);
|
||||
}
|
||||
|
||||
@@ -609,6 +681,25 @@
|
||||
.replace(/\s*.+?\.useStrict *=.+/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes `source` to a file with the given `filename` to the current
|
||||
* working directory.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to write.
|
||||
* @param {String} filename The name of the file.
|
||||
*/
|
||||
function writeFile(source, filename) {
|
||||
// correct overly aggressive Closure Compiler minification
|
||||
source = source.replace(/prototype\s*=\s*{\s*valueOf\s*:\s*1\s*}/, 'prototype={valueOf:1,y:1}');
|
||||
|
||||
// re-remove "use strict" added by the minifier
|
||||
if (!useStrict) {
|
||||
source = removeUseStrictDirective(source);
|
||||
}
|
||||
fs.writeFileSync(path.join(cwd, filename), source);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// display help message
|
||||
@@ -629,25 +720,47 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// Backbone build
|
||||
if (isBackbone) {
|
||||
// don't expose `_.forIn` or `_.forOwn` if `isUnderscore` is `true` unless
|
||||
// requested by `include`
|
||||
if (isUnderscore) {
|
||||
if (includeMethods.indexOf('forIn') == -1) {
|
||||
source = source.replace(/ *lodash\.forIn *=.+\n/, '');
|
||||
}
|
||||
if (includeMethods.indexOf('forOwn') == -1) {
|
||||
source = source.replace(/ *lodash\.forOwn *=.+\n/, '');
|
||||
}
|
||||
}
|
||||
|
||||
// add methods required by Backbone or Underscore
|
||||
[
|
||||
{ 'flag': isBackbone, 'methodNames': backboneDependencies },
|
||||
{ 'flag': isUnderscore, 'methodNames': underscoreMethods }
|
||||
]
|
||||
.some(function(data) {
|
||||
var flag = data.flag,
|
||||
methodNames = data.methodNames;
|
||||
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
// add any additional sub-dependencies
|
||||
backboneDependencies = getDependencies(backboneDependencies);
|
||||
methodNames = getDependencies(methodNames);
|
||||
|
||||
if (filterType == 'exclude') {
|
||||
// remove excluded methods from `backboneDependencies`
|
||||
includeMethods = lodash.without.apply(lodash, [backboneDependencies].concat(excludeMethods));
|
||||
// remove excluded methods from `methodNames`
|
||||
includeMethods = lodash.without.apply(lodash, [methodNames].concat(excludeMethods));
|
||||
}
|
||||
else if (filterType) {
|
||||
// merge backbone dependencies into `includeMethods`
|
||||
includeMethods = lodash.union(includeMethods, backboneDependencies);
|
||||
// merge `methodNames` into `includeMethods`
|
||||
includeMethods = lodash.union(includeMethods, methodNames);
|
||||
}
|
||||
else {
|
||||
// include only the Backbone dependencies
|
||||
includeMethods = backboneDependencies;
|
||||
// include only the `methodNames`
|
||||
includeMethods = methodNames;
|
||||
}
|
||||
filterType = 'include';
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
@@ -717,14 +830,13 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// simplify template snippets
|
||||
// simplify template snippets by removing unnecessary brackets
|
||||
source = source.replace(
|
||||
RegExp(
|
||||
"'else if \\(thisArg\\) \\{\\\\n' \\+\\s*" +
|
||||
"' callback = iteratorBind\\(callback, thisArg\\)\\\\n' \\+\\s*" +
|
||||
"'}'"
|
||||
, 'g'),
|
||||
"'else if (thisArg) callback = iteratorBind(callback, thisArg)'"
|
||||
RegExp("{(\\\\n' *\\+\\s*.*?\\+\\n\\s*' *)}(?:\\\\n)?' *([,\\n])", 'g'), "$1'$2"
|
||||
);
|
||||
|
||||
source = source.replace(
|
||||
RegExp("{(\\\\n' *\\+\\s*.*?\\+\\n\\s*' *)}(?:\\\\n)?' *\\+", 'g'), "$1;\\n'+"
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -739,32 +851,20 @@
|
||||
if (!iteratorName) {
|
||||
return;
|
||||
}
|
||||
var snippet,
|
||||
funcNames = [],
|
||||
objectSnippets = [],
|
||||
token = '__isTypeToken__';
|
||||
var funcNames = [],
|
||||
objectSnippets = [];
|
||||
|
||||
// build replacement code
|
||||
lodash.forOwn({
|
||||
'Arguments': "'[object Arguments]'",
|
||||
'Date': 'dateClass',
|
||||
'Function': 'funcClass',
|
||||
'Number': 'numberClass',
|
||||
'RegExp': 'regexpClass',
|
||||
'String': 'stringClass'
|
||||
}, function(value, key) {
|
||||
// skip `isArguments` if a legacy build
|
||||
if (isLegacy && key == 'Arguments') {
|
||||
return;
|
||||
}
|
||||
var funcName = 'is' + key,
|
||||
funcCode = matchFunction(source, funcName);
|
||||
|
||||
if (funcCode) {
|
||||
if (!snippet) {
|
||||
// use snippet to mark the insert position
|
||||
snippet = funcCode;
|
||||
}
|
||||
funcNames.push(funcName);
|
||||
objectSnippets.push("'" + key + "': " + value);
|
||||
}
|
||||
@@ -774,30 +874,22 @@
|
||||
if (funcNames.length < 2) {
|
||||
return;
|
||||
}
|
||||
// add a token to mark the position to insert new code
|
||||
source = source.replace(snippet, '\n' + token + '\n' + snippet);
|
||||
|
||||
// remove existing isType functions
|
||||
funcNames.forEach(function(funcName) {
|
||||
source = removeFunction(source, funcName);
|
||||
});
|
||||
|
||||
// replace token with new DRY code
|
||||
source = source.replace(token,
|
||||
// insert new DRY code after the method assignments
|
||||
var snippet = getMethodAssignments(source);
|
||||
source = source.replace(snippet, snippet + '\n' +
|
||||
' // add `_.' + funcNames.join('`, `_.') + '`\n' +
|
||||
' ' + iteratorName + '({\n ' + objectSnippets.join(',\n ') + '\n }, function(className, key) {\n' +
|
||||
" lodash['is' + key] = function(value) {\n" +
|
||||
' return toString.call(value) == className;\n' +
|
||||
' };\n' +
|
||||
' });'
|
||||
' });\n'
|
||||
);
|
||||
|
||||
// tweak `isArguments` fallback
|
||||
snippet = !isLegacy && getIsArgumentsFallback(source);
|
||||
if (snippet) {
|
||||
var modified = '\n' + snippet.replace(/isArguments/g, 'lodash.$&');
|
||||
source = source.replace(snippet, modified);
|
||||
}
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -812,11 +904,11 @@
|
||||
modified = snippet;
|
||||
|
||||
// remove native `Function#bind` branch in `_.bind`
|
||||
if (funcName == 'bind' ) {
|
||||
if (funcName == 'bind') {
|
||||
modified = modified.replace(/(?:\s*\/\/.*)*\s*else if *\(isBindFast[^}]+}/, '');
|
||||
}
|
||||
// remove native `Array.isArray` branch in `_.isArray`
|
||||
else if (funcName == 'isArray') {
|
||||
else {
|
||||
modified = modified.replace(/nativeIsArray * \|\|/, '');
|
||||
}
|
||||
source = source.replace(snippet, modified);
|
||||
@@ -834,8 +926,8 @@
|
||||
// replace `_.isArguments` with fallback
|
||||
if (!isRemoved(source, 'isArguments')) {
|
||||
source = source.replace(
|
||||
matchFunction(source, 'isArguments').replace(/[\s\S]+?var isArguments *=/, ''),
|
||||
getIsArgumentsFallback(source).match(/isArguments *=([\s\S]+?) *};/)[1] + ' };\n'
|
||||
matchFunction(source, 'isArguments').replace(/[\s\S]+?function isArguments/, ''),
|
||||
getIsArgumentsFallback(source).match(/isArguments *= *function([\s\S]+?) *};/)[1] + ' }\n'
|
||||
);
|
||||
|
||||
source = removeIsArgumentsFallback(source);
|
||||
@@ -860,25 +952,37 @@
|
||||
source = source.replace(reFunc, '$1' + getFunctionSource(lodash[funcName]) + ';\n');
|
||||
});
|
||||
|
||||
// replace `callee` in `_.merge` with `merge`
|
||||
source = source.replace(matchFunction(source, 'merge'), function(match) {
|
||||
return match.replace(/\bcallee\b/g, 'merge');
|
||||
});
|
||||
|
||||
// remove `hasDontEnumBug`, `iteratesOwnLast`, `noArgsEnum` assignment
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var hasDontEnumBug\b[\s\S]+?}\(1\)\);\n/, '');
|
||||
|
||||
// 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 *\(result *&& *hasDontEnumBug[\s\S]+?\n\1}/, '');
|
||||
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(hasDontEnumBug[\s\S]+?\n\1}/, '');
|
||||
|
||||
// remove IE `shift` and `splice` fix from mutator Array functions mixin
|
||||
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(value.length *=== *0[\s\S]+?\n\1}/, '');
|
||||
|
||||
// remove `noCharByIndex` from `_.reduceRight`
|
||||
source = source.replace(/noCharByIndex *&&[^:]+: *([^;]+)/g, '$1');
|
||||
|
||||
// remove `noArraySliceOnStrings` from `_.toArray`
|
||||
source = source.replace(/noArraySliceOnStrings *\?[^:]+: *([^)]+)/g, '$1');
|
||||
|
||||
// remove `noCharByIndex` from `_.reduceRight`
|
||||
source = source.replace(/noCharByIndex *&&[^:]+: *([^;]+)/g, '$1');
|
||||
|
||||
source = removeVar(source, 'extendIteratorOptions');
|
||||
source = removeVar(source, 'hasDontEnumBug');
|
||||
source = removeVar(source, 'iteratorTemplate');
|
||||
source = removeVar(source, 'noArraySliceOnStrings');
|
||||
source = removeVar(source, 'noCharByIndex');
|
||||
source = removeIsArgumentsFallback(source);
|
||||
source = removeKeysOptimization(source);
|
||||
source = removeNoArgsClass(source);
|
||||
source = removeNoNodeClass(source);
|
||||
}
|
||||
else {
|
||||
// inline `iteratorTemplate` template
|
||||
@@ -937,9 +1041,6 @@
|
||||
// remove `LoDash.prototype` additions
|
||||
source = source.replace(/(?:\s*\/\/.*)*\s*LoDash.prototype *=[\s\S]+?\/\*-+\*\//, '');
|
||||
}
|
||||
if (isRemoved(source, 'sortBy')) {
|
||||
source = removeFunction(source, 'compareAscending');
|
||||
}
|
||||
if (isRemoved(source, 'template')) {
|
||||
// remove `templateSettings` assignment
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *lodash\.templateSettings[\s\S]+?};\n/, '');
|
||||
@@ -947,32 +1048,34 @@
|
||||
if (isRemoved(source, 'toArray')) {
|
||||
source = removeVar(source, 'noArraySliceOnStrings');
|
||||
}
|
||||
if (isRemoved(source, 'isArray', 'isEmpty', 'isEqual')) {
|
||||
source = removeVar(source, 'arrayClass');
|
||||
if (isRemoved(source, 'clone', 'merge')) {
|
||||
source = removeFunction(source, 'isPlainObject');
|
||||
}
|
||||
if (isRemoved(source, 'bind', 'bindAll', 'functions', 'isEqual', 'isFunction', 'result', 'toArray')) {
|
||||
source = removeVar(source, 'funcClass');
|
||||
if (isRemoved(source, 'clone', 'isArguments', 'isEmpty', 'isEqual', 'size')) {
|
||||
source = removeNoArgsClass(source);
|
||||
}
|
||||
if (isRemoved(source, 'bind', 'clone', 'isObject', 'keys')) {
|
||||
source = removeVar(source, 'objectTypes');
|
||||
if (isRemoved(source, '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', 'isArray', 'keys')) {
|
||||
source = removeVar(source, 'reNative');
|
||||
}
|
||||
if (isRemoved(source, 'createIterator', 'extend', 'isEqual')) {
|
||||
source = removeVar(source, 'hasDontEnumBug');
|
||||
if (isRemoved(source, 'createIterator', 'clone', 'merge')) {
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var iteratesOwnLast;|.+?iteratesOwnLast *=.+/g, '');
|
||||
}
|
||||
if (isRemoved(source, 'createIterator', 'contains', 'isEmpty', 'isEqual', 'isString')) {
|
||||
source = removeVar(source, 'stringClass');
|
||||
if (isRemoved(source, 'createIterator', 'isEqual')) {
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var hasDontEnumBug;|.+?hasDontEnumBug *=.+/g, '');
|
||||
}
|
||||
if (isRemoved(source, 'createIterator', 'keys')) {
|
||||
source = removeVar(source, 'nativeKeys');
|
||||
}
|
||||
if (isRemoved(source, 'createIterator', 'reduceRight')) {
|
||||
source = removeVar(source, 'noCharByIndex');
|
||||
if (!source.match(/var (?:hasDontEnumBug|iteratesOwnLast|noArgsEnum)\b/g)) {
|
||||
// remove `hasDontEnumBug`, `iteratesOwnLast`, `noArgsEnum` assignment
|
||||
source = source.replace(/ *\(function\(\) *{\s*var props\b[\s\S]+?}\(1\)\);/, '');
|
||||
}
|
||||
|
||||
// remove pseudo private properties
|
||||
@@ -987,20 +1090,16 @@
|
||||
source = source.replace(/^ *;\n/gm, '');
|
||||
|
||||
// begin the minification process
|
||||
if (filterType || isBackbone || isLegacy || isMobile || isStrict) {
|
||||
fs.writeFileSync(path.join(cwd, 'lodash.custom.js'), source);
|
||||
if (filterType || isBackbone || isLegacy || isMobile || isStrict || isUnderscore) {
|
||||
writeFile(source, 'lodash.custom.js');
|
||||
|
||||
minify(source, 'lodash.custom.min', function(result) {
|
||||
// re-remove "use strict" added by the minifier
|
||||
if (!useStrict) {
|
||||
result = removeUseStrictDirective(result);
|
||||
}
|
||||
fs.writeFileSync(path.join(cwd, 'lodash.custom.min.js'), result);
|
||||
writeFile(result, 'lodash.custom.min.js');
|
||||
});
|
||||
}
|
||||
else {
|
||||
minify(source, 'lodash.min', function(result) {
|
||||
fs.writeFileSync(path.join(cwd, 'lodash.min.js'), result);
|
||||
writeFile(result, 'lodash.min.js');
|
||||
});
|
||||
}
|
||||
}());
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
source = source.replace(/(\w)\["([^."]+)"\]/g, '$1.$2');
|
||||
|
||||
// correct AMD module definition for AMD build optimizers
|
||||
source = source.replace(/("function")==(typeof define)&&\(?("object")==(typeof define\.amd)(&&define\.amd)\)?/, '$2==$1&&$4==$3$5');
|
||||
source = source.replace(/("function")\s*==\s*(typeof define)\s*&&\s*\(?\s*("object")\s*==\s*(typeof define\.amd)\s*&&\s*(define\.amd)\s*\)?/, '$2==$1&&$4==$3&&$5');
|
||||
|
||||
// add license
|
||||
source = license + '\n;' + source;
|
||||
|
||||
@@ -7,43 +7,69 @@
|
||||
|
||||
/** Used to minify variables embedded in compiled strings */
|
||||
var compiledVars = [
|
||||
'accumulator',
|
||||
'args',
|
||||
'arrayClass',
|
||||
'bind',
|
||||
'callback',
|
||||
'className',
|
||||
'collection',
|
||||
'compareAscending',
|
||||
'concat',
|
||||
'ctor',
|
||||
'funcClass',
|
||||
'funcs',
|
||||
'hasOwnProperty',
|
||||
'identity',
|
||||
'index',
|
||||
'isFunc',
|
||||
'iteratee',
|
||||
'iterateeIndex',
|
||||
'iteratorBind',
|
||||
'length',
|
||||
'methodName',
|
||||
'nativeKeys',
|
||||
'noaccum',
|
||||
'object',
|
||||
'objectTypes',
|
||||
'ownIndex',
|
||||
'ownProps',
|
||||
'prop',
|
||||
'propertyIsEnumerable',
|
||||
'propIndex',
|
||||
'props',
|
||||
'property',
|
||||
'propertyIsEnumerable',
|
||||
'result',
|
||||
'skipProto',
|
||||
'slice',
|
||||
'stringClass',
|
||||
'target',
|
||||
'thisArg',
|
||||
'toString',
|
||||
'value'
|
||||
'value',
|
||||
|
||||
// lesser used variables
|
||||
'accumulator',
|
||||
'args',
|
||||
'argsIndex',
|
||||
'argsLength',
|
||||
'arrayLikeClasses',
|
||||
'ArrayProto',
|
||||
'bind',
|
||||
'callee',
|
||||
'className',
|
||||
'compareAscending',
|
||||
'destValue',
|
||||
'forIn',
|
||||
'found',
|
||||
'funcs',
|
||||
'indexOf',
|
||||
'indicator',
|
||||
'isArguments',
|
||||
'isArr',
|
||||
'isArray',
|
||||
'isFunc',
|
||||
'isFunction',
|
||||
'isPlainObject',
|
||||
'methodName',
|
||||
'noaccum',
|
||||
'objectClass',
|
||||
'objectTypes',
|
||||
'pass',
|
||||
'properties',
|
||||
'property',
|
||||
'propsLength',
|
||||
'recursive',
|
||||
'source',
|
||||
'stack',
|
||||
'stackLength',
|
||||
'target',
|
||||
'valueProp'
|
||||
];
|
||||
|
||||
/** Used to minify `compileIterator` option properties */
|
||||
@@ -61,6 +87,7 @@
|
||||
'isKeysFast',
|
||||
'object',
|
||||
'objectBranch',
|
||||
'noArgsEnum',
|
||||
'noCharByIndex',
|
||||
'shadowed',
|
||||
'top',
|
||||
@@ -70,6 +97,9 @@
|
||||
|
||||
/** Used to minify variables and string values to a single character */
|
||||
var minNames = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
||||
minNames.push.apply(minNames, minNames.map(function(value) {
|
||||
return value + value;
|
||||
}));
|
||||
|
||||
/** Used to protect the specified properties from getting minified */
|
||||
var propWhitelist = [
|
||||
@@ -90,6 +120,7 @@
|
||||
'compact',
|
||||
'compose',
|
||||
'contains',
|
||||
'countBy',
|
||||
'criteria',
|
||||
'debounce',
|
||||
'defaults',
|
||||
@@ -97,6 +128,7 @@
|
||||
'delay',
|
||||
'detect',
|
||||
'difference',
|
||||
'drop',
|
||||
'each',
|
||||
'environment',
|
||||
'escape',
|
||||
@@ -119,6 +151,7 @@
|
||||
'head',
|
||||
'identity',
|
||||
'include',
|
||||
'index',
|
||||
'indexOf',
|
||||
'initial',
|
||||
'inject',
|
||||
@@ -149,6 +182,7 @@
|
||||
'map',
|
||||
'max',
|
||||
'memoize',
|
||||
'merge',
|
||||
'methods',
|
||||
'min',
|
||||
'mixin',
|
||||
@@ -188,6 +222,7 @@
|
||||
'values',
|
||||
'variable',
|
||||
'VERSION',
|
||||
'where',
|
||||
'without',
|
||||
'wrap',
|
||||
'zip',
|
||||
@@ -209,6 +244,22 @@
|
||||
// remove unrecognized JSDoc tags so Closure Compiler won't complain
|
||||
source = source.replace(/@(?:alias|category)\b.*/g, '');
|
||||
|
||||
// manually convert `arrayLikeClasses` property assignments because
|
||||
// Closure Compiler errors trying to minify them
|
||||
source = source.replace(/(arrayLikeClasses =)[\s\S]+?= *true/,
|
||||
"$1{'[object Arguments]': true, '[object Array]': true, '[object Boolean]': false, " +
|
||||
"'[object Date]': false, '[object Function]': false, '[object Number]': false, " +
|
||||
"'[object Object]': false, '[object RegExp]': false, '[object String]': true }"
|
||||
);
|
||||
|
||||
// manually convert `cloneableClasses` property assignments because
|
||||
// Closure Compiler errors trying to minify them
|
||||
source = source.replace(/(cloneableClasses =)[\s\S]+?= *true/,
|
||||
"$1{'[object Arguments]': false, '[object Array]': true, '[object Boolean]': true, " +
|
||||
"'[object Date]': true, '[object Function]': false, '[object Number]': true, " +
|
||||
"'[object Object]': true, '[object RegExp]': true, '[object String]': true }"
|
||||
);
|
||||
|
||||
// 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']");
|
||||
@@ -233,7 +284,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
// remove whitespace from `_.template` related regexpes
|
||||
// remove whitespace from `_.template` related regexes
|
||||
source = source.replace(/(?:reDelimiterCode\w+|reEmptyString\w+|reInsertVariable) *=.+/g, function(match) {
|
||||
return match.replace(/ |\\n/g, '');
|
||||
});
|
||||
@@ -247,35 +298,59 @@
|
||||
.replace("') {\\n'", "'){'")
|
||||
|
||||
// remove `useSourceURL` variable
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*\n)* *var useSourceURL[\s\S]+?catch[^}]+}\n/, '');
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var useSourceURL[\s\S]+?catch[^}]+}\n/, '');
|
||||
|
||||
// remove debug sourceURL use in `_.template`
|
||||
source = source.replace(/(?:\s*\/\/.*\n)* *if *\(useSourceURL[^}]+}/, '');
|
||||
|
||||
// minify internal properties used by `_.sortBy`
|
||||
// minify internal properties used by 'compareAscending', `_.clone`, `_.merge`, and `_.sortBy`
|
||||
(function() {
|
||||
var properties = ['criteria', 'value'],
|
||||
snippets = source.match(/( +)(?:function compareAscending|var sortBy)\b[\s\S]+?\n\1}/g);
|
||||
var properties = ['criteria', 'index', 'source', 'value'],
|
||||
snippets = source.match(/( +)(?:function clone|function compareAscending|var merge|var sortBy)\b[\s\S]+?\n\1}/g);
|
||||
|
||||
if (!snippets) {
|
||||
return;
|
||||
}
|
||||
snippets.forEach(function(snippet) {
|
||||
var modified = snippet,
|
||||
isSortBy = /var sortBy\b/.test(modified),
|
||||
isCompilable = /(?:var merge|var sortBy)\b/.test(modified),
|
||||
isInlined = !/\bcreateIterator\b/.test(modified);
|
||||
|
||||
// minify properties
|
||||
properties.forEach(function(property, index) {
|
||||
// add quotes around properties in the inlined `_.sortBy` of the mobile
|
||||
// build so Closure Compiler won't mung them
|
||||
if (isSortBy && isInlined) {
|
||||
modified = modified
|
||||
.replace(RegExp('\\.' + property + '\\b', 'g'), "['" + minNames[index] + "']")
|
||||
.replace(RegExp('\\b' + property + ' *:', 'g'), "'" + minNames[index] + "':");
|
||||
var reBracketProp = RegExp("\\['(" + property + ")'\\]", 'g'),
|
||||
reDotProp = RegExp('\\.' + property + '\\b', 'g'),
|
||||
rePropColon = RegExp("(')?\\b" + property + "\\1 *:", 'g');
|
||||
|
||||
if (isCompilable) {
|
||||
// add quotes around properties in the inlined `_.merge` and `_.sortBy`
|
||||
// of the mobile build so Closure Compiler won't mung them
|
||||
if (isInlined) {
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
||||
.replace(reDotProp, "['" + minNames[index] + "']")
|
||||
.replace(rePropColon, "'" + minNames[index] + "':");
|
||||
}
|
||||
else {
|
||||
modified = modified
|
||||
.replace(reBracketProp, '.' + minNames[index])
|
||||
.replace(reDotProp, '.' + minNames[index])
|
||||
.replace(rePropColon, minNames[index] + ':');
|
||||
}
|
||||
}
|
||||
else {
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
||||
.replace(reDotProp, '.' + minNames[index])
|
||||
.replace(rePropColon, "'" + minNames[index] + "':")
|
||||
|
||||
// correct `value.source` in regexp branch of `_.clone`
|
||||
if (property == 'source') {
|
||||
modified = modified.replace("value['" + minNames[index] + "']", "value['source']");
|
||||
}
|
||||
}
|
||||
modified = modified.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
||||
});
|
||||
|
||||
// replace with modified snippet
|
||||
source = source.replace(snippet, modified);
|
||||
});
|
||||
@@ -340,7 +415,7 @@
|
||||
else {
|
||||
// minify property name strings
|
||||
modified = modified.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
|
||||
// minify property names in regexps and accessors
|
||||
// minify property names in regexes and accessors
|
||||
if (isCreateIterator) {
|
||||
modified = modified.replace(RegExp('([\\.|/])' + property + '\\b' , 'g'), '$1' + minNames[index]);
|
||||
}
|
||||
|
||||
874
doc/README.md
874
doc/README.md
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@
|
||||
// generate Markdown
|
||||
$markdown = docdown(array(
|
||||
'path' => '../' . $file,
|
||||
'title' => 'Lo-Dash <sup>v0.4.2</sup>',
|
||||
'title' => 'Lo-Dash <sup>v0.5.0</sup>',
|
||||
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
|
||||
));
|
||||
|
||||
|
||||
69
lodash.min.js
vendored
69
lodash.min.js
vendored
@@ -1,35 +1,40 @@
|
||||
/*!
|
||||
Lo-Dash 0.4.2 lodash.com/license
|
||||
Lo-Dash 0.5.0 lodash.com/license
|
||||
Underscore.js 1.3.3 github.com/documentcloud/underscore/blob/master/LICENSE
|
||||
*/
|
||||
;(function(e,t){"use strict";function s(e){return new o(e)}function o(e){if(e&&e._wrapped)return e;this._wrapped=e}function u(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||30),s=i?{}:e;if(i)for(var o=t-1;++o<r;)n=e[o]+"",(Y.call(s,n)?s[n]:s[n]=[]).push(e[o]);return function(e){if(i){var n=e+"";return Y.call(s,n)&&-1<E(s[n],e)}return-1<E(s,e,t)}}function a(){for(var e,t,n,s=-1,o=arguments.length,u={e:"",f:"",j:"",p:"",c:{d:""},m:{d:""}};++s<o;)for(t in e=arguments[s],e)n=(n=e[t])==r?"":n,/d|i/.test(t)?
|
||||
("string"==typeof n&&(n={b:n,l:n}),u.c[t]=n.b,u.m[t]=n.l):u[t]=n;e=u.a,t=/^[^,]+/.exec(e)[0],u.g=t,u.h=mt,u.k=wt,u.o=J,u.q=u.q!==i,u.r=u.r!==i,"n"in u||(u.n=yt),u.f||(u.f="if(!"+t+")return D");if("g"!=t||!u.c.i)u.c=r;t="",u.r&&(t+="'use strict';"),t+="var n,p="+u.g+",D",u.j&&(t+="="+u.j),t+=";"+u.f+";"+u.p+";",u.c&&(t+="var s=p.length;n=-1;",u.m&&(t+="if(s===s>>>0){"),u.n&&(t+="if(J.call(p)==G){p=p.split('')}"),t+=u.c.d+";while(++n<s){"+u.c.i+"}",u.m&&(t+="}"));if(u.m){u.c&&(t+="else{"),u.h||(t+="var E=typeof p=='function'&&C.call(p,'prototype');"
|
||||
),u.k&&u.q?t+="var A=u(p),z=-1,s=A.length;"+u.m.d+";while(++z<s){n=A[z];if(!(E&&n=='prototype')){"+u.m.i+"}}":(t+=u.m.d+";for(n in p){",u.h?(u.q&&(t+="if(l.call(p,n)){"),t+=u.m.i+";",u.q&&(t+="}")):(t+="if(!(E&&n=='prototype')",u.q&&(t+="&&l.call(p,n)"),t+="){"+u.m.i+"}"),t+="}");if(u.h){t+="var i=p.constructor;";for(n=0;7>n;n++)t+="n='"+u.o[n]+"';if(","constructor"==u.o[n]&&(t+="!(i&&i.prototype===p)&&"),t+="l.call(p,n)){"+u.m.i+"}"}u.c&&(t+="}")}return t+=u.e+";return D",Function("c,d,h,j,l,m,r,x,u,C,F,G,J"
|
||||
,"return function("+e+"){"+t+"}")(ut,C,f,lt,Y,L,p,St,ot,et,tt,pt,nt)}function f(e,n){return e=e.a,n=n.a,e===t?1:n===t?-1:e<n?-1:e>n?1:0}function l(e,t){return Q[t]}function c(e){return"\\"+xt[e]}function h(e){return Et[e]}function p(e,t){return function(n,r,i){return e.call(t,n,r,i)}}function d(){}function v(e,t){if(I.test(t))return"<e%-"+t+"%>";var n=Q.length;return Q[n]="'+__e("+t+")+'",K+n}function m(e,t,n,r){return e=Q.length,t?Q[e]="';"+t+";__p+='":n?Q[e]="'+__e("+n+")+'":r&&(Q[e]="'+((__t=("+
|
||||
r+"))==null?'':__t)+'"),K+e}function g(e,t){if(I.test(t))return"<e%="+t+"%>";var n=Q.length;return Q[n]="'+((__t=("+t+"))==null?'':__t)+'",K+n}function y(e,t,n,r){if(!e)return n;var i=e.length,s=3>arguments.length;r&&(t=p(t,r));if(i===i>>>0){var o=yt&&nt.call(e)==pt?e.split(""):e;for(i&&s&&(n=o[--i]);i--;)n=t(n,o[i],i,e);return n}o=Zt(e);for((i=o.length)&&s&&(n=e[o[--i]]);i--;)s=o[i],n=t(n,e[s],s,e);return n}function b(e,t,n){if(e)return t==r||n?e[0]:tt.call(e,0,t)}function w(e,t){var n=[];if(!e)
|
||||
return n;for(var r,i=-1,s=e.length;++i<s;)r=e[i],Gt(r)?Z.apply(n,t?r:w(r)):n.push(r);return n}function E(e,t,n){if(!e)return-1;var r=-1,i=e.length;if(n){if("number"!=typeof n)return r=T(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 S(e,t,n){var r=-Infinity,i=r;if(!e)return i;var s=-1,o=e.length;if(!t){for(;++s<o;)e[s]>i&&(i=e[s]);return i}for(n&&(t=p(t,n));++s<o;)n=t(e[s],s,e),n>r&&(r=n,i=e[s]);return i}function x(e,t,n){return e?tt.call(e,t==r||
|
||||
n?1:t):[]}function T(e,t,n,r){if(!e)return 0;var i=0,s=e.length;if(n){r&&(n=C(n,r));for(t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r}else for(;i<s;)r=i+s>>>1,e[r]<t?i=r+1:s=r;return i}function N(e,t,n,r){var s=[];if(!e)return s;var o=-1,u=e.length,a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n?r&&(n=p(n,r)):n=L;++o<u;)if(r=n(e[o],o,e),t?!o||a[a.length-1]!==r:0>E(a,r))a.push(r),s.push(e[o]);return s}function C(e,t){function n(){var o=arguments,u=t;return i||(e=t[r]),s.length&&(o=o.length?G.apply(s,o)
|
||||
:s),this instanceof n?(d.prototype=e.prototype,u=new d,(o=e.apply(u,o))&&St[typeof o]?o:u):e.apply(u,o)}var r,i=nt.call(e)==lt;if(i){if(bt||rt&&2<arguments.length)return rt.call.apply(rt,arguments)}else r=t,t=e;var s=tt.call(arguments,2);return n}function k(e,t,s){s||(s=[]);if(e===t)return 0!==e||1/e==1/t;if(e==r||t==r)return e===t;e._chain&&(e=e._wrapped),t._chain&&(t=t._wrapped);if(e.isEqual&&nt.call(e.isEqual)==lt)return e.isEqual(t);if(t.isEqual&&nt.call(t.isEqual)==lt)return t.isEqual(e);var o=
|
||||
nt.call(e);if(o!=nt.call(t))return i;switch(o){case pt:return e==""+t;case ct:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case at:case ft:return+e==+t;case ht:return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if("object"!=typeof e||"object"!=typeof t)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==ut){if(f=e.length,a=f==t.length)for(;f--&&(a=k(e[f],t[f],s)););}else{if("constructor"in e!="constructor"in t||e.constructor!=
|
||||
t.constructor)return i;for(var l in e)if(Y.call(e,l)&&(f++,!(a=Y.call(t,l)&&k(e[l],t[l],s))))break;if(a){for(l in t)if(Y.call(t,l)&&!(f--))break;a=!f}if(a&&mt)for(;7>++u&&(l=J[u],!Y.call(e,l)||!!(a=Y.call(t,l)&&k(e[l],t[l],s))););}return s.pop(),a}function L(e){return e}function A(e){Bt(Qt(e),function(t){var r=s[t]=e[t];o.prototype[t]=function(){var e=[this._wrapped];return arguments.length&&Z.apply(e,arguments),e=r.apply(s,e),this._chain&&(e=new o(e),e._chain=n),e}})}var n=!0,r=null,i=!1,O,M,_,D
|
||||
,P="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),H=Array.prototype,B=Object.prototype,j=0,F=e._,I=/[-+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,q=/\b__p\+='';/g,R=/\b(__p\+=)''\+/g,U=/(__e\(.*?\)|\b__t\))\+'';/g,z=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,W=RegExp("^"+(B.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),X=/__token__(\d+)/g,V=/[&<"']/g,$=/['\n\r\t\u2028\u2029\\]/g
|
||||
,J="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),K="__token__",Q=[],G=H.concat,Y=B.hasOwnProperty,Z=H.push,et=B.propertyIsEnumerable,tt=H.slice,nt=B.toString,rt=W.test(rt=tt.bind)&&rt,it=W.test(it=Array.isArray)&&it,st=e.isFinite,ot=W.test(ot=Object.keys)&&ot,ut="[object Array]",at="[object Boolean]",ft="[object Date]",lt="[object Function]",ct="[object Number]",ht="[object RegExp]",pt="[object String]",dt=e.clearTimeout,vt=e.setTimeout
|
||||
,mt=!et.call({valueOf:0},"valueOf"),gt="x"!=tt.call("x")[0],yt="xx"!="x"[0]+Object("x")[0],bt=rt&&/\n|Opera/.test(rt+nt.call(e.opera)),wt=ot&&/^.+$|true/.test(ot+!!e.attachEvent),Et={"&":"&","<":"<",'"':""","'":"'"},St={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i},xt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:"obj"
|
||||
};var Tt={a:"g,e,I",j:"g",p:"if(!e){e=m}else if(I)e=r(e,I)",i:"e(p[n],n,g)"},Nt={j:"true",i:"if(!e(p[n],n,g))return!D"},Ct={q:i,r:i,a:"w",j:"w",p:"for(var q=1,s=arguments.length;q<s;q++){p=arguments[q];"+(mt?"if(p){":""),i:"D[n]=p[n]",e:(mt?"}":"")+"}"},kt={j:"[]",i:"e(p[n],n,g)&&D.push(p[n])"},Lt={p:"if(I)e=r(e,I)"},At={i:{l:Tt.i}},Ot={j:"",f:"if(!g)return[]",d:{b:"D=Array(s)",l:"D="+(wt?"Array(s)":"[]")},i:{b:"D[n]=e(p[n],n,g)",l:"D"+(wt?"[z]=":".push")+"(e(p[n],n,g))"}},Mt=a({a:"w",f:"if(!(w&&x[typeof w]))throw TypeError()"
|
||||
,j:"[]",i:"D.push(n)"}),_t=a({a:"g,H",j:"false",n:i,d:{b:"if(J.call(p)==G)return g.indexOf(H)>-1"},i:"if(p[n]===H)return true"}),Dt=a(Tt,Nt),Pt=a(Tt,kt),Ht=a(Tt,Lt,{j:"",i:"if(e(p[n],n,g))return p[n]"}),Bt=a(Tt,Lt),jt=a(Tt,{j:"{}",p:"var y,o=typeof e=='function';if(o&&I)e=r(e,I)",i:"y=o?e(p[n],n,g):p[n][e];(l.call(D,y)?D[y]:D[y]=[]).push(p[n])"}),Ft=a(Ot,{a:"g,t",p:"var b=F.call(arguments,2),o=typeof t=='function'",i:{b:"D[n]=(o?t:p[n][t]).apply(p[n],b)",l:"D"+(wt?"[z]=":".push")+"((o?t:p[n][t]).apply(p[n],b))"
|
||||
}}),It=a(Tt,Ot),qt=a(Ot,{a:"g,B",i:{b:"D[n]=p[n][B]",l:"D"+(wt?"[z]=":".push")+"(p[n][B])"}}),Rt=a({a:"g,e,a,I",j:"a",p:"var v=arguments.length<3;if(I)e=r(e,I)",d:{b:"if(v)D=g[++n]"},i:{b:"D=e(D,p[n],n,g)",l:"D=v?(v=false,p[n]):e(D,p[n],n,g)"}}),Ut=a(Tt,kt,{i:"!"+kt.i}),zt=a(Tt,Nt,{j:"false",i:Nt.i.replace("!","")}),Wt=a(Tt,Ot,{p:"if(typeof e=='string'){var y=e;e=function(g){return g[y]}}else if(I)e=r(e,I)",i:{b:"D[n]={a:e(p[n],n,g),b:p[n]}",l:"D"+(wt?"[z]=":".push")+"({a:e(p[n],n,g),b:p[n]})"},e
|
||||
:"D.sort(h);s=D.length;while(s--){D[s]=D[s].b}"}),Xt=a({q:i,r:i,a:"w",j:"w",p:"var k=arguments,s=k.length;if(s>1){for(var n=1;n<s;n++)D[k[n]]=d(D[k[n]],D);return D}",i:"if(J.call(D[n])==j)D[n]=d(D[n],D)"}),Vt=a(Ct,{i:"if(D[n]==null)"+Ct.i}),$t=a(Ct),Jt=a(Tt,Lt,At,{q:i}),Kt=a(Tt,Lt,At),Qt=a({q:i,a:"w",j:"[]",i:"if(J.call(p[n])==j)D.push(n)",e:"D.sort()"});Bt({Arguments:"[object Arguments]",Date:ft,Function:lt,Number:ct,RegExp:ht,String:pt},function(e,t){s["is"+t]=function(t){return nt.call(t)==e}}
|
||||
),s.isArguments(arguments)||(s.isArguments=function(e){return!!e&&!!Y.call(e,"callee")});var Gt=it||function(e){return nt.call(e)==ut},Yt=a({a:"K",j:"true",p:"var f=J.call(K);if(f==c||f==G)return!K.length",i:{l:"return false"}}),Zt=ot?function(e){return"function"==typeof e&&et.call(e,"prototype")?Mt(e):ot(e)}:Mt,en=a({a:"w",j:"[]",i:"D.push(p[n])"});s.VERSION="0.4.2",s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=C,s.bindAll=Xt,s.chain=function(e)
|
||||
{return e=new o(e),e._chain=n,e},s.clone=function(e){return e&&St[typeof e]?Gt(e)?e.slice():$t({},e):e},s.compact=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length;++n<r;)e[n]&&t.push(e[n]);return t},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=_t,s.debounce=function(e,t,n){function i(){a=r,n||e.apply(u,s)}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,dt(a),a=vt(i,t),r&&(o=
|
||||
e.apply(u,s)),o}},s.defaults=Vt,s.defer=function(e){var n=tt.call(arguments,1);return vt(function(){return e.apply(t,n)},1)},s.delay=function(e,n){var r=tt.call(arguments,2);return vt(function(){return e.apply(t,r)},n)},s.difference=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length,i=G.apply(t,arguments),i=u(i,r);++n<r;)i(e[n])||t.push(e[n]);return t},s.escape=function(e){return e==r?"":(e+"").replace(V,h)},s.every=Dt,s.extend=$t,s.filter=Pt,s.find=Ht,s.first=b,s.flatten=w,s.forEach=Bt,
|
||||
s.forIn=Jt,s.forOwn=Kt,s.functions=Qt,s.groupBy=jt,s.has=function(e,t){return Y.call(e,t)},s.identity=L,s.indexOf=E,s.initial=function(e,t,n){return e?tt.call(e,0,-(t==r||n?1:t)):[]},s.intersection=function(e){var t=[];if(!e)return t;for(var n,r=-1,i=e.length,s=tt.call(arguments,1),o=[];++r<i;)n=e[r],0>E(t,n)&&Dt(s,function(e,t){return(o[t]||(o[t]=u(e)))(n)})&&t.push(n);return t},s.invoke=Ft,s.isArray=Gt,s.isBoolean=function(e){return e===n||e===i||nt.call(e)==at},s.isElement=function(e){return!!
|
||||
e&&1==e.nodeType},s.isEmpty=Yt,s.isEqual=k,s.isFinite=function(e){return st(e)&&nt.call(e)==ct},s.isNaN=function(e){return nt.call(e)==ct&&e!=+e},s.isNull=function(e){return e===r},s.isObject=function(e){return e&&St[typeof e]},s.isUndefined=function(e){return e===t},s.keys=Zt,s.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:tt.call(e,-t||i)}},s.lastIndexOf=function(e,t,n){if(!e)return-1;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},s.map=It,s.max=S,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Y.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.min=function(e,t,n){var r=Infinity,i=r;if(!e)return i;var s=-1,o=e.length;if(!t){for(;++s<o;)e[s]<i&&(i=e[s]);return i}for(n&&(t=p(t,n));++s<o;)n=t(e[s],s,e),n<r&&(r=n,i=e[s]);return i},s.mixin=A,s.noConflict=function(){return e._=F,this},s.once=function(e){var t,r=i;return function(){return r?t:(r=n,t=
|
||||
e.apply(this,arguments))}},s.partial=function(e){var t=tt.call(arguments,1),n=t.length;return function(){var r;return r=arguments,r.length&&(t.length=n,Z.apply(t,r)),r=1==t.length?e.call(this,t[0]):e.apply(this,t),t.length=n,r}},s.pick=function(e){for(var t,n=0,r=G.apply(H,arguments),i=r.length,s={};++n<i;)t=r[n],t in e&&(s[t]=e[t]);return s},s.pluck=qt,s.range=function(e,t,n){n||(n=1),t==r&&(t=e||0,e=0);for(var i=-1,t=Math.max(0,Math.ceil((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reduce=
|
||||
Rt,s.reduceRight=y,s.reject=Ut,s.rest=x,s.result=function(e,t){if(!e)return r;var n=e[t];return nt.call(n)==lt?e[t]():n},s.shuffle=function(e){if(!e)return[];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},s.size=function(e){if(!e)return 0;var t=e.length;return t===t>>>0?e.length:Zt(e).length},s.some=zt,s.sortBy=Wt,s.sortedIndex=T,s.tap=function(e,t){return t(e),e},s.template=function(e,t,n){n||(n={});var i,o;i=n.escape;var u=n.evaluate,
|
||||
a=n.interpolate,f=s.templateSettings,n=n.variable;i==r&&(i=f.escape),u==r&&(u=f.evaluate),a==r&&(a=f.interpolate),i&&(e=e.replace(i,v)),a&&(e=e.replace(a,g)),u!=O&&(O=u,D=RegExp((u?u.source:"($^)")+"|<e%-([\\s\\S]+?)%>|<e%=([\\s\\S]+?)%>","g")),i=Q.length,e=e.replace(D,m),i=i!=Q.length,e="__p += '"+e.replace($,c).replace(X,l)+"';",Q.length=0,n||(n=f.variable||M||"obj",i?e="with("+n+"){"+e+"}":(n!=M&&(M=n,_=RegExp("(\\(\\s*)"+n+"\\."+n+"\\b","g")),e=e.replace(z,"$&"+n+".").replace(_,"$1__d"))),e=(
|
||||
i?e.replace(q,""):e).replace(R,"$1").replace(U,"$1;"),e="function("+n+"){"+n+"||("+n+"={});var __t,__p='',__e=_.escape"+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":",__d="+n+"."+n+"||"+n+";")+e+"return __p}";try{o=Function("_","return "+e)(s)}catch(h){o=function(){throw h}}return t?o(t):(o.source=e,o)},s.throttle=function(e,t){function n(){a=new Date,u=r,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?(a=r,s=e
|
||||
.apply(o,i)):u||(u=vt(n,f)),s}},s.times=function(e,t,n){var r=-1;if(n)for(;++r<e;)t.call(n,r);else for(;++r<e;)t(r)},s.toArray=function(e){if(!e)return[];if(e.toArray&&nt.call(e.toArray)==lt)return e.toArray();var t=e.length;return t===t>>>0?(gt?nt.call(e)==pt:"string"==typeof e)?e.split(""):tt.call(e):en(e)},s.union=function(){for(var e=-1,t=[],n=G.apply(t,arguments),r=n.length;++e<r;)0>E(t,n[e])&&t.push(n[e]);return t},s.uniq=N,s.uniqueId=function(e){var t=j++;return e?e+t:t},s.values=en,s.without=
|
||||
function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length,i=u(arguments,1,20);++n<r;)i(e[n])||t.push(e[n]);return t},s.wrap=function(e,t){return function(){var n=[e];return arguments.length&&Z.apply(n,arguments),t.apply(this,n)}},s.zip=function(e){if(!e)return[];for(var t=-1,n=S(qt(arguments,"length")),r=Array(n);++t<n;)r[t]=qt(arguments,t);return r},s.zipObject=function(e,t){if(!e)return{};var n=-1,r=e.length,i={};for(t||(t=[]);++n<r;)i[e[n]]=t[n];return i},s.all=Dt,s.any=zt,s.collect=It,s.detect=
|
||||
Ht,s.each=Bt,s.foldl=Rt,s.foldr=y,s.head=b,s.include=_t,s.inject=Rt,s.methods=Qt,s.select=Pt,s.tail=x,s.take=b,s.unique=N,o.prototype=s.prototype,A(s),o.prototype.chain=function(){return this._chain=n,this},o.prototype.value=function(){return this._wrapped},Bt("pop push reverse shift sort splice unshift".split(" "),function(e){var t=H[e];o.prototype[e]=function(){var e=this._wrapped;return t.apply(e,arguments),e.length===0&&delete e[0],this._chain&&(e=new o(e),e._chain=n),e}}),Bt(["concat","join"
|
||||
,"slice"],function(e){var t=H[e];o.prototype[e]=function(){var e=t.apply(this._wrapped,arguments);return this._chain&&(e=new o(e),e._chain=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):P?"object"==typeof module&&module&&module.s==P?(module.s=s)._=s:P._=s:e._=s})(this);
|
||||
;(function(e,t){"use strict";function s(e){return new o(e)}function o(e){if(e&&e._wrapped)return e;this._wrapped=e}function u(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||30),s=i?{}:e;if(i)for(var o=t-1;++o<r;)n=e[o]+"",(ot.call(s,n)?s[n]:s[n]=[]).push(e[o]);return function(e){if(i){var n=e+"";return ot.call(s,n)&&-1<C(s[n],e)}return-1<C(s,e,t)}}function a(){for(var e,t,n,s=-1,o=arguments.length,u={e:"",f:"",j:"",q:"",c:{d:""},m:{d:""}};++s<o;)for(t in e=arguments[s],e)n=(n=e[t])==r?"":n,/d|i/.test(t
|
||||
)?("string"==typeof n&&(n={b:n,l:n}),u.c[t]=n.b,u.m[t]=n.l):u[t]=n;e=u.a,t=/^[^,]+/.exec(e)[0],u.g=t,u.h=Nt,u.k=Pt,u.n=kt,u.p=nt,u.r=u.r!==i,u.s=u.s!==i,"o"in u||(u.o=Ot),u.f||(u.f="if(!"+t+")return s");if("b"!=t||!u.c.i)u.c=r;t="",u.s&&(t+="'use strict';"),t+="var g,y,h="+u.g+",s",u.j&&(t+="="+u.j),t+=";"+u.f+";"+u.q+";",u.c&&(t+="var j=h.length;g=-1;",u.m&&(t+="if(j>-1&&j===j>>>0){"),u.o&&(t+="if(x.call(h)==v){h=h.split('')}"),t+=u.c.d+";while(++g<j){y=h[g];"+u.c.i+"}",u.m&&(t+="}"));if(u.m){u.
|
||||
c?t+="else{":u.n&&(t+="var j=h.length;g=-1;if(j&&P(h)){while(++g<j){y=h[g+=''];"+u.m.i+"}}else{"),u.h||(t+="var t=typeof h=='function'&&p.call(h,'prototype');"),u.k&&u.r?t+="var m=-1,n=k(h),j=n.length;"+u.m.d+";while(++m<j){g=n[m];if(!(t&&g=='prototype')){y=h[g];"+u.m.i+"}}":(t+=u.m.d+";for(g in h){",u.h?(u.r&&(t+="if(e.call(h,g)){"),t+="y=h[g];"+u.m.i+";",u.r&&(t+="}")):(t+="if(!(t&&g=='prototype')",u.r&&(t+="&&e.call(h,g)"),t+="){y=h[g];"+u.m.i+"}"),t+="}");if(u.h){t+="var d=h.constructor;";for(
|
||||
n=0;7>n;n++)t+="g='"+u.p[n]+"';if(","constructor"==u.p[n]&&(t+="!(d&&d.prototype===h)&&"),t+="e.call(h,g)){y=h[g];"+u.m.i+"}"}if(u.c||u.n)t+="}"}return t+=u.e+";return s",Function("D,E,F,I,c,K,e,f,N,P,R,T,U,i,X,Y,k,p,u,v,x","var G=function("+e+"){"+t+"};return G")(Ht,I,M,f,st,Zt,ot,_,C,b,Jt,w,p,d,wt,Ft,dt,at,ft,St,lt)}function f(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;return e===t?1:n===t?-1:e<n?-1:e>n?1:r<i?-1:1}function l(e,t){return it[t]}function c(e){return"\\"+It[e]}function h(e){return jt[e]}function p
|
||||
(e,t){var n=i;if(!e||"object"!=typeof e||!t&&b(e))return n;var r=e.constructor;return(!Mt||"function"==typeof e.toString||"string"!=typeof (e+""))&&(!w(r)||r instanceof r)?Ct?(Zt(e,function(t,r){return n=!ot.call(e,r),i}),n===i):(Zt(e,function(e,t){n=t}),n===i||ot.call(e,n)):n}function d(e,t){return function(n,r,i){return e.call(t,n,r,i)}}function v(){}function m(e,t){if(V.test(t))return"<e%-"+t+"%>";var n=it.length;return it[n]="'+__e("+t+")+'",rt+n}function g(e,t,n,r){return e=it.length,t?it[e]="'+__e("+
|
||||
t+")+'":r?it[e]="';"+r+";__p+='":n&&(it[e]="'+((__t=("+n+"))==null?'':__t)+'"),rt+e}function y(e,t){if(V.test(t))return"<e%="+t+"%>";var n=it.length;return it[n]="'+((__t=("+t+"))==null?'':__t)+'",rt+n}function b(e){return lt.call(e)==vt}function w(e){return"function"==typeof e}function E(e,t,s,o,u){if(e==r)return e;s&&(t=i),u||(u={d:r}),u.d==r&&(u.d=!(!q.clone&&!U.clone&&!z.clone));if(((s=Ft[typeof e])||u.d)&&e.clone&&w(e.clone))return u.d=r,e.clone(t);if(s){var a=lt.call(e);if(!Bt[a]||Lt&&b(e))
|
||||
return e;var f=a==mt,s=f||(a==wt?p(e,n):s)}if(!s||!t)return s?f?ft.call(e):Yt({},e):e;s=e.constructor;switch(a){case gt:return new s(e==n);case yt:return new s(+e);case bt:case St:return new s(e);case Et:return s(e.source,Q.exec(e))}o||(o=[]);for(a=o.length;a--;)if(o[a].c==e)return o[a].d;var a=e.length,l=f?s(a):{};o.push({d:l,c:e});if(f)for(f=-1;++f<a;)l[f]=E(e[f],t,r,o,u);else en(e,function(e,n){l[n]=E(e,t,r,o,u)});return l}function S(e,t,s,o){if(e==r||t==r)return e===t;o||(o={value:r}),o.value==
|
||||
r&&(o.value=!(!q.isEqual&&!U.isEqual&&!z.isEqual));if(Ft[typeof e]||Ft[typeof t]||o.value){e._chain&&(e=e._wrapped),t._chain&&(t=t._wrapped);if(e.isEqual&&w(e.isEqual))return o.value=r,e.isEqual(t);if(t.isEqual&&w(t.isEqual))return o.value=r,t.isEqual(e)}if(e===t)return 0!==e||1/e==1/t;var u=lt.call(e);if(u!=lt.call(t))return i;switch(u){case gt:case yt:return+e==+t;case bt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case Et:case St:return e==t+""}var a=Ht[u];if(Lt&&!a&&(a=b(e))&&!b(t)||!a&&(u!=wt||Mt&&
|
||||
("function"!=typeof e.toString&&"string"==typeof (e+"")||"function"!=typeof t.toString&&"string"==typeof (t+""))))return i;s||(s=[]);for(u=s.length;u--;)if(s[u]==e)return n;var u=-1,f=n,l=0;s.push(e);if(a){l=e.length;if(f=l==t.length)for(;l--&&(f=S(e[l],t[l],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!w(a)||!(a instanceof a&&w(f)&&f instanceof f)))return i;for(var c in e)if(ot.call(e,c)&&(l++,!ot.call(t,c)||!S(e[c],t[c],s,o)))return i;for(c in t)if(ot.call(t,c)&&!(l--))return i;if(
|
||||
Nt)for(;7>++u;)if(c=nt[u],ot.call(e,c)&&(!ot.call(t,c)||!S(e[c],t[c],s,o)))return i;return n}function x(e,t,n,r){if(!e)return n;var i=e.length,s=3>arguments.length;r&&(t=d(t,r));if(-1<i&&i===i>>>0){var o=Ot&<.call(e)==St?e.split(""):e;for(i&&s&&(n=o[--i]);i--;)n=t(n,o[i],i,e);return n}o=rn(e);for((i=o.length)&&s&&(n=e[o[--i]]);i--;)s=o[i],n=t(n,e[s],s,e);return n}function T(e,t,n){if(e)return t==r||n?e[0]:ft.call(e,0,t)}function N(e,t){var n=[];if(!e)return n;for(var r,i=-1,s=e.length;++i<s;)r=
|
||||
e[i],Jt(r)?ut.apply(n,t?r:N(r)):n.push(r);return n}function C(e,t,n){if(!e)return-1;var r=-1,i=e.length;if(n){if("number"!=typeof n)return r=A(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 k(e,t,n){var r=-Infinity,i=r;if(!e)return i;var s=-1,o=e.length;if(!t){for(;++s<o;)e[s]>i&&(i=e[s]);return i}for(n&&(t=d(t,n));++s<o;)n=t(e[s],s,e),n>r&&(r=n,i=e[s]);return i}function L(e,t,n){return e?ft.call(e,t==r||n?1:t):[]}function A(e,t,n,r){if(!e)return 0
|
||||
;var i=0,s=e.length;if(n){r&&(n=M(n,r));for(t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r}else for(;i<s;)r=i+s>>>1,e[r]<t?i=r+1:s=r;return i}function O(e,t,n,r){var s=[];if(!e)return s;var o=-1,u=e.length,a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n?r&&(n=d(n,r)):n=_;++o<u;)if(r=n(e[o],o,e),t?!o||a[a.length-1]!==r:0>C(a,r))a.push(r),s.push(e[o]);return s}function M(e,t){function n(){var o=arguments,u=t;return i||(e=t[r]),s.length&&(o=o.length?st.apply(s,o):s),this instanceof n?(v.prototype=e.prototype
|
||||
,u=new v,(o=e.apply(u,o))&&Ft[typeof o]?o:u):e.apply(u,o)}var r,i=w(e);if(i){if(Dt||ct&&2<arguments.length)return ct.call.apply(ct,arguments)}else r=t,t=e;var s=ft.call(arguments,2);return n}function _(e){return e}function D(e){cn(tn(e),function(t){var r=s[t]=e[t];o.prototype[t]=function(){var e=[this._wrapped];return arguments.length&&ut.apply(e,arguments),e=r.apply(s,e),this._chain&&(e=new o(e),e._chain=n),e}})}var n=!0,r=null,i=!1,P,H,B,j,F="object"==typeof exports&&exports&&("object"==typeof
|
||||
global&&global&&global==global.global&&(e=global),exports),I=Array.prototype,q=Boolean.prototype,R=Object.prototype,U=Number.prototype,z=String.prototype,W=0,X=e._,V=/[-+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,$=/\b__p\+='';/g,J=/\b(__p\+=)''\+/g,K=/(__e\(.*?\)|\b__t\))\+'';/g,Q=/\w*$/,G=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,Y=RegExp("^"+(R.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),Z=/__token__(\d+)/g,et=/[&<"']/g
|
||||
,tt=/['\n\r\t\u2028\u2029\\]/g,nt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),rt="__token__",it=[],st=I.concat,ot=R.hasOwnProperty,ut=I.push,at=R.propertyIsEnumerable,ft=I.slice,lt=R.toString,ct=Y.test(ct=ft.bind)&&ct,ht=Y.test(ht=Array.isArray)&&ht,pt=e.isFinite,dt=Y.test(dt=Object.keys)&&dt,vt="[object Arguments]",mt="[object Array]",gt="[object Boolean]",yt="[object Date]",bt="[object Number]",wt="[object Object]",Et="[object RegExp]"
|
||||
,St="[object String]",xt=e.clearTimeout,Tt=e.setTimeout,Nt,Ct,kt=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)kt=!n;Nt=4>(t+"").length,Ct="x"!=t[0]})(1);var Lt=!b(arguments),At="x"!=ft.call("x")[0],Ot="xx"!="x"[0]+Object("x")[0];try{var Mt=("[object Object]",lt.call(e.document||0)==wt)}catch(_t){}var Dt=ct&&/\n|Opera/.test(ct+lt.call(e.opera)),Pt=dt&&/^.+$|true/.test(dt+!!e.attachEvent),Ht={"[object Arguments]":n,"[object Array]"
|
||||
:n,"[object Boolean]":i,"[object Date]":i,"[object Function]":i,"[object Number]":i,"[object Object]":i,"[object RegExp]":i,"[object String]":n},Bt={"[object Arguments]":i,"[object Array]":n,"[object Boolean]":n,"[object Date]":n,"[object Function]":i,"[object Number]":n,"[object Object]":n,"[object RegExp]":n,"[object String]":n},jt={"&":"&","<":"<",'"':""","'":"'"},Ft={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},It={"\\":"\\","'":"'","\n":"n","\r"
|
||||
:"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:"obj"};var qt={a:"b,a,w",j:"b",q:"if(!a)a=f;else if(w)a=i(a,w)",i:"if(a(y,g,b)===false)return s"},Rt={j:"{}",q:"var o;if(typeof a!='function'){var ii=a;a=function(y){return y[ii]}}else if(w)a=i(a,w)",i:"o=a(y,g,b);(e.call(s,o)?s[o]++:s[o]=1)"},Ut={j:"true",i:"if(!a(y,g,b))return!s"},zt={r:i,s:i,a:"l",j:"l",q:"for(var B=1,C=arguments.length;B<C;B++){if(h=arguments[B]){"
|
||||
,i:"s[g]=y",e:"}}"},Wt={j:"[]",i:"a(y,g,b)&&s.push(y)"},Xt={q:"if(w)a=i(a,w)"},Vt={i:{l:qt.i}},$t={j:"",f:"if(!b)return[]",d:{b:"s=Array(j)",l:"s="+(Pt?"Array(j)":"[]")},i:{b:"s[g]=a(y,g,b)",l:"s"+(Pt?"[m]=":".push")+"(a(y,g,b))"}};Lt&&(b=function(e){return!!e&&!!ot.call(e,"callee")});var Jt=ht||function(e){return lt.call(e)==mt};w(/x/)&&(w=function(e){return"[object Function]"==lt.call(e)});var Kt=a({a:"l",f:"if(!(l&&Y[typeof l]))throw TypeError()",j:"[]",i:"s.push(g)"}),Qt=a(zt,{i:"if(s[g]==null)"+
|
||||
zt.i}),Gt=a({r:i,a:"l",j:"{}",q:"var r=c.apply(E,arguments)",i:"if(N(r,g)<0)s[g]=y"}),Yt=a(zt),Zt=a(qt,Xt,Vt,{r:i}),en=a(qt,Xt,Vt),tn=a({r:i,a:"l",j:"[]",i:"if(T(y))s.push(g)",e:"s.sort()"}),nn=a({a:"y",j:"true",q:"var H=x.call(y),j=y.length;if(D[H]"+(Lt?"||P(y)":"")+"||(H==X&&j>-1&&j===j>>>0&&T(y.splice)))return!j",i:{l:"return false"}}),rn=dt?function(e){return"function"==typeof e&&at.call(e,"prototype")?Kt(e):dt(e)}:Kt,sn=a({a:"l",j:"[]",i:"s.push(y)"}),on=a({a:"b,hh",j:"false",o:i,d:{b:"if(x.call(h)==v)return b.indexOf(hh)>-1"
|
||||
},i:"if(y===hh)return true"}),un=a(qt,Rt),an=a(qt,Ut),fn=a(qt,Wt),ln=a(qt,Xt,{j:"",i:"if(a(y,g,b))return y"}),cn=a(qt,Xt),hn=a(qt,Rt,{i:"o=a(y,g,b);(e.call(s,o)?s[o]:s[o]=[]).push(y)"}),pn=a($t,{a:"b,V",q:"var A=u.call(arguments,2),S=typeof V=='function'",i:{b:"s[g]=(S?V:y[V]).apply(y,A)",l:"s"+(Pt?"[m]=":".push")+"((S?V:y[V]).apply(y,A))"}}),dn=a(qt,$t),vn=a(zt,{a:"l,ee,O,ff",q:"var J,L,Q,gg,dd=O==U;if(!dd)ff=[];for(var B=1,C=dd?2:arguments.length;B<C;B++){if(h=arguments[B]){",i:"if(y&&((Q=R(y))||U(y))){L=false;gg=ff.length;while(gg--)if(L=ff[gg].c==y)break;if(L){s[g]=ff[gg].d}else{J=(J=s[g])&&Q?(R(J)?J:[]):(U(J)?J:{});ff.push({d:J,c:y});s[g]=G(J,y,U,ff)}}else if(y!=null)s[g]=y"
|
||||
}),mn=a($t,{a:"b,bb",i:{b:"s[g]=y[bb]",l:"s"+(Pt?"[m]=":".push")+"(y[bb])"}}),gn=a({a:"b,a,z,w",j:"z",q:"var W=arguments.length<3;if(w)a=i(a,w)",d:{b:"if(W)s=b[++g]"},i:{b:"s=a(s,y,g,b)",l:"s=W?(W=false,y):a(s,y,g,b)"}}),yn=a(qt,Wt,{i:"!"+Wt.i}),bn=a(qt,Ut,{j:"false",i:Ut.i.replace("!","")}),wn=a(qt,Rt,$t,{i:{b:"s[g]={a:a(y,g,b),b:g,d:y}",l:"s"+(Pt?"[m]=":".push")+"({a:a(y,g,b),b:g,d:y})"},e:"s.sort(I);j=s.length;while(j--)s[j]=s[j].d"}),En=a(Wt,{a:"b,aa",q:"var Z,o,q,r=[];K(aa,function(y,o){r.push(o)});var cc=r.length"
|
||||
,i:"for(Z=true,q=0;q<cc;q++){o=r[q];if(!(Z=y[o]===aa[o]))break}if(Z)s.push(y)"}),Sn=a({r:i,s:i,a:"l",j:"l",q:"var M=arguments,j=M.length;if(j>1){for(var g=1;g<j;g++)s[M[g]]=F(s[M[g]],s);return s}",i:"if(T(s[g]))s[g]=F(s[g],s)"});s.VERSION="0.5.0",s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=M,s.bindAll=Sn,s.chain=function(e){return e=new o(e),e._chain=n,e},s.clone=E,s.compact=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length;++n<r;)e[n
|
||||
]&&t.push(e[n]);return t},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=on,s.countBy=un,s.debounce=function(e,t,n){function i(){a=r,n||e.apply(u,s)}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,xt(a),a=Tt(i,t),r&&(o=e.apply(u,s)),o}},s.defaults=Qt,s.defer=function(e){var n=ft.call(arguments,1);return Tt(function(){return e.apply(t,n)},1)},s.delay=function(e,n){var r=ft.call(arguments
|
||||
,2);return Tt(function(){return e.apply(t,r)},n)},s.difference=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length,i=st.apply(t,arguments),i=u(i,r);++n<r;)i(e[n])||t.push(e[n]);return t},s.drop=Gt,s.escape=function(e){return e==r?"":(e+"").replace(et,h)},s.every=an,s.extend=Yt,s.filter=fn,s.find=ln,s.first=T,s.flatten=N,s.forEach=cn,s.forIn=Zt,s.forOwn=en,s.functions=tn,s.groupBy=hn,s.has=function(e,t){return ot.call(e,t)},s.identity=_,s.indexOf=C,s.initial=function(e,t,n){return e?ft.call
|
||||
(e,0,-(t==r||n?1:t)):[]},s.intersection=function(e){var t=[];if(!e)return t;for(var n,r=-1,i=e.length,s=ft.call(arguments,1),o=[];++r<i;)n=e[r],0>C(t,n)&&an(s,function(e,t){return(o[t]||(o[t]=u(e)))(n)})&&t.push(n);return t},s.invoke=pn,s.isArguments=b,s.isArray=Jt,s.isBoolean=function(e){return e===n||e===i||lt.call(e)==gt},s.isElement=function(e){return!!e&&1==e.nodeType},s.isEmpty=nn,s.isEqual=S,s.isFinite=function(e){return pt(e)&<.call(e)==bt},s.isFunction=w,s.isNaN=function(e){return lt.call
|
||||
(e)==bt&&e!=+e},s.isNull=function(e){return e===r},s.isObject=function(e){return e&&Ft[typeof e]},s.isUndefined=function(e){return e===t},s.keys=rn,s.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:ft.call(e,-t||i)}},s.lastIndexOf=function(e,t,n){if(!e)return-1;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},s.map=dn,s.max=k,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments
|
||||
[0];return ot.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=vn,s.min=function(e,t,n){var r=Infinity,i=r;if(!e)return i;var s=-1,o=e.length;if(!t){for(;++s<o;)e[s]<i&&(i=e[s]);return i}for(n&&(t=d(t,n));++s<o;)n=t(e[s],s,e),n<r&&(r=n,i=e[s]);return i},s.mixin=D,s.noConflict=function(){return e._=X,this},s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.partial=function(e){var t=ft.call(arguments,1),n=t.length;return function(){var r;return r=
|
||||
arguments,r.length&&(t.length=n,ut.apply(t,r)),r=1==t.length?e.call(this,t[0]):e.apply(this,t),t.length=n,r}},s.pick=function(e){for(var t,n=0,r=st.apply(I,arguments),i=r.length,s={};++n<i;)t=r[n],t in e&&(s[t]=e[t]);return s},s.pluck=mn,s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=Math.max(0,Math.ceil((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reduce=gn,s.reduceRight=x,s.reject=yn,s.rest=L,s.result=function(e,t){if(!e)return r;var n=e[t];return w(n)?e[t]():n},s
|
||||
.shuffle=function(e){if(!e)return[];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},s.size=function(e){if(!e)return 0;var t=lt.call(e),n=e.length;return Ht[t]||Lt&&b(e)||t==wt&&-1<n&&n===n>>>0&&w(e.splice)?n:rn(e).length},s.some=bn,s.sortBy=wn,s.sortedIndex=A,s.tap=function(e,t){return t(e),e},s.template=function(e,t,n){n||(n={});var o,u;o=n.escape;var a=n.evaluate,f=n.interpolate,h=s.templateSettings,n=n.variable;o==r&&(o=h.escape),a==r&&
|
||||
(a=h.evaluate||i),f==r&&(f=h.interpolate),o&&(e=e.replace(o,m)),f&&(e=e.replace(f,y)),a!=P&&(P=a,j=RegExp("<e%-([\\s\\S]+?)%>|<e%=([\\s\\S]+?)%>"+(a?"|"+a.source:""),"g")),o=it.length,e=e.replace(j,g),o=o!=it.length,e="__p += '"+e.replace(tt,c).replace(Z,l)+"';",it.length=0,n||(n=h.variable||H||"obj",o?e="with("+n+"){"+e+"}":(n!=H&&(H=n,B=RegExp("(\\(\\s*)"+n+"\\."+n+"\\b","g")),e=e.replace(G,"$&"+n+".").replace(B,"$1__d"))),e=(o?e.replace($,""):e).replace(J,"$1").replace(K,"$1;"),e="function("+n+"){"+
|
||||
n+"||("+n+"={});var __t,__p='',__e=_.escape"+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":",__d="+n+"."+n+"||"+n+";")+e+"return __p}";try{u=Function("_","return "+e)(s)}catch(p){u=function(){throw p}}return t?u(t):(u.source=e,u)},s.throttle=function(e,t){function n(){a=new Date,u=r,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?(a=r,s=e.apply(o,i)):u||(u=Tt(n,f)),s}},s.times=function(e,t,n){var r=-1;if(n)for(;++
|
||||
r<e;)t.call(n,r);else for(;++r<e;)t(r)},s.toArray=function(e){if(!e)return[];if(e.toArray&&w(e.toArray))return e.toArray();var t=e.length;return-1<t&&t===t>>>0?(At?lt.call(e)==St:"string"==typeof e)?e.split(""):ft.call(e):sn(e)},s.union=function(){for(var e=-1,t=[],n=st.apply(t,arguments),r=n.length;++e<r;)0>C(t,n[e])&&t.push(n[e]);return t},s.uniq=O,s.uniqueId=function(e){var t=W++;return e?e+t:t},s.values=sn,s.where=En,s.without=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length,i=u(arguments
|
||||
,1,20);++n<r;)i(e[n])||t.push(e[n]);return t},s.wrap=function(e,t){return function(){var n=[e];return arguments.length&&ut.apply(n,arguments),t.apply(this,n)}},s.zip=function(e){if(!e)return[];for(var t=-1,n=k(mn(arguments,"length")),r=Array(n);++t<n;)r[t]=mn(arguments,t);return r},s.zipObject=function(e,t){if(!e)return{};var n=-1,r=e.length,i={};for(t||(t=[]);++n<r;)i[e[n]]=t[n];return i},s.all=an,s.any=bn,s.collect=dn,s.detect=ln,s.each=cn,s.foldl=gn,s.foldr=x,s.head=T,s.include=on,s.inject=gn,
|
||||
s.methods=tn,s.select=fn,s.tail=L,s.take=T,s.unique=O,cn({Date:yt,Number:bt,RegExp:Et,String:St},function(e,t){s["is"+t]=function(t){return lt.call(t)==e}}),o.prototype=s.prototype,D(s),o.prototype.chain=function(){return this._chain=n,this},o.prototype.value=function(){return this._wrapped},cn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=I[e];o.prototype[e]=function(){var e=this._wrapped;return t.apply(e,arguments),e.length===0&&delete e[0],this._chain&&(e=new o(e),e
|
||||
._chain=n),e}}),cn(["concat","join","slice"],function(e){var t=I[e];o.prototype[e]=function(){var e=t.apply(this._wrapped,arguments);return this._chain&&(e=new o(e),e._chain=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):F?"object"==typeof module&&module&&module.t==F?(module.t=s)._=s:F._=s:e._=s})(this);
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "lodash",
|
||||
"version": "0.4.2",
|
||||
"description": "A drop-in replacement for Underscore.js that delivers performance improvements, bug fixes, and additional features.",
|
||||
"version": "0.5.0",
|
||||
"description": "A drop-in replacement for Underscore.js delivering performance, bug fixes, and additional features.",
|
||||
"homepage": "http://lodash.com",
|
||||
"main": "lodash",
|
||||
"keywords": [
|
||||
@@ -21,7 +21,7 @@
|
||||
],
|
||||
"author": {
|
||||
"name": "John-David Dalton",
|
||||
"email": "john@fusejs.com",
|
||||
"email": "john.david.dalton@gmail.com",
|
||||
"web": "http://allyoucanleet.com/"
|
||||
},
|
||||
"bugs": {
|
||||
@@ -42,6 +42,9 @@
|
||||
"node",
|
||||
"rhino"
|
||||
],
|
||||
"jam": {
|
||||
"main": "lodash.min.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node build",
|
||||
"test": "node test/test"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<script>
|
||||
var lodash = _.noConflict();
|
||||
</script>
|
||||
<script src="../vendor/underscore/underscore.js"></script>
|
||||
<script src="../vendor/underscore/underscore-min.js"></script>
|
||||
<script src="../vendor/platform.js/platform.js"></script>
|
||||
<script src="../vendor/benchmark.js/benchmark.js"></script>
|
||||
<script src="../vendor/firebug-lite/src/firebug-lite-debug.js"></script>
|
||||
|
||||
89
perf/perf.js
89
perf/perf.js
@@ -132,11 +132,14 @@
|
||||
|
||||
// potentially expensive
|
||||
for (index = 0; index < this.count; index++) {
|
||||
bindAllObjects[index] = belt.clone(lodash);
|
||||
bindAllObjects[index] = belt.reduce(funcNames, function(object, funcName) {
|
||||
object[funcName] = lodash[funcName];
|
||||
return object;
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof groupBy != 'undefined') {
|
||||
if (typeof countBy != 'undefined') {
|
||||
var wordToNumber = {
|
||||
'one': 1,
|
||||
'two': 2,
|
||||
@@ -515,6 +518,62 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.clone` with an object')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.clone(object);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.clone(object);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.countBy` with `callback` iterating an array')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.countBy(numbers, function(num) { return num >> 1; });
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.countBy(numbers, function(num) { return num >> 1; });
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.countBy` with `property` name iterating an array')
|
||||
.add('Lo-Dash', {
|
||||
'fn': function() {
|
||||
lodash.countBy(words, 'length');
|
||||
},
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
.add('Underscore', {
|
||||
'fn': function() {
|
||||
_.countBy(words, 'length');
|
||||
},
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.countBy` with `callback` iterating an object')
|
||||
.add('Lo-Dash', {
|
||||
'fn': function() {
|
||||
lodash.countBy(wordToNumber, function(num) { return num >> 1; });
|
||||
},
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
.add('Underscore', {
|
||||
'fn': function() {
|
||||
_.countBy(wordToNumber, function(num) { return num >> 1; });
|
||||
},
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.difference`')
|
||||
.add('Lo-Dash', function() {
|
||||
@@ -749,13 +808,13 @@
|
||||
'fn': function() {
|
||||
lodash.groupBy(words, 'length');
|
||||
},
|
||||
'teardown': 'function groupBy(){}'
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
.add('Underscore', {
|
||||
'fn': function() {
|
||||
_.groupBy(words, 'length');
|
||||
},
|
||||
'teardown': 'function groupBy(){}'
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
);
|
||||
|
||||
@@ -765,13 +824,13 @@
|
||||
'fn': function() {
|
||||
lodash.groupBy(wordToNumber, function(num) { return num >> 1; });
|
||||
},
|
||||
'teardown': 'function groupBy(){}'
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
.add('Underscore', {
|
||||
'fn': function() {
|
||||
_.groupBy(wordToNumber, function(num) { return num >> 1; });
|
||||
},
|
||||
'teardown': 'function groupBy(){}'
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
);
|
||||
|
||||
@@ -1101,16 +1160,6 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.size` with an array')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.size(numbers);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.size(numbers);
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.size` with an object')
|
||||
.add('Lo-Dash', function() {
|
||||
@@ -1149,13 +1198,13 @@
|
||||
'fn': function() {
|
||||
lodash.sortBy(words, 'length');
|
||||
},
|
||||
'teardown': 'function groupBy(){}'
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
.add('Underscore', {
|
||||
'fn': function() {
|
||||
_.sortBy(words, 'length');
|
||||
},
|
||||
'teardown': 'function groupBy(){}'
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
);
|
||||
|
||||
@@ -1179,7 +1228,7 @@
|
||||
return wordToNumber[value];
|
||||
});
|
||||
},
|
||||
'teardown': 'function groupBy(){}'
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
.add('Underscore', {
|
||||
'fn': function() {
|
||||
@@ -1187,7 +1236,7 @@
|
||||
return wordToNumber[value];
|
||||
});
|
||||
},
|
||||
'teardown': 'function groupBy(){}'
|
||||
'teardown': 'function countBy(){}'
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -70,10 +70,10 @@
|
||||
|
||||
var label1 = document.createElement('label');
|
||||
label1.innerHTML =
|
||||
'<input name="norequire" type="checkbox">No RequireJS</label>';
|
||||
'<input name="norequire" type="checkbox">No RequireJS';
|
||||
|
||||
var label2 = document.createElement('label');
|
||||
label2.innerHTML = ' ' +
|
||||
label2.innerHTML = ' ' +
|
||||
'<select name="build">' +
|
||||
'<option value="dev">Developement</option>' +
|
||||
'<option value="prod">Production</option>' +
|
||||
|
||||
572
test/test.js
572
test/test.js
@@ -27,6 +27,17 @@
|
||||
_._ || _
|
||||
);
|
||||
|
||||
/** Used to pass falsey values to methods */
|
||||
var falsey = [
|
||||
,
|
||||
'',
|
||||
0,
|
||||
false,
|
||||
NaN,
|
||||
null,
|
||||
undefined
|
||||
];
|
||||
|
||||
/** Shortcut used to make object properties immutable */
|
||||
var freeze = Object.freeze;
|
||||
|
||||
@@ -77,6 +88,16 @@
|
||||
QUnit.module('lodash');
|
||||
|
||||
(function() {
|
||||
// ensure this test is executed before any other template tests to avoid false positives
|
||||
test('should initialize `reEvaluateDelimiter` correctly (test with production build)', function() {
|
||||
var data = { 'a': [1, 2] },
|
||||
settings = _.templateSettings;
|
||||
|
||||
_.templateSettings = { 'interpolate': /\{\{(.+?)\}\}/g };
|
||||
equal(_.template('{{ a.join(",") }}', data), '1,2');
|
||||
_.templateSettings = settings;
|
||||
});
|
||||
|
||||
test('supports loading lodash.js as the "lodash" module', function() {
|
||||
if (window.document && window.require) {
|
||||
equal((lodashModule || {}).moduleName, 'lodash');
|
||||
@@ -142,6 +163,104 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.clone');
|
||||
|
||||
(function() {
|
||||
function Klass() { this.a = 1; }
|
||||
Klass.prototype = { 'b': 1 };
|
||||
|
||||
var nonCloneable = {
|
||||
'an arguments object': arguments,
|
||||
'an element': window.document && document.body,
|
||||
'a function': Klass,
|
||||
'a Klass instance': new Klass
|
||||
};
|
||||
|
||||
var objects = {
|
||||
'an array': ['a', 'b', 'c', ''],
|
||||
'an array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 },
|
||||
'boolean': false,
|
||||
'boolean object': Object(false),
|
||||
'an object': { 'a': 0, 'b': 1, 'c': 3 },
|
||||
'an object with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
|
||||
'null': null,
|
||||
'a number': 3,
|
||||
'a number object': Object(3),
|
||||
'a regexp': /a/gim,
|
||||
'a string': 'a',
|
||||
'a string object': Object('a'),
|
||||
'undefined': undefined
|
||||
};
|
||||
|
||||
objects['an array'].length = 5;
|
||||
|
||||
_.forOwn(objects, function(object, key) {
|
||||
test('should deep clone ' + key + ' correctly', function() {
|
||||
var clone = _.clone(object, true);
|
||||
|
||||
if (object == null) {
|
||||
equal(clone, object);
|
||||
} else {
|
||||
deepEqual(clone.valueOf(), object.valueOf());
|
||||
}
|
||||
if (_.isObject(object)) {
|
||||
ok(clone !== object);
|
||||
} else {
|
||||
skipTest();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
_.forOwn(nonCloneable, function(object, key) {
|
||||
test('should not clone ' + key, function() {
|
||||
ok(_.clone(object) === object);
|
||||
ok(_.clone(object, true) === object);
|
||||
});
|
||||
});
|
||||
|
||||
test('should shallow clone when used as `callback` for `_.map`', function() {
|
||||
var expected = [{ 'a': [0] }, { 'b': [1] }],
|
||||
actual = _.map(expected, _.clone);
|
||||
|
||||
ok(actual != expected && actual.a == expected.a && actual.b == expected.b);
|
||||
});
|
||||
|
||||
test('should deep clone objects with circular references', function() {
|
||||
var object = {
|
||||
'foo': { 'b': { 'foo': { 'c': { } } } },
|
||||
'bar': { }
|
||||
};
|
||||
|
||||
object.foo.b.foo.c = object;
|
||||
object.bar.b = object.foo.b;
|
||||
|
||||
var clone = _.clone(object, true);
|
||||
ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.foo.c && clone !== object);
|
||||
});
|
||||
|
||||
test('should clone using Klass#clone', function() {
|
||||
var object = new Klass;
|
||||
Klass.prototype.clone = function() { return new Klass; };
|
||||
|
||||
var clone = _.clone(object);
|
||||
ok(clone !== object && clone instanceof Klass);
|
||||
|
||||
clone = _.clone(object, true);
|
||||
ok(clone !== object && clone instanceof Klass);
|
||||
|
||||
delete Klass.prototype.clone;
|
||||
});
|
||||
|
||||
test('should clone problem JScript properties (test in IE < 9)', function() {
|
||||
deepEqual(_.clone(shadowed), shadowed);
|
||||
ok(_.clone(shadowed) != shadowed);
|
||||
deepEqual(_.clone(shadowed, true), shadowed);
|
||||
ok(_.clone(shadowed, true) != shadowed);
|
||||
});
|
||||
}(1, 2, 3));
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.contains');
|
||||
|
||||
(function() {
|
||||
@@ -159,6 +278,21 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.countBy');
|
||||
|
||||
(function() {
|
||||
test('should only add elements to own, not inherited, properties', function() {
|
||||
var actual = _.countBy([4.2, 6.1, 6.4], function(num) {
|
||||
return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
|
||||
});
|
||||
|
||||
deepEqual(actual.constructor, 1);
|
||||
deepEqual(actual.hasOwnProperty, 2);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.debounce');
|
||||
|
||||
(function() {
|
||||
@@ -191,6 +325,34 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.drop');
|
||||
|
||||
(function() {
|
||||
var object = { 'a': 1, 'b': 2, 'c': 3 },
|
||||
actual = { 'b': 2 };
|
||||
|
||||
test('should accept individual property names', function() {
|
||||
deepEqual(_.drop(object, 'a', 'c'), actual);
|
||||
});
|
||||
|
||||
test('should accept an array of property names', function() {
|
||||
deepEqual(_.drop(object, ['a', 'c']), actual);
|
||||
});
|
||||
|
||||
test('should accept mixes of individual and arrays of property names', function() {
|
||||
deepEqual(_.drop(object, ['a'], 'c'), actual);
|
||||
});
|
||||
|
||||
test('should iterate over inherited properties', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype = object;
|
||||
|
||||
deepEqual(_.drop(new Foo, 'a', 'c'), actual);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.escape');
|
||||
|
||||
(function() {
|
||||
@@ -267,6 +429,20 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.filter');
|
||||
|
||||
(function() {
|
||||
test('should not modify the resulting value from within `callback`', function() {
|
||||
var actual = _.filter([0], function(value, index, array) {
|
||||
return (array[index] = 1);
|
||||
});
|
||||
|
||||
deepEqual(actual, [0]);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.find');
|
||||
|
||||
(function() {
|
||||
@@ -318,6 +494,10 @@
|
||||
|
||||
_.forEach(object, function(value, key) { keys.push(key); });
|
||||
deepEqual(keys, ['length']);
|
||||
|
||||
keys = []; object.length = Math.pow(2, 32);
|
||||
_.forEach(object, function(value, key) { keys.push(key); });
|
||||
deepEqual(keys, ['length']);
|
||||
});
|
||||
|
||||
_.each([
|
||||
@@ -399,34 +579,55 @@
|
||||
});
|
||||
});
|
||||
|
||||
_.each(['forEach', 'forIn', 'forOwn'], function(methodName) {
|
||||
var func = _[methodName];
|
||||
QUnit.module('lodash.' + methodName + ' can exit early');
|
||||
|
||||
test('can exit early when iterating arrays', function() {
|
||||
var array = [1, 2, 3],
|
||||
values = [];
|
||||
|
||||
func(array, function(value) { values.push(value); return false; });
|
||||
deepEqual(values, [1]);
|
||||
});
|
||||
|
||||
test('can exit early when iterating objects', function() {
|
||||
var object = { 'a': 1, 'b': 2, 'c': 3 },
|
||||
values = [];
|
||||
|
||||
func(object, function(value) { values.push(value); return false; });
|
||||
equal(values.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.groupBy');
|
||||
|
||||
(function() {
|
||||
test('supports the `thisArg` argument', function() {
|
||||
var actual = _.groupBy([1.3, 2.1, 2.4], function(num) {
|
||||
var actual = _.groupBy([4.2, 6.1, 6.4], function(num) {
|
||||
return this.floor(num);
|
||||
}, Math);
|
||||
|
||||
deepEqual(actual, { '1': [1.3], '2': [2.1, 2.4] });
|
||||
deepEqual(actual, { '4': [4.2], '6': [6.1, 6.4] });
|
||||
});
|
||||
|
||||
test('should only add elements to own, not inherited, properties', function() {
|
||||
var actual = _.groupBy([1.3, 2.1, 2.4], function(num) {
|
||||
return Math.floor(num) > 1 ? 'hasOwnProperty' : 'constructor';
|
||||
var actual = _.groupBy([4.2, 6.1, 6.4], function(num) {
|
||||
return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
|
||||
});
|
||||
|
||||
deepEqual(actual.constructor, [1.3]);
|
||||
deepEqual(actual.hasOwnProperty, [2.1, 2.4]);
|
||||
deepEqual(actual.constructor, [4.2]);
|
||||
deepEqual(actual.hasOwnProperty, [6.1, 6.4]);
|
||||
});
|
||||
|
||||
test('should work with an object for `collection`', function() {
|
||||
var actual = _.groupBy({ 'a': 1.3, 'b': 2.1, 'c': 2.4 }, function(num) {
|
||||
var actual = _.groupBy({ 'a': 4.2, 'b': 6.1, 'c': 6.4 }, function(num) {
|
||||
return Math.floor(num);
|
||||
});
|
||||
|
||||
deepEqual(actual, { '1': [1.3], '2': [2.1, 2.4] });
|
||||
deepEqual(actual, { '4': [4.2], '6': [6.1, 6.4] });
|
||||
});
|
||||
}());
|
||||
|
||||
@@ -493,6 +694,8 @@
|
||||
QUnit.module('lodash.isEmpty');
|
||||
|
||||
(function() {
|
||||
var args = arguments;
|
||||
|
||||
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
|
||||
equal(_.isEmpty(shadowed), false);
|
||||
});
|
||||
@@ -505,16 +708,93 @@
|
||||
Foo.prototype = { 'a': 1 };
|
||||
equal(_.isEmpty(Foo), true);
|
||||
});
|
||||
}());
|
||||
|
||||
test('should work with an object that has a `length` property', function() {
|
||||
equal(_.isEmpty({ 'length': 0 }), false);
|
||||
});
|
||||
|
||||
test('should work with jQuery/MooTools DOM query collections', function() {
|
||||
function Foo(elements) { Array.prototype.push.apply(this, elements); }
|
||||
Foo.prototype = { 'length': 0, 'splice': Array.prototype.splice };
|
||||
|
||||
equal(_.isEmpty(new Foo([])), true);
|
||||
});
|
||||
|
||||
test('should work with `arguments` objects (test in IE < 9)', function() {
|
||||
equal(_.isEmpty(args), false);
|
||||
});
|
||||
}(1, 2, 3));
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.isEqual');
|
||||
|
||||
(function() {
|
||||
test('should work with `arguments` objects (test in IE < 9)', function() {
|
||||
var args1 = (function() { return arguments; }(1, 2, 3)),
|
||||
args2 = (function() { return arguments; }(1, 2, 3)),
|
||||
args3 = (function() { return arguments; }(1, 2));
|
||||
|
||||
equal(_.isEqual(args1, args2), true);
|
||||
equal(_.isEqual(args1, args3), false);
|
||||
});
|
||||
|
||||
test('should respect custom `isEqual` result despite objects strict equaling each other', function() {
|
||||
var object = { 'isEqual': function() { return false; } };
|
||||
equal(_.isEqual(object, object), false);
|
||||
});
|
||||
|
||||
test('should use custom `isEqual` methods on primitives', function() {
|
||||
Boolean.prototype.isEqual = function() { return true; };
|
||||
equal(_.isEqual(true, false), true);
|
||||
delete Boolean.prototype.isEqual;
|
||||
});
|
||||
|
||||
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
|
||||
equal(_.isEqual(shadowed, {}), false);
|
||||
});
|
||||
|
||||
test('should return `true` for like-objects from different documents', function() {
|
||||
if (window.document) {
|
||||
var body = document.body,
|
||||
iframe = document.createElement('iframe'),
|
||||
object = { 'a': 1, 'b': 2, 'c': 3 };
|
||||
|
||||
body.appendChild(iframe);
|
||||
var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
|
||||
idoc.write("<script>parent._._object = { 'a': 1, 'b': 2, 'c': 3 };<\/script>");
|
||||
idoc.close();
|
||||
}
|
||||
// ensure `_._object` is assigned (unassigned in Opera 10.00)
|
||||
if (_._object) {
|
||||
equal(_.isEqual(object, _._object), true);
|
||||
body.removeChild(iframe);
|
||||
delete _._object;
|
||||
}
|
||||
else {
|
||||
skipTest();
|
||||
}
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.isObject');
|
||||
|
||||
(function() {
|
||||
test('should avoid V8 bug #2291', function() {
|
||||
// trigger V8 bug
|
||||
// http://code.google.com/p/v8/issues/detail?id=2291
|
||||
var obj = {},
|
||||
str = 'foo';
|
||||
|
||||
// 1: Useless comparison statement, this is half the trigger
|
||||
obj == obj;
|
||||
// 2: Initial check with object, this is the other half of the trigger
|
||||
_.isObject(obj);
|
||||
|
||||
equal(_.isObject(str), false);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -532,6 +812,12 @@
|
||||
QUnit.module('lodash.keys');
|
||||
|
||||
(function() {
|
||||
var args = arguments;
|
||||
|
||||
test('should work with `arguments` objects (test in IE < 9)', function() {
|
||||
deepEqual(_.keys(args), ['0', '1', '2']);
|
||||
});
|
||||
|
||||
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype.a = 1;
|
||||
@@ -553,7 +839,7 @@
|
||||
Foo.prototype = { 'c': 3 };
|
||||
deepEqual(_.keys(Foo), expected);
|
||||
});
|
||||
}());
|
||||
}(1, 2, 3));
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
@@ -590,6 +876,87 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.merge');
|
||||
|
||||
(function() {
|
||||
var args = arguments;
|
||||
|
||||
test('should merge `source` into the destination object', function() {
|
||||
var stooges = [
|
||||
{ 'name': 'moe' },
|
||||
{ 'name': 'larry' }
|
||||
];
|
||||
|
||||
var ages = [
|
||||
{ 'age': 40 },
|
||||
{ 'age': 50 }
|
||||
];
|
||||
|
||||
var heights = [
|
||||
{ 'height': '5\'4"' },
|
||||
{ 'height': '5\'5"' },
|
||||
];
|
||||
|
||||
var expected = [
|
||||
{ 'name': 'moe', 'age': 40, 'height': '5\'4"' },
|
||||
{ 'name': 'larry', 'age': 50, 'height': '5\'5"' }
|
||||
];
|
||||
|
||||
deepEqual(_.merge(stooges, ages, heights), expected);
|
||||
});
|
||||
|
||||
test('should merge sources containing circular references', function() {
|
||||
var object = {
|
||||
'foo': { 'a': 1 },
|
||||
'bar': { 'a': 2 }
|
||||
};
|
||||
|
||||
var source = {
|
||||
'foo': { 'b': { 'foo': { 'c': { } } } },
|
||||
'bar': { }
|
||||
};
|
||||
|
||||
source.foo.b.foo.c = source;
|
||||
source.bar.b = source.foo.b;
|
||||
|
||||
var actual = _.merge(object, source);
|
||||
|
||||
ok(actual.bar.b === actual.foo.b && actual.foo.b.foo.c === actual.foo.b.foo.c.foo.b.foo.c);
|
||||
});
|
||||
|
||||
test('should merge problem JScript properties (test in IE < 9)', function() {
|
||||
var object = [{
|
||||
'constructor': 1,
|
||||
'hasOwnProperty': 2,
|
||||
'isPrototypeOf': 3
|
||||
}];
|
||||
|
||||
var source = [{
|
||||
'propertyIsEnumerable': 4,
|
||||
'toLocaleString': 5,
|
||||
'toString': 6,
|
||||
'valueOf': 7
|
||||
}];
|
||||
|
||||
deepEqual(_.merge(object, source), [shadowed]);
|
||||
});
|
||||
|
||||
test('should not treat `arguments` objects as plain objects', function() {
|
||||
var object = {
|
||||
'args': args
|
||||
};
|
||||
|
||||
var source = {
|
||||
'args': { '3': 4 }
|
||||
};
|
||||
|
||||
var actual = _.merge(object, source);
|
||||
equal(_.isArguments(actual.args), false);
|
||||
});
|
||||
}(1, 2, 3));
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.partial');
|
||||
|
||||
(function() {
|
||||
@@ -632,6 +999,19 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.pick');
|
||||
|
||||
(function() {
|
||||
test('should iterate over inherited properties', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype = { 'a': 1, 'b': 2, 'c': 3 };
|
||||
|
||||
deepEqual(_.pick(new Foo, 'b'), { 'b': 2 });
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.pluck');
|
||||
|
||||
(function() {
|
||||
@@ -643,6 +1023,30 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.range');
|
||||
|
||||
(function() {
|
||||
var func = _.range;
|
||||
|
||||
test('should treat falsey `start` arguments as `0`', function() {
|
||||
_.each(falsey, function(value, index) {
|
||||
if (index) {
|
||||
deepEqual(_.range(value), []);
|
||||
deepEqual(_.range(value, 1), [0]);
|
||||
} else {
|
||||
deepEqual(_.range(), []);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('should coerce arguments to numbers', function() {
|
||||
var actual = [func('0',1), func('1'), func(0, 1, '1')];
|
||||
deepEqual(actual, [[0], [0], [0]]);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.reduceRight');
|
||||
|
||||
(function() {
|
||||
@@ -710,12 +1114,23 @@
|
||||
});
|
||||
|
||||
test('should allow a falsey `object` argument', function() {
|
||||
var func = _.size;
|
||||
try {
|
||||
var actual = [func(), func(undefined), func(null), func(false), func(0)];
|
||||
} catch(e) { }
|
||||
_.each(falsey, function(index, value) {
|
||||
try {
|
||||
var actual = index ? _.size(value) : _.size();
|
||||
} catch(e) { }
|
||||
equal(actual, 0);
|
||||
})
|
||||
});
|
||||
|
||||
deepEqual(actual, [0, 0, 0, 0, 0]);
|
||||
test('should work with an object that has a `length` property', function() {
|
||||
equal(_.size({ 'length': 3 }), 1);
|
||||
});
|
||||
|
||||
test('should work with jQuery/MooTools DOM query collections', function() {
|
||||
function Foo(elements) { Array.prototype.push.apply(this, elements); }
|
||||
Foo.prototype = { 'length': 0, 'splice': Array.prototype.splice };
|
||||
|
||||
equal(_.size(new Foo([1, 2, 3])), 3);
|
||||
});
|
||||
|
||||
test('should work with `arguments` objects (test in IE < 9)', function() {
|
||||
@@ -732,6 +1147,28 @@
|
||||
QUnit.module('lodash.sortBy');
|
||||
|
||||
(function() {
|
||||
test('should perform a stable sort (test in IE > 8, Opera, and V8)', function() {
|
||||
function Pair(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
var collection = [
|
||||
new Pair(1, 1), new Pair(1, 2),
|
||||
new Pair(1, 3), new Pair(1, 4),
|
||||
new Pair(1, 5), new Pair(1, 6),
|
||||
new Pair(2, 1), new Pair(2, 2),
|
||||
new Pair(2, 3), new Pair(2, 4),
|
||||
new Pair(2, 5), new Pair(2, 6)
|
||||
];
|
||||
|
||||
var actual = _.sortBy(collection, function(pair) {
|
||||
return pair.x;
|
||||
});
|
||||
|
||||
deepEqual(actual, collection);
|
||||
});
|
||||
|
||||
test('supports the `thisArg` argument', function() {
|
||||
var actual = _.sortBy([1, 2, 3], function(num) {
|
||||
return this.sin(num);
|
||||
@@ -855,6 +1292,19 @@
|
||||
ok(false);
|
||||
}
|
||||
});
|
||||
|
||||
test('should not error with IE conditional comments enabled (test with development build)', function() {
|
||||
var compiled = _.template(''),
|
||||
pass = true;
|
||||
|
||||
/*@cc_on @*/
|
||||
try {
|
||||
compiled();
|
||||
} catch(e) {
|
||||
pass = false;
|
||||
}
|
||||
ok(pass);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -945,6 +1395,54 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.where');
|
||||
|
||||
(function() {
|
||||
var array = [
|
||||
{ 'a': 1 },
|
||||
{ 'a': 1 },
|
||||
{ 'a': 1, 'b': 2 },
|
||||
{ 'a': 2, 'b': 2 },
|
||||
{ 'a': 3 }
|
||||
];
|
||||
|
||||
test('should filter by properties', function() {
|
||||
deepEqual(_.where(array, { 'a': 1 }), [{ 'a': 1 }, { 'a': 1 }, { 'a': 1, 'b': 2 }]);
|
||||
deepEqual(_.where(array, { 'a': 2 }), [{ 'a': 2, 'b': 2 }]);
|
||||
deepEqual(_.where(array, { 'a': 3 }), [{ 'a': 3 }]);
|
||||
deepEqual(_.where(array, { 'b': 1 }), []);
|
||||
deepEqual(_.where(array, { 'b': 2 }), [{ 'a': 1, 'b': 2 }, { 'a': 2, 'b': 2 }]);
|
||||
deepEqual(_.where(array, { 'a': 1, 'b': 2 }), [{ 'a': 1, 'b': 2 }]);
|
||||
});
|
||||
|
||||
test('should filter by inherited properties', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype = { 'b': 2 };
|
||||
|
||||
var properties = new Foo;
|
||||
properties.a = 1;
|
||||
|
||||
deepEqual(_.where(array, properties), [{ 'a': 1, 'b': 2 }]);
|
||||
});
|
||||
|
||||
test('should filter by problem JScript properties (test in IE < 9)', function() {
|
||||
var collection = [shadowed];
|
||||
deepEqual(_.where(collection, shadowed), [shadowed]);
|
||||
});
|
||||
|
||||
test('should work with an object for `collection`', function() {
|
||||
var collection = {
|
||||
'x': { 'a': 1 },
|
||||
'y': { 'a': 3 },
|
||||
'z': { 'a': 1, 'b': 2 }
|
||||
};
|
||||
|
||||
deepEqual(_.where(collection, { 'a': 1 }), [{ 'a': 1 }, { 'a': 1, 'b': 2 }]);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.zipObject');
|
||||
|
||||
(function() {
|
||||
@@ -1014,15 +1512,14 @@
|
||||
var func = _[methodName],
|
||||
pass = true;
|
||||
|
||||
try {
|
||||
func();
|
||||
func(undefined);
|
||||
func(null);
|
||||
func(false);
|
||||
func(0);
|
||||
} catch(e) {
|
||||
pass = false;
|
||||
}
|
||||
_.each(falsey, function(value, index) {
|
||||
try {
|
||||
index ? func() : func(value);
|
||||
} catch(e) {
|
||||
pass = false;
|
||||
}
|
||||
});
|
||||
|
||||
ok(pass, methodName + ' allows a falsey `array` argument');
|
||||
});
|
||||
});
|
||||
@@ -1053,23 +1550,18 @@
|
||||
identity = _.identity,
|
||||
pass = true;
|
||||
|
||||
try {
|
||||
if (/^(?:contains|toArray)$/.test(methodName)) {
|
||||
func();
|
||||
func(undefined);
|
||||
func(null);
|
||||
func(false);
|
||||
func(0);
|
||||
_.each(falsey, function(value, index) {
|
||||
try {
|
||||
if (/^(?:contains|toArray)$/.test(methodName)) {
|
||||
index ? func() : func(value);
|
||||
} else if (index) {
|
||||
func(value, identity);
|
||||
}
|
||||
} catch(e) {
|
||||
pass = false;
|
||||
}
|
||||
else {
|
||||
func(undefined, identity);
|
||||
func(null, identity);
|
||||
func(false, identity);
|
||||
func(0, identity);
|
||||
}
|
||||
} catch(e) {
|
||||
pass = false;
|
||||
}
|
||||
});
|
||||
|
||||
ok(pass, methodName + ' allows a falsey `collection` argument');
|
||||
});
|
||||
});
|
||||
|
||||
57
vendor/backbone/backbone.js
vendored
57
vendor/backbone/backbone.js
vendored
@@ -134,6 +134,9 @@
|
||||
|
||||
rest = [];
|
||||
events = events.split(eventSplitter);
|
||||
|
||||
// Fill up `rest` with the callback arguments. Since we're only copying
|
||||
// the tail of `arguments`, a loop is much faster than Array#slice.
|
||||
for (i = 1, length = arguments.length; i < length; i++) {
|
||||
rest[i - 1] = arguments[i];
|
||||
}
|
||||
@@ -295,7 +298,7 @@
|
||||
|
||||
// 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))) {
|
||||
if (!_.isEqual(prev[attr], val) || (_.has(now, attr) !== _.has(prev, attr))) {
|
||||
this.changed[attr] = val;
|
||||
if (!options.silent) this._pending[attr] = true;
|
||||
} else {
|
||||
@@ -432,7 +435,7 @@
|
||||
url: function() {
|
||||
var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError();
|
||||
if (this.isNew()) return base;
|
||||
return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
|
||||
return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
|
||||
},
|
||||
|
||||
// **parse** converts a response into the hash of attributes to be `set` on
|
||||
@@ -555,7 +558,7 @@
|
||||
var Collection = Backbone.Collection = function(models, options) {
|
||||
options || (options = {});
|
||||
if (options.model) this.model = options.model;
|
||||
if (options.comparator !== undefined) this.comparator = options.comparator;
|
||||
if (options.comparator !== void 0) this.comparator = options.comparator;
|
||||
this._reset();
|
||||
this.initialize.apply(this, arguments);
|
||||
if (models) this.reset(models, {silent: true, parse: options.parse});
|
||||
@@ -628,9 +631,7 @@
|
||||
// Merge in duplicate models.
|
||||
if (options.merge) {
|
||||
for (i = 0, length = dups.length; i < length; i++) {
|
||||
if (model = this._byId[dups[i].id]) {
|
||||
model.set(dups[i], options);
|
||||
}
|
||||
if (model = this._byId[dups[i].id]) model.set(dups[i], options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,7 +738,7 @@
|
||||
options || (options = {});
|
||||
if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
|
||||
var boundComparator = _.bind(this.comparator, this);
|
||||
if (this.comparator.length == 1) {
|
||||
if (this.comparator.length === 1) {
|
||||
this.models = this.sortBy(boundComparator);
|
||||
} else {
|
||||
this.models.sort(boundComparator);
|
||||
@@ -771,7 +772,7 @@
|
||||
// models to the collection instead of resetting.
|
||||
fetch: function(options) {
|
||||
options = options ? _.clone(options) : {};
|
||||
if (options.parse === undefined) options.parse = true;
|
||||
if (options.parse === void 0) options.parse = true;
|
||||
var collection = this;
|
||||
var success = options.success;
|
||||
options.success = function(resp, status, xhr) {
|
||||
@@ -842,9 +843,7 @@
|
||||
|
||||
// Internal method to remove a model's ties to a collection.
|
||||
_removeReference: function(model) {
|
||||
if (this == model.collection) {
|
||||
delete model.collection;
|
||||
}
|
||||
if (this === model.collection) delete model.collection;
|
||||
model.off('all', this._onModelEvent, this);
|
||||
},
|
||||
|
||||
@@ -853,10 +852,8 @@
|
||||
// events simply proxy through. "add" and "remove" events that originate
|
||||
// in other collections are ignored.
|
||||
_onModelEvent: function(event, model, collection, options) {
|
||||
if ((event == 'add' || event == 'remove') && collection != this) return;
|
||||
if (event == 'destroy') {
|
||||
this.remove(model, options);
|
||||
}
|
||||
if ((event === 'add' || event === 'remove') && collection !== this) return;
|
||||
if (event === 'destroy') this.remove(model, options);
|
||||
if (model && event === 'change:' + model.idAttribute) {
|
||||
delete this._byId[model.previous(model.idAttribute)];
|
||||
if (model.id != null) this._byId[model.id] = model;
|
||||
@@ -1029,6 +1026,9 @@
|
||||
var docMode = document.documentMode;
|
||||
var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
|
||||
|
||||
// Normalize root to always include trailing slash
|
||||
if (!trailingSlash.test(this.options.root)) this.options.root += '/';
|
||||
|
||||
if (oldIE && this._wantsHashChange) {
|
||||
this.iframe = Backbone.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
|
||||
this.navigate(fragment);
|
||||
@@ -1048,7 +1048,7 @@
|
||||
// opened by a non-pushState browser.
|
||||
this.fragment = fragment;
|
||||
var loc = this.location;
|
||||
var atRoot = (loc.pathname == this.options.root) && !loc.search;
|
||||
var atRoot = (loc.pathname.replace(/[^/]$/, '$&/') === this.options.root) && !loc.search;
|
||||
|
||||
// If we've started off with a route from a `pushState`-enabled browser,
|
||||
// but we're currently in a browser that doesn't support it...
|
||||
@@ -1065,9 +1065,7 @@
|
||||
this.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
|
||||
}
|
||||
|
||||
if (!this.options.silent) {
|
||||
return this.loadUrl();
|
||||
}
|
||||
if (!this.options.silent) return this.loadUrl();
|
||||
},
|
||||
|
||||
// Disable Backbone.history, perhaps temporarily. Not useful in a real app,
|
||||
@@ -1088,10 +1086,10 @@
|
||||
// calls `loadUrl`, normalizing across the hidden iframe.
|
||||
checkUrl: function(e) {
|
||||
var current = this.getFragment();
|
||||
if (current == this.fragment && this.iframe) {
|
||||
if (current === this.fragment && this.iframe) {
|
||||
current = this.getFragment(this.getHash(this.iframe));
|
||||
}
|
||||
if (current == this.fragment) return false;
|
||||
if (current === this.fragment) return false;
|
||||
if (this.iframe) this.navigate(current);
|
||||
this.loadUrl() || this.loadUrl(this.getHash());
|
||||
},
|
||||
@@ -1121,9 +1119,9 @@
|
||||
if (!History.started) return false;
|
||||
if (!options || options === true) options = {trigger: options};
|
||||
var frag = (fragment || '').replace(routeStripper, '');
|
||||
if (this.fragment == frag) return;
|
||||
if (this.fragment === frag) return;
|
||||
this.fragment = frag;
|
||||
var url = (frag.indexOf(this.options.root) != 0 ? this.options.root : '') + frag;
|
||||
var url = (frag.indexOf(this.options.root) !== 0 ? this.options.root : '') + frag;
|
||||
|
||||
// If pushState is available, we use it to set the fragment as a real URL.
|
||||
if (this._hasPushState) {
|
||||
@@ -1133,7 +1131,7 @@
|
||||
// fragment to store history.
|
||||
} else if (this._wantsHashChange) {
|
||||
this._updateHash(this.location, frag, options.replace);
|
||||
if (this.iframe && (frag != this.getFragment(this.getHash(this.iframe)))) {
|
||||
if (this.iframe && (frag !== this.getFragment(this.getHash(this.iframe)))) {
|
||||
// Opening and closing the iframe tricks IE7 and earlier to push a
|
||||
// history entry on hash-tag change. When replace is true, we don't
|
||||
// want this.
|
||||
@@ -1158,6 +1156,7 @@
|
||||
location.hash = fragment;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Backbone.View
|
||||
@@ -1291,8 +1290,8 @@
|
||||
_ensureElement: function() {
|
||||
if (!this.el) {
|
||||
var attrs = _.extend({}, getValue(this, 'attributes'));
|
||||
if (this.id) attrs.id = this.id;
|
||||
if (this.className) attrs['class'] = this.className;
|
||||
if (this.id) attrs.id = getValue(this, 'id');
|
||||
if (this.className) attrs['class'] = getValue(this, 'className');
|
||||
this.setElement(this.make(getValue(this, 'tagName'), attrs), false);
|
||||
} else {
|
||||
this.setElement(this.el, false);
|
||||
@@ -1303,9 +1302,7 @@
|
||||
|
||||
// The self-propagating extend function that Backbone classes use.
|
||||
var extend = function(protoProps, classProps) {
|
||||
var child = inherits(this, protoProps, classProps);
|
||||
child.extend = this.extend;
|
||||
return child;
|
||||
return inherits(this, protoProps, classProps);
|
||||
};
|
||||
|
||||
// Set up inheritance for the model, collection, and view.
|
||||
@@ -1352,7 +1349,7 @@
|
||||
}
|
||||
|
||||
// Ensure that we have the appropriate request data.
|
||||
if (!options.data && model && (method == 'create' || method == 'update')) {
|
||||
if (!options.data && model && (method === 'create' || method === 'update')) {
|
||||
params.contentType = 'application/json';
|
||||
params.data = JSON.stringify(model);
|
||||
}
|
||||
|
||||
52
vendor/backbone/test/router.js
vendored
52
vendor/backbone/test/router.js
vendored
@@ -20,9 +20,11 @@ $(document).ready(function() {
|
||||
_.extend(this, _.pick($('<a></a>', {href: href})[0],
|
||||
'href',
|
||||
'hash',
|
||||
'host',
|
||||
'search',
|
||||
'fragment',
|
||||
'pathname'
|
||||
'pathname',
|
||||
'protocol'
|
||||
));
|
||||
// In IE, anchor.pathname does not contain a leading slash though
|
||||
// window.location.pathname does.
|
||||
@@ -318,4 +320,52 @@ $(document).ready(function() {
|
||||
strictEqual(Backbone.history.fragment, 'x');
|
||||
});
|
||||
|
||||
test("Router: Normalize root.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root');
|
||||
Backbone.history = new Backbone.History({
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url) {
|
||||
strictEqual(url, '/root/fragment');
|
||||
}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
pushState: true,
|
||||
root: '/root',
|
||||
hashChange: false
|
||||
});
|
||||
Backbone.history.navigate('fragment');
|
||||
});
|
||||
|
||||
test("Router: Normalize root.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root#fragment');
|
||||
Backbone.history = new Backbone.History({
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url) {},
|
||||
replaceState: function(state, title, url) {
|
||||
strictEqual(url, 'http://example.com/root/fragment');
|
||||
}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
pushState: true,
|
||||
root: '/root'
|
||||
});
|
||||
});
|
||||
|
||||
test("Router: Normalize root.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root');
|
||||
Backbone.history = new Backbone.History({location: location});
|
||||
Backbone.history.loadUrl = function() { ok(true); };
|
||||
Backbone.history.start({
|
||||
pushState: true,
|
||||
root: '/root'
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
14
vendor/backbone/test/view.js
vendored
14
vendor/backbone/test/view.js
vendored
@@ -135,6 +135,20 @@ $(document).ready(function() {
|
||||
ok(!view.el);
|
||||
});
|
||||
|
||||
test("View: with className and id functions", 2, function() {
|
||||
var View = Backbone.View.extend({
|
||||
className: function() {
|
||||
return 'className';
|
||||
},
|
||||
id: function() {
|
||||
return 'id';
|
||||
}
|
||||
});
|
||||
var view = new View();
|
||||
strictEqual(view.el.className, 'className');
|
||||
strictEqual(view.el.id, 'id');
|
||||
});
|
||||
|
||||
test("View: with attributes", 2, function() {
|
||||
var view = new Backbone.View({attributes : {'class': 'one', id: 'two'}});
|
||||
equal(view.el.className, 'one');
|
||||
|
||||
57
vendor/benchmark.js/README.md
vendored
57
vendor/benchmark.js/README.md
vendored
@@ -1,30 +1,34 @@
|
||||
# Benchmark.js <sup>v1.0.0-pre</sup>
|
||||
# Benchmark.js <sup>v1.0.0</sup>
|
||||
|
||||
A [robust](http://calendar.perfplanet.com/2010/bulletproof-javascript-benchmarks/ "Bulletproof JavaScript benchmarks") benchmarking library that works on nearly all JavaScript platforms<sup><a name="fnref1" href="#fn1">1</a></sup>, supports high-resolution timers, and returns statistically significant results. As seen on [jsPerf](http://jsperf.com/).
|
||||
|
||||
## BestieJS
|
||||
## Download
|
||||
|
||||
Benchmark.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
|
||||
* [Development source](https://raw.github.com/bestiejs/benchmark.js/1.0.0/benchmark.js)
|
||||
|
||||
## Documentation
|
||||
## Dive in
|
||||
|
||||
The documentation for Benchmark.js can be viewed here: <http://benchmarkjs.com/docs>
|
||||
We’ve got [API docs](http://benchmarkjs.com/docs) and [unit tests](http://benchmarkjs.com/tests).
|
||||
|
||||
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/benchmark.js/wiki/Roadmap).
|
||||
|
||||
## Support
|
||||
|
||||
Benchmark.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.8.6, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
||||
|
||||
## Installation and usage
|
||||
|
||||
In a browser or Adobe AIR:
|
||||
|
||||
~~~ html
|
||||
```html
|
||||
<script src="benchmark.js"></script>
|
||||
~~~
|
||||
```
|
||||
|
||||
Optionally, expose Java’s nanosecond timer by adding the `nano` applet to the `<body>`:
|
||||
|
||||
~~~ html
|
||||
```html
|
||||
<applet code="nano" archive="nano.jar"></applet>
|
||||
~~~
|
||||
```
|
||||
|
||||
Or enable Chrome’s microsecond timer by using the [command line switch](http://peter.sh/experiments/chromium-command-line-switches/#enable-benchmarking):
|
||||
|
||||
@@ -32,37 +36,37 @@ Or enable Chrome’s microsecond timer by using the [command line switch](http:/
|
||||
|
||||
Via [npm](http://npmjs.org/):
|
||||
|
||||
~~~ bash
|
||||
```bash
|
||||
npm install benchmark
|
||||
~~~
|
||||
```
|
||||
|
||||
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
var Benchmark = require('benchmark');
|
||||
~~~
|
||||
```
|
||||
|
||||
Optionally, use the [microtime module](https://github.com/wadey/node-microtime) by Wade Simmons:
|
||||
|
||||
~~~ bash
|
||||
```bash
|
||||
npm install microtime
|
||||
~~~
|
||||
```
|
||||
|
||||
In [Narwhal](http://narwhaljs.org/) and [RingoJS v0.7.0-](http://ringojs.org/):
|
||||
In [RingoJS v0.7.0-](http://ringojs.org/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
var Benchmark = require('benchmark').Benchmark;
|
||||
~~~
|
||||
```
|
||||
|
||||
In [Rhino](http://www.mozilla.org/rhino/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
load('benchmark.js');
|
||||
~~~
|
||||
```
|
||||
|
||||
In an AMD loader like [RequireJS](http://requirejs.org/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
require({
|
||||
'paths': {
|
||||
'benchmark': 'path/to/benchmark'
|
||||
@@ -84,11 +88,11 @@ require({
|
||||
Benchmark.platform = platform;
|
||||
console.log(Benchmark.platform.name);
|
||||
});
|
||||
~~~
|
||||
```
|
||||
|
||||
Usage example:
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
var suite = new Benchmark.Suite;
|
||||
|
||||
// add tests
|
||||
@@ -112,12 +116,11 @@ suite.add('RegExp#test', function() {
|
||||
// > RegExp#test x 4,161,532 +-0.99% (59 cycles)
|
||||
// > String#indexOf x 6,139,623 +-1.00% (131 cycles)
|
||||
// > Fastest is String#indexOf
|
||||
~~~
|
||||
```
|
||||
|
||||
## Footnotes
|
||||
## BestieJS
|
||||
|
||||
1. Benchmark.js has been tested in at least Adobe AIR 2.6, Chrome 5-15, Firefox 1.5-8, IE 6-10, Opera 9.25-11.52, Safari 2-5.1.1, Node.js 0.4.8-0.6.1, Narwhal 0.3.2, RingoJS 0.7-0.8, and Rhino 1.7RC3.
|
||||
<a name="fn1" title="Jump back to footnote 1 in the text." href="#fnref1">↩</a>
|
||||
Benchmark.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
|
||||
|
||||
## Authors
|
||||
|
||||
|
||||
238
vendor/benchmark.js/benchmark.js
vendored
238
vendor/benchmark.js/benchmark.js
vendored
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Benchmark.js v1.0.0-pre <http://benchmarkjs.com/>
|
||||
* Benchmark.js v1.0.0 <http://benchmarkjs.com/>
|
||||
* Copyright 2010-2012 Mathias Bynens <http://mths.be/>
|
||||
* Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
|
||||
* Modified by John-David Dalton <http://allyoucanleet.com/>
|
||||
@@ -244,6 +244,36 @@
|
||||
} catch(e) {
|
||||
support.getAllKeys = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if own properties are iterated before inherited properties (all but IE < 9).
|
||||
*
|
||||
* @name iteratesOwnLast
|
||||
* @memberOf Benchmark.support
|
||||
* @type Boolean
|
||||
*/
|
||||
support.iteratesOwnFirst = (function() {
|
||||
var props = [];
|
||||
function ctor() { this.x = 1; }
|
||||
ctor.prototype = { 'y': 1 };
|
||||
for (var prop in new ctor) { props.push(prop); }
|
||||
return props[0] == 'x';
|
||||
}());
|
||||
|
||||
/**
|
||||
* Detect if a node's [[Class]] is resolvable (all but IE < 9)
|
||||
* and that the JS engine errors when attempting to coerce an object to a
|
||||
* string without a `toString` property value of `typeof` "function".
|
||||
*
|
||||
* @name nodeClass
|
||||
* @memberOf Benchmark.support
|
||||
* @type Boolean
|
||||
*/
|
||||
try {
|
||||
support.nodeClass = ({ 'toString': 0 } + '', toString.call(doc || 0) != '[object Object]');
|
||||
} catch(e) {
|
||||
support.nodeClass = true;
|
||||
}
|
||||
}());
|
||||
|
||||
/**
|
||||
@@ -583,14 +613,17 @@
|
||||
while (++index < length) {
|
||||
if ((index - start) in tail) {
|
||||
object[index] = tail[index - start];
|
||||
} else {
|
||||
} else if (index in object) {
|
||||
delete object[index];
|
||||
}
|
||||
}
|
||||
// delete excess elements
|
||||
deleteCount = deleteCount > elementCount ? deleteCount - elementCount : 0;
|
||||
while (deleteCount--) {
|
||||
delete object[length + deleteCount];
|
||||
index = length + deleteCount;
|
||||
if (index in object) {
|
||||
delete object[index];
|
||||
}
|
||||
}
|
||||
object.length = length;
|
||||
return result;
|
||||
@@ -941,7 +974,13 @@
|
||||
// escape the `{` for Firefox 1
|
||||
result = (/^[^{]+\{([\s\S]*)}\s*$/.exec(fn) || 0)[1];
|
||||
}
|
||||
return (result || '').replace(/^\s+|\s+$/g, '');
|
||||
// trim string
|
||||
result = (result || '').replace(/^\s+|\s+$/g, '');
|
||||
|
||||
// detect strings containing only the "use strict" directive
|
||||
return /^(?:\/\*+[\w|\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result)
|
||||
? ''
|
||||
: result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -994,36 +1033,43 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified `value` is an object created by the `Object`
|
||||
* constructor assuming objects created by the `Object` constructor have no
|
||||
* inherited enumerable properties and assuming there are no `Object.prototype`
|
||||
* extensions.
|
||||
* Checks if a given `value` is an object created by the `Object` constructor
|
||||
* assuming objects created by the `Object` constructor have no inherited
|
||||
* enumerable properties and that there are no `Object.prototype` extensions.
|
||||
*
|
||||
* @private
|
||||
* @param {Mixed} value The value to check.
|
||||
* @returns {Boolean} Returns `true` if `value` is an object, else `false`.
|
||||
* @returns {Boolean} Returns `true` if the `value` is a plain `Object` object, else `false`.
|
||||
*/
|
||||
function isObject(value) {
|
||||
var ctor,
|
||||
result = !!value && toString.call(value) == '[object Object]';
|
||||
|
||||
if (result && noArgumentsClass) {
|
||||
// avoid false positives for `arguments` objects in IE < 9
|
||||
result = !isArguments(value);
|
||||
function isPlainObject(value) {
|
||||
// avoid non-objects and false positives for `arguments` objects in IE < 9
|
||||
var result = false;
|
||||
if (!(value && typeof value == 'object') || isArguments(value)) {
|
||||
return result;
|
||||
}
|
||||
if (result) {
|
||||
// IE < 9 presents nodes like `Object` objects:
|
||||
// IE < 8 are missing the node's constructor property
|
||||
// IE 8 node constructors are typeof "object"
|
||||
ctor = value.constructor;
|
||||
// check if the constructor is `Object` as `Object instanceof Object` is `true`
|
||||
if ((result = isClassOf(ctor, 'Function') && ctor instanceof ctor)) {
|
||||
// An object's own properties are iterated before inherited properties.
|
||||
// If the last iterated key belongs to an object's own property then
|
||||
// there are no inherited enumerable properties.
|
||||
forProps(value, function(subValue, subKey) { result = subKey; });
|
||||
result = result === true || hasKey(value, result);
|
||||
// IE < 9 presents DOM nodes as `Object` objects except they have `toString`
|
||||
// methods that are `typeof` "string" and still can coerce nodes to strings.
|
||||
// Also check that the constructor is `Object` (i.e. `Object instanceof Object`)
|
||||
var ctor = value.constructor;
|
||||
if ((support.nodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) &&
|
||||
(!isClassOf(ctor, 'Function') || ctor instanceof ctor)) {
|
||||
// In most environments an object's own properties are iterated before
|
||||
// its inherited properties. If the last iterated property is an object's
|
||||
// own property then there are no inherited enumerable properties.
|
||||
if (support.iteratesOwnFirst) {
|
||||
forProps(value, function(subValue, subKey) {
|
||||
result = subKey;
|
||||
});
|
||||
return result === false || hasKey(value, result);
|
||||
}
|
||||
// IE < 9 iterates inherited properties before own properties. If the first
|
||||
// iterated property is an object's own property then there are no inherited
|
||||
// enumerable properties.
|
||||
forProps(value, function(subValue, subKey) {
|
||||
result = !hasKey(value, subKey);
|
||||
return false;
|
||||
});
|
||||
return result === false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1265,7 +1311,7 @@
|
||||
break;
|
||||
|
||||
case '[object Object]':
|
||||
isObject(value) && (clone = new ctor);
|
||||
isPlainObject(value) && (clone = {});
|
||||
break;
|
||||
|
||||
case '[object Number]':
|
||||
@@ -2405,13 +2451,12 @@
|
||||
|
||||
var source = {
|
||||
'setup': getSource(bench.setup, preprocess('m$.setup()')),
|
||||
'fn': getSource(fn, preprocess('f$(' + fnArg + ')')),
|
||||
'fn': getSource(fn, preprocess('m$.fn(' + fnArg + ')')),
|
||||
'fnArg': fnArg,
|
||||
'teardown': getSource(bench.teardown, preprocess('m$.teardown()'))
|
||||
};
|
||||
|
||||
var compiled = bench.compiled,
|
||||
count = bench.count = clone.count,
|
||||
var count = bench.count = clone.count,
|
||||
decompilable = support.decompilation || stringable,
|
||||
id = bench.id,
|
||||
isEmpty = !(source.fn || stringable),
|
||||
@@ -2433,77 +2478,77 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (!compiled) {
|
||||
// compile in setup/teardown functions and the test loop
|
||||
compiled = bench.compiled = createFunction(preprocess('t$'), interpolate(
|
||||
preprocess(deferred
|
||||
? 'var d$=this,#{fnArg}=d$,m$=d$.benchmark._original,f$=m$.fn,su$=m$.setup,td$=m$.teardown;' +
|
||||
// when `deferred.cycles` is `0` then...
|
||||
'if(!d$.cycles){' +
|
||||
// set `deferred.fn`
|
||||
'd$.fn=function(){var #{fnArg}=d$;if(typeof f$=="function"){try{#{fn}\n}catch(e$){f$(d$)}}else{#{fn}\n}};' +
|
||||
// set `deferred.teardown`
|
||||
'd$.teardown=function(){d$.cycles=0;if(typeof td$=="function"){try{#{teardown}\n}catch(e$){td$()}}else{#{teardown}\n}};' +
|
||||
// execute the benchmark's `setup`
|
||||
'if(typeof su$=="function"){try{#{setup}\n}catch(e$){su$()}}else{#{setup}\n};' +
|
||||
// start timer
|
||||
't$.start(d$);' +
|
||||
// execute `deferred.fn` and return a dummy object
|
||||
'}d$.fn();return{}'
|
||||
// Compile in setup/teardown functions and the test loop.
|
||||
// Create a new compiled test, instead of using the cached `bench.compiled`,
|
||||
// to avoid potential engine optimizations enabled over the life of the test.
|
||||
var compiled = bench.compiled = createFunction(preprocess('t$'), interpolate(
|
||||
preprocess(deferred
|
||||
? 'var d$=this,#{fnArg}=d$,m$=d$.benchmark._original,f$=m$.fn,su$=m$.setup,td$=m$.teardown;' +
|
||||
// when `deferred.cycles` is `0` then...
|
||||
'if(!d$.cycles){' +
|
||||
// set `deferred.fn`
|
||||
'd$.fn=function(){var #{fnArg}=d$;if(typeof f$=="function"){try{#{fn}\n}catch(e$){f$(d$)}}else{#{fn}\n}};' +
|
||||
// set `deferred.teardown`
|
||||
'd$.teardown=function(){d$.cycles=0;if(typeof td$=="function"){try{#{teardown}\n}catch(e$){td$()}}else{#{teardown}\n}};' +
|
||||
// execute the benchmark's `setup`
|
||||
'if(typeof su$=="function"){try{#{setup}\n}catch(e$){su$()}}else{#{setup}\n};' +
|
||||
// start timer
|
||||
't$.start(d$);' +
|
||||
// execute `deferred.fn` and return a dummy object
|
||||
'}d$.fn();return{}'
|
||||
|
||||
: 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count,n$=t$.ns;#{setup}\n#{begin};' +
|
||||
'while(i$--){#{fn}\n}#{end};#{teardown}\nreturn{elapsed:r$,uid:"#{uid}"}'),
|
||||
: 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count,n$=t$.ns;#{setup}\n#{begin};' +
|
||||
'while(i$--){#{fn}\n}#{end};#{teardown}\nreturn{elapsed:r$,uid:"#{uid}"}'),
|
||||
source
|
||||
));
|
||||
|
||||
try {
|
||||
if (isEmpty) {
|
||||
// Firefox may remove dead code from Function#toString results
|
||||
// http://bugzil.la/536085
|
||||
throw new Error('The test "' + name + '" is empty. This may be the result of dead code removal.');
|
||||
}
|
||||
else if (!deferred) {
|
||||
// pretest to determine if compiled code is exits early, usually by a
|
||||
// rogue `return` statement, by checking for a return object with the uid
|
||||
bench.count = 1;
|
||||
compiled = (compiled.call(bench, timer) || {}).uid == uid && compiled;
|
||||
bench.count = count;
|
||||
}
|
||||
} catch(e) {
|
||||
compiled = null;
|
||||
clone.error = e || new Error(String(e));
|
||||
bench.count = count;
|
||||
}
|
||||
// fallback when a test exits early or errors during pretest
|
||||
if (decompilable && !compiled && !deferred && !isEmpty) {
|
||||
compiled = createFunction(preprocess('t$'), interpolate(
|
||||
preprocess(
|
||||
(clone.error && !stringable
|
||||
? 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count'
|
||||
: 'function f$(){#{fn}\n}var r$,s$,m$=this,i$=m$.count'
|
||||
) +
|
||||
',n$=t$.ns;#{setup}\n#{begin};m$.f$=f$;while(i$--){m$.f$()}#{end};' +
|
||||
'delete m$.f$;#{teardown}\nreturn{elapsed:r$}'
|
||||
),
|
||||
source
|
||||
));
|
||||
|
||||
try {
|
||||
if (isEmpty) {
|
||||
// Firefox may remove dead code from Function#toString results
|
||||
// http://bugzil.la/536085
|
||||
throw new Error('The test "' + name + '" is empty. This may be the result of dead code removal.');
|
||||
}
|
||||
else if (!deferred) {
|
||||
// pretest to determine if compiled code is exits early, usually by a
|
||||
// rogue `return` statement, by checking for a return object with the uid
|
||||
bench.count = 1;
|
||||
compiled = (compiled.call(bench, timer) || {}).uid == uid && compiled;
|
||||
bench.count = count;
|
||||
}
|
||||
} catch(e) {
|
||||
compiled = null;
|
||||
clone.error = e || new Error(String(e));
|
||||
// pretest one more time to check for errors
|
||||
bench.count = 1;
|
||||
compiled.call(bench, timer);
|
||||
bench.compiled = compiled;
|
||||
bench.count = count;
|
||||
delete clone.error;
|
||||
}
|
||||
// fallback when a test exits early or errors during pretest
|
||||
if (decompilable && !compiled && !deferred && !isEmpty) {
|
||||
compiled = createFunction(preprocess('t$'), interpolate(
|
||||
preprocess(
|
||||
(clone.error && !stringable
|
||||
? 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count'
|
||||
: 'function f$(){#{fn}\n}var r$,s$,m$=this,i$=m$.count'
|
||||
) +
|
||||
',n$=t$.ns;#{setup}\n#{begin};m$.f$=f$;while(i$--){m$.f$()}#{end};' +
|
||||
'delete m$.f$;#{teardown}\nreturn{elapsed:r$}'
|
||||
),
|
||||
source
|
||||
));
|
||||
|
||||
try {
|
||||
// pretest one more time to check for errors
|
||||
bench.count = 1;
|
||||
compiled.call(bench, timer);
|
||||
catch(e) {
|
||||
bench.count = count;
|
||||
if (clone.error) {
|
||||
compiled = null;
|
||||
} else {
|
||||
bench.compiled = compiled;
|
||||
bench.count = count;
|
||||
delete clone.error;
|
||||
}
|
||||
catch(e) {
|
||||
bench.count = count;
|
||||
if (clone.error) {
|
||||
compiled = null;
|
||||
} else {
|
||||
bench.compiled = compiled;
|
||||
clone.error = e || new Error(String(e));
|
||||
}
|
||||
clone.error = e || new Error(String(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3046,6 +3091,7 @@
|
||||
|
||||
/**
|
||||
* The maximum time a benchmark is allowed to run before finishing (secs).
|
||||
*
|
||||
* Note: Cycle delays aren't counted toward the maximum time.
|
||||
*
|
||||
* @memberOf Benchmark.options
|
||||
@@ -3219,7 +3265,7 @@
|
||||
* @memberOf Benchmark
|
||||
* @type String
|
||||
*/
|
||||
'version': '1.0.0-pre',
|
||||
'version': '1.0.0',
|
||||
|
||||
// an object of environment/feature detection flags
|
||||
'support': support,
|
||||
|
||||
17
vendor/docdown/README.md
vendored
17
vendor/docdown/README.md
vendored
@@ -1,4 +1,4 @@
|
||||
# Docdown <sup>v1.0.0-pre</sup>
|
||||
# Docdown <sup>v1.0.0</sup>
|
||||
|
||||
A simple JSDoc to Markdown documentation generator.
|
||||
|
||||
@@ -12,7 +12,7 @@ For a list of upcoming features, check out our [roadmap](https://github.com/jdal
|
||||
|
||||
Usage example:
|
||||
|
||||
~~~ php
|
||||
```php
|
||||
require("docdown.php");
|
||||
|
||||
// generate Markdown
|
||||
@@ -20,18 +20,7 @@ $markdown = docdown(array(
|
||||
"path" => $filepath,
|
||||
"url" => "https://github.com/username/project/blob/master/my.js"
|
||||
));
|
||||
~~~
|
||||
|
||||
## Cloning this repo
|
||||
|
||||
To clone this repository just use:
|
||||
|
||||
~~~ bash
|
||||
git clone https://github.com/docdown/docdown.git
|
||||
cd docdown
|
||||
~~~
|
||||
|
||||
Feel free to fork and send pull requests if you see improvements!
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
4
vendor/docdown/src/DocDown/Entry.php
vendored
4
vendor/docdown/src/DocDown/Entry.php
vendored
@@ -140,7 +140,7 @@ class Entry {
|
||||
preg_match('#\*\s*@example\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
|
||||
if (count($result)) {
|
||||
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', "\n", $result[1]));
|
||||
$result = '~~~ ' . $this->lang . "\n" . $result . "\n~~~";
|
||||
$result = '```' . $this->lang . "\n" . $result . "\n```";
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -196,7 +196,7 @@ class Entry {
|
||||
* @returns {Array} The entry `param` data.
|
||||
*/
|
||||
public function getParams( $index = null ) {
|
||||
preg_match_all('#\*\s*@param\s+\{([^}]+)\}\s+(\[[^]]+\]|[$\w]+)\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#i', $this->entry, $result);
|
||||
preg_match_all('#\*\s*@param\s+\{([^}]+)\}\s+(\[.+\]|[$\w]+)\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#i', $this->entry, $result);
|
||||
if (count($result = array_filter(array_slice($result, 1)))) {
|
||||
// repurpose array
|
||||
foreach ($result as $param) {
|
||||
|
||||
10
vendor/docdown/src/DocDown/Generator.php
vendored
10
vendor/docdown/src/DocDown/Generator.php
vendored
@@ -208,6 +208,7 @@ class Generator {
|
||||
$openTag = "\n<!-- div -->\n";
|
||||
$closeTag = "\n<!-- /div -->\n";
|
||||
$result = array('# ' . $this->options['title']);
|
||||
$toc = 'toc';
|
||||
|
||||
// initialize $api array
|
||||
foreach ($this->entries as $entry) {
|
||||
@@ -304,10 +305,15 @@ class Generator {
|
||||
|
||||
$compiling = $compiling ? ($result[] = $closeTag) : true;
|
||||
|
||||
// assign TOC hash
|
||||
if (count($result) == 2) {
|
||||
$toc = $member;
|
||||
}
|
||||
|
||||
// add root entry
|
||||
array_push(
|
||||
$result,
|
||||
$openTag, '## ' . (count($result) == 2 ? '<a id="toc"></a>' : '') . '`' . $member . '`',
|
||||
$openTag, '## ' . (count($result) == 2 ? '<a id="' . $toc . '"></a>' : '') . '`' . $member . '`',
|
||||
Generator::interpolate('* [`' . $member . '`](##{hash})', $entry)
|
||||
);
|
||||
|
||||
@@ -401,7 +407,7 @@ class Generator {
|
||||
}
|
||||
|
||||
// close tags add TOC link reference
|
||||
array_push($result, $closeTag, $closeTag, '', ' [1]: #toc "Jump back to the TOC."');
|
||||
array_push($result, $closeTag, $closeTag, '', ' [1]: #' . $toc . ' "Jump back to the TOC."');
|
||||
|
||||
// cleanup whitespace
|
||||
return trim(preg_replace('/ +\n/', "\n", join($result, "\n")));
|
||||
|
||||
37
vendor/platform.js/README.md
vendored
37
vendor/platform.js/README.md
vendored
@@ -1,4 +1,4 @@
|
||||
# Platform.js <sup>v1.0.0-pre</sup>
|
||||
# Platform.js <sup>v1.0.0</sup>
|
||||
|
||||
A platform detection library that works on nearly all JavaScript platforms<sup><a name="fnref1" href="#fn1">1</a></sup>.
|
||||
|
||||
@@ -16,35 +16,39 @@ The documentation for Platform.js can be viewed here: [/doc/README.md](https://g
|
||||
|
||||
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/platform.js/wiki/Roadmap).
|
||||
|
||||
## Support
|
||||
|
||||
Platform.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.8.6, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
||||
|
||||
## Installation and usage
|
||||
|
||||
In a browser or Adobe AIR:
|
||||
|
||||
~~~ html
|
||||
```html
|
||||
<script src="platform.js"></script>
|
||||
~~~
|
||||
```
|
||||
|
||||
Via [npm](http://npmjs.org/):
|
||||
|
||||
~~~ bash
|
||||
```bash
|
||||
npm install platform
|
||||
~~~
|
||||
```
|
||||
|
||||
In [Narwhal](http://narwhaljs.org/), [Node.js](http://nodejs.org/), and [RingoJS](http://ringojs.org/):
|
||||
In [Node.js](http://nodejs.org/) and [RingoJS](http://ringojs.org/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
var platform = require('platform');
|
||||
~~~
|
||||
```
|
||||
|
||||
In [Rhino](http://www.mozilla.org/rhino/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
load('platform.js');
|
||||
~~~
|
||||
```
|
||||
|
||||
In an AMD loader like [RequireJS](http://requirejs.org/):
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
require({
|
||||
'paths': {
|
||||
'platform': 'path/to/platform'
|
||||
@@ -53,11 +57,11 @@ require({
|
||||
['platform'], function(platform) {
|
||||
console.log(platform.name);
|
||||
});
|
||||
~~~
|
||||
```
|
||||
|
||||
Usage example:
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
// on IE10 x86 platform preview running in IE7 compatibility mode on Windows 7 64 bit edition
|
||||
platform.name; // 'IE'
|
||||
platform.version; // '10.0'
|
||||
@@ -81,12 +85,7 @@ info.version; // '11.52'
|
||||
info.layout; // 'Presto'
|
||||
info.os; // 'Mac OS X 10.7.2'
|
||||
info.description; // 'Opera 11.52 (identifying as Firefox 4.0) on Mac OS X 10.7.2'
|
||||
~~~
|
||||
|
||||
## Footnotes
|
||||
|
||||
1. Platform.js has been tested in at least Adobe AIR 2.6, Chrome 5-15, Firefox 1.5-8, IE 6-10, Opera 9.25-11.52, Safari 2-5.1.1, Node.js 0.4.8-0.6.1, Narwhal 0.3.2, RingoJS 0.7-0.8, and Rhino 1.7RC3.
|
||||
<a name="fn1" title="Jump back to footnote 1 in the text." href="#fnref1">↩</a>
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
104
vendor/platform.js/platform.js
vendored
104
vendor/platform.js/platform.js
vendored
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Platform.js v1.0.0-pre <http://mths.be/platform>
|
||||
* Platform.js v1.0.0 <http://mths.be/platform>
|
||||
* Copyright 2010-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Available under MIT license <http://mths.be/mit>
|
||||
*/
|
||||
@@ -297,7 +297,7 @@
|
||||
'Opera Mini',
|
||||
'Opera',
|
||||
'Chrome',
|
||||
{ 'label': 'Chrome Mobile', 'pattern': 'CrMo' },
|
||||
{ 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },
|
||||
{ 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
|
||||
{ 'label': 'IE', 'pattern': 'MSIE' },
|
||||
'Safari'
|
||||
@@ -512,12 +512,11 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Return platform description when the platform object is coerced to a string.
|
||||
* Returns `platform.description` when the platform object is coerced to a string.
|
||||
*
|
||||
* @name toString
|
||||
* @memberOf platform
|
||||
* @type Function
|
||||
* @returns {String} The platform description.
|
||||
* @returns {String} Returns `platform.description` if available, else an empty string.
|
||||
*/
|
||||
function toStringPlatform() {
|
||||
return this.description || '';
|
||||
@@ -573,7 +572,7 @@
|
||||
// detect non-Opera versions (order is important)
|
||||
if (!version) {
|
||||
version = getVersion([
|
||||
'(?:Cloud9|CrMo|Opera ?Mini|Raven|Silk(?!/[\\d.]+$))',
|
||||
'(?:Cloud9|CriOS|CrMo|Opera ?Mini|Raven|Silk(?!/[\\d.]+$))',
|
||||
'Version',
|
||||
qualify(name),
|
||||
'(?:Firefox|Minefield|NetFront)'
|
||||
@@ -708,7 +707,7 @@
|
||||
))
|
||||
) && !reOpera.test(data = parse.call(forOwn, ua.replace(reOpera, '') + ';')) && data.name) {
|
||||
|
||||
// when "indentifying" the UA contains both Opera and the other browser's name
|
||||
// when "indentifying", the UA contains both Opera and the other browser's name
|
||||
data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
|
||||
if (reOpera.test(name)) {
|
||||
if (/IE/.test(data) && os == 'Mac OS') {
|
||||
@@ -716,7 +715,7 @@
|
||||
}
|
||||
data = 'identify' + data;
|
||||
}
|
||||
// when "masking" the UA contains only the other browser's name
|
||||
// when "masking", the UA contains only the other browser's name
|
||||
else {
|
||||
data = 'mask' + data;
|
||||
if (operaClass) {
|
||||
@@ -760,7 +759,7 @@
|
||||
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : '5');
|
||||
} else {
|
||||
layout[1] = 'like Chrome';
|
||||
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 535.21 ? 18 : '19');
|
||||
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : '21');
|
||||
}
|
||||
// add the postfix of ".x" or "+" for approximate versions
|
||||
layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+');
|
||||
@@ -769,6 +768,30 @@
|
||||
version = data;
|
||||
}
|
||||
}
|
||||
// detect Opera desktop modes
|
||||
if (name == 'Opera' && (data = /(?:zbov|zvav)$/.exec(os))) {
|
||||
name += ' ';
|
||||
description.unshift('desktop mode');
|
||||
if (data == 'zvav') {
|
||||
name += 'Mini';
|
||||
version = null;
|
||||
} else {
|
||||
name += 'Mobile';
|
||||
}
|
||||
}
|
||||
// detect Chrome desktop mode
|
||||
else if (name == 'Safari' && /Chrome/.exec(layout[1])) {
|
||||
description.unshift('desktop mode');
|
||||
name = 'Chrome Mobile';
|
||||
version = null;
|
||||
|
||||
if (/Mac OS X/.test(os)) {
|
||||
manufacturer = 'Apple';
|
||||
os = 'iOS 4.3+';
|
||||
} else {
|
||||
os = null;
|
||||
}
|
||||
}
|
||||
// strip incorrect OS versions
|
||||
if (version && version.indexOf(data = /[\d.]+$/.exec(os)) == 0 &&
|
||||
ua.indexOf('/' + data + '-') > -1) {
|
||||
@@ -793,9 +816,25 @@
|
||||
if (product) {
|
||||
description.push((/^on /.test(description[description.length -1]) ? '' : 'on ') + product);
|
||||
}
|
||||
// parse OS into an object
|
||||
if (os) {
|
||||
data = / ([\d.+]+)$/.exec(os);
|
||||
os = {
|
||||
'architecture': 32,
|
||||
'family': data ? os.replace(data[0], '') : os,
|
||||
'version': data ? data[1] : null,
|
||||
'toString': function() {
|
||||
var version = this.version;
|
||||
return this.family + (version ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : '');
|
||||
}
|
||||
};
|
||||
}
|
||||
// add browser/OS architecture
|
||||
if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i).test(arch) && !/\bi686\b/i.test(arch)) {
|
||||
os = os && os + (data.test(os) ? '' : ' 64-bit');
|
||||
if ((data = / (?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
|
||||
if (os) {
|
||||
os.architecture = 64;
|
||||
os.family = os.family.replace(data, '');
|
||||
}
|
||||
if (name && (/WOW64/i.test(ua) ||
|
||||
(useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform)))) {
|
||||
description.unshift('32-bit');
|
||||
@@ -834,11 +873,46 @@
|
||||
* The name of the operating system.
|
||||
*
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
* @type Object
|
||||
*/
|
||||
'os': os && (name &&
|
||||
!(os == os.split(' ')[0] && (os == name.split(' ')[0] || product)) &&
|
||||
description.push(product ? '(' + os + ')' : 'on ' + os), os),
|
||||
'os': os
|
||||
? (name &&
|
||||
!(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product)) &&
|
||||
description.push(product ? '(' + os + ')' : 'on ' + os), os)
|
||||
: {
|
||||
|
||||
/**
|
||||
* The CPU architecture the OS is built for.
|
||||
*
|
||||
* @memberOf platform.os
|
||||
* @type String|Null
|
||||
*/
|
||||
'architecture': null,
|
||||
|
||||
/**
|
||||
* The family of the OS.
|
||||
*
|
||||
* @memberOf platform.os
|
||||
* @type String|Null
|
||||
*/
|
||||
'family': null,
|
||||
|
||||
/**
|
||||
* The version of the OS.
|
||||
*
|
||||
* @memberOf platform.os
|
||||
* @type String|Null
|
||||
*/
|
||||
'version': null,
|
||||
|
||||
/**
|
||||
* Returns the OS string.
|
||||
*
|
||||
* @memberOf platform.os
|
||||
* @returns {String} The OS string.
|
||||
*/
|
||||
'toString': function() { return 'null'; }
|
||||
},
|
||||
|
||||
/**
|
||||
* The platform description.
|
||||
|
||||
28
vendor/qunit-clib/README.md
vendored
28
vendor/qunit-clib/README.md
vendored
@@ -1,15 +1,19 @@
|
||||
# QUnit CLIB <sup>v1.0.0-pre</sup>
|
||||
# QUnit CLIB <sup>v1.0.0</sup>
|
||||
## command-line interface boilerplate
|
||||
|
||||
QUnit CLIB helps extend QUnit's CLI support to many common CLI environments<sup><a name="fnref1" href="#fn1">1</a></sup>.
|
||||
QUnit CLIB helps extend QUnit's CLI support to many common CLI environments.
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
||||
## Support
|
||||
|
||||
QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, RingoJS v0.8.0, and Rhino v1.7RC3-RC5.
|
||||
|
||||
## Usage
|
||||
|
||||
~~~ js
|
||||
```js
|
||||
(function(window) {
|
||||
|
||||
// use a single load function
|
||||
@@ -39,25 +43,13 @@ QUnit CLIB helps extend QUnit's CLI support to many common CLI environments<sup>
|
||||
QUnit.start();
|
||||
}
|
||||
}(typeof global == 'object' && global || this));
|
||||
~~~
|
||||
|
||||
## Cloning this repo
|
||||
|
||||
To clone this repository just use:
|
||||
|
||||
~~~ bash
|
||||
git clone https://github.com/jdalton/qunit-clib.git
|
||||
cd qunit-clib
|
||||
~~~
|
||||
|
||||
Feel free to fork and send pull requests if you see improvements!
|
||||
```
|
||||
|
||||
## Footnotes
|
||||
|
||||
1. QUnit CLIB has been tested in at least Node.js v0.4.8-0.6.1, Narwhal v0.3.2, RingoJS v0.7.0-0.8.0, and Rhino v1.7RC3.
|
||||
<a name="fn1" title="Jump back to footnote 1 in the text." href="#fnref1">↩</a>
|
||||
1. QUnit v1.3.0 does not work with Narwhal or Ringo < v0.8.0
|
||||
|
||||
2. QUnit v1.3.0 does not work with Narwhal or Ringo < v0.8.0
|
||||
2. Rhino v1.7RC4 does not support timeout fallbacks `clearTimeout` and `setTimeout`
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
4
vendor/qunit-clib/qunit-clib.js
vendored
4
vendor/qunit-clib/qunit-clib.js
vendored
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* QUnit CLI Boilerplate v1.0.0-pre
|
||||
* QUnit CLI Boilerplate v1.0.0
|
||||
* Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Based on a gist by Jörn Zaefferer <https://gist.github.com/722381>
|
||||
* Available under MIT license <http://mths.be/mit>
|
||||
@@ -92,6 +92,8 @@
|
||||
* @returns {Number} The the ID of the timeout.
|
||||
*/
|
||||
function schedule(fn, delay, args, repeated) {
|
||||
// Rhino 1.7RC4 will error assigning `task` below
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=775566
|
||||
var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, {
|
||||
'run': function() {
|
||||
fn.apply(global, args);
|
||||
|
||||
201
vendor/requirejs/require.js
vendored
201
vendor/requirejs/require.js
vendored
@@ -1,21 +1,25 @@
|
||||
/** vim: et:ts=4:sw=4:sts=4
|
||||
* @license RequireJS 2.0.4 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
* @license RequireJS 2.0.5 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
|
||||
*/
|
||||
/*jslint regexp: true, nomen: true */
|
||||
//Not using strict: uneven strict support in browsers, #392, and causes
|
||||
//problems with requirejs.exec()/transpiler plugins that may not be strict.
|
||||
/*jslint regexp: true, nomen: true, sloppy: true */
|
||||
/*global window, navigator, document, importScripts, jQuery, setTimeout, opera */
|
||||
|
||||
var requirejs, require, define;
|
||||
(function (global) {
|
||||
'use strict';
|
||||
|
||||
var version = '2.0.4',
|
||||
var req, s, head, baseElement, dataMain, src,
|
||||
interactiveScript, currentlyAddingScript, mainScript, subPath,
|
||||
version = '2.0.5',
|
||||
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
|
||||
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
|
||||
jsSuffixRegExp = /\.js$/,
|
||||
currDirRegExp = /^\.\//,
|
||||
ostring = Object.prototype.toString,
|
||||
op = Object.prototype,
|
||||
ostring = op.toString,
|
||||
hasOwn = op.hasOwnProperty,
|
||||
ap = Array.prototype,
|
||||
aps = ap.slice,
|
||||
apsp = ap.splice,
|
||||
@@ -33,9 +37,7 @@ var requirejs, require, define;
|
||||
contexts = {},
|
||||
cfg = {},
|
||||
globalDefQueue = [],
|
||||
useInteractive = false,
|
||||
req, s, head, baseElement, dataMain, src,
|
||||
interactiveScript, currentlyAddingScript, mainScript, subPath;
|
||||
useInteractive = false;
|
||||
|
||||
function isFunction(it) {
|
||||
return ostring.call(it) === '[object Function]';
|
||||
@@ -76,7 +78,7 @@ var requirejs, require, define;
|
||||
}
|
||||
|
||||
function hasProp(obj, prop) {
|
||||
return obj.hasOwnProperty(prop);
|
||||
return hasOwn.call(obj, prop);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,7 +154,7 @@ var requirejs, require, define;
|
||||
//look up paths relative to the moduleName
|
||||
var args = aps.call(arguments, 0), lastArg;
|
||||
if (enableBuildCallback &&
|
||||
isFunction((lastArg = args[args.length - 1]))) {
|
||||
isFunction((lastArg = args[args.length - 1]))) {
|
||||
lastArg.__requireJsBuild = true;
|
||||
}
|
||||
args.push(relMap);
|
||||
@@ -169,14 +171,14 @@ var requirejs, require, define;
|
||||
], function (item) {
|
||||
var prop = item[1] || item[0];
|
||||
req[item[0]] = context ? makeContextModuleFunc(context[prop], relMap) :
|
||||
//If no context, then use default context. Reference from
|
||||
//contexts instead of early binding to default context, so
|
||||
//that during builds, the latest instance of the default
|
||||
//context with its config gets used.
|
||||
function () {
|
||||
var ctx = contexts[defContextName];
|
||||
return ctx[prop].apply(ctx, arguments);
|
||||
};
|
||||
//If no context, then use default context. Reference from
|
||||
//contexts instead of early binding to default context, so
|
||||
//that during builds, the latest instance of the default
|
||||
//context with its config gets used.
|
||||
function () {
|
||||
var ctx = contexts[defContextName];
|
||||
return ctx[prop].apply(ctx, arguments);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -221,7 +223,9 @@ var requirejs, require, define;
|
||||
}
|
||||
|
||||
function newContext(contextName) {
|
||||
var config = {
|
||||
var inCheckLoaded, Module, context, handlers,
|
||||
checkLoadedTimeoutId,
|
||||
config = {
|
||||
waitSeconds: 7,
|
||||
baseUrl: './',
|
||||
paths: {},
|
||||
@@ -239,9 +243,7 @@ var requirejs, require, define;
|
||||
//should be executed, by the order they
|
||||
//load. Important for consistent cycle resolution
|
||||
//behavior.
|
||||
waitAry = [],
|
||||
inCheckLoaded, Module, context, handlers,
|
||||
checkLoadedTimeoutId;
|
||||
waitAry = [];
|
||||
|
||||
/**
|
||||
* Trims the . and .. from an array of path segments.
|
||||
@@ -254,7 +256,7 @@ var requirejs, require, define;
|
||||
*/
|
||||
function trimDots(ary) {
|
||||
var i, part;
|
||||
for (i = 0; ary[i]; i+= 1) {
|
||||
for (i = 0; ary[i]; i += 1) {
|
||||
part = ary[i];
|
||||
if (part === '.') {
|
||||
ary.splice(i, 1);
|
||||
@@ -287,12 +289,12 @@ var requirejs, require, define;
|
||||
* @returns {String} normalized name
|
||||
*/
|
||||
function normalize(name, baseName, applyMap) {
|
||||
var baseParts = baseName && baseName.split('/'),
|
||||
var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment,
|
||||
foundMap, foundI, foundStarMap, starI,
|
||||
baseParts = baseName && baseName.split('/'),
|
||||
normalizedBaseParts = baseParts,
|
||||
map = config.map,
|
||||
starMap = map && map['*'],
|
||||
pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment,
|
||||
foundMap;
|
||||
starMap = map && map['*'];
|
||||
|
||||
//Adjust any relative paths.
|
||||
if (name && name.charAt(0) === '.') {
|
||||
@@ -343,28 +345,41 @@ var requirejs, require, define;
|
||||
for (j = baseParts.length; j > 0; j -= 1) {
|
||||
mapValue = map[baseParts.slice(0, j).join('/')];
|
||||
|
||||
//baseName segment has config, find if it has one for
|
||||
//baseName segment has config, find if it has one for
|
||||
//this name.
|
||||
if (mapValue) {
|
||||
mapValue = mapValue[nameSegment];
|
||||
if (mapValue) {
|
||||
//Match, update name to the new value.
|
||||
foundMap = mapValue;
|
||||
foundI = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundMap && starMap && starMap[nameSegment]) {
|
||||
foundMap = starMap[nameSegment];
|
||||
}
|
||||
|
||||
if (foundMap) {
|
||||
nameParts.splice(0, i, foundMap);
|
||||
name = nameParts.join('/');
|
||||
break;
|
||||
}
|
||||
|
||||
//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];
|
||||
starI = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundMap && foundStarMap) {
|
||||
foundMap = foundStarMap;
|
||||
foundI = starI;
|
||||
}
|
||||
|
||||
if (foundMap) {
|
||||
nameParts.splice(0, foundI, foundMap);
|
||||
name = nameParts.join('/');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,7 +390,7 @@ var requirejs, require, define;
|
||||
if (isBrowser) {
|
||||
each(scripts(), function (scriptNode) {
|
||||
if (scriptNode.getAttribute('data-requiremodule') === name &&
|
||||
scriptNode.getAttribute('data-requirecontext') === context.contextName) {
|
||||
scriptNode.getAttribute('data-requirecontext') === context.contextName) {
|
||||
scriptNode.parentNode.removeChild(scriptNode);
|
||||
return true;
|
||||
}
|
||||
@@ -412,13 +427,13 @@ var requirejs, require, define;
|
||||
* @returns {Object}
|
||||
*/
|
||||
function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
|
||||
var index = name ? name.indexOf('!') : -1,
|
||||
var url, pluginModule, suffix,
|
||||
index = name ? name.indexOf('!') : -1,
|
||||
prefix = null,
|
||||
parentName = parentModuleMap ? parentModuleMap.name : null,
|
||||
originalName = name,
|
||||
isDefine = true,
|
||||
normalizedName = '',
|
||||
url, pluginModule, suffix;
|
||||
normalizedName = '';
|
||||
|
||||
//If no name, then it means it is a require call, generate an
|
||||
//internal name.
|
||||
@@ -471,8 +486,8 @@ var requirejs, require, define;
|
||||
originalName: originalName,
|
||||
isDefine: isDefine,
|
||||
id: (prefix ?
|
||||
prefix + '!' + normalizedName :
|
||||
normalizedName) + suffix
|
||||
prefix + '!' + normalizedName :
|
||||
normalizedName) + suffix
|
||||
};
|
||||
}
|
||||
|
||||
@@ -492,7 +507,7 @@ var requirejs, require, define;
|
||||
mod = registry[id];
|
||||
|
||||
if (hasProp(defined, id) &&
|
||||
(!mod || mod.defineEmitComplete)) {
|
||||
(!mod || mod.defineEmitComplete)) {
|
||||
if (name === 'defined') {
|
||||
fn(defined[id]);
|
||||
}
|
||||
@@ -659,7 +674,7 @@ var requirejs, require, define;
|
||||
|
||||
traced[id] = mod;
|
||||
|
||||
each(depArray, function(depMap) {
|
||||
each(depArray, function (depMap) {
|
||||
var depId = depMap.id,
|
||||
depMod = registry[depId],
|
||||
value;
|
||||
@@ -699,13 +714,13 @@ var requirejs, require, define;
|
||||
}
|
||||
|
||||
function checkLoaded() {
|
||||
var waitInterval = config.waitSeconds * 1000,
|
||||
var map, modId, err, usingPathFallback,
|
||||
waitInterval = config.waitSeconds * 1000,
|
||||
//It is possible to disable the wait interval by using waitSeconds of 0.
|
||||
expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
|
||||
noLoads = [],
|
||||
stillLoading = false,
|
||||
needCycleCheck = true,
|
||||
map, modId, err, usingPathFallback;
|
||||
needCycleCheck = true;
|
||||
|
||||
//Do not bother if this call was a result of a cycle break.
|
||||
if (inCheckLoaded) {
|
||||
@@ -819,7 +834,7 @@ var requirejs, require, define;
|
||||
};
|
||||
|
||||
Module.prototype = {
|
||||
init: function(depMaps, factory, errback, options) {
|
||||
init: function (depMaps, factory, errback, options) {
|
||||
options = options || {};
|
||||
|
||||
//Do not do more inits if already done. Can happen if there
|
||||
@@ -916,7 +931,7 @@ var requirejs, require, define;
|
||||
}
|
||||
},
|
||||
|
||||
load: function() {
|
||||
load: function () {
|
||||
var url = this.map.url;
|
||||
|
||||
//Regular dependency.
|
||||
@@ -937,11 +952,11 @@ var requirejs, require, define;
|
||||
return;
|
||||
}
|
||||
|
||||
var id = this.map.id,
|
||||
var err, cjsModule,
|
||||
id = this.map.id,
|
||||
depExports = this.depExports,
|
||||
exports = this.exports,
|
||||
factory = this.factory,
|
||||
err, cjsModule;
|
||||
factory = this.factory;
|
||||
|
||||
if (!this.inited) {
|
||||
this.fetch();
|
||||
@@ -974,9 +989,9 @@ var requirejs, require, define;
|
||||
//favor a non-undefined return value over exports use.
|
||||
cjsModule = this.module;
|
||||
if (cjsModule &&
|
||||
cjsModule.exports !== undefined &&
|
||||
//Make sure it is not already the exports value
|
||||
cjsModule.exports !== this.exports) {
|
||||
cjsModule.exports !== undefined &&
|
||||
//Make sure it is not already the exports value
|
||||
cjsModule.exports !== this.exports) {
|
||||
exports = cjsModule.exports;
|
||||
} else if (exports === undefined && this.usingExports) {
|
||||
//exports already set the defined value.
|
||||
@@ -1032,15 +1047,15 @@ var requirejs, require, define;
|
||||
}
|
||||
},
|
||||
|
||||
callPlugin: function() {
|
||||
callPlugin: function () {
|
||||
var map = this.map,
|
||||
id = map.id,
|
||||
pluginMap = makeModuleMap(map.prefix, null, false, true);
|
||||
|
||||
on(pluginMap, 'defined', bind(this, function (plugin) {
|
||||
var name = this.map.name,
|
||||
parentName = this.map.parentMap ? this.map.parentMap.name : null,
|
||||
load, normalizedMap, normalizedMod;
|
||||
var load, normalizedMap, normalizedMod,
|
||||
name = this.map.name,
|
||||
parentName = this.map.parentMap ? this.map.parentMap.name : null;
|
||||
|
||||
//If current map is not normalized, wait for that
|
||||
//normalized name to load instead of continuing.
|
||||
@@ -1057,12 +1072,12 @@ var requirejs, require, define;
|
||||
false,
|
||||
true);
|
||||
on(normalizedMap,
|
||||
'defined', bind(this, function (value) {
|
||||
this.init([], function () { return value; }, null, {
|
||||
enabled: true,
|
||||
ignore: true
|
||||
});
|
||||
}));
|
||||
'defined', bind(this, function (value) {
|
||||
this.init([], function () { return value; }, null, {
|
||||
enabled: true,
|
||||
ignore: true
|
||||
});
|
||||
}));
|
||||
normalizedMod = registry[normalizedMap.id];
|
||||
if (normalizedMod) {
|
||||
if (this.events.error) {
|
||||
@@ -1127,9 +1142,9 @@ var requirejs, require, define;
|
||||
//Use parentName here since the plugin's name is not reliable,
|
||||
//could be some weird string with no path that actually wants to
|
||||
//reference the parentName's path.
|
||||
plugin.load(map.name, makeRequire(map.parentMap, true, function (deps, cb) {
|
||||
plugin.load(map.name, makeRequire(map.parentMap, true, function (deps, cb, er) {
|
||||
deps.rjsSkipMap = true;
|
||||
return context.require(deps, cb);
|
||||
return context.require(deps, cb, er);
|
||||
}), load, config);
|
||||
}));
|
||||
|
||||
@@ -1209,7 +1224,7 @@ var requirejs, require, define;
|
||||
this.check();
|
||||
},
|
||||
|
||||
on: function(name, cb) {
|
||||
on: function (name, cb) {
|
||||
var cbs = this.events[name];
|
||||
if (!cbs) {
|
||||
cbs = this.events[name] = [];
|
||||
@@ -1362,7 +1377,12 @@ var requirejs, require, define;
|
||||
//update the maps for them, since their info, like URLs to load,
|
||||
//may have changed.
|
||||
eachProp(registry, function (mod, id) {
|
||||
mod.map = makeModuleMap(id);
|
||||
//If module already has init called, since it is too
|
||||
//late to modify them, and ignore unnormalized ones
|
||||
//since they are transient.
|
||||
if (!mod.inited && !mod.map.unnormalized) {
|
||||
mod.map = makeModuleMap(id);
|
||||
}
|
||||
});
|
||||
|
||||
//If a deps array or a config callback is specified, then call
|
||||
@@ -1471,6 +1491,10 @@ var requirejs, require, define;
|
||||
},
|
||||
|
||||
undef: function (id) {
|
||||
//Bind any waiting define() calls to this context,
|
||||
//fix for #408
|
||||
takeGlobalQueue();
|
||||
|
||||
var map = makeModuleMap(id, null, true),
|
||||
mod = registry[id];
|
||||
|
||||
@@ -1509,9 +1533,9 @@ var requirejs, require, define;
|
||||
* @param {String} moduleName the name of the module to potentially complete.
|
||||
*/
|
||||
completeLoad: function (moduleName) {
|
||||
var shim = config.shim[moduleName] || {},
|
||||
shExports = shim.exports && shim.exports.exports,
|
||||
found, args, mod;
|
||||
var found, args, mod,
|
||||
shim = config.shim[moduleName] || {},
|
||||
shExports = shim.exports && shim.exports.exports;
|
||||
|
||||
takeGlobalQueue();
|
||||
|
||||
@@ -1538,9 +1562,7 @@ var requirejs, require, define;
|
||||
//of those calls/init calls changes the registry.
|
||||
mod = registry[moduleName];
|
||||
|
||||
if (!found &&
|
||||
!defined[moduleName] &&
|
||||
mod && !mod.inited) {
|
||||
if (!found && !defined[moduleName] && mod && !mod.inited) {
|
||||
if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
|
||||
if (hasPathFallback(moduleName)) {
|
||||
return;
|
||||
@@ -1633,7 +1655,8 @@ var requirejs, require, define;
|
||||
}
|
||||
|
||||
//Join the path parts together, then figure out if baseUrl is needed.
|
||||
url = syms.join('/') + (ext || '.js');
|
||||
url = syms.join('/');
|
||||
url += (ext || (/\?/.test(url) ? '' : '.js'));
|
||||
url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
|
||||
}
|
||||
|
||||
@@ -1670,7 +1693,7 @@ var requirejs, require, define;
|
||||
//all old browsers will be supported, but this one was easy enough
|
||||
//to support and still makes sense.
|
||||
if (evt.type === 'load' ||
|
||||
(readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
|
||||
(readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
|
||||
//Reset interactive script so a script node is not held onto for
|
||||
//to long.
|
||||
interactiveScript = null;
|
||||
@@ -1710,8 +1733,8 @@ var requirejs, require, define;
|
||||
req = requirejs = function (deps, callback, errback, optional) {
|
||||
|
||||
//Find the right context, use default
|
||||
var contextName = defContextName,
|
||||
context, config;
|
||||
var context, config,
|
||||
contextName = defContextName;
|
||||
|
||||
// Determine if have config object in the call.
|
||||
if (!isArray(deps) && typeof deps !== 'string') {
|
||||
@@ -1810,8 +1833,8 @@ var requirejs, require, define;
|
||||
if (isBrowser) {
|
||||
//In the browser so use a script tag
|
||||
node = config.xhtml ?
|
||||
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
|
||||
document.createElement('script');
|
||||
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
|
||||
document.createElement('script');
|
||||
node.type = config.scriptType || 'text/javascript';
|
||||
node.charset = 'utf-8';
|
||||
node.async = true;
|
||||
@@ -1828,15 +1851,15 @@ var requirejs, require, define;
|
||||
//UNFORTUNATELY Opera implements attachEvent but does not follow the script
|
||||
//script execution mode.
|
||||
if (node.attachEvent &&
|
||||
//Check if node.attachEvent is artificially added by custom script or
|
||||
//natively supported by browser
|
||||
//read https://github.com/jrburke/requirejs/issues/187
|
||||
//if we can NOT find [native code] then it must NOT natively supported.
|
||||
//in IE8, node.attachEvent does not have toString()
|
||||
//Note the test for "[native code" with no closing brace, see:
|
||||
//https://github.com/jrburke/requirejs/issues/273
|
||||
!(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
|
||||
!isOpera) {
|
||||
//Check if node.attachEvent is artificially added by custom script or
|
||||
//natively supported by browser
|
||||
//read https://github.com/jrburke/requirejs/issues/187
|
||||
//if we can NOT find [native code] then it must NOT natively supported.
|
||||
//in IE8, node.attachEvent does not have toString()
|
||||
//Note the test for "[native code" with no closing brace, see:
|
||||
//https://github.com/jrburke/requirejs/issues/273
|
||||
!(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
|
||||
!isOpera) {
|
||||
//Probably IE. IE (at least 6-8) do not fire
|
||||
//script onload right after executing the script, so
|
||||
//we cannot tie the anonymous define call to a name.
|
||||
|
||||
12
vendor/underscore/test/collections.js
vendored
12
vendor/underscore/test/collections.js
vendored
@@ -253,6 +253,18 @@ $(document).ready(function() {
|
||||
equal(grouped['5'].join(' '), 'three seven eight');
|
||||
});
|
||||
|
||||
test('collections: countBy', function() {
|
||||
var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; });
|
||||
equal(parity['true'], 2);
|
||||
equal(parity['false'], 3);
|
||||
|
||||
var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
|
||||
var grouped = _.countBy(list, 'length');
|
||||
equal(grouped['3'], 4);
|
||||
equal(grouped['4'], 3);
|
||||
equal(grouped['5'], 3);
|
||||
});
|
||||
|
||||
test('collections: sortedIndex', function() {
|
||||
var numbers = [10, 20, 30, 40, 50], num = 35;
|
||||
var indexForNum = _.sortedIndex(numbers, num);
|
||||
|
||||
32
vendor/underscore/underscore-min.js
vendored
Normal file
32
vendor/underscore/underscore-min.js
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Underscore.js 1.3.3
|
||||
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Underscore is freely distributable under the MIT license.
|
||||
// Portions of Underscore are inspired or borrowed from Prototype,
|
||||
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
||||
// For all details and documentation:
|
||||
// http://documentcloud.github.com/underscore
|
||||
(function(){var s=this,L=s._,p={},k=Array.prototype,q=Object.prototype,M=k.push,i=k.slice,N=k.unshift,m=q.toString,O=q.hasOwnProperty,z=k.forEach,A=k.map,B=k.reduce,C=k.reduceRight,D=k.filter,E=k.every,F=k.some,r=k.indexOf,G=k.lastIndexOf,q=Array.isArray,P=Object.keys,t=Function.prototype.bind,b=function(a){return new l(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a,c,
|
||||
d){if(a!=null)if(z&&a.forEach===z)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(c.call(d,a[e],e,a)===p)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===p)break};b.map=b.collect=function(a,c,d){var b=[];if(a==null)return b;if(A&&a.map===A)return a.map(c,d);j(a,function(a,g,h){b[b.length]=c.call(d,a,g,h)});return b};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduce===B){e&&(c=b.bind(c,e));return f?a.reduce(c,
|
||||
d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(C&&a.reduceRight===C){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,c,b){var e;H(a,function(a,g,h){if(c.call(b,a,g,h)){e=
|
||||
a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(D&&a.filter===D)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(E&&a.every===E)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,a,g,h)))return p});return!!e};var H=b.some=b.any=
|
||||
function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(F&&a.some===F)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return p});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(r&&a.indexOf===r)return a.indexOf(c)!=-1;return b=H(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};
|
||||
b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0]&&a.length<65535)return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0]&&a.length<65535)return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
|
||||
return e.value};b.shuffle=function(a){var c,b=0,e=[];j(a,function(a){c=Math.floor(Math.random()*++b);e[b-1]=e[c];e[c]=a});return e};b.sortBy=function(a,c,d){var e=I(a,c);return b.pluck(b.map(a,function(a,c,b){return{value:a,criteria:e.call(d,a,c,b)}}).sort(function(a,c){var b=a.criteria,d=c.criteria;return b===void 0?1:d===void 0?-1:b<d?-1:b>d?1:0}),"value")};var I=function(a,c){return b.isFunction(c)?c:function(a){return a[c]}},J=function(a,c,b){var e={},f=I(a,c);j(a,function(a,c){var i=f(a,c);b(e,
|
||||
i,a)});return e};b.groupBy=function(a,c){return J(a,c,function(a,c,b){(a[c]||(a[c]=[])).push(b)})};b.countBy=function(a,c){return J(a,c,function(a,c){a[c]||(a[c]=0);a[c]++})};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var c=d(c),e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<c?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:b.isArray(a)||b.isArguments(a)?i.call(a):a.toArray&&b.isFunction(a.toArray)?a.toArray():b.values(a)};b.size=function(a){return b.isArray(a)?a.length:b.keys(a).length};
|
||||
b.first=b.head=b.take=function(a,c,b){return c!=null&&!b?i.call(a,0,c):a[0]};b.initial=function(a,c,b){return i.call(a,0,a.length-(c==null||b?1:c))};b.last=function(a,c,b){return c!=null&&!b?i.call(a,Math.max(a.length-c,0)):a[a.length-1]};b.rest=b.tail=function(a,c,b){return i.call(a,c==null||b?1:c)};b.compact=function(a){return b.filter(a,function(a){return!!a})};var n=function(a,c,d){j(a,function(a){b.isArray(a)?c?M.apply(d,a):n(a,c,d):d.push(a)});return d};b.flatten=function(a,c){return n(a,c,
|
||||
[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(c?b.last(d)!==g||!d.length:!b.include(d,g)){d.push(g);e.push(a[h])}return d},[]);return e};b.union=function(){return b.uniq(n(arguments,true,[]))};b.intersection=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=n(i.call(arguments,
|
||||
1),true,[]);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.zipObject=function(a,c){for(var b={},e=0,f=a.length;e<f;e++)b[a[e]]=c[e];return b};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d){d=b.sortedIndex(a,c);return a[d]===c?d:-1}if(r&&a.indexOf===r)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,
|
||||
c){if(a==null)return-1;if(G&&a.lastIndexOf===G)return a.lastIndexOf(c);for(var b=a.length;b--;)if(a[b]===c)return b;return-1};b.range=function(a,c,b){if(arguments.length<=1){c=a||0;a=0}for(var b=arguments[2]||1,e=Math.max(Math.ceil((c-a)/b),0),f=0,g=Array(e);f<e;){g[f++]=a;a=a+b}return g};var K=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,
|
||||
e.concat(i.call(arguments)));K.prototype=a.prototype;var b=new K,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,c){var b=i.call(arguments,2);return setTimeout(function(){return a.apply(null,
|
||||
b)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i,j=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);j()},c));if(g)h=true;else{g=true;i=a.apply(d,e)}j();return i}};b.debounce=function(a,b,d){var e;return function(){var f=this,g=arguments,h=d&&!e;clearTimeout(e);e=setTimeout(function(){e=null;d||a.apply(f,g)},b);h&&a.apply(f,g)}};b.once=function(a){var b=
|
||||
false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=P||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,
|
||||
d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var b={};j(n(i.call(arguments,1),true,[]),function(d){d in a&&(b[d]=a[d])});return b};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?
|
||||
a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};var u=function(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=m.call(a);if(e!=m.call(c))return false;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==
|
||||
+c;case "[object RegExp]":return a.source==c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){f=a.length;if(g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&u(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)){f++;if(!(g=b.has(c,h)&&
|
||||
u(a[h],c[h],d)))break}if(g){for(h in c)if(b.has(c,h)&&!f--)break;g=!f}}d.pop();return g};b.isEqual=function(a,b){return u(a,b,[])};b.isEmpty=function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=q||function(a){return m.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};j("Arguments,Function,String,Number,Date,RegExp".split(","),function(a){b["is"+
|
||||
a]=function(b){return m.call(b)=="[object "+a+"]"}});b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||m.call(a)=="[object Boolean]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return O.call(a,b)};b.noConflict=function(){s._=L;return this};b.identity=function(a){return a};
|
||||
b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};var Q={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},R=/[&<>"'\/]/g;b.escape=function(a){return(""+a).replace(R,function(a){return Q[a]})};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){S(c,b[c]=a[c])})};var T=0;b.uniqueId=function(a){var b=T++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,
|
||||
escape:/<%-([\s\S]+?)%>/g};var v=/.^/,o={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},w;for(w in o)o[o[w]]=w;var U=/\\|'|\r|\n|\t|\u2028|\u2029/g,V=/\\(\\|'|r|n|t|u2028|u2029)/g,x=function(a){return a.replace(V,function(a,b){return o[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(U,function(a){return"\\"+o[a]}).replace(d.escape||v,function(a,b){return"'+\n((__t=("+x(b)+"))==null?'':_.escape(__t))+\n'"}).replace(d.interpolate||
|
||||
v,function(a,b){return"'+\n((__t=("+x(b)+"))==null?'':__t)+\n'"}).replace(d.evaluate||v,function(a,b){return"';\n"+x(b)+"\n__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};b.chain=function(a){return b(a).chain()};
|
||||
var l=function(a){this._wrapped=a};b.prototype=l.prototype;var y=function(a,c){return c?b(a).chain():a},S=function(a,c){l.prototype[a]=function(){var a=i.call(arguments);N.call(a,this._wrapped);return y(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];l.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);(a=="shift"||a=="splice")&&d.length===0&&delete d[0];return y(d,this._chain)}});j(["concat","join","slice"],function(a){var b=
|
||||
k[a];l.prototype[a]=function(){return y(b.apply(this._wrapped,arguments),this._chain)}});l.prototype.chain=function(){this._chain=true;return this};l.prototype.value=function(){return this._wrapped}}).call(this);
|
||||
40
vendor/underscore/underscore.js
vendored
40
vendor/underscore/underscore.js
vendored
@@ -267,7 +267,7 @@
|
||||
|
||||
// Sort the object's values by a criterion produced by an iterator.
|
||||
_.sortBy = function(obj, val, context) {
|
||||
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
|
||||
var iterator = lookupIterator(obj, val);
|
||||
return _.pluck(_.map(obj, function(value, index, list) {
|
||||
return {
|
||||
value : value,
|
||||
@@ -281,16 +281,38 @@
|
||||
}), 'value');
|
||||
};
|
||||
|
||||
// An internal function to generate lookup iterators.
|
||||
var lookupIterator = function(obj, val) {
|
||||
return _.isFunction(val) ? val : function(obj) { return obj[val]; };
|
||||
};
|
||||
|
||||
// An internal function used for aggregate "group by" operations.
|
||||
var group = function(obj, val, behavior) {
|
||||
var result = {};
|
||||
var iterator = lookupIterator(obj, val);
|
||||
each(obj, function(value, index) {
|
||||
var key = iterator(value, index);
|
||||
behavior(result, key, value);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
// Groups the object's values by a criterion. Pass either a string attribute
|
||||
// to group by, or a function that returns the criterion.
|
||||
_.groupBy = function(obj, val) {
|
||||
var result = {};
|
||||
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
|
||||
each(obj, function(value, index) {
|
||||
var key = iterator(value, index);
|
||||
return group(obj, val, function(result, key, value) {
|
||||
(result[key] || (result[key] = [])).push(value);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
// Counts instances of an object that group by a certain criterion. Pass
|
||||
// either a string attribute to count by, or a function that returns the
|
||||
// criterion.
|
||||
_.countBy = function(obj, val) {
|
||||
return group(obj, val, function(result, key, value) {
|
||||
result[key] || (result[key] = 0);
|
||||
result[key]++;
|
||||
});
|
||||
};
|
||||
|
||||
// Use a comparator function to figure out the smallest index at which
|
||||
@@ -709,7 +731,7 @@
|
||||
};
|
||||
|
||||
// Internal recursive comparison function for `isEqual`.
|
||||
function eq(a, b, stack) {
|
||||
var eq = function(a, b, stack) {
|
||||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||||
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
|
||||
if (a === b) return a !== 0 || 1 / a == 1 / b;
|
||||
@@ -794,7 +816,7 @@
|
||||
// Remove the first object from the stack of traversed objects.
|
||||
stack.pop();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// Perform a deep comparison to check if two objects are equal.
|
||||
_.isEqual = function(a, b) {
|
||||
@@ -832,7 +854,7 @@
|
||||
return toString.call(obj) == '[object ' + name + ']';
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
// Define a fallback version of the method in browsers (ahem, IE), where
|
||||
// there isn't any inspectable "Arguments" type.
|
||||
if (!_.isArguments(arguments)) {
|
||||
|
||||
Reference in New Issue
Block a user