mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-29 14:37:49 +00:00
Compare commits
224 Commits
0.8.2
...
1.0.0-rc.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54b862bd79 | ||
|
|
e37e1c109a | ||
|
|
939123785b | ||
|
|
221b347bd9 | ||
|
|
af9bf3e852 | ||
|
|
ed8746df77 | ||
|
|
bb187db49d | ||
|
|
081e72b3ea | ||
|
|
6188c38053 | ||
|
|
12b0186f5a | ||
|
|
9bccc9c53c | ||
|
|
351b2b320e | ||
|
|
94258feb09 | ||
|
|
8b0f033a78 | ||
|
|
f58f255fc8 | ||
|
|
e3eabcf648 | ||
|
|
9aa506cbd7 | ||
|
|
d8cff7b90f | ||
|
|
07e7bca9eb | ||
|
|
e1f442be90 | ||
|
|
c5d579e0e3 | ||
|
|
5271c2e08f | ||
|
|
9010a7ddbc | ||
|
|
bb95fb7d07 | ||
|
|
2edb11376d | ||
|
|
e7f5ebf912 | ||
|
|
da9758c2f3 | ||
|
|
3e11d58d73 | ||
|
|
6b35c097d6 | ||
|
|
619ba13265 | ||
|
|
529c5b8abf | ||
|
|
3a5ed6e800 | ||
|
|
52cddc015b | ||
|
|
4a01f4f65f | ||
|
|
f9768cb5a3 | ||
|
|
221e0e550c | ||
|
|
d2d1d42d0f | ||
|
|
faf018a097 | ||
|
|
a2a71a107e | ||
|
|
fc9c937e67 | ||
|
|
b4f2e9b442 | ||
|
|
1672645e73 | ||
|
|
4a42c44101 | ||
|
|
383b1a5769 | ||
|
|
77bac4cf9e | ||
|
|
e2b8e530c9 | ||
|
|
e9f752bd67 | ||
|
|
4b31921eb4 | ||
|
|
3df9fc6225 | ||
|
|
b57fe466ce | ||
|
|
bd4bff3b6b | ||
|
|
9d4618a223 | ||
|
|
93636180df | ||
|
|
fcceaa168f | ||
|
|
2639cc6138 | ||
|
|
4a99c2e928 | ||
|
|
7d5af3df05 | ||
|
|
c88b80d2a0 | ||
|
|
819d4abaa2 | ||
|
|
20630aeb47 | ||
|
|
0c0db3babb | ||
|
|
e7761f7e57 | ||
|
|
064fd497ae | ||
|
|
49c60b6b75 | ||
|
|
ca7f36506c | ||
|
|
155f0a9736 | ||
|
|
25e1eb3ce9 | ||
|
|
f2f980928b | ||
|
|
1d121a97a7 | ||
|
|
211d13da09 | ||
|
|
11343d469e | ||
|
|
d7c8041aa1 | ||
|
|
9587e30af8 | ||
|
|
76fa7affaf | ||
|
|
2971dd8672 | ||
|
|
2a33fe3564 | ||
|
|
46cdf5da70 | ||
|
|
28c801bfd4 | ||
|
|
c22cd40293 | ||
|
|
56bd430983 | ||
|
|
d873890e46 | ||
|
|
d29b8eca3c | ||
|
|
6f258000fe | ||
|
|
255211cd07 | ||
|
|
f6d28a90e3 | ||
|
|
ed66ff88a1 | ||
|
|
82e58f2bf9 | ||
|
|
797a87ca26 | ||
|
|
ec6a709393 | ||
|
|
07cbfdb424 | ||
|
|
3b9bd944fb | ||
|
|
934e585cb3 | ||
|
|
3a68f4cf54 | ||
|
|
bd00fcb875 | ||
|
|
905dd5a70f | ||
|
|
c65250ec39 | ||
|
|
607eec6ff0 | ||
|
|
14fb3bde60 | ||
|
|
6782bc8ca2 | ||
|
|
3db6841305 | ||
|
|
f478fa8029 | ||
|
|
d255f8400f | ||
|
|
a1545c60d6 | ||
|
|
ed48603ab5 | ||
|
|
23a0507439 | ||
|
|
482e013887 | ||
|
|
265727c30f | ||
|
|
4d3f4e096b | ||
|
|
7629bca62d | ||
|
|
2712f17262 | ||
|
|
86a37559ba | ||
|
|
b504a557f4 | ||
|
|
e849b46f6b | ||
|
|
738dc50a6f | ||
|
|
3138523b5b | ||
|
|
537643a4c3 | ||
|
|
04bfe098ed | ||
|
|
c507887bdd | ||
|
|
ee261313ac | ||
|
|
c9c152bc8a | ||
|
|
6c8e19a321 | ||
|
|
218e3b66f2 | ||
|
|
1d3488fa8e | ||
|
|
f4c1682592 | ||
|
|
28ac6623c7 | ||
|
|
16ab179e1d | ||
|
|
a8ff5385dc | ||
|
|
9dc33c6086 | ||
|
|
b17c576705 | ||
|
|
96f8f2891b | ||
|
|
581d73afe0 | ||
|
|
1baefebe8f | ||
|
|
39fb05033f | ||
|
|
c6093c084c | ||
|
|
dfec6d9a6d | ||
|
|
08b1261c75 | ||
|
|
2ad6faae3a | ||
|
|
4eff301db3 | ||
|
|
447e43e8f4 | ||
|
|
7457001275 | ||
|
|
fcabd5e79e | ||
|
|
594002316c | ||
|
|
eccf92ebaf | ||
|
|
ad9ddc5621 | ||
|
|
1825dd916e | ||
|
|
dfcde8171e | ||
|
|
b0361183df | ||
|
|
71fe13b249 | ||
|
|
442f51224d | ||
|
|
974678f500 | ||
|
|
8329409c03 | ||
|
|
06c2ac2724 | ||
|
|
04e9e8f9d8 | ||
|
|
7a3330cb8c | ||
|
|
cae29941ea | ||
|
|
15cf2ad076 | ||
|
|
2f16f6dc23 | ||
|
|
528aebffe4 | ||
|
|
e82b2f0cbe | ||
|
|
73e64f3e4a | ||
|
|
15f5b1f830 | ||
|
|
1b0a77f9a8 | ||
|
|
0f82ae3644 | ||
|
|
de3b01b54b | ||
|
|
c17e3646d5 | ||
|
|
26aed3e89e | ||
|
|
74caea8f8f | ||
|
|
2cf07fa072 | ||
|
|
1181cd2fd7 | ||
|
|
850d55ab45 | ||
|
|
a0c91b8754 | ||
|
|
937bdc05c8 | ||
|
|
453755bfa1 | ||
|
|
400b6fbb61 | ||
|
|
8c4e882fa3 | ||
|
|
84eec23793 | ||
|
|
7dfe69f6a5 | ||
|
|
ada6115073 | ||
|
|
e1643566f9 | ||
|
|
053a9a6317 | ||
|
|
425b976cc0 | ||
|
|
5f5f1b1e09 | ||
|
|
e6f4935c7b | ||
|
|
6452e5976b | ||
|
|
2383dff317 | ||
|
|
de3e5042fb | ||
|
|
0dcc35152c | ||
|
|
8eecfcbfaf | ||
|
|
efa3e60f89 | ||
|
|
782df659bc | ||
|
|
0aa158824f | ||
|
|
da7fb44e5d | ||
|
|
4b59ef802e | ||
|
|
be5789cd56 | ||
|
|
9adf0e5d59 | ||
|
|
e2de22470e | ||
|
|
3b7ab2e553 | ||
|
|
8617dedc46 | ||
|
|
0b8f1a9a58 | ||
|
|
16748c0920 | ||
|
|
01ec585a44 | ||
|
|
b5f2295f37 | ||
|
|
d6ca0199b7 | ||
|
|
2257c5e547 | ||
|
|
b5a3d39799 | ||
|
|
a26c3e9d3c | ||
|
|
98a09532eb | ||
|
|
d736789bbc | ||
|
|
82a6cfc03a | ||
|
|
62e9c7c75a | ||
|
|
eb32bd45e7 | ||
|
|
4b95f07923 | ||
|
|
dea8ad4c49 | ||
|
|
96553b217c | ||
|
|
3f79ed5d91 | ||
|
|
1e4283aad3 | ||
|
|
1dda31a28c | ||
|
|
10c87012be | ||
|
|
bda00bf512 | ||
|
|
c8f871ff2a | ||
|
|
58dc0b1aef | ||
|
|
4cd4d8f31a | ||
|
|
b751fd738d | ||
|
|
f97c6fb94c |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
*.custom.*
|
||||
.DS_Store
|
||||
*.custom.*
|
||||
node_modules/
|
||||
vendor/closure-compiler/
|
||||
vendor/uglifyjs/
|
||||
|
||||
16
.jamignore
16
.jamignore
@@ -1,14 +1,12 @@
|
||||
*.custom.*
|
||||
.*
|
||||
*.custom.*
|
||||
*.md
|
||||
*.txt
|
||||
build.js
|
||||
index.js
|
||||
build/
|
||||
doc/*.php
|
||||
doc/
|
||||
node_modules/
|
||||
perf/*.sh
|
||||
test/*.sh
|
||||
test/test-build.js
|
||||
test/template/
|
||||
vendor/closure-compiler
|
||||
vendor/docdown
|
||||
vendor/uglifyjs
|
||||
perf/
|
||||
test/
|
||||
vendor/
|
||||
|
||||
14
.npmignore
14
.npmignore
@@ -1,15 +1,25 @@
|
||||
*.custom.*
|
||||
.*
|
||||
*.custom.*
|
||||
*.d.ts
|
||||
doc/*.php
|
||||
node_modules/
|
||||
perf/*.html
|
||||
perf/*-ui.js
|
||||
perf/*.sh
|
||||
test/*.html
|
||||
test/*-ui.js
|
||||
test/*.sh
|
||||
vendor/*.gz
|
||||
vendor/backbone/
|
||||
vendor/docdown/
|
||||
vendor/benchmark.js/*.jar
|
||||
vendor/closure-compiler
|
||||
vendor/docdown
|
||||
vendor/firebug-lite/
|
||||
vendor/json3/
|
||||
vendor/jquery/
|
||||
vendor/qunit/qunit/*.css
|
||||
vendor/qunit/qunit/*-1.8.0.js
|
||||
vendor/requirejs/
|
||||
vendor/underscore/*-min.js
|
||||
vendor/uglifyjs
|
||||
vendor/underscore/test/
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
- 0.8
|
||||
before_script:
|
||||
- "curl -H 'Accept: application/vnd.github.v3.raw' https://api.github.com/repos/bestiejs/lodash/git/blobs/a2787b470c577cee2404d186c562dd9835f779f5 | tar xvz -C vendor"
|
||||
- "curl -H 'Accept: application/vnd.github.v3.raw' https://api.github.com/repos/bestiejs/lodash/git/blobs/3390b259e04829538e4d3635d12b317dd6103eca | tar xvz -C vendor"
|
||||
|
||||
172
README.md
172
README.md
@@ -1,17 +1,25 @@
|
||||
# Lo-Dash <sup>v0.8.2</sup>
|
||||
# Lo-Dash <sup>v1.0.0-rc.2</sup>
|
||||
[](http://travis-ci.org/bestiejs/lodash)
|
||||
|
||||
A drop-in replacement<sup>[*](https://github.com/bestiejs/lodash/wiki/Drop-in-Disclaimer)</sup> for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), delivering [performance](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#resolved-underscorejs-issues), and [additional features](http://lodash.com/#features).
|
||||
|
||||
Lo-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.
|
||||
A utility library, usable as a drop-in replacement for Underscore, delivering [performance](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#resolved-underscorejs-issues), and [additional features](http://lodash.com/#features).
|
||||
|
||||
## Download
|
||||
|
||||
* [Development build](https://raw.github.com/bestiejs/lodash/v0.8.2/lodash.js)
|
||||
* [Production build](https://raw.github.com/bestiejs/lodash/v0.8.2/lodash.min.js)
|
||||
* [Underscore build](https://raw.github.com/bestiejs/lodash/v0.8.2/lodash.underscore.min.js) tailored for projects already using Underscore
|
||||
* CDN copies of ≤ [v0.8.2](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.8.2/lodash.min.js) are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/)
|
||||
* For optimal file size, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
|
||||
* Lo-Dash builds:<br>
|
||||
[Development](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.2/lodash.js) and
|
||||
[Production](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.2/lodash.min.js)
|
||||
|
||||
* Underscore builds:<br>
|
||||
[Development](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.2/lodash.underscore.js) and
|
||||
[Production](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.2/lodash.underscore.min.js)
|
||||
|
||||
* CDN copies of ≤ v1.0.0-rc.2’s builds are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/):<br>
|
||||
[Lo-Dash development](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.js),
|
||||
[Lo-Dash production](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.min.js),
|
||||
[Underscore development](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.underscore.js), and
|
||||
[Underscore production](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.underscore.min.js)
|
||||
|
||||
* For optimal file size, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
|
||||
|
||||
## Dive in
|
||||
|
||||
@@ -30,26 +38,29 @@ For more information check out these screencasts over Lo-Dash:
|
||||
* [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)
|
||||
* [Lo-Dash’s approach to native method use](https://vimeo.com/48576012)
|
||||
* [CascadiaJS: Lo-Dash for a better utility belt](http://www.youtube.com/watch?v=dpPy4f_SeEk)
|
||||
|
||||
## Features
|
||||
|
||||
* AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
|
||||
* [_(…)](http://lodash.com/docs#_) supports intuitive chaining without calling [_(…).chain](http://lodash.com/docs#prototype_chain)
|
||||
* [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”* defined](http://michaux.ca/articles/lazy-function-definition-pattern) methods
|
||||
* [_.clone](http://lodash.com/docs#clone) supports *“deep”* cloning
|
||||
* [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` argument
|
||||
* [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early
|
||||
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an object’s own and inherited properties
|
||||
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an object’s own properties
|
||||
* [_.isPlainObject](http://lodash.com/docs#isPlainObject) checks if values are created by the `Object` constructor
|
||||
* [_.lateBind](http://lodash.com/docs#lateBind) for late binding
|
||||
* [_.merge](http://lodash.com/docs#merge) for a *“deep”* [_.extend](http://lodash.com/docs#extend)
|
||||
* [_.partial](http://lodash.com/docs#partial) for partial application without `this` binding
|
||||
* [_.pick](http://lodash.com/docs#pick) and [_.omit](http://lodash.com/docs#omit) accept `callback` and `thisArg` arguments
|
||||
* [_.template](http://lodash.com/docs#template) utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
|
||||
* [_.pick](http://lodash.com/docs#pick) and [_.omit](http://lodash.com/docs#omit) accepts `callback` and `thisArg` arguments
|
||||
* [_.template](http://lodash.com/docs#template) supports [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6) and utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
|
||||
* [_.contains](http://lodash.com/docs#contains), [_.size](http://lodash.com/docs#size), [_.toArray](http://lodash.com/docs#toArray),
|
||||
[and more…](http://lodash.com/docs "_.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.pluck, _.reduce, _.reduceRight, _.reject, _.some, _.sortBy, _.where") accept strings
|
||||
[and more…](http://lodash.com/docs "_.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.some, _.sortBy, _.where") accept strings
|
||||
|
||||
## Support
|
||||
|
||||
Lo-Dash has been tested in at least Chrome 5~22, Firefox 1~16, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.11, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
||||
Lo-Dash has been tested in at least Chrome 5~23, Firefox 1~16, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.15, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
||||
|
||||
## Custom builds
|
||||
|
||||
@@ -61,7 +72,8 @@ To top it off, we handle all method dependency and alias mapping for you.
|
||||
lodash backbone
|
||||
```
|
||||
|
||||
* CSP builds, supporting default Content Security Policy restrictions, may be created using the `csp` modifier argument.
|
||||
* CSP builds, supporting default [Content Security Policy](http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html) restrictions, may be created using the `csp` modifier argument.
|
||||
The `csp` modifier is an alais of the `mobile` modifier. Chrome extensions will require [sandboxing](http://developer.chrome.com/trunk/extensions/sandboxingEval.html) or the use of either the `csp`, `mobile`, or `underscore` build.
|
||||
```bash
|
||||
lodash csp
|
||||
```
|
||||
@@ -125,14 +137,19 @@ lodash backbone plus=random,template
|
||||
lodash backbone plus="random, template"
|
||||
```
|
||||
|
||||
* Use the `template` argument to pass the file path pattern used to match template files to precompile
|
||||
* Use the `template` argument to pass the file path pattern used to match template files to precompile.
|
||||
```bash
|
||||
lodash template="./*.jst"
|
||||
```
|
||||
|
||||
* Use the `settings` argument to pass the template settings used when precompiling templates
|
||||
* Use the `settings` argument to pass the template settings used when precompiling templates.
|
||||
```bash
|
||||
lodash settings="{interpolate:/\\{\\{([\\s\\S]+?)\\}\\}/g}"
|
||||
```
|
||||
|
||||
* Use the `moduleId` argument to specify the AMD module ID of Lo-Dash, which defaults to “lodash”, used by precompiled templates.
|
||||
```bash
|
||||
lodash moduleId="underscore"
|
||||
```
|
||||
|
||||
All arguments, except `legacy` with `csp` or `mobile`, may be combined.<br>
|
||||
@@ -158,7 +175,7 @@ In browsers:
|
||||
<script src="lodash.js"></script>
|
||||
```
|
||||
|
||||
Using [npm](http://npmjs.org/):
|
||||
Using [`npm`](http://npmjs.org/):
|
||||
|
||||
```bash
|
||||
npm install lodash
|
||||
@@ -167,13 +184,22 @@ npm install -g lodash
|
||||
npm link lodash
|
||||
```
|
||||
|
||||
To avoid potential issues, update `npm` before installing Lo-Dash:
|
||||
|
||||
```bash
|
||||
npm install npm -g
|
||||
```
|
||||
|
||||
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
|
||||
|
||||
```js
|
||||
var _ = require('lodash');
|
||||
|
||||
// or as a drop-in replacement for Underscore
|
||||
var _ = require('lodash/lodash.underscore');
|
||||
```
|
||||
|
||||
**Note:** If Lo-Dash is installed globally, [run `npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory before attempting to `require` it.
|
||||
**Note:** If Lo-Dash is installed globally, run [`npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory before requiring it.
|
||||
|
||||
In [RingoJS v0.7.0-](http://ringojs.org/):
|
||||
|
||||
@@ -202,89 +228,39 @@ require({
|
||||
|
||||
## Resolved Underscore.js issues
|
||||
|
||||
* Add AMD loader support [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L118-140)]
|
||||
* Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L510-516)]
|
||||
* 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.8.2/test/test.js#L470-487)]
|
||||
* 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.8.2/test/test.js#L523-547)]
|
||||
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [#742](https://github.com/documentcloud/underscore/issues/742), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L142-148)]
|
||||
* `_.clone` should allow `deep` cloning [[#595](https://github.com/documentcloud/underscore/pull/595), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L214-225)]
|
||||
* `_.contains` should work with strings [[#667](https://github.com/documentcloud/underscore/pull/667), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L267-276)]
|
||||
* `_.extend` should recursively extend objects [[#379](https://github.com/documentcloud/underscore/pull/379), [#718](https://github.com/documentcloud/underscore/issues/718), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L968-990)]
|
||||
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L465-468)]
|
||||
* `_.forEach` should allow exiting iteration early [[#211](https://github.com/documentcloud/underscore/issues/211), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L553-571)]
|
||||
* `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L712-717)]
|
||||
* `_.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.8.2/test/test.js#L772-784)]
|
||||
* `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L865-867)]
|
||||
* `_.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.8.2/test/test.js#L1243-1246)]
|
||||
|
||||
## Optimized methods <sup>(50+)</sup>
|
||||
|
||||
* `_.bind`
|
||||
* `_.bindAll`
|
||||
* `_.compact`
|
||||
* `_.contains`, `_.include`
|
||||
* `_.defaults`
|
||||
* `_.difference`
|
||||
* `_.each`
|
||||
* `_.every`, `_.all`
|
||||
* `_.extend`
|
||||
* `_.filter`, `_.select`
|
||||
* `_.find`, `_.detect`
|
||||
* `_.flatten`
|
||||
* `_.forEach`, `_.each`
|
||||
* `_.functions`, `_.methods`
|
||||
* `_.groupBy`
|
||||
* `_.indexOf`
|
||||
* `_.intersection`
|
||||
* `_.invert`
|
||||
* `_.invoke`
|
||||
* `_.isArguments`
|
||||
* `_.isDate`
|
||||
* `_.isFinite`
|
||||
* `_.isFunction`
|
||||
* `_.isObject`
|
||||
* `_.isNumber`
|
||||
* `_.isRegExp`
|
||||
* `_.isString`
|
||||
* `_.keys`
|
||||
* `_.lastIndexOf`
|
||||
* `_.map`, `_.collect`
|
||||
* `_.max`
|
||||
* `_.memoize`
|
||||
* `_.min`
|
||||
* `_.mixin`
|
||||
* `_.omit`
|
||||
* `_.pairs`
|
||||
* `_.pick`
|
||||
* `_.pluck`
|
||||
* `_.reduce`, `_.foldl`, `_.inject`
|
||||
* `_.reject`
|
||||
* `_.result`
|
||||
* `_.shuffle`
|
||||
* `_.some`, `_.any`
|
||||
* `_.sortBy`
|
||||
* `_.sortedIndex`
|
||||
* `_.template`
|
||||
* `_.throttle`
|
||||
* `_.toArray`
|
||||
* `_.union`
|
||||
* `_.uniq`, `_.unique`
|
||||
* `_.values`
|
||||
* `_.where`
|
||||
* `_.without`
|
||||
* `_.wrap`
|
||||
* `_.zip`
|
||||
* plus all `_(…)` method wrappers
|
||||
* Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L605-L611)]
|
||||
* Fix cross-browser object iteration bugs [[#60](https://github.com/documentcloud/underscore/issues/60), [#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L618-L642)]
|
||||
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [#742](https://github.com/documentcloud/underscore/issues/742), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L140-L146)]
|
||||
* `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L807-L812)]
|
||||
* `_.isObject` should avoid V8 bug [#2291](http://code.google.com/p/v8/issues/detail?id=2291) [[#605](https://github.com/documentcloud/underscore/issues/605), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L888-L900)]
|
||||
* `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L981-L983)]
|
||||
* `_.range` should coerce arguments to numbers [[#634](https://github.com/documentcloud/underscore/issues/634), [#683](https://github.com/documentcloud/underscore/issues/683), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L1382-L1385)]
|
||||
|
||||
## Release Notes
|
||||
|
||||
### <sup>v0.8.2</sup>
|
||||
### <sup>v1.0.0-rc.2</sup> ###
|
||||
|
||||
* Ensured `_.map` returns an array when passed a falsey collection
|
||||
* Ensured `_.throttle` clears its timeout when `func` is called
|
||||
* Made `_.max`, `_.min`, `_.shuffle` support iterating objects
|
||||
* Reduced `createIterator`, `_.clone`, and `_.compact`
|
||||
* Re-optimized `_.max`, `_.min`, and `_.sortedIndex`
|
||||
* Specified more method chaining behaviors
|
||||
* Updated `underscore` build compatibility to v1.4.3
|
||||
|
||||
### <sup>v1.0.0-rc.1</sup> ###
|
||||
|
||||
#### Compatibility Warnings ####
|
||||
|
||||
* Made `_(…)` chain automatically without needing to call `_#chain`
|
||||
* Made `_.isEqual` equate `arguments` objects to similar `Object` objects
|
||||
* Made `_.clone` copy the enumerable properties of `arguments` objects and objects<br>
|
||||
created by constructors other than `Object` are cloned to plain `Object` objects
|
||||
|
||||
#### Changes ####
|
||||
|
||||
* Ensure Lo-Dash runs in the JS engine embedded in Adobe products
|
||||
* Ensured `_.reduce` and `_.reduceRight` pass the correct number of `callback` arguments
|
||||
* Ensured `_.throttle` nulls the `timeoutId`
|
||||
* Made deep `_.clone` more closely follow the structured clone algorithm and copy array properties assigned by `RegExp#exec`
|
||||
* Optimized compiled templates in Firefox
|
||||
* Optimized `_.forEach`, `_.forOwn`, `_.isNumber`, and `_.isString`
|
||||
* Simplified `iteratorTemplate`
|
||||
|
||||
The full changelog is available [here](https://github.com/bestiejs/lodash/wiki/Changelog).
|
||||
|
||||
|
||||
255
build/minify.js
255
build/minify.js
@@ -8,22 +8,25 @@
|
||||
path = require('path'),
|
||||
spawn = require('child_process').spawn;
|
||||
|
||||
/** The directory that is the base of the repository */
|
||||
/** The path of the directory that is the base of the repository */
|
||||
var basePath = fs.realpathSync(path.join(__dirname, '..'));
|
||||
|
||||
/** The directory where the Closure Compiler is located */
|
||||
/** The path of the directory where the Closure Compiler is located */
|
||||
var closurePath = path.join(basePath, 'vendor', 'closure-compiler', 'compiler.jar');
|
||||
|
||||
/** Load other modules */
|
||||
var preprocess = require('./pre-compile'),
|
||||
postprocess = require('./post-compile'),
|
||||
uglifyJS = require('../vendor/uglifyjs/uglify-js');
|
||||
var preprocess = require('./pre-compile.js'),
|
||||
postprocess = require('./post-compile.js'),
|
||||
uglifyJS = require('../vendor/uglifyjs/uglify-js.js');
|
||||
|
||||
/** Closure Compiler command-line options */
|
||||
var closureOptions = [
|
||||
'--compilation_level=ADVANCED_OPTIMIZATIONS',
|
||||
'--warning_level=QUIET'
|
||||
];
|
||||
/** The Closure Compiler command-line options */
|
||||
var closureOptions = ['--warning_level=QUIET'];
|
||||
|
||||
/** The Closure Compiler optimization modes */
|
||||
var optimizationModes = {
|
||||
'simple': 'SIMPLE_OPTIMIZATIONS',
|
||||
'advanced': 'ADVANCED_OPTIMIZATIONS'
|
||||
};
|
||||
|
||||
/** Reassign `existsSync` for older versions of Node */
|
||||
fs.existsSync || (fs.existsSync = path.existsSync);
|
||||
@@ -31,11 +34,20 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* The exposed `minify` function minifies a given Lo-Dash `source` and invokes
|
||||
* the `onComplete` callback when finished.
|
||||
* Minifies a given Lo-Dash `source` and invokes the `options.onComplete`
|
||||
* callback when finished. The `onComplete` callback is invoked with one
|
||||
* argument; (outputSource).
|
||||
*
|
||||
* @param {Array|String} [source=''] The source to minify or array of commands.
|
||||
* -o, --output - Write output to a given path/filename.
|
||||
* -s, --silent - Skip status updates normally logged to the console.
|
||||
* -t, --template - Applies template specific minifier options.
|
||||
*
|
||||
* @param {Object} [options={}] The options object.
|
||||
* outputPath - Write output to a given path/filename.
|
||||
* isSilent - Skip status updates normally logged to the console.
|
||||
* isTemplate - Applies template specific minifier options.
|
||||
* onComplete - The function called once minification has finished.
|
||||
*/
|
||||
function minify(source, options) {
|
||||
source || (source = '');
|
||||
@@ -77,6 +89,10 @@
|
||||
* @constructor
|
||||
* @param {String} source The source to minify.
|
||||
* @param {Object} options The options object.
|
||||
* outputPath - Write output to a given path/filename.
|
||||
* isSilent - Skip status updates normally logged to the console.
|
||||
* isTemplate - Applies template specific minifier options.
|
||||
* onComplete - The function called once minification has finished.
|
||||
*/
|
||||
function Minify(source, options) {
|
||||
// juggle arguments
|
||||
@@ -84,9 +100,10 @@
|
||||
options = source || options;
|
||||
source = options.source || '';
|
||||
}
|
||||
this.compiled = {};
|
||||
this.hybrid = {};
|
||||
this.compiled = { 'simple': {}, 'advanced': {} };
|
||||
this.hybrid = { 'simple': {}, 'advanced': {} };
|
||||
this.uglified = {};
|
||||
|
||||
this.isSilent = !!options.isSilent;
|
||||
this.isTemplate = !!options.isTemplate;
|
||||
this.outputPath = options.outputPath;
|
||||
@@ -99,7 +116,7 @@
|
||||
};
|
||||
|
||||
// begin the minification process
|
||||
closureCompile.call(this, source, onClosureCompile.bind(this));
|
||||
closureCompile.call(this, source, 'simple', onClosureSimpleCompile.bind(this));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -110,37 +127,22 @@
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The JavaScript source to minify.
|
||||
* @param {String} [message] The message to log.
|
||||
* @param {Function} callback The function to call once the process completes.
|
||||
* @param {String} mode The optimization mode.
|
||||
* @param {Function} callback The function called once the process has completed.
|
||||
*/
|
||||
function closureCompile(source, message, callback) {
|
||||
var options = closureOptions.slice();
|
||||
|
||||
function closureCompile(source, mode, callback) {
|
||||
// use simple optimizations when minifying template files
|
||||
if (this.isTemplate) {
|
||||
options = options.map(function(value) {
|
||||
return value.replace(/^(compilation_level)=.+$/, '$1=SIMPLE_OPTIMIZATIONS');
|
||||
});
|
||||
}
|
||||
var options = closureOptions.slice();
|
||||
options.push('--compilation_level=' + optimizationModes[this.isTemplate ? 'simple' : mode]);
|
||||
|
||||
// the standard error stream, standard output stream, and Closure Compiler process
|
||||
// the standard error stream, standard output stream, and the Closure Compiler process
|
||||
var error = '',
|
||||
output = '',
|
||||
compiler = spawn('java', ['-jar', closurePath].concat(options));
|
||||
|
||||
// juggle arguments
|
||||
if (typeof message == 'function') {
|
||||
callback = message;
|
||||
message = null;
|
||||
}
|
||||
|
||||
if (!this.isSilent) {
|
||||
console.log(message == null
|
||||
? 'Compressing ' + path.basename(this.outputPath, '.js') + ' using the Closure Compiler...'
|
||||
: message
|
||||
);
|
||||
console.log('Compressing ' + path.basename(this.outputPath, '.js') + ' using the Closure Compiler (' + mode + ')...');
|
||||
}
|
||||
|
||||
compiler.stdout.on('data', function(data) {
|
||||
// append the data to the output stream
|
||||
output += data;
|
||||
@@ -152,9 +154,8 @@
|
||||
});
|
||||
|
||||
compiler.on('exit', function(status) {
|
||||
var exception = null;
|
||||
|
||||
// `status` contains the process exit code
|
||||
var exception = null;
|
||||
if (status) {
|
||||
exception = new Error(error);
|
||||
exception.status = status;
|
||||
@@ -173,27 +174,17 @@
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The JavaScript source to minify.
|
||||
* @param {String} [message] The message to log.
|
||||
* @param {Function} callback The function to call once the process completes.
|
||||
* @param {String} label The label to log.
|
||||
* @param {Function} callback The function called once the process has completed.
|
||||
*/
|
||||
function uglify(source, message, callback) {
|
||||
function uglify(source, label, callback) {
|
||||
var exception,
|
||||
result,
|
||||
ugly = uglifyJS.uglify;
|
||||
|
||||
// juggle arguments
|
||||
if (typeof message == 'function') {
|
||||
callback = message;
|
||||
message = null;
|
||||
}
|
||||
|
||||
if (!this.isSilent) {
|
||||
console.log(message == null
|
||||
? 'Compressing ' + path.basename(this.outputPath, '.js') + ' using UglifyJS...'
|
||||
: message
|
||||
);
|
||||
console.log('Compressing ' + path.basename(this.outputPath, '.js') + ' using ' + label + '...');
|
||||
}
|
||||
|
||||
try {
|
||||
result = ugly.gen_code(
|
||||
// enable unsafe transformations
|
||||
@@ -217,45 +208,79 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* The `closureCompile()` callback.
|
||||
* The Closure Compiler callback for simple optimizations.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {String} result The resulting minified source.
|
||||
*/
|
||||
function onClosureCompile(exception, result) {
|
||||
function onClosureSimpleCompile(exception, result) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
// store the post-processed Closure Compiler result and gzip it
|
||||
this.compiled.source = result = postprocess(result);
|
||||
gzip(result, onClosureGzip.bind(this));
|
||||
result = postprocess(result);
|
||||
this.compiled.simple.source = result;
|
||||
gzip(result, onClosureSimpleGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* The Closure Compiler `gzip` callback.
|
||||
* The Closure Compiler `gzip` callback for simple optimizations.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {Buffer} result The resulting gzipped source.
|
||||
*/
|
||||
function onClosureGzip(exception, result) {
|
||||
function onClosureSimpleGzip(exception, result) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.compiled.simple.gzip = result;
|
||||
|
||||
// store the gzipped result and report the size
|
||||
this.compiled.gzip = result;
|
||||
|
||||
// next, minify the source using only UglifyJS
|
||||
uglify.call(this, this.source, onUglify.bind(this));
|
||||
// next, compile the source using advanced optimizations
|
||||
closureCompile.call(this, this.source, 'advanced', onClosureAdvancedCompile.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* The `uglify()` callback.
|
||||
* The Closure Compiler callback for advanced optimizations.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {String} result The resulting minified source.
|
||||
*/
|
||||
function onClosureAdvancedCompile(exception, result) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
result = postprocess(result);
|
||||
this.compiled.advanced.source = result;
|
||||
gzip(result, onClosureAdvancedGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* The Closure Compiler `gzip` callback for advanced optimizations.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {Buffer} result The resulting gzipped source.
|
||||
*/
|
||||
function onClosureAdvancedGzip(exception, result) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.compiled.advanced.gzip = result;
|
||||
|
||||
// next, minify the source using only UglifyJS
|
||||
uglify.call(this, this.source, 'UglifyJS', onUglify.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* The UglifyJS callback.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
@@ -265,8 +290,8 @@
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
// store the post-processed Uglified result and gzip it
|
||||
this.uglified.source = result = postprocess(result);
|
||||
result = postprocess(result);
|
||||
this.uglified.source = result;
|
||||
gzip(result, onUglifyGzip.bind(this));
|
||||
}
|
||||
|
||||
@@ -284,74 +309,112 @@
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
var message = 'Compressing ' + path.basename(this.outputPath, '.js') + ' using hybrid minification...';
|
||||
|
||||
// store the gzipped result and report the size
|
||||
this.uglified.gzip = result;
|
||||
|
||||
// next, minify the Closure Compiler minified source using UglifyJS
|
||||
uglify.call(this, this.compiled.source, message, onHybrid.bind(this));
|
||||
// next, minify the already Closure Compiler simple optimized source using UglifyJS
|
||||
uglify.call(this, this.compiled.simple.source, 'hybrid (simple)', onSimpleHybrid.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* The hybrid `uglify()` callback.
|
||||
* The hybrid callback for simple optimizations.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {String} result The resulting minified source.
|
||||
*/
|
||||
function onHybrid(exception, result) {
|
||||
function onSimpleHybrid(exception, result) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
// store the post-processed Uglified result and gzip it
|
||||
this.hybrid.source = result = postprocess(result);
|
||||
gzip(result, onHybridGzip.bind(this));
|
||||
result = postprocess(result);
|
||||
this.hybrid.simple.source = result;
|
||||
gzip(result, onSimpleHybridGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* The hybrid `gzip` callback.
|
||||
* The hybrid `gzip` callback for simple optimizations.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {Buffer} result The resulting gzipped source.
|
||||
*/
|
||||
function onHybridGzip(exception, result) {
|
||||
function onSimpleHybridGzip(exception, result) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
// store the gzipped result and report the size
|
||||
this.hybrid.gzip = result;
|
||||
this.hybrid.simple.gzip = result;
|
||||
|
||||
// next, minify the already Closure Compiler advance optimized source using UglifyJS
|
||||
uglify.call(this, this.compiled.advanced.source, 'hybrid (advanced)', onAdvancedHybrid.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* The hybrid callback for advanced optimizations.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {String} result The resulting minified source.
|
||||
*/
|
||||
function onAdvancedHybrid(exception, result) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
result = postprocess(result);
|
||||
this.hybrid.advanced.source = result;
|
||||
gzip(result, onAdvancedHybridGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* The hybrid `gzip` callback for advanced optimizations.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {Buffer} result The resulting gzipped source.
|
||||
*/
|
||||
function onAdvancedHybridGzip(exception, result) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.hybrid.advanced.gzip = result;
|
||||
|
||||
// finish by choosing the smallest compressed file
|
||||
onComplete.call(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback executed after JavaScript source is minified and gzipped.
|
||||
* The callback executed after the source is minified and gzipped.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function onComplete() {
|
||||
var compiled = this.compiled,
|
||||
hybrid = this.hybrid,
|
||||
uglified = this.uglified;
|
||||
var compiledSimple = this.compiled.simple,
|
||||
compiledAdvanced = this.compiled.advanced,
|
||||
uglified = this.uglified,
|
||||
hybridSimple = this.hybrid.simple,
|
||||
hybridAdvanced = this.hybrid.advanced;
|
||||
|
||||
// select the smallest gzipped file and use its minified counterpart as the
|
||||
// official minified release (ties go to Closure Compiler)
|
||||
var min = Math.min(compiled.gzip.length, hybrid.gzip.length, uglified.gzip.length);
|
||||
|
||||
// pass the minified source to the minify instances "onComplete" callback
|
||||
this.onComplete(
|
||||
compiled.gzip.length == min
|
||||
? compiled.source
|
||||
: uglified.gzip.length == min
|
||||
? uglified.source
|
||||
: hybrid.source
|
||||
// official minified release (ties go to the Closure Compiler)
|
||||
var min = Math.min(
|
||||
compiledSimple.gzip.length,
|
||||
compiledAdvanced.gzip.length,
|
||||
uglified.gzip.length,
|
||||
hybridSimple.gzip.length,
|
||||
hybridAdvanced.gzip.length
|
||||
);
|
||||
|
||||
// pass the minified source to the "onComplete" callback
|
||||
[compiledSimple, compiledAdvanced, uglified, hybridSimple, hybridAdvanced].some(function(data) {
|
||||
if (data.gzip.length == min) {
|
||||
this.onComplete(data.source);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
'lodash':
|
||||
'/*!\n' +
|
||||
' Lo-Dash @VERSION lodash.com/license\n' +
|
||||
' Underscore.js 1.4.2 underscorejs.org/LICENSE\n' +
|
||||
' Underscore.js 1.4.3 underscorejs.org/LICENSE\n' +
|
||||
'*/',
|
||||
'underscore':
|
||||
'/*! Underscore.js @VERSION underscorejs.org/LICENSE */'
|
||||
@@ -26,9 +26,12 @@
|
||||
* @returns {String} Returns the processed source.
|
||||
*/
|
||||
function postprocess(source) {
|
||||
// move vars exposed by Closure Compiler into the IIFE
|
||||
// move vars exposed by the Closure Compiler into the IIFE
|
||||
source = source.replace(/^((?:(['"])use strict\2;)?(?:var (?:[a-z]+=(?:!0|!1|null)[,;])+)?)([\s\S]*?function[^)]+\){)/, '$3$1');
|
||||
|
||||
// correct overly aggressive Closure Compiler advanced optimizations
|
||||
source = source.replace(/prototype\s*=\s*{\s*valueOf\s*:\s*1\s*}/, 'prototype={valueOf:1,y:1}');
|
||||
|
||||
// unescape properties (i.e. foo["bar"] => foo.bar)
|
||||
source = source.replace(/(\w)\["([^."]+)"\]/g, function(match, left, right) {
|
||||
return /\W/.test(right) ? match : (left + '.' + right);
|
||||
@@ -46,7 +49,7 @@
|
||||
if (!snippet) {
|
||||
return source;
|
||||
}
|
||||
// add license
|
||||
// add copyright/license header
|
||||
return licenseTemplate[/call\(this\);?$/.test(source) ? 'underscore' : 'lodash']
|
||||
.replace('@VERSION', snippet[2]) + '\n;' + source;
|
||||
}
|
||||
|
||||
144
build/post-install.js
Normal file
144
build/post-install.js
Normal file
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env node
|
||||
;(function() {
|
||||
'use strict';
|
||||
|
||||
/** Load Node modules */
|
||||
var exec = require('child_process').exec,
|
||||
fs = require('fs'),
|
||||
https = require('https'),
|
||||
path = require('path'),
|
||||
tar = require('../vendor/tar/tar.js'),
|
||||
zlib = require('zlib');
|
||||
|
||||
/** The path of the directory that is the base of the repository */
|
||||
var basePath = fs.realpathSync(path.join(__dirname, '..'));
|
||||
|
||||
/** The path of the `vendor` directory */
|
||||
var vendorPath = path.join(basePath, 'vendor');
|
||||
|
||||
/** The Git object ID of `closure-compiler.tar.gz` */
|
||||
var closureId = 'a2787b470c577cee2404d186c562dd9835f779f5';
|
||||
|
||||
/** The Git object ID of `uglifyjs.tar.gz` */
|
||||
var uglifyId = '3390b259e04829538e4d3635d12b317dd6103eca';
|
||||
|
||||
/** The media type for raw blob data */
|
||||
var mediaType = 'application/vnd.github.v3.raw';
|
||||
|
||||
/** Used to reference parts of the blob href */
|
||||
var location = (function() {
|
||||
var host = 'api.github.com',
|
||||
origin = 'https://api.github.com',
|
||||
pathname = '/repos/bestiejs/lodash/git/blobs';
|
||||
|
||||
return {
|
||||
'host': host,
|
||||
'href': host + origin + pathname,
|
||||
'origin': origin,
|
||||
'pathname': pathname
|
||||
};
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Fetches a required `.tar.gz` dependency with the given Git object ID from
|
||||
* the Lo-Dash repo on GitHub. The object ID may be obtained by running
|
||||
* `git hash-object path/to/dependency.tar.gz`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} options The options object.
|
||||
* id - The Git object ID of the `.tar.gz` file.
|
||||
* onComplete - The function, invoked with one argument (exception),
|
||||
* called once the extraction has finished.
|
||||
* path - The path of the extraction directory.
|
||||
* title - The dependency's title used in status updates logged to the console.
|
||||
*/
|
||||
function getDependency(options) {
|
||||
options || (options = {});
|
||||
|
||||
var id = options.id,
|
||||
onComplete = options.onComplete,
|
||||
path = options.path,
|
||||
title = options.title;
|
||||
|
||||
function callback(exception) {
|
||||
if (exception) {
|
||||
console.error([
|
||||
'There was a problem installing ' + title + '. To manually install, run:',
|
||||
'',
|
||||
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + id + " | tar xvz -C '" + path + "'"
|
||||
].join('\n'));
|
||||
}
|
||||
onComplete(exception);
|
||||
}
|
||||
|
||||
console.log('Downloading ' + title + '...');
|
||||
|
||||
https.get({
|
||||
'host': location.host,
|
||||
'path': location.pathname + '/' + id,
|
||||
'headers': {
|
||||
// By default, all GitHub blob API endpoints return a JSON document
|
||||
// containing Base64-encoded blob data. Overriding the `Accept` header
|
||||
// with the GitHub raw media type returns the blob data directly.
|
||||
// See http://developer.github.com/v3/media/.
|
||||
'Accept': mediaType
|
||||
}
|
||||
}, function(response) {
|
||||
var decompressor = zlib.createUnzip(),
|
||||
parser = new tar.Extract({ 'path': path });
|
||||
|
||||
decompressor.on('error', callback)
|
||||
parser.on('end', callback).on('error', callback);
|
||||
response.pipe(decompressor).pipe(parser);
|
||||
})
|
||||
.on('error', callback);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
exec('npm -g root', function(exception, stdout) {
|
||||
if (!exception) {
|
||||
try {
|
||||
var isGlobal = path.resolve(basePath, '..') == fs.realpathSync(stdout.trim());
|
||||
} catch(e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
if (exception) {
|
||||
console.error([
|
||||
'Oops! There was a problem detecting the install mode. If you’re installing the',
|
||||
'Lo-Dash command-line executable (via `npm install -g lodash`), you’ll need to',
|
||||
'manually install UglifyJS and the Closure Compiler by running:',
|
||||
'',
|
||||
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + closureId + " | tar xvz -C '" + vendorPath + "'",
|
||||
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + uglifyId + " | tar xvz -C '" + vendorPath + "'",
|
||||
'',
|
||||
'Please submit an issue on the GitHub issue tracker: ' + process.env.npm_package_bugs_url
|
||||
].join('\n'));
|
||||
|
||||
console.error(exception);
|
||||
}
|
||||
if (!isGlobal) {
|
||||
return;
|
||||
}
|
||||
// download the Closure Compiler
|
||||
getDependency({
|
||||
'title': 'the Closure Compiler',
|
||||
'id': closureId,
|
||||
'path': vendorPath,
|
||||
'onComplete': function() {
|
||||
// download UglifyJS
|
||||
getDependency({
|
||||
'title': 'UglifyJS',
|
||||
'id': uglifyId,
|
||||
'path': vendorPath,
|
||||
'onComplete': function() {
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}());
|
||||
@@ -11,80 +11,36 @@
|
||||
'argsLength',
|
||||
'callback',
|
||||
'collection',
|
||||
'concat',
|
||||
'createCallback',
|
||||
'ctor',
|
||||
'guard',
|
||||
'hasOwnProperty',
|
||||
'index',
|
||||
'isArguments',
|
||||
'isString',
|
||||
'iteratee',
|
||||
'length',
|
||||
'nativeKeys',
|
||||
'object',
|
||||
'objectTypes',
|
||||
'ownIndex',
|
||||
'ownProps',
|
||||
'prop',
|
||||
'propertyIsEnumerable',
|
||||
'propIndex',
|
||||
'props',
|
||||
'result',
|
||||
'skipProto',
|
||||
'slice',
|
||||
'stringClass',
|
||||
'thisArg',
|
||||
'toString',
|
||||
'undefined',
|
||||
'value',
|
||||
|
||||
// lesser used variables
|
||||
'accumulator',
|
||||
'args',
|
||||
'arrayLikeClasses',
|
||||
'ArrayProto',
|
||||
'bind',
|
||||
'callee',
|
||||
'className',
|
||||
'compareAscending',
|
||||
'forIn',
|
||||
'found',
|
||||
'funcs',
|
||||
'indexOf',
|
||||
'indicator',
|
||||
'isArguments',
|
||||
'isArr',
|
||||
'isArray',
|
||||
'isFunc',
|
||||
'isFunction',
|
||||
'isPlainObject',
|
||||
'methodName',
|
||||
'noaccum',
|
||||
'noop',
|
||||
'objectClass',
|
||||
'objectTypes',
|
||||
'pass',
|
||||
'properties',
|
||||
'property',
|
||||
'propsLength',
|
||||
'source',
|
||||
'stackA',
|
||||
'stackB',
|
||||
'stackLength',
|
||||
'target'
|
||||
'thisArg'
|
||||
];
|
||||
|
||||
/** Used to minify `compileIterator` option properties */
|
||||
var iteratorOptions = [
|
||||
'args',
|
||||
'array',
|
||||
'arrayBranch',
|
||||
'beforeLoop',
|
||||
'arrayLoop',
|
||||
'bottom',
|
||||
'firstArg',
|
||||
'hasDontEnumBug',
|
||||
'inLoop',
|
||||
'init',
|
||||
'isKeysFast',
|
||||
'object',
|
||||
'objectBranch',
|
||||
'objectLoop',
|
||||
'noArgsEnum',
|
||||
'noCharByIndex',
|
||||
'shadowed',
|
||||
@@ -102,17 +58,17 @@
|
||||
/** Used to protect the specified properties from getting minified */
|
||||
var propWhitelist = [
|
||||
'_',
|
||||
'__chain__',
|
||||
'__wrapped__',
|
||||
'after',
|
||||
'all',
|
||||
'amd',
|
||||
'any',
|
||||
'assign',
|
||||
'attachEvent',
|
||||
'bind',
|
||||
'bindAll',
|
||||
'bindKey',
|
||||
'chain',
|
||||
'clearTimeout',
|
||||
'clone',
|
||||
'collect',
|
||||
'compact',
|
||||
@@ -144,6 +100,7 @@
|
||||
'forIn',
|
||||
'forOwn',
|
||||
'functions',
|
||||
'global',
|
||||
'groupBy',
|
||||
'has',
|
||||
'head',
|
||||
@@ -179,7 +136,6 @@
|
||||
'keys',
|
||||
'last',
|
||||
'lastIndexOf',
|
||||
'lateBind',
|
||||
'map',
|
||||
'max',
|
||||
'memoize',
|
||||
@@ -204,7 +160,6 @@
|
||||
'rest',
|
||||
'result',
|
||||
'select',
|
||||
'setTimeout',
|
||||
'shuffle',
|
||||
'size',
|
||||
'some',
|
||||
@@ -215,7 +170,6 @@
|
||||
'take',
|
||||
'tap',
|
||||
'template',
|
||||
'templates',
|
||||
'templateSettings',
|
||||
'throttle',
|
||||
'times',
|
||||
@@ -234,6 +188,9 @@
|
||||
'wrap',
|
||||
'zip',
|
||||
|
||||
// property used by the `lodash underscore` build
|
||||
'__chain__',
|
||||
|
||||
// properties used by underscore.js
|
||||
'_chain',
|
||||
'_wrapped'
|
||||
@@ -252,19 +209,20 @@
|
||||
source || (source = '');
|
||||
options || (options = {});
|
||||
|
||||
// remove unrecognized JSDoc tags so Closure Compiler won't complain
|
||||
// remove unrecognized JSDoc tags so the Closure Compiler won't complain
|
||||
source = source.replace(/@(?:alias|category)\b.*/g, '');
|
||||
|
||||
if (options.isTemplate) {
|
||||
return source;
|
||||
}
|
||||
|
||||
// remove copyright to add later in post-compile.js
|
||||
// remove copyright/license header to add later in post-compile.js
|
||||
source = source.replace(/\/\*![\s\S]+?\*\//, '');
|
||||
|
||||
// add brackets to whitelisted properties so Closure Compiler won't mung them
|
||||
// add brackets to whitelisted properties so the Closure Compiler won't mung them
|
||||
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
|
||||
source = source.replace(RegExp('\\.(' + propWhitelist.join('|') + ')\\b', 'g'), "['$1']");
|
||||
source = source.replace(RegExp('\\.(' + propWhitelist.join('|') + ')\\b', 'g'), function(match, prop) {
|
||||
return "['" + prop.replace(/['\n\r\t]/g, '\\$&') + "']";
|
||||
});
|
||||
|
||||
// remove brackets from `_.escape()` in `_.template`
|
||||
source = source.replace(/__e *= *_\['escape']/g, '__e=_.escape');
|
||||
@@ -279,16 +237,25 @@
|
||||
source = source.replace("result[length]['value']", 'result[length].value');
|
||||
|
||||
// remove whitespace from string literals
|
||||
source = source.replace(/'(?:(?=(\\?))\1.)*?'/g, function(string) {
|
||||
source = source.replace(/^([ "'\w]+:)? *"(?:(?=(\\?))\2.)*?"|'(?:(?=(\\?))\3.)*?'/gm, function(string, captured) {
|
||||
// remove object literal property name
|
||||
if (/:$/.test(captured)) {
|
||||
string = string.slice(captured.length);
|
||||
}
|
||||
// avoids removing the '\n' of the `stringEscapes` object
|
||||
return string.replace(/\[object |delete |else |function | in |return\s+[\w']|throw |typeof |use strict|var |@ |'\\n'|\\\\n|\\n|\s+/g, function(match) {
|
||||
string = string.replace(/\[object |delete |else |function | in |return\s+[\w"']|throw |typeof |use strict|var |@ |(["'])\\n\1|\\\\n|\\n|\s+/g, function(match) {
|
||||
return match == false || match == '\\n' ? '' : match;
|
||||
});
|
||||
// prepend object literal property name
|
||||
return (captured || '') + string;
|
||||
});
|
||||
|
||||
// add newline to `+"__p+='"` in underscore.js `_.template`
|
||||
source = source.replace(/\+"__p\+='"/g, '+"\\n__p+=\'"');
|
||||
|
||||
// add newline to `body + '}'` in `createFunction`
|
||||
source = source.replace(/body *\+ *'}'/, 'body+"\\n}"');
|
||||
|
||||
// remove whitespace from `_.template` related regexes
|
||||
source = source.replace(/(?:reEmptyString\w+|reInsertVariable) *=.+/g, function(match) {
|
||||
return match.replace(/ |\\n/g, '');
|
||||
@@ -296,11 +263,8 @@
|
||||
|
||||
// remove newline from double-quoted strings in `_.template`
|
||||
source = source
|
||||
.replace('"\';\\n__with ("', '"\';__with("')
|
||||
.replace('"\\n}__\\n__p += \'"', '"}____p+=\'"')
|
||||
.replace('"__p = \'"', '"__p=\'"')
|
||||
.replace('"\';\\n"', '"\';"')
|
||||
.replace("') {\\n'", "'){'")
|
||||
.replace('"__p += \'"', '"__p+=\'"')
|
||||
.replace('"\';\n"', '"\';"')
|
||||
|
||||
// remove `useSourceURL` variable
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var useSourceURL[\s\S]+?catch[^}]+}\n/, '');
|
||||
@@ -308,18 +272,16 @@
|
||||
// remove debug sourceURL use in `_.template`
|
||||
source = source.replace(/(?:\s*\/\/.*\n)* *var sourceURL[^;]+;|\+ *sourceURL/g, '');
|
||||
|
||||
// minify internal properties used by 'compareAscending', `_.merge`, and `_.sortBy`
|
||||
// minify internal properties used by 'compareAscending' and `_.sortBy`
|
||||
(function() {
|
||||
var properties = ['criteria', 'index', 'value'],
|
||||
snippets = source.match(/( +)(?:function compareAscending|var merge|var sortBy)\b[\s\S]+?\n\1}/g);
|
||||
snippets = source.match(/( +)function (?:compareAscending|sortBy)\b[\s\S]+?\n\1}/g);
|
||||
|
||||
if (!snippets) {
|
||||
return;
|
||||
}
|
||||
snippets.forEach(function(snippet) {
|
||||
var modified = snippet,
|
||||
isCompilable = /(?:var merge|var sortBy)\b/.test(modified),
|
||||
isInlined = !/\bcreateIterator\b/.test(modified);
|
||||
var modified = snippet;
|
||||
|
||||
// minify properties
|
||||
properties.forEach(function(property, index) {
|
||||
@@ -327,33 +289,10 @@
|
||||
reDotProp = RegExp('\\.' + property + '\\b', 'g'),
|
||||
rePropColon = RegExp("([^?\\s])\\s*([\"'])?\\b" + property + "\\2 *:", '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, "$1'" + minNames[index] + "':");
|
||||
}
|
||||
else {
|
||||
modified = modified
|
||||
.replace(reBracketProp, '.' + minNames[index])
|
||||
.replace(reDotProp, '.' + minNames[index])
|
||||
.replace(rePropColon, '$1' + minNames[index] + ':');
|
||||
}
|
||||
}
|
||||
else {
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
||||
.replace(reDotProp, '.' + minNames[index])
|
||||
.replace(rePropColon, "$1'" + minNames[index] + "':")
|
||||
|
||||
// correct `value.source` in regexp branch of `_.clone`
|
||||
if (property == 'source') {
|
||||
modified = modified.replace("value['" + minNames[index] + "']", "value['source']");
|
||||
}
|
||||
}
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
||||
.replace(reDotProp, "['" + minNames[index] + "']")
|
||||
.replace(rePropColon, "$1'" + minNames[index] + "':");
|
||||
});
|
||||
|
||||
// replace with modified snippet
|
||||
@@ -385,8 +324,10 @@
|
||||
isIteratorTemplate = /var iteratorTemplate\b/.test(snippet),
|
||||
modified = snippet;
|
||||
|
||||
// add brackets to whitelisted properties so Closure Compiler won't mung them
|
||||
modified = modified.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), "['$1']");
|
||||
// add brackets to iterator option properties so the Closure Compiler won't mung them
|
||||
modified = modified.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), function(match, prop) {
|
||||
return "['" + prop.replace(/['\n\r\t]/g, '\\$&') + "']";
|
||||
});
|
||||
|
||||
if (isCreateIterator) {
|
||||
// replace with modified snippet early and clip snippet to the `factory`
|
||||
@@ -400,9 +341,9 @@
|
||||
// ensure properties in compiled strings aren't minified
|
||||
modified = modified.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minNames[index]);
|
||||
|
||||
// correct `typeof x == 'object'`
|
||||
if (variable == 'object') {
|
||||
modified = modified.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), "$1object'");
|
||||
// correct `typeof` values
|
||||
if (/^(?:boolean|function|object|number|string|undefined)$/.test(variable)) {
|
||||
modified = modified.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), '$1' + variable + "'");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -413,17 +354,11 @@
|
||||
modified = modified.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
||||
}
|
||||
else {
|
||||
if (property == 'array' || property == 'object') {
|
||||
// minify "array" and "object" sub property names
|
||||
modified = modified.replace(RegExp("'" + property + "'( *[\\]:])", 'g'), "'" + minNames[index] + "'$1");
|
||||
}
|
||||
else {
|
||||
// minify property name strings
|
||||
modified = modified.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
|
||||
// minify property names in regexes and accessors
|
||||
if (isCreateIterator) {
|
||||
modified = modified.replace(RegExp('([\\.|/])' + property + '\\b' , 'g'), '$1' + minNames[index]);
|
||||
}
|
||||
// minify property name strings
|
||||
modified = modified.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
|
||||
// minify property names in accessors
|
||||
if (isCreateIterator) {
|
||||
modified = modified.replace(RegExp('\\.' + property + '\\b' , 'g'), '.' + minNames[index]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
584
doc/README.md
584
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.8.2</sup>',
|
||||
'title' => 'Lo-Dash <sup>v1.0.0-rc.2</sup>',
|
||||
'toc' => 'categories',
|
||||
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
|
||||
));
|
||||
|
||||
76
lodash.min.js
vendored
76
lodash.min.js
vendored
@@ -1,39 +1,41 @@
|
||||
/*!
|
||||
Lo-Dash 0.8.2 lodash.com/license
|
||||
Underscore.js 1.4.2 underscorejs.org/LICENSE
|
||||
Lo-Dash 1.0.0-rc.2 lodash.com/license
|
||||
Underscore.js 1.4.3 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(e,t){function s(e){if(e&&e.__wrapped__)return e;if(!(this instanceof s))return new s(e);this.__wrapped__=e}function o(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||H),s=i?{}:e;if(i)for(n=t-1;++n<r;){var o=e[n]+"";(Z.call(s,o)?s[o]:s[o]=[]).push(e[n])}return function(e){if(i){var n=e+"";return Z.call(s,n)&&-1<T(s[n],e)}return-1<T(s,e,t)}}function u(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1;if(e<n||n===t)return-1}return r<i?-1:1}function a(e,t,n){function r(){var u=arguments
|
||||
,a=s?this:t;return i||(e=t[o]),n.length&&(u=u.length?n.concat(nt.call(u)):n),this instanceof r?(p.prototype=e.prototype,a=new p,(u=e.apply(a,u))&&Ht[typeof u]?u:a):e.apply(a,u)}var i=m(e),s=!n,o=e;return s&&(n=t),r}function f(e,n){return e?"function"!=typeof e?function(t){return t[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:A}function l(){for(var e={e:"",g:Et,i:"",j:Mt,m:Tt,n:kt,o:J,p:"",q:n,r:_t,c:{d:""},l:{d:""}},t,i=-1;t=arguments[++i];)for(var s in t){var o=t[s];/d|h/.test(s)?("string"==typeof
|
||||
o&&(o={b:o,k:o}),e.c[s]=o.b,e.l[s]=o.k):e[s]=o}t=e.a;if("d"!=(e.f=/^[^,]+/.exec(t)[0])||!e.c.h)e.c=r;i="",e.r&&(i+="'use strict';"),i+="var i,A,j="+e.f+",t="+(e.i||e.f)+";if(!"+e.f+")return t;"+e.p+";",e.c&&(i+="var k=j.length;i=-1;",e.l&&(i+="if(k===+k){"),e.n&&(i+="if(y.call(j)==w){j=j.split('')}"),i+=e.c.d+";while(++i<k){A=j[i];"+e.c.h+"}",e.l&&(i+="}"));if(e.l){e.c?i+="else {":e.m&&(i+="var k=j.length;i=-1;if(k&&O(j)){while(++i<k){A=j[i+=''];"+e.l.h+"}}else {"),e.g||(i+="var u=typeof j=='function'&&q.call(j,'prototype');"
|
||||
);if(e.j&&e.q)i+="var n=-1,o=Y[typeof j]?l(j):[],k=o.length;"+e.l.d+";while(++n<k){i=o[n];",e.g||(i+="if(!(u&&i=='prototype')){"),i+="A=j[i];"+e.l.h+"",e.g||(i+="}");else{i+=e.l.d+";for(i in j){";if(!e.g||e.q)i+="if(",e.g||(i+="!(u&&i=='prototype')"),!e.g&&e.q&&(i+="&&"),e.q&&(i+="h.call(j,i)"),i+="){";i+="A=j[i];"+e.l.h+";";if(!e.g||e.q)i+="}"}i+="}";if(e.g){i+="var g=j.constructor;";for(s=0;7>s;s++)i+="i='"+e.o[s]+"';if(","constructor"==e.o[s]&&(i+="!(g&&g.prototype===j)&&"),i+="h.call(j,i)){A=j[i];"+
|
||||
e.l.h+"}"}if(e.c||e.m)i+="}"}return i+=e.e+";return t",Function("D,E,F,I,e,f,J,h,M,O,Q,S,T,X,Y,l,q,v,w,y,z","var G=function("+t+"){"+i+"};return G")(Dt,_,L,u,Q,f,en,Z,T,v,$t,m,Jt,mt,Ht,ut,tt,nt,yt,rt)}function c(e){return"\\"+Bt[e]}function h(e){return Qt[e]}function p(){}function d(e){return Gt[e]}function v(e){return rt.call(e)==ct}function m(e){return"function"==typeof e}function g(e){var t=i;if(!e||"object"!=typeof e||v(e))return t;var n=e.constructor;return(!Lt||"function"==typeof e.toString||"string"!=typeof
|
||||
(e+""))&&(!m(n)||n instanceof n)?xt?(en(e,function(e,n,r){return t=!Z.call(r,n),i}),t===i):(en(e,function(e,n){t=n}),t===i||Z.call(e,t)):t}function y(e,t,n,s,o){if(e==r)return e;n&&(t=i);if(n=Ht[typeof e]){var u=rt.call(e);if(!Pt[u]||Nt&&v(e))return e;var a=u==ht,n=a||(u==mt?Jt(e):n)}if(!n||!t)return n?a?nt.call(e):Zt({},e):e;n=e.constructor;switch(u){case pt:case dt:return new n(+e);case vt:case yt:return new n(e);case gt:return n(e.source,U.exec(e))}s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[
|
||||
u]==e)return o[u];var f=a?n(e.length):{};return s.push(e),o.push(f),(a?mn:tn)(e,function(e,n){f[n]=y(e,t,r,s,o)}),f}function b(e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Ht[typeof e]||Ht[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=rt.call(e);if(u!=rt.call(t))return i;switch(u){case pt:case dt:return+e==+t;case vt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case gt:case yt:return e==t+""}var a=Dt[u];if(Nt&&!a&&(a=v(e))&&!v(t)||!a&&(u!=mt||Lt&&("function"!=typeof e.
|
||||
toString&&"string"==typeof (e+"")||"function"!=typeof t.toString&&"string"==typeof (t+""))))return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var u=-1,f=n,l=0;s.push(e),o.push(t);if(a){l=e.length;if(f=l==t.length)for(;l--&&(f=b(e[l],t[l],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!m(a)||!(a instanceof a&&m(f)&&f instanceof f)))return i;for(var c in e)if(Z.call(e,c)&&(l++,!Z.call(t,c)||!b(e[c],t[c],s,o)))return i;for(c in t)if(Z.call(t,c)&&!(l--))return i;if(
|
||||
Et)for(;7>++u;)if(c=J[u],Z.call(e,c)&&(!Z.call(t,c)||!b(e[c],t[c],s,o)))return i;return n}function w(e,t,n){var r=-Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=f(t,n),mn(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,o=e)});else for(;++i<s;)e[i]>o&&(o=e[i]);return o}function E(e,t,n,r){var s=e,o=e?e.length:0,u=3>arguments.length;if(o!==+o)var a=sn(e),o=a.length;else kt&&rt.call(e)==yt&&(s=e.split(""));return mn(e,function(e,f,l){f=a?a[--o]:--o,n=u?(u=i,s[f]):t.call(r,n,s[f],f,l)}),n}function S(e,t,n){
|
||||
if(e)return t==r||n?e[0]:nt.call(e,0,t)}function x(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];$t(s)?et.apply(i,t?s:x(s)):i.push(s)}return i}function T(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof n)r=(0>n?at(0,i+n):n||0)-1;else if(n)return r=C(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function N(e,t,n){return e?nt.call(e,t==r||n?1:t):[]}function C(e,t,n,r){var i=0,s=e?e.length:i;if(n){n=f(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 k(e,t,n,r){var s=-1,o=e?e.length:0,u=[],a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n=f(n,r);++s<o;)if(r=n(e[s],s,e),t?!s||a[a.length-1]!==r:0>T(a,r))a.push(r),u.push(e[s]);return u}function L(e,t){return Ot||it&&2<arguments.length?it.call.apply(it,arguments):a(e,t,nt.call(arguments,2))}function A(e){return e}function O(e){mn(nn(e),function(t){var r=s[t]=e[t];s.prototype[t]=function(){var e=[this.__wrapped__];return arguments.length&&et.apply(e,arguments)
|
||||
,e=r.apply(s,e),this.__chain__&&(e=new s(e),e.__chain__=n),e}})}var n=!0,r=null,i=!1,M="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),_=Array.prototype,D=Object.prototype,P=0,H=30,B=e._,j=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,F=/&(?:amp|lt|gt|quot|#x27);/g,I=/\b__p\+='';/g,q=/\b(__p\+=)''\+/g,R=/(__e\(.*?\)|\b__t\))\+'';/g,U=/\w*$/,z=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,W=RegExp("^"+(D.valueOf+""
|
||||
).replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),X=/($^)/,V=/[&<>"']/g,$=/['\n\r\t\u2028\u2029\\]/g,J="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),K=Math.ceil,Q=_.concat,G=Math.floor,Y=W.test(Y=Object.getPrototypeOf)&&Y,Z=D.hasOwnProperty,et=_.push,tt=D.propertyIsEnumerable,nt=_.slice,rt=D.toString,it=W.test(it=nt.bind)&&it,st=W.test(st=Array.isArray)&&st,ot=e.isFinite,ut=W.test(ut=Object.keys)&&ut
|
||||
,at=Math.max,ft=Math.min,lt=Math.random,ct="[object Arguments]",ht="[object Array]",pt="[object Boolean]",dt="[object Date]",vt="[object Number]",mt="[object Object]",gt="[object RegExp]",yt="[object String]",bt=e.clearTimeout,wt=e.setTimeout,Et,St,xt,Tt=n;(function(){function e(){this.x=1}var t={0:1,length:1},n=[];e.prototype={valueOf:1,y:1};for(var r in new e)n.push(r);for(r in arguments)Tt=!r;Et=4>(n+"").length,xt="x"!=n[0],St=(n.splice.call(t,0,1),t[0])})(1);var Nt=!v(arguments),Ct="x"!=nt.call("x"
|
||||
)[0],kt="xx"!="x"[0]+Object("x")[0];try{var Lt=("[object Object]",rt.call(e.document||0)==mt)}catch(At){}var Ot=it&&/\n|Opera/.test(it+rt.call(e.opera)),Mt=ut&&/^.+$|true/.test(ut+!!e.attachEvent),_t=!Ot,Dt={};Dt[pt]=Dt[dt]=Dt["[object Function]"]=Dt[vt]=Dt[mt]=Dt[gt]=i,Dt[ct]=Dt[ht]=Dt[yt]=n;var Pt={};Pt[ct]=Pt["[object Function]"]=i,Pt[ht]=Pt[pt]=Pt[dt]=Pt[vt]=Pt[mt]=Pt[gt]=Pt[yt]=n;var Ht={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},Bt={"\\":"\\","'":"'","\n":"n"
|
||||
,"\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""};var jt={a:"d,c,x",p:"c=f(c,x)",h:"if(c(A,i,d)===false)return t"},Ft={i:"{}",p:"c=f(c,x)",h:"var p=c(A,i,d);(h.call(t,p)?t[p]++:t[p]=1)"},It={i:"true",h:"if(!c(A,i,d))return!t"},qt={q:i,r:i,a:"m",p:"for(var a=1,b=arguments.length;a<b;a++){if(j=arguments[a]){",h:"t[i]=A",e:"}}"},Rt={i:"[]",h:"c(A,i,d)&&t.push(A)"},Ut={p:"c=f(c,x)"}
|
||||
,zt={h:{k:jt.h}},Wt={i:"d||[]",d:{b:"t=Array(k)",k:"t="+(Mt?"Array(k)":"[]")},h:{b:"t[i]=c(A,i,d)",k:"t"+(Mt?"[n]=":".push")+"(c(A,i,d))"}},Xt={q:i,a:"m,c,x",i:"{}",p:"var R=typeof c=='function';if(R)c=f(c,x);else var s=e.apply(E,arguments)",h:"if(R?!c(A,i,m):M(s,i)<0)t[i]=A"},Vt=l({a:"m",i:"{}",h:"t[A]=i"});Nt&&(v=function(e){return e?Z.call(e,"callee"):i});var $t=st||function(e){return rt.call(e)==ht};m(/x/)&&(m=function(e){return"[object Function]"==rt.call(e)});var Jt=Y?function(e){if(!e||"object"!=typeof
|
||||
e)return i;var t=e.valueOf,n="function"==typeof t&&(n=Y(t))&&Y(n);return n?e==n||Y(e)==n&&!v(e):g(e)}:g,Kt=l({a:"m",i:"[]",h:"t.push(i)"}),Qt={"&":"&","<":"<",">":">",'"':""","'":"'"},Gt=Vt(Qt),Yt=l(qt,{h:"if(t[i]==null)"+qt.h}),Zt=l(qt),en=l(jt,Ut,zt,{q:i}),tn=l(jt,Ut,zt),nn=l({q:i,a:"m",i:"[]",h:"S(A)&&t.push(i)",e:"t.sort()"}),rn=l({a:"A",i:"true",p:"var H=y.call(A),k=A.length;if(D[H]"+(Nt?"||O(A)":"")+"||(H==X&&k===+k&&S(A.splice)))return!k",h:{k:"return false"}}),sn=ut?function(
|
||||
e){var t=typeof e;return"function"==t&&tt.call(e,"prototype")?Kt(e):e&&Ht[t]?ut(e):[]}:Kt,on=l(qt,{a:"m,dd,N",p:"var P,C=arguments,a=0;if(N==I){var b=2,ee=C[3],ff=C[4]}else var b=C.length,ee=[],ff=[];while(++a<b){if(j=C[a]){",h:"if((dd=A)&&((P=Q(dd))||T(dd))){var K=false,gg=ee.length;while(gg--)if(K=ee[gg]==dd)break;if(K){t[i]=ff[gg]}else {ee.push(dd);ff.push(A=(A=t[i],P)?(Q(A)?A:[]):(T(A)?A:{}));t[i]=G(A,dd,I,ee,ff)}}else if(dd!=null)t[i]=dd"}),un=l(Xt),an=l({a:"m",i:"[]",h:"t"+(Mt?"[n]=":".push"
|
||||
)+"([i,A])"}),fn=l(Xt,{p:"if(typeof c!='function'){var i=0,s=e.apply(E,arguments),k=s.length;while(++i<k){var p=s[i];if(p in m)t[p]=m[p]}}else {c=f(c,x)",h:"if(c(A,i,m))t[i]=A",e:"}"}),ln=l({a:"m",i:"[]",h:"t.push(A)"}),cn=l({a:"d,hh",i:"false",n:i,d:{b:"if(y.call(d)==w)return d.indexOf(hh)>-1"},h:"if(A===hh)return true"}),hn=l(jt,Ft),pn=l(jt,It),dn=l(jt,Rt),vn=l(jt,Ut,{i:"z",h:"if(c(A,i,d))return A"}),mn=l(jt,Ut),gn=l(jt,Ft,{h:"var p=c(A,i,d);(h.call(t,p)?t[p]:t[p]=[]).push(A)"}),yn=l(Wt,{a:"d,U"
|
||||
,p:"var C=v.call(arguments,2),R=typeof U=='function'",h:{b:"t[i]=(R?U:A[U]).apply(A,C)",k:"t"+(Mt?"[n]=":".push")+"((R?U:A[U]).apply(A,C))"}}),bn=l(jt,Wt),wn=l(Wt,{a:"d,bb",h:{b:"t[i]=A[bb]",k:"t"+(Mt?"[n]=":".push")+"(A[bb])"}}),En=l({a:"d,c,B,x",i:"B",p:"var V=arguments.length<3;c=f(c,x)",d:{b:"if(V)t=j[++i]"},h:{b:"t=c(t,A,i,d)",k:"t=V?(V=false,A):c(t,A,i,d)"}}),Sn=l(jt,Rt,{h:"!"+Rt.h}),xn=l(jt,It,{i:"false",h:It.h.replace("!","")}),Tn=l(jt,Ft,Wt,{h:{b:"t[i]={a:c(A,i,d),b:i,c:A}",k:"t"+(Mt?"[n]="
|
||||
:".push")+"({a:c(A,i,d),b:i,c:A})"},e:"t.sort(I);k=t.length;while(k--)t[k]=t[k].c"}),Nn=l(Rt,{a:"d,aa",p:"var s=[];J(aa,function(A,p){s.push(p)});var cc=s.length",h:"for(var Z=true,r=0;r<cc;r++){var p=s[r];if(!(Z=A[p]===aa[p]))break}Z&&t.push(A)"}),Cn=l({q:i,r:i,a:"m",p:"var L=arguments,i=0,k=L.length;if(k>1){while(++i<k)t[L[i]]=F(t[L[i]],t);return t}",h:"if(S(A))t[i]=F(A,t)"});s.VERSION="0.8.2",s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=L,s.bindAll=
|
||||
Cn,s.chain=function(e){return e=new s(e),e.__chain__=n,e},s.clone=y,s.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},s.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},s.contains=cn,s.countBy=hn,s.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,bt(a),a=wt(i,t),r&&(o=e.apply(u,s)),o}},s.defaults=
|
||||
Yt,s.defer=function(e){var n=nt.call(arguments,1);return wt(function(){return e.apply(t,n)},1)},s.delay=function(e,n){var r=nt.call(arguments,2);return wt(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=Q.apply(_,arguments),i=o(i,r);++n<r;){var s=e[n];i(s)||t.push(s)}return t},s.escape=function(e){return e==r?"":(e+"").replace(V,h)},s.every=pn,s.extend=Zt,s.filter=dn,s.find=vn,s.first=S,s.flatten=x,s.forEach=mn,s.forIn=en,s.forOwn=tn,
|
||||
s.functions=nn,s.groupBy=gn,s.has=function(e,t){return e?Z.call(e,t):i},s.identity=A,s.indexOf=T,s.initial=function(e,t,n){return e?nt.call(e,0,-(t==r||n?1:t)):[]},s.intersection=function(e){var t=arguments.length,n=[],r=-1,i=e?e.length:0,s=[];e:for(;++r<i;){var u=e[r];if(0>T(s,u)){for(var a=1;a<t;a++)if(!(n[a]||(n[a]=o(arguments[a])))(u))continue e;s.push(u)}}return s},s.invert=Vt,s.invoke=yn,s.isArguments=v,s.isArray=$t,s.isBoolean=function(e){return e===n||e===i||rt.call(e)==pt},s.isDate=function(
|
||||
e){return rt.call(e)==dt},s.isElement=function(e){return e?1===e.nodeType:i},s.isEmpty=rn,s.isEqual=b,s.isFinite=function(e){return ot(e)&&rt.call(e)==vt},s.isFunction=m,s.isNaN=function(e){return rt.call(e)==vt&&e!=+e},s.isNull=function(e){return e===r},s.isNumber=function(e){return rt.call(e)==vt},s.isObject=function(e){return e?Ht[typeof e]:i},s.isPlainObject=Jt,s.isRegExp=function(e){return rt.call(e)==gt},s.isString=function(e){return rt.call(e)==yt},s.isUndefined=function(e){return e===t},s
|
||||
.keys=sn,s.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:nt.call(e,-t||i)}},s.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?at(0,r+n):ft(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},s.lateBind=function(e,t){return a(t,e,nt.call(arguments,2))},s.map=bn,s.max=w,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Z.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=on,s.min=function(e,t,n){var r=
|
||||
Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=f(t,n),mn(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,o=e)});else for(;++i<s;)e[i]<o&&(o=e[i]);return o},s.mixin=O,s.noConflict=function(){return e._=B,this},s.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},s.omit=un,s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.pairs=an,s.partial=function(e){return a(e,nt.call(arguments,1))},s.pick=fn,s.pluck=
|
||||
wn,s.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+G(lt()*((+t||0)-e+1))},s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=at(0,K((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reduce=En,s.reduceRight=E,s.reject=Sn,s.rest=N,s.result=function(e,t){var n=e?e[t]:r;return m(n)?e[t]():n},s.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return mn(e,function(e){var r=G(lt()*(++t+1));n[t]=n[r],n[r]=e}),n},s.size=function(e){var t=e?e.length:0;return t===+
|
||||
t?t:sn(e).length},s.some=xn,s.sortBy=Tn,s.sortedIndex=C,s.tap=function(e,t){return t(e),e},s.template=function(e,t,n){e||(e=""),n||(n={});var r,i,o=0,u=s.templateSettings,a="__p += '",f=n.variable||u.variable,l=f;e.replace(RegExp((n.escape||u.escape||X).source+"|"+(n.interpolate||u.interpolate||X).source+"|"+(n.evaluate||u.evaluate||X).source+"|$","g"),function(t,n,i,s,u){a+=e.slice(o,u).replace($,c),a+=n?"'+__e("+n+")+'":s?"';"+s+";__p+='":i?"'+((__t=("+i+"))==null?'':__t)+'":"",r||(r=s||j.test(
|
||||
n||i)),o=u+t.length}),a+="';",l||(f="obj",r?a="with("+f+"){"+a+"}":(n=RegExp("(\\(\\s*)"+f+"\\."+f+"\\b","g"),a=a.replace(z,"$&"+f+".").replace(n,"$1__d"))),a=(r?a.replace(I,""):a).replace(q,"$1").replace(R,"$1;"),a="function("+f+"){"+(l?"":f+"||("+f+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(l?"":",__d="+f+"."+f+"||"+f)+";")+a+"return __p}";try{i=Function("_","return "+a)(s)}catch(h){throw h.source=a,h}return t?i(t):(i.source=
|
||||
a,i)},s.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(){var r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(bt(u),a=r,s=e.apply(o,i)):u||(u=wt(n,f)),s}},s.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},s.toArray=function(e){if(!e)return[];var t=e.length;return t===+t?(Ct?rt.call(e)==yt:"string"==typeof e)?e.split(""):nt.call(e):ln(e)},s.unescape=function(e){return e==r?"":(e+"").replace(F,d)},s.union=
|
||||
function(){for(var e=-1,t=Q.apply(_,arguments),n=t.length,r=[];++e<n;){var i=t[e];0>T(r,i)&&r.push(i)}return r},s.uniq=k,s.uniqueId=function(e){var t=P++;return e?e+t:t},s.values=ln,s.where=Nn,s.without=function(e){for(var t=-1,n=e?e.length:0,r=o(arguments,1,20),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.wrap=function(e,t){return function(){var n=[e];return arguments.length&&et.apply(n,arguments),t.apply(this,n)}},s.zip=function(e){for(var t=-1,n=e?w(wn(arguments,"length")):0,r=Array(n);++
|
||||
t<n;)r[t]=wn(arguments,t);return r},s.all=pn,s.any=xn,s.collect=bn,s.detect=vn,s.drop=N,s.each=mn,s.foldl=En,s.foldr=E,s.head=S,s.include=cn,s.inject=En,s.methods=nn,s.select=dn,s.tail=N,s.take=S,s.unique=k,O(s),s.prototype.chain=function(){return this.__chain__=n,this},s.prototype.value=function(){return this.__wrapped__},mn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=_[e];s.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),St&&e.length===0&&delete
|
||||
e[0],this.__chain__&&(e=new s(e),e.__chain__=n),e}}),mn(["concat","join","slice"],function(e){var t=_[e];s.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new s(e),e.__chain__=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):M?"object"==typeof module&&module&&module.exports==M?(module.exports=s)._=s:M._=s:e._=s})(this);
|
||||
;(function(e,t){function s(e){if(e&&"object"==typeof e&&e.__wrapped__)return e;if(!(this instanceof s))return new s(e);this.__wrapped__=e}function o(t,n){return e.eval("(function("+t+"){"+n+"})")}function u(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||it);if(i)for(var s={},n=t-1;++n<r;){var o=e[n]+"";(Tt.call(s,o)?s[o]:s[o]=[]).push(e[n])}return function(n){if(i){var r=n+"";return Tt.call(s,r)&&-1<W(s[r],n)}return-1<W(e,n,t)}}function a(e){return e.charCodeAt(0)}function f(e,t){var n=e.b,r=t.b,e=e.a,
|
||||
t=t.a;if(e!==t){if(e>t||"undefined"==typeof e)return 1;if(e<t||"undefined"==typeof t)return-1}return n<r?-1:1}function l(e,t,n){function i(){var a=arguments,f=o?this:t;return s||(e=t[u]),n.length&&(a=a.length?n.concat(g(a)):n),this instanceof i?(m.prototype=e.prototype,f=new m,m.prototype=r,a=e.apply(f,a),k(a)?a:f):e.apply(f,a)}var s=C(e),o=!n,u=t;return o&&(n=t),s||(t=e),i}function c(e,t){return e?"function"!=typeof e?function(t){return t[e]}:"undefined"!=typeof t?function(n,r,i){return e.call(t
|
||||
,n,r,i)}:e:K}function h(){for(var e={b:"",c:"",e:Kt,f:Jt,g:"",h:Yt,i:en,j:bt,k:"",l:n},t,r=0;t=arguments[r];r++)for(var i in t)e[i]=t[i];t=e.a,e.d=/^[^,]+/.exec(t)[0],r="var i,l="+e.d+",t="+e.d+";if(!"+e.d+")return t;"+e.k+";",e.b?(r+="var m=l.length;i=-1;if(typeof m=='number'){",e.i&&(r+="if(k(l)){l=l.split('')}"),r+="while(++i<m){"+e.b+"}}else {"):e.h&&(r+="var m=l.length;i=-1;if(m&&j(l)){while(++i<m){i+='';"+e.g+"}}else {"),e.e||(r+="var u=typeof l=='function'&&s.call(l,'prototype');");if(e.f&&
|
||||
e.l)r+="var q=-1,r=p[typeof l]?n(l):[],m=r.length;while(++q<m){i=r[q];",e.e||(r+="if(!(u&&i=='prototype')){"),r+=e.g+"",e.e||(r+="}");else{r+="for(i in l){";if(!e.e||e.l)r+="if(",e.e||(r+="!(u&&i=='prototype')"),!e.e&&e.l&&(r+="&&"),e.l&&(r+="h.call(l,i)"),r+="){";r+=e.g+";";if(!e.e||e.l)r+="}"}r+="}";if(e.e){r+="var f=l.constructor;";for(i=0;7>i;i++)r+="i='"+e.j[i]+"';if(","constructor"==e.j[i]&&(r+="!(f&&f.prototype===l)&&"),r+="h.call(l,i)){"+e.g+"}"}if(e.b||e.h)r+="}";return r+=e.c+";return t"
|
||||
,o("e,h,j,k,p,n,s","return function("+t+"){"+r+"}")(c,Tt,b,A,on,_t,Ct)}function p(e){return"\\"+un[e]}function d(e){return dn[e]}function v(e){return"function"!=typeof e.toString&&"string"==typeof (e+"")}function m(){}function g(e,t,n){t||(t=0),"undefined"==typeof n&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++r<n;)i[r]=e[t+r];return i}function y(e){return vn[e]}function b(e){return kt.call(e)==Bt}function w(e){var t=i;if(!e||"object"!=typeof e||b(e))return t;var n=e.constructor;return!
|
||||
C(n)&&(!tn||!v(e))||n instanceof n?Qt?(hn(e,function(e,n,r){return t=!Tt.call(r,n),i}),t===i):(hn(e,function(e,n){t=n}),t===i||Tt.call(e,t)):t}function E(e){var t=[];return pn(e,function(e,n){t.push(n)}),t}function S(e,t,n,s,o){if(e==r)return e;n&&(t=i);if(n=k(e)){var u=kt.call(e);if(!rn[u]||tn&&v(e))return e;var a=gn(e)}if(!n||!t)return n?a?g(e):cn({},e):e;n=sn[u];switch(u){case Ft:case It:return new n(+e);case qt:case zt:return new n(e);case Ut:return n(e.source,ct.exec(e))}s||(s=[]),o||(o=[]);
|
||||
for(u=s.length;u--;)if(s[u]==e)return o[u];var f=a?n(e.length):{};return s.push(e),o.push(f),(a?wn:pn)(e,function(e,n){f[n]=S(e,t,r,s,o)}),a&&(Tt.call(e,"index")&&(f.index=e.index),Tt.call(e,"input")&&(f.input=e.input)),f}function x(e){var t=[];return hn(e,function(e,n){C(e)&&t.push(n)}),t.sort()}function T(e){var t={};return pn(e,function(e,n){t[e]=n}),t}function N(e,t,s,o){if(e===t)return 0!==e||1/e==1/t;if(e==r||t==r)return e===t;var u=kt.call(e),a=kt.call(t);u==Bt&&(u=Rt),a==Bt&&(a=Rt);if(u!=
|
||||
a)return i;switch(u){case Ft:case It:return+e==+t;case qt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case Ut:case zt:return e==t+""}a=u==jt;if(!a){if(e.__wrapped__||t.__wrapped__)return N(e.__wrapped__||e,t.__wrapped__||t);if(u!=Rt||tn&&(v(e)||v(t)))return i;var u=Zt&&b(e)?Object:e.constructor,f=Zt&&b(t)?Object:t.constructor;if(u!=f&&(!C(u)||!(u instanceof u&&C(f)&&f instanceof f)))return i}s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var l=n,c=0;s.push(e),o.push(t);if(a){c=e.length
|
||||
;if(l=c==t.length)for(;c--&&(l=N(e[c],t[c],s,o)););return l}return hn(e,function(e,n,r){if(Tt.call(r,n))return c++,l=Tt.call(t,n)&&N(e,t[n],s,o)}),l&&hn(t,function(e,t,n){if(Tt.call(n,t))return l=-1<--c}),l}function C(e){return"function"==typeof e}function k(e){return e?on[typeof e]:i}function L(e){return"number"==typeof e||kt.call(e)==qt}function A(e){return"string"==typeof e||kt.call(e)==zt}function O(e,t,n){var i=arguments,s=0,o=2,u=i[3],a=i[4];n!==rt&&(u=[],a=[],"number"!=typeof n&&(o=i.length
|
||||
));for(;++s<o;)pn(i[s],function(t,n){var i,s,o;if(t&&((s=gn(t))||yn(t))){for(var f=u.length;f--;)if(i=u[f]==t)break;i?e[n]=a[f]:(u.push(t),a.push(o=(o=e[n],s)?gn(o)?o:[]:yn(o)?o:{}),e[n]=O(o,t,rt,u,a))}else t!=r&&(e[n]=t)});return e}function M(e){var t=[];return pn(e,function(e){t.push(e)}),t}function _(e,t,n){var r=-1,s=e?e.length:0,o=i,n=(0>n?Dt(0,s+n):n)||0;return"number"==typeof s?o=-1<(A(e)?e.indexOf(t,n):W(e,t,n)):wn(e,function(e){if(++r>=n)return!(o=e===t)}),o}function D(e,t,r){var i=n,t=c
|
||||
(t,r);if(gn(e))for(var r=-1,s=e.length;++r<s&&(i=!!t(e[r],r,e)););else wn(e,function(e,n,r){return i=!!t(e,n,r)});return i}function P(e,t,n){var r=[],t=c(t,n);if(gn(e))for(var n=-1,i=e.length;++n<i;){var s=e[n];t(s,n,e)&&r.push(s)}else wn(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function H(e,t,n){var r,t=c(t,n);return wn(e,function(e,n,s){if(t(e,n,s))return r=e,i}),r}function B(e,t,n){var r=-1,i=e?e.length:0,s=Array("number"==typeof i?i:0),t=c(t,n);if(gn(e))for(;++r<i;)s[r]=t(e[r],r,e);else wn
|
||||
(e,function(e,n,i){s[++r]=t(e,n,i)});return s}function j(e,t,n){var r=-Infinity,i=-1,s=e?e.length:0,o=r;if(t||!gn(e))t=!t&&A(e)?a:c(t,n),wn(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,o=e)});else for(;++i<s;)e[i]>o&&(o=e[i]);return o}function F(e,t){return B(e,t+"")}function I(e,t,n,r){var s=3>arguments.length;return t||(t=K),wn(e,function(e,o,u){n=s?(s=i,e):t.call(r,n,e,o,u)}),n}function q(e,t,n,r){var s=e,o=e?e.length:0,u=3>arguments.length;if("number"!=typeof o)var a=bn(e),o=a.length;else en&&A(e)&&
|
||||
(s=e.split(""));return t||(t=K),wn(e,function(e,f,l){f=a?a[--o]:--o,n=u?(u=i,s[f]):t.call(r,n,s[f],f,l)}),n}function R(e,t,n){var r,t=c(t,n);if(gn(e))for(var n=-1,i=e.length;++n<i&&!(r=t(e[n],n,e)););else wn(e,function(e,n,i){return!(r=t(e,n,i))});return!!r}function U(e,t,n){if(e){var i=e.length;return t==r||n?e[0]:g(e,0,Pt(Dt(0,t),i))}}function z(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];gn(s)?Nt.apply(i,t?s:z(s)):i.push(s)}return i}function W(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof
|
||||
n)r=(0>n?Dt(0,i+n):n||0)-1;else if(n)return r=V(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function X(e,t,n){return g(e,t==r||n?1:Dt(0,t))}function V(e,t,n,r){for(var i=0,s=e?e.length:i,n=n?c(n,r):K,t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r;return i}function $(e,t,n,r){var s=-1,o=e?e.length:0,u=[],a=u;"function"==typeof t&&(r=n,n=t,t=i);var f=!t&&74<o;if(f)var l={};n&&(a=[],n=c(n,r));for(;++s<o;){var r=e[s],h=n?n(r,s,e):r;f&&(a=Tt.call(l,h+"")?l[h]:l[h]=[]);if(t?!s||a[a.length-1
|
||||
]!==h:0>W(a,h))(n||f)&&a.push(h),u.push(r)}return u}function J(e,t){return $t||Lt&&2<arguments.length?Lt.call.apply(Lt,arguments):l(e,t,g(arguments,2))}function K(e){return e}function Q(e){wn(x(e),function(t){var n=s[t]=e[t];s.prototype[t]=function(){var e=[this.__wrapped__];return Nt.apply(e,arguments),e=n.apply(s,e),new s(e)}})}function G(){return this.__wrapped__}var n=!0,r=null,i=!1,Y="object"==typeof exports&&exports,Z="object"==typeof global&&global;Z.global===Z&&(e=Z);var et=[],tt=new function(
|
||||
){},nt=0,rt=tt,it=30,st=e._,ot=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,ut=/&(?:amp|lt|gt|quot|#x27);/g,at=/\b__p\+='';/g,ft=/\b(__p\+=)''\+/g,lt=/(__e\(.*?\)|\b__t\))\+'';/g,ct=/\w*$/,ht=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,pt=RegExp("^"+(tt.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),dt=/\$\{((?:(?=\\?)\\?[\s\S])*?)}/g,vt=/<%=([\s\S]+?)%>/g,mt=/($^)/,gt=/[&<>"']/g,yt=/['\n\r\t\u2028\u2029\\]/g,bt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf"
|
||||
.split(" "),wt=Math.ceil,Et=et.concat,St=Math.floor,xt=pt.test(xt=Object.getPrototypeOf)&&xt,Tt=tt.hasOwnProperty,Nt=et.push,Ct=tt.propertyIsEnumerable,kt=tt.toString,Lt=pt.test(Lt=g.bind)&&Lt,At=pt.test(At=Array.isArray)&&At,Ot=e.isFinite,Mt=e.isNaN,_t=pt.test(_t=Object.keys)&&_t,Dt=Math.max,Pt=Math.min,Ht=Math.random,Bt="[object Arguments]",jt="[object Array]",Ft="[object Boolean]",It="[object Date]",qt="[object Number]",Rt="[object Object]",Ut="[object RegExp]",zt="[object String]",Wt=!/1/.test
|
||||
(Function("1")),Xt=!!e.attachEvent,Vt=Lt&&!/\n|true/.test(Lt+Xt),$t=Lt&&!Vt,Jt=_t&&(Xt||Vt),Kt,Qt,Gt=(Gt={0:1,length:1},et.splice.call(Gt,0,1),Gt[0]),Yt=n;(function(){function e(){this.x=1}var t=[];e.prototype={valueOf:1,y:1};for(var n in new e)t.push(n);for(n in arguments)Yt=!n;Kt=!/valueOf/.test(t),Qt="x"!=t[0]})(1);var Zt=!b(arguments),en="xx"!="x"[0]+Object("x")[0];try{var tn=("[object Object]",kt.call(document)==Rt)}catch(nn){}var rn={"[object Function]":i};rn[Bt]=rn[jt]=rn[Ft]=rn[It]=rn[qt]=
|
||||
rn[Rt]=rn[Ut]=rn[zt]=n;var sn={};sn[jt]=Array,sn[Ft]=Boolean,sn[It]=Date,sn[Rt]=Object,sn[qt]=Number,sn[Ut]=RegExp,sn[zt]=String;var on={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i},un={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:vt,variable:""};if(Xt||Vt||!Wt)o=Function;var an={a:"o,v,g",k:"for(var a=1,b=typeof g=='number'?2:arguments.length;a<b;a++){if((l=arguments[a])){"
|
||||
,g:"t[i]=l[i]",c:"}}"},fn={a:"d,c,w",k:"c=c&&typeof w=='undefined'?c:e(c,w)",b:"if(c(l[i],i,d)===false)return t",g:"if(c(l[i],i,d)===false)return t"},ln={b:r},cn=h(an);Zt&&(b=function(e){return e?Tt.call(e,"callee"):i});var hn=h(fn,ln,{l:i}),pn=h(fn,ln),dn={"&":"&","<":"<",">":">",'"':""","'":"'"},vn=T(dn),mn=h(an,{g:"if(t[i]==null)"+an.g}),gn=At||function(e){return kt.call(e)==jt};C(/x/)&&(C=function(e){return"[object Function]"==kt.call(e)});var yn=xt?function(e){if(!e||"object"!=typeof
|
||||
e)return i;var t=e.valueOf,n="function"==typeof t&&(n=xt(t))&&xt(n);return n?e==n||xt(e)==n&&!b(e):w(e)}:w,bn=_t?function(e){return"function"==typeof e&&Ct.call(e,"prototype")?E(e):k(e)?_t(e):[]}:E,wn=h(fn);s.assign=cn,s.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=x(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=J(e[i],e)}return e},s.chain=function(e){return new s(e)},s.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},s.countBy=function(e,t,n
|
||||
){var r={},t=c(t,n);return wn(e,function(e,n,i){n=t(e,n,i),Tt.call(r,n)?r[n]++:r[n]=1}),r},s.defaults=mn,s.difference=function(e){for(var t=-1,n=e?e.length:0,r=Et.apply(et,arguments),r=u(r,n),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.filter=P,s.flatten=z,s.forEach=wn,s.forIn=hn,s.forOwn=pn,s.functions=x,s.groupBy=function(e,t,n){var r={},t=c(t,n);return wn(e,function(e,n,i){n=t(e,n,i),(Tt.call(r,n)?r[n]:r[n]=[]).push(e)}),r},s.initial=function(e,t,n){if(!e)return[];var i=e.length;return g
|
||||
(e,0,Pt(Dt(0,i-(t==r||n?1:t||0)),i))},s.intersection=function(e){var t=arguments,n=t.length,r={},i=[];return wn(e,function(e){if(0>W(i,e)){for(var s=n;--s;)if(!(r[s]||(r[s]=u(t[s])))(e))return;i.push(e)}}),i},s.invert=T,s.invoke=function(e,t){var n=g(arguments,2),r="function"==typeof t,i=[];return wn(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},s.keys=bn,s.map=B,s.max=j,s.merge=O,s.min=function(e,t,n){var r=Infinity,i=-1,s=e?e.length:0,o=r;if(t||!gn(e))t=!t&&A(e)?a:c(t,n),wn(e,function(e,n,i)
|
||||
{n=t(e,n,i),n<r&&(r=n,o=e)});else for(;++i<s;)e[i]<o&&(o=e[i]);return o},s.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},s.omit=function(e,t,n){var r="function"==typeof t,i={};if(r)t=c(t,n);else var s=Et.apply(et,arguments);return hn(e,function(e,n,o){if(r?!t(e,n,o):0>W(s,n,1))i[n]=e}),i},s.pairs=function(e){var t=[];return pn(e,function(e,n){t.push([n,e])}),t},s.pick=function(e,t,n){var r={};if("function"!=typeof t)for(var i=0,s=Et.apply
|
||||
(et,arguments),o=s.length;++i<o;){var u=s[i];u in e&&(r[u]=e[u])}else t=c(t,n),hn(e,function(e,n,i){t(e,n,i)&&(r[n]=e)});return r},s.pluck=F,s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=Dt(0,wt((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reject=function(e,t,n){return t=c(t,n),P(e,function(e,n,r){return!t(e,n,r)})},s.rest=X,s.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return wn(e,function(e){var r=St(Ht()*(++t+1));n[t]=n[r],n[r]=e}),n},s.sortBy=function(e,
|
||||
t,n){var r=[],t=c(t,n);wn(e,function(e,n,i){r.push({a:t(e,n,i),b:n,c:e})}),e=r.length;for(r.sort(f);e--;)r[e]=r[e].c;return r},s.tap=function(e,t){return t(e),e},s.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},s.toArray=function(e){return"number"==typeof (e?e.length:0)?en&&A(e)?e.split(""):g(e):M(e)},s.union=function(){return $(Et.apply(et,arguments))},s.uniq=$,s.values=M,s.where=function(e,t){var n=bn(t);return P(e,function(e){for(var r=n.length;r--;){var i=
|
||||
e[n[r]]===t[n[r]];if(!i)break}return!!i})},s.without=function(e){for(var t=-1,n=e?e.length:0,r=u(arguments,1,20),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.zip=function(e){for(var t=-1,n=e?j(F(arguments,"length")):0,r=Array(n);++t<n;)r[t]=F(arguments,t);return r},s.collect=B,s.drop=X,s.each=wn,s.extend=cn,s.methods=x,s.select=P,s.tail=X,s.unique=$,Q(s),s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=J,s.bindKey=function(e,t){return l(e,t,g
|
||||
(arguments,2))},s.clone=S,s.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},s.contains=_,s.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,clearTimeout(a),a=setTimeout(i,t),r&&(o=e.apply(u,s)),o}},s.defer=function(e){var n=g(arguments,1);return setTimeout(function(){e.apply(t,n)},1)},s.delay=function(e,n){var r=g(arguments,2);return setTimeout
|
||||
(function(){e.apply(t,r)},n)},s.escape=function(e){return e==r?"":(e+"").replace(gt,d)},s.every=D,s.find=H,s.has=function(e,t){return e?Tt.call(e,t):i},s.identity=K,s.indexOf=W,s.isArguments=b,s.isArray=gn,s.isBoolean=function(e){return e===n||e===i||kt.call(e)==Ft},s.isDate=function(e){return kt.call(e)==It},s.isElement=function(e){return e?1===e.nodeType:i},s.isEmpty=function(e){var t=n;if(!e)return t;var r=kt.call(e),s=e.length;return r==jt||r==zt||r==Bt||Zt&&b(e)||r==Rt&&"number"==typeof s&&C
|
||||
(e.splice)?!s:(pn(e,function(){return t=i}),t)},s.isEqual=N,s.isFinite=function(e){return Ot(e)&&!Mt(parseFloat(e))},s.isFunction=C,s.isNaN=function(e){return L(e)&&e!=+e},s.isNull=function(e){return e===r},s.isNumber=L,s.isObject=k,s.isPlainObject=yn,s.isRegExp=function(e){return kt.call(e)==Ut},s.isString=A,s.isUndefined=function(e){return"undefined"==typeof e},s.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?Dt(0,r+n):Pt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1
|
||||
},s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Tt.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.mixin=Q,s.noConflict=function(){return e._=st,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){return l(e,g(arguments,1))},s.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+St(Ht()*((+t||0)-e+1))},s.reduce=I,s.reduceRight=q,s.result=function(e,
|
||||
t){var n=e?e[t]:r;return C(n)?e[t]():n},s.size=function(e){var t=e?e.length:0;return"number"==typeof t?t:bn(e).length},s.some=R,s.sortedIndex=V,s.template=function(e,t,n){e||(e=""),n||(n={});var r,i,u=s.templateSettings,a=0,f=n.interpolate||u.interpolate||mt,l="__p+='",c=n.variable||u.variable,h=c;e.replace(RegExp((n.escape||u.escape||mt).source+"|"+f.source+"|"+(f===vt?dt:mt).source+"|"+(n.evaluate||u.evaluate||mt).source+"|$","g"),function(t,n,i,s,o,u){return i||(i=s),l+=e.slice(a,u).replace(yt
|
||||
,p),n&&(l+="'+__e("+n+")+'"),o&&(l+="';"+o+";__p+='"),i&&(l+="'+((__t=("+i+"))==null?'':__t)+'"),r||(r=o||ot.test(n||i)),a=u+t.length,t}),l+="';\n",h||(c="obj",r?l="with("+c+"){"+l+"}":(n=RegExp("(\\(\\s*)"+c+"\\."+c+"\\b","g"),l=l.replace(ht,"$&"+c+".").replace(n,"$1__d"))),l=(r?l.replace(at,""):l).replace(ft,"$1").replace(lt,"$1;"),l="function("+c+"){"+(h?"":c+"||("+c+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(h?"":",__d="+
|
||||
c+"."+c+"||"+c)+";")+l+"return __p}";try{i=o("_","return "+l)(s)}catch(d){throw d.source=l,d}return t?i(t):(i.source=l,i)},s.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(){var f=new Date,l=t-(f-a);return i=arguments,o=this,0>=l?(clearTimeout(u),u=r,a=f,s=e.apply(o,i)):u||(u=setTimeout(n,l)),s}},s.unescape=function(e){return e==r?"":(e+"").replace(ut,y)},s.uniqueId=function(e){return(e==r?"":e+"")+ ++nt},s.wrap=function(e,t){return function(){var n=
|
||||
[e];return Nt.apply(n,arguments),t.apply(this,n)}},s.all=D,s.any=R,s.detect=H,s.foldl=I,s.foldr=q,s.include=_,s.inject=I,pn(s,function(e,t){s.prototype[t]||(s.prototype[t]=function(){var t=[this.__wrapped__];return Nt.apply(t,arguments),e.apply(s,t)})}),s.first=U,s.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:g(e,Dt(0,i-t))}},s.take=U,s.head=U,pn(s,function(e,t){s.prototype[t]||(s.prototype[t]=function(t,n){var i=e(this.__wrapped__,t,n);return t==r||n?i:new s(i)})}),s.VERSION="1.0.0-rc.2"
|
||||
,s.prototype.chain=function(){return this},s.prototype.toString=function(){return""+this.__wrapped__},s.prototype.value=G,s.prototype.valueOf=G,wn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=et[e];s.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),Gt&&e.length===0&&delete e[0],this}}),wn(["concat","join","slice"],function(e){var t=et[e];s.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return new s(e)}}),typeof define=="function"&&typeof
|
||||
define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):Y?"object"==typeof module&&module&&module.exports==Y?(module.exports=s)._=s:Y._=s:e._=s})(this);
|
||||
3798
lodash.underscore.js
Normal file
3798
lodash.underscore.js
Normal file
File diff suppressed because it is too large
Load Diff
65
lodash.underscore.min.js
vendored
65
lodash.underscore.min.js
vendored
@@ -1,36 +1,33 @@
|
||||
/*!
|
||||
Lo-Dash 0.8.2 lodash.com/license
|
||||
Underscore.js 1.4.2 underscorejs.org/LICENSE
|
||||
Lo-Dash 1.0.0-rc.2 (Custom Build) lodash.com/license
|
||||
Build: `lodash underscore -m -o ./lodash.underscore.min.js`
|
||||
Underscore.js 1.4.3 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(e,t){function s(e,t,r){var s;if(!e)return i;var t=x(t,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(s=e[r],t(s,r,e))return n}else for(r in e)if(it.call(e,r)&&(s=e[r],t(s,r,e)))return n;return i}function o(e,t,n,r){var s,o,u=n;if(!e)return u;var a=3>arguments.length,t=x(t,r),f=e.length;s=-1;if(f===+f)for(a&&(u=e[++s]);++s<f;)o=e[s],u=t(u,o,s,e);else for(s in e)it.call(e,s)&&(o=e[s],u=a?(a=i,o):t(u,o,s,e));return u}function u(e,t){var n,r,i=e||[];if(!e)return i;var s=e.length;n=-1;if(s===+
|
||||
s)for(i=Array(s);++n<s;)r=e[n],i[n]=r[t];else for(n in i=[],e)it.call(e,n)&&(r=e[n],i.push(r[t]));return i}function a(e,t,n){var r,i=e||[];if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]=t(r,n,e);else for(n in i=[],e)it.call(e,n)&&(r=e[n],i.push(t(r,n,e)));return i}function f(e,t,n){var r;if(!e)return e;var t=x(t,n),i=e.length,n=-1;if(i===+i)for(;++n<i;)r=e[n],t(r,n,e);else for(n in e)it.call(e,n)&&(r=e[n],t(r,n,e));return e}function l(e,n,r){var i,s=t;if(!
|
||||
e)return s;var n=x(n,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(i=e[r],n(i,r,e))return i}else for(r in e)if(it.call(e,r)&&(i=e[r],n(i,r,e)))return i;return s}function c(e,t,n){var r,i=[];if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],t(r,n,e)&&i.push(r);else for(n in e)it.call(e,n)&&(r=e[n],t(r,n,e)&&i.push(r));return i}function h(e,t,r){var s;if(!e)return n;var t=x(t,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(s=e[r],!t(s,r,e))return i}else for(r in e)if(it.call(e,r)&&
|
||||
(s=e[r],!t(s,r,e)))return i;return n}function p(e,t){var r,s;if(!e)return i;var o=e.length;r=-1;if(o===+o){if(ut.call(e)==wt)return-1<e.indexOf(t);for(;++r<o;)if(s=e[r],s===t)return n}else for(r in e)if(it.call(e,r)&&(s=e[r],s===t))return n;return i}function d(e){var t,n,r=[];if(!e)return r;for(t in e)it.call(e,t)&&(n=e[t],r.push(n));return r}function v(e){var t,n,r=[];if(!e)return r;for(t in e)n=e[t],L(n)&&r.push(t);return r.sort(),r}function m(e,t,n){var r;if(!e)return e;t=x(t,n);for(r in e)n=e
|
||||
[r],t(n,r,e);return e}function g(e){var t,n,r=e;if(!e)return e;for(var i=1,s=arguments.length;i<s;i++)if(r=arguments[i])for(t in r)n=r[t],e[t]=n;return e}function y(e){var t,n=[];if(!e)return n;for(t in e)it.call(e,t)&&n.push(t);return n}function b(e){var t,n,r={};if(!e)return r;for(t in e)it.call(e,t)&&(n=e[t],r[n]=t);return r}function w(e){if(e&&e.__wrapped__)return e;if(!(this instanceof w))return new w(e);this.__wrapped__=e}function E(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1
|
||||
;if(e<n||n===t)return-1}return r<i?-1:1}function S(e,t,n){function r(){var i=arguments,s=t;return n.length&&(i=i.length?n.concat(ot.call(i)):n),this instanceof r?(C.prototype=e.prototype,s=new C,(i=e.apply(s,i))&&Tt[typeof i]?i:s):e.apply(s,i)}return r}function x(e,n){return e?"function"!=typeof e?function(t){return t[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:q}function T(e){return"\\"+Nt[e]}function N(e){return kt[e]}function C(){}function k(e){return Lt[e]}function L(e){return"function"==typeof
|
||||
e}function A(e){var t=i;if(!e||"object"!=typeof e||isArguments(e))return t;var n=e.constructor;return!L(n)||n instanceof n?(m(e,function(e,n){t=n}),t===i||it.call(e,t)):t}function O(e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Tt[typeof e]||Tt[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=ut.call(e);if(u!=ut.call(t))return i;switch(u){case vt:case mt:return+e==+t;case gt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case bt:case wt:return e==t+""}var a=Ct(e);if(!a&&u!=yt
|
||||
)return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var f=n,u=0;s.push(e),o.push(t);if(a){u=e.length;if(f=u==t.length)for(;u--&&(f=O(e[u],t[u],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!L(a)||!(a instanceof a&&L(f)&&f instanceof f)))return i;for(var l in e)if(it.call(e,l)&&(u++,!it.call(t,l)||!O(e[l],t[l],s,o)))return i;for(l in t)if(it.call(t,l)&&!(u--))return i;return n}function M(e,t,n){var r=-Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=x(t,n),f(e,function(
|
||||
e,n,i){n=t(e,n,i),n>r&&(r=n,o=e)});else for(;++i<s;)e[i]>o&&(o=e[i]);return o}function _(e,t,n,r){var s=e?e.length:0,o=3>arguments.length;if(s!==+s)var u=At(e),s=u.length;return f(e,function(a,f,l){f=u?u[--s]:--s,n=o?(o=i,e[f]):t.call(r,n,e[f],f,l)}),n}function D(e,t,n){if(e)return t==r||n?e[0]:ot.call(e,0,t)}function P(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];Ct(s)?st.apply(i,t?s:P(s)):i.push(s)}return i}function H(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof n)r=(0>n?ht(0,
|
||||
i+n):n||0)-1;else if(n)return r=j(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function B(e,t,n){return e?ot.call(e,t==r||n?1:t):[]}function j(e,t,n,r){var i=0,s=e?e.length:i;if(n){n=x(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 F(e,t,n,r){var s=-1,o=e?e.length:0,u=[],a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n=x(n,r);++s<o;)if(r=n(e[s],s,e),t?!s||a[a.length-1]!==r:0>H(a,r))a.push(r),u.push(e[s]);return u}function I
|
||||
(e,t){return xt||at&&2<arguments.length?at.call.apply(at,arguments):S(e,t,ot.call(arguments,2))}function q(e){return e}function R(e){f(v(e),function(t){var r=w[t]=e[t];w.prototype[t]=function(){var e=[this.__wrapped__];return arguments.length&&st.apply(e,arguments),e=r.apply(w,e),this.__chain__&&(e=new w(e),e.__chain__=n),e}})}var n=!0,r=null,i=!1,U="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),z=Array.prototype,W=Object.prototype,
|
||||
X=0,V=e._,$=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,J=/&(?:amp|lt|gt|quot|#x27);/g,K=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,Q=RegExp("^"+(W.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),G=/($^)/,Y=/[&<>"']/g,Z=/['\n\r\t\u2028\u2029\\]/g,et=Math.ceil,tt=z.concat,nt=Math.floor,rt=Q.test(rt=Object.getPrototypeOf)&&rt,it=W.hasOwnProperty,st=z.push,ot=z.slice,ut=W.toString,at=Q.test(at=ot.bind)&&at,ft=Q.test(ft=Array.isArray
|
||||
)&&ft,lt=e.isFinite,ct=Q.test(ct=Object.keys)&&ct,ht=Math.max,pt=Math.min,dt=Math.random,vt="[object Boolean]",mt="[object Date]",gt="[object Number]",yt="[object Object]",bt="[object RegExp]",wt="[object String]",Et=e.clearTimeout,St=e.setTimeout,xt=at&&/\n|Opera/.test(at+ut.call(e.opera)),Tt={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},Nt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};w.templateSettings={escape:/<%-([\s\S]+?)%>/g
|
||||
,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},w.isArguments=function(e){return"[object Arguments]"==ut.call(e)},w.isArguments(arguments)||(w.isArguments=function(e){return e?it.call(e,"callee"):i});var Ct=ft||function(e){return"[object Array]"==ut.call(e)};L(/x/)&&(L=function(e){return"[object Function]"==ut.call(e)});var W=rt?function(e){if(!e||"object"!=typeof e)return i;var t=e.valueOf,n="function"==typeof t&&(n=rt(t))&&rt(n);return n?e==n||rt(e)==n&&!isArguments(e):A
|
||||
(e)}:A,kt={"&":"&","<":"<",">":">",'"':""","'":"'"},Lt=b(kt),At=ct?function(e){return e&&Tt[typeof e]?ct(e):[]}:y;w.VERSION="0.8.2",w.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},w.bind=I,w.bindAll=function(e){var t,n,r=e,i=e;if(!e)return i;n=arguments,t=0;var s=n.length;if(1<s){for(;++t<s;)i[n[t]]=I(i[n[t]],i);return i}for(t in r)n=r[t],L(n)&&(i[t]=I(n,i));return i},w.chain=function(e){return e=new w(e),e.__chain__=n,e},w.clone=function(
|
||||
e){return e&&Tt[typeof e]?Ct(e)?ot.call(e):g({},e):e},w.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},w.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},w.contains=p,w.countBy=function(e,t,n){var r,i={};if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],r=t(r,n,e),it.call(i,r)?i[r]++:i[r]=1;else for(n in e)it.call(e,n)&&(r=e[n],r=t(r,n,e),it.call(i,r)?
|
||||
i[r]++:i[r]=1);return i},w.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,Et(a),a=St(i,t),r&&(o=e.apply(u,s)),o}},w.defaults=function(e){var t,n,i=e;if(!e)return e;for(var s=1,o=arguments.length;s<o;s++)if(i=arguments[s])for(t in i)n=i[t],e[t]==r&&(e[t]=n);return e},w.defer=function(e){var n=ot.call(arguments,1);return St(function(){return e.apply(t,n)},1)},w.delay=function(e,n){var r=ot.call(arguments,2);return St
|
||||
(function(){return e.apply(t,r)},n)},w.difference=function(e){for(var t=-1,n=e.length,r=tt.apply(z,arguments),i=[];++t<n;){var s=e[t];0>H(r,s,n)&&i.push(s)}return i},w.escape=function(e){return e==r?"":(e+"").replace(Y,N)},w.every=h,w.extend=g,w.filter=c,w.find=l,w.first=D,w.flatten=P,w.forEach=f,w.forIn=m,w.forOwn=function(e,t,n){var r;if(!e)return e;t=x(t,n);for(r in e)it.call(e,r)&&(n=e[r],t(n,r,e));return e},w.functions=v,w.groupBy=function(e,t,n){var r,i={};if(!e)return i;var t=x(t,n),s=e.length
|
||||
,n=-1;if(s===+s)for(;++n<s;){r=e[n];var o=t(r,n,e);(it.call(i,o)?i[o]:i[o]=[]).push(r)}else for(n in e)it.call(e,n)&&(r=e[n],o=t(r,n,e),(it.call(i,o)?i[o]:i[o]=[]).push(r));return i},w.has=function(e,t){return e?it.call(e,t):i},w.identity=q,w.indexOf=H,w.initial=function(e,t,n){return e?ot.call(e,0,-(t==r||n?1:t)):[]},w.intersection=function(e){var t=arguments.length,n=-1,r=e.length,i=[];e:for(;++n<r;){var s=e[n];if(0>H(i,s)){for(var o=1;o<t;o++)if(0>H(arguments[o],s))continue e;i.push(s)}}return i
|
||||
},w.invert=b,w.invoke=function(e,t){var n,r,i=e,s=e||[];if(!e)return s;var o=ot.call(arguments,2),u="function"==typeof t,a=i.length;n=-1;if(a===+a)for(s=Array(a);++n<a;)r=i[n],s[n]=(u?t:r[t]).apply(r,o);else for(n in s=[],i)it.call(i,n)&&(r=i[n],s.push((u?t:r[t]).apply(r,o)));return s},w.isArray=Ct,w.isBoolean=function(e){return e===n||e===i||ut.call(e)==vt},w.isDate=function(e){return ut.call(e)==mt},w.isElement=function(e){return e?1===e.nodeType:i},w.isEmpty=function(e){var t;if(!e)return n;var r=
|
||||
ut.call(e),s=e.length;if(Ct(e)||r==wt||r==yt&&s===+s&&L(e.splice))return!s;for(t in e)if(it.call(e,t))return i;return n},w.isEqual=O,w.isFinite=function(e){return lt(e)&&ut.call(e)==gt},w.isFunction=L,w.isNaN=function(e){return ut.call(e)==gt&&e!=+e},w.isNull=function(e){return e===r},w.isNumber=function(e){return ut.call(e)==gt},w.isObject=function(e){return e?Tt[typeof e]:i},w.isPlainObject=W,w.isRegExp=function(e){return ut.call(e)==bt},w.isString=function(e){return ut.call(e)==wt},w.isUndefined=
|
||||
function(e){return e===t},w.keys=At,w.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:ot.call(e,-t||i)}},w.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?ht(0,r+n):pt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},w.map=a,w.max=M,w.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return it.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},w.min=function(e,t,n){var r=Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+
|
||||
s)t=x(t,n),f(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,o=e)});else for(;++i<s;)e[i]<o&&(o=e[i]);return o},w.mixin=R,w.noConflict=function(){return e._=V,this},w.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},w.omit=function(e,t,n){var r,i,s=e,o={};if(!e)return o;var u="function"==typeof t;if(u)t=x(t,n);else var a=tt.apply(z,arguments);for(r in s)if(i=s[r],u?!t(i,r,e):0>H(a,r))o[r]=i;return o},w.once=function(e){var t,s=i;return function(){
|
||||
return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},w.pairs=function(e){var t,n,r=[];if(!e)return r;for(t in e)it.call(e,t)&&(n=e[t],r.push([t,n]));return r},w.pick=function(e,t,n){var r,i,s=e,o={};if(!e)return o;if("function"!=typeof t){r=0,i=tt.apply(z,arguments);for(s=i.length;++r<s;){var u=i[r];u in e&&(o[u]=e[u])}}else for(r in t=x(t,n),s)i=s[r],t(i,r,e)&&(o[r]=i);return o},w.pluck=u,w.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+nt(dt()*((+t||0)-e+1))},w.range=function(
|
||||
e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=ht(0,et((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},w.reduce=o,w.reduceRight=_,w.reject=function(e,t,n){var r,i=[];if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],!t(r,n,e)&&i.push(r);else for(n in e)it.call(e,n)&&(r=e[n],!t(r,n,e)&&i.push(r));return i},w.rest=B,w.result=function(e,t){var n=e?e[t]:r;return L(n)?e[t]():n},w.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return f(e,function(e){var r=nt(dt()*(++
|
||||
t+1));n[t]=n[r],n[r]=e}),n},w.size=function(e){var t=e?e.length:0;return t===+t?t:At(e).length},w.some=s,w.sortBy=function(e,t,n){var r,i=e||[];if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]={a:t(r,n,e),b:n,c:r};else for(n in i=[],e)it.call(e,n)&&(r=e[n],i.push({a:t(r,n,e),b:n,c:r}));i.sort(E);for(s=i.length;s--;)i[s]=i[s].c;return i},w.sortedIndex=j,w.tap=function(e,t){return t(e),e},w.template=function(e,t,n){e||(e=""),n||(n={});var r,i,s=0,o=w.templateSettings
|
||||
,u="__p += '",a=n.variable||o.variable,f=a;e.replace(RegExp((n.escape||o.escape||G).source+"|"+(n.interpolate||o.interpolate||G).source+"|"+(n.evaluate||o.evaluate||G).source+"|$","g"),function(t,n,i,o,a){u+=e.slice(s,a).replace(Z,T),u+=n?"'+__e("+n+")+'":o?"';"+o+";__p+='":i?"'+((__t=("+i+"))==null?'':__t)+'":"",r||(r=o||$.test(n||i)),s=a+t.length}),u+="';",f||(a="obj",r?u="with("+a+"){"+u+"}":(n=RegExp("(\\(\\s*)"+a+"\\."+a+"\\b","g"),u=u.replace(K,"$&"+a+".").replace(n,"$1__d"))),u="function("+
|
||||
a+"){"+(f?"":a+"||("+a+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(f?"":",__d="+a+"."+a+"||"+a)+";")+u+"return __p}";try{i=Function("_","return "+u)(w)}catch(l){throw l.source=u,l}return t?i(t):(i.source=u,i)},w.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(){var r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(Et(u),a=r,s=e.apply(o,i)):u||(u=St(n,f)),s}},w.times=function(
|
||||
e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},w.toArray=function(e){if(!e)return[];var t=e.length;return t===+t?"string"==typeof e?e.split(""):ot.call(e):d(e)},w.unescape=function(e){return e==r?"":(e+"").replace(J,k)},w.union=function(){for(var e=-1,t=tt.apply(z,arguments),n=t.length,r=[];++e<n;){var i=t[e];0>H(r,i)&&r.push(i)}return r},w.uniq=F,w.uniqueId=function(e){var t=X++;return e?e+t:t},w.values=d,w.where=function(e,t){var r,i,s=[];if(!e)return s;var o=[];m(t,function(
|
||||
e,t){o.push(t)});var u=o.length,a=e.length;r=-1;if(a===+a)for(;++r<a;){i=e[r];for(var f=n,l=0;l<u&&(f=o[l],f=i[f]===t[f]);l++);f&&s.push(i)}else for(r in e)if(it.call(e,r)){i=e[r],f=n;for(l=0;l<u&&(f=o[l],f=i[f]===t[f]);l++);f&&s.push(i)}return s},w.without=function(e){for(var t=-1,n=e.length,r=[];++t<n;){var i=e[t];0>H(arguments,i,1)&&r.push(i)}return r},w.wrap=function(e,t){return function(){var n=[e];return arguments.length&&st.apply(n,arguments),t.apply(this,n)}},w.zip=function(e){for(var t=-1
|
||||
,n=e?M(u(arguments,"length")):0,r=Array(n);++t<n;)r[t]=u(arguments,t);return r},w.all=h,w.any=s,w.collect=a,w.detect=l,w.drop=B,w.each=f,w.foldl=o,w.foldr=_,w.head=D,w.include=p,w.inject=o,w.methods=v,w.select=c,w.tail=B,w.take=D,w.unique=F,R(w),w.prototype.chain=function(){return this.__chain__=n,this},w.prototype.value=function(){return this.__wrapped__},f("pop push reverse shift sort splice unshift".split(" "),function(e){var t=z[e];w.prototype[e]=function(){var e=this.__wrapped__;return t.apply
|
||||
(e,arguments),this.__chain__&&(e=new w(e),e.__chain__=n),e}}),f(["concat","join","slice"],function(e){var t=z[e];w.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new w(e),e.__chain__=n),e}}),U?"object"==typeof module&&module&&module.exports==U?(module.exports=w)._=w:U._=w:e._=w})(this);
|
||||
;(function(e,t){function n(e){if(e&&"object"==typeof e&&e.__wrapped__)return e;if(!(this instanceof n))return new n(e);this.__wrapped__=e}function r(e,t){var n=e.b,r=t.b,e=e.a,t=t.a;if(e!==t){if(e>t||"undefined"==typeof e)return 1;if(e<t||"undefined"==typeof t)return-1}return n<r?-1:1}function i(e,t,n){function r(){var i=arguments,s=t;return n.length&&(i=i.length?n.concat(f(i)):n),this instanceof r?(a.prototype=e.prototype,s=new a,a.prototype=null,i=e.apply(s,i),y(i)?i:s):e.apply(s,i)}return r}function s
|
||||
(e,t){return e?"function"!=typeof e?function(t){return t[e]}:"undefined"!=typeof t?function(n,r,i){return e.call(t,n,r,i)}:e:I}function o(e){return"\\"+St[e]}function u(e){return Nt[e]}function a(){}function f(e,t,n){t||(t=0),"undefined"==typeof n&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++r<n;)i[r]=e[t+r];return i}function l(e){return Ct[e]}function c(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)for(var i in r)e[i]=r[i]}return e}function h(e){
|
||||
var t=[];return Tt(e,function(e,n){t.push(n)}),t}function p(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)for(var i in r)null==e[i]&&(e[i]=r[i])}return e}function d(e){var t=[];return xt(e,function(e,n){g(e)&&t.push(n)}),t.sort()}function v(e){var t={};return Tt(e,function(e,n){t[e]=n}),t}function m(e,t,n,r){if(e===t)return 0!==e||1/e==1/t;if(null==e||null==t)return e===t;var i=rt.call(e),s=rt.call(t);if(i!=s)return!1;switch(i){case pt:case dt:return+e==+t;case vt
|
||||
:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case gt:case yt:return e==t+""}s=i==ht;if(!s){if(e.__wrapped__||t.__wrapped__)return m(e.__wrapped__||e,t.__wrapped__||t);if(i!=mt)return!1;var i=e.constructor,o=t.constructor;if(i!=o&&(!g(i)||!(i instanceof i&&g(o)&&o instanceof o)))return!1}n||(n=[]),r||(r=[]);for(i=n.length;i--;)if(n[i]==e)return r[i]==t;var u=!0,a=0;n.push(e),r.push(t);if(s){a=e.length;if(u=a==t.length)for(;a--&&(u=m(e[a],t[a],n,r)););return u}return xt(e,function(e,i,s){if(tt.call(s,i)
|
||||
)return a++,!(u=tt.call(t,i)&&m(e,t[i],n,r))&&X}),u&&xt(t,function(e,t,n){if(tt.call(n,t))return!(u=-1<--a)&&X}),u}function g(e){return"function"==typeof e}function y(e){return e?Et[typeof e]:!1}function b(e){return"number"==typeof e||rt.call(e)==vt}function w(e){return"string"==typeof e||rt.call(e)==yt}function E(e){var t=[];return Tt(e,function(e){t.push(e)}),t}function S(e,t){var n=!1;return"number"==typeof (e?e.length:0)?n=-1<P(e,t):At(e,function(e){return(n=e===t)&&X}),n}function x(e,t,n){var r=!0
|
||||
,t=s(t,n);if(kt(e))for(var n=-1,i=e.length;++n<i&&(r=!!t(e[n],n,e)););else At(e,function(e,n,i){return!(r=!!t(e,n,i))&&X});return r}function T(e,t,n){var r=[],t=s(t,n);if(kt(e))for(var n=-1,i=e.length;++n<i;){var o=e[n];t(o,n,e)&&r.push(o)}else At(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function N(e,t,n){var r,t=s(t,n);return At(e,function(e,n,i){if(t(e,n,i))return r=e,X}),r}function C(e,t,n){var r=-1,i=e?e.length:0,o=Array("number"==typeof i?i:0),t=s(t,n);if(kt(e))for(;++r<i;)o[r]=t(e[r
|
||||
],r,e);else At(e,function(e,n,i){o[++r]=t(e,n,i)});return o}function k(e,t,n){var r=-Infinity,i=-1,o=e?e.length:0,u=r;if(t||!kt(e))t=s(t,n),At(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,u=e)});else for(;++i<o;)e[i]>u&&(u=e[i]);return u}function L(e,t){return C(e,t+"")}function A(e,t,n,r){var i=3>arguments.length;return t||(t=I),At(e,function(e,s,o){n=i?(i=!1,e):t.call(r,n,e,s,o)}),n}function O(e,t,n,r){var i=e?e.length:0,s=3>arguments.length;if("number"!=typeof i)var o=Lt(e),i=o.length;return t||(t=I
|
||||
),At(e,function(u,a,f){a=o?o[--i]:--i,n=s?(s=!1,e[a]):t.call(r,n,e[a],a,f)}),n}function M(e,t,n){var r,t=s(t,n);if(kt(e))for(var n=-1,i=e.length;++n<i&&!(r=t(e[n],n,e)););else At(e,function(e,n,i){return(r=t(e,n,i))&&X});return!!r}function _(e,t,n){if(e){var r=e.length;return null==t||n?e[0]:f(e,0,lt(ft(0,t),r))}}function D(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];kt(s)?nt.apply(i,t?s:D(s)):i.push(s)}return i}function P(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof n)r=(0>n?ft
|
||||
(0,i+n):n||0)-1;else if(n)return r=B(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function H(e,t,n){return f(e,null==t||n?1:ft(0,t))}function B(e,t,n,r){for(var i=0,o=e?e.length:i,n=n?s(n,r):I,t=n(t);i<o;)r=i+o>>>1,n(e[r])<t?i=r+1:o=r;return i}function j(e,t,n,r){var i=-1,o=e?e.length:0,u=[],a=u;"function"==typeof t&&(r=n,n=t,t=!1),n&&(a=[],n=s(n,r));for(;++i<o;){var r=e[i],f=n?n(r,i,e):r;if(t?!i||a[a.length-1]!==f:0>P(a,f))n&&a.push(f),u.push(r)}return u}function F(e,t){return bt||
|
||||
it&&2<arguments.length?it.call.apply(it,arguments):i(e,t,f(arguments,2))}function I(e){return e}function q(e){At(d(e),function(t){var r=n[t]=e[t];n.prototype[t]=function(){var e=[this.__wrapped__];return nt.apply(e,arguments),e=r.apply(n,e),this.__chain__&&(e=new n(e),e.__chain__=!0),e}})}var R="object"==typeof exports&&exports,U="object"==typeof global&&global;U.global===U&&(e=U);var z=[],U=new function(){},W=0,X=U,V=e._,$=/&(?:amp|lt|gt|quot|#x27);/g,J=RegExp("^"+(U.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g
|
||||
,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),K=/($^)/,Q=/[&<>"']/g,G=/['\n\r\t\u2028\u2029\\]/g,Y=Math.ceil,Z=z.concat,et=Math.floor,tt=U.hasOwnProperty,nt=z.push,rt=U.toString,it=J.test(it=f.bind)&&it,st=J.test(st=Array.isArray)&&st,ot=e.isFinite,ut=e.isNaN,at=J.test(at=Object.keys)&&at,ft=Math.max,lt=Math.min,ct=Math.random,ht="[object Array]",pt="[object Boolean]",dt="[object Date]",vt="[object Number]",mt="[object Object]",gt="[object RegExp]",yt="[object String]",U=!!e.attachEvent,U=it&&!/\n|true/
|
||||
.test(it+U),bt=it&&!U,wt=(wt={0:1,length:1},z.splice.call(wt,0,1),wt[0]),Et={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,"undefined":!1},St={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};n.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},n.isArguments=function(e){return"[object Arguments]"==rt.call(e)},n.isArguments(arguments)||(n.isArguments=function(e){return e?tt.call(e,"callee"):!1}
|
||||
);var xt=function(e,t){var n;if(!e)return e;t||(t=I);for(n in e)if(t(e[n],n,e)===X)break;return e},Tt=function(e,t){var n;if(!e)return e;t||(t=I);for(n in e)if(tt.call(e,n)&&t(e[n],n,e)===X)break;return e},Nt={"&":"&","<":"<",">":">",'"':""","'":"'"},Ct=v(Nt),kt=st||function(e){return rt.call(e)==ht};g(/x/)&&(g=function(e){return"[object Function]"==rt.call(e)});var Lt=at?function(e){return y(e)?at(e):[]}:h,At=function(e,t,n){if(!e)return e;var t=t&&"undefined"==typeof n?t:s(t
|
||||
,n),r=e.length,n=-1;if("number"==typeof r){for(;++n<r;)if(t(e[n],n,e)===X)return e}else for(n in e)if(tt.call(e,n)&&t(e[n],n,e)===X)return e};n.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=d(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=F(e[i],e)}return e},n.chain=function(e){return e=new n(e),e.__chain__=!0,e},n.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},n.countBy=function(e,t,n){var r={},t=s(t,n);return At(e,function(e,n,i){n=t(e,n,i)
|
||||
,tt.call(r,n)?r[n]++:r[n]=1}),r},n.defaults=p,n.difference=function(e){for(var t=-1,n=e.length,r=Z.apply(z,arguments),i=[];++t<n;){var s=e[t];0>P(r,s,n)&&i.push(s)}return i},n.filter=T,n.flatten=D,n.forEach=At,n.functions=d,n.groupBy=function(e,t,n){var r={},t=s(t,n);return At(e,function(e,n,i){n=t(e,n,i),(tt.call(r,n)?r[n]:r[n]=[]).push(e)}),r},n.initial=function(e,t,n){if(!e)return[];var r=e.length;return f(e,0,lt(ft(0,r-(null==t||n?1:t||0)),r))},n.intersection=function(e){var t=arguments,n=t.length
|
||||
,r=[];return At(e,function(e){if(0>P(r,e)){for(var i=n;--i;)if(0>P(t[i],e))return;r.push(e)}}),r},n.invert=v,n.invoke=function(e,t){var n=f(arguments,2),r="function"==typeof t,i=[];return At(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},n.keys=Lt,n.map=C,n.max=k,n.min=function(e,t,n){var r=Infinity,i=-1,o=e?e.length:0,u=r;if(t||!kt(e))t=s(t,n),At(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,u=e)});else for(;++i<o;)e[i]<u&&(u=e[i]);return u},n.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<
|
||||
r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},n.omit=function(e){var t=Z.apply(z,arguments),n={};return xt(e,function(e,r){0>P(t,r,1)&&(n[r]=e)}),n},n.pairs=function(e){var t=[];return Tt(e,function(e,n){t.push([n,e])}),t},n.pick=function(e){for(var t=0,n=Z.apply(z,arguments),r=n.length,i={};++t<r;){var s=n[t];s in e&&(i[s]=e[s])}return i},n.pluck=L,n.range=function(e,t,n){e=+e||0,n=+n||1,null==t&&(t=e,e=0);for(var r=-1,t=ft(0,Y((t-e)/n)),i=Array(t);++r<t;)i[r]=e,e+=n;return i},n.reject=function(
|
||||
e,t,n){return t=s(t,n),T(e,function(e,n,r){return!t(e,n,r)})},n.rest=H,n.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return At(e,function(e){var r=et(ct()*(++t+1));n[t]=n[r],n[r]=e}),n},n.sortBy=function(e,t,n){var i=[],t=s(t,n);At(e,function(e,n,r){i.push({a:t(e,n,r),b:n,c:e})}),e=i.length;for(i.sort(r);e--;)i[e]=i[e].c;return i},n.tap=function(e,t){return t(e),e},n.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},n.toArray=function(e){return"number"==typeof
|
||||
(e?e.length:0)?f(e):E(e)},n.union=function(){return j(Z.apply(z,arguments))},n.uniq=j,n.values=E,n.where=function(e,t){var n=Lt(t);return T(e,function(e){for(var r=n.length;r--;){var i=e[n[r]]===t[n[r]];if(!i)break}return!!i})},n.without=function(e){for(var t=-1,n=e.length,r=[];++t<n;){var i=e[t];0>P(arguments,i,1)&&r.push(i)}return r},n.zip=function(e){for(var t=-1,n=e?k(L(arguments,"length")):0,r=Array(n);++t<n;)r[t]=L(arguments,t);return r},n.collect=C,n.drop=H,n.each=At,n.extend=c,n.methods=d
|
||||
,n.select=T,n.tail=H,n.unique=j,n.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},n.bind=F,n.clone=function(e){return e&&Et[typeof e]?kt(e)?f(e):c({},e):e},n.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},n.contains=S,n.debounce=function(e,t,n){function r(){u=null,n||(s=e.apply(o,i))}var i,s,o,u;return function(){var a=n&&!u;return i=arguments,o=this,clearTimeout(u),u=setTimeout(
|
||||
r,t),a&&(s=e.apply(o,i)),s}},n.defer=function(e){var n=f(arguments,1);return setTimeout(function(){e.apply(t,n)},1)},n.delay=function(e,n){var r=f(arguments,2);return setTimeout(function(){e.apply(t,r)},n)},n.escape=function(e){return null==e?"":(e+"").replace(Q,u)},n.every=x,n.find=N,n.has=function(e,t){return e?tt.call(e,t):!1},n.identity=I,n.indexOf=P,n.isArray=kt,n.isBoolean=function(e){return!0===e||!1===e||rt.call(e)==pt},n.isDate=function(e){return rt.call(e)==dt},n.isElement=function(e){return e?1===
|
||||
e.nodeType:!1},n.isEmpty=function(e){if(!e)return!0;if(kt(e)||w(e))return!e.length;for(var t in e)if(tt.call(e,t))return!1;return!0},n.isEqual=m,n.isFinite=function(e){return ot(e)&&!ut(parseFloat(e))},n.isFunction=g,n.isNaN=function(e){return b(e)&&e!=+e},n.isNull=function(e){return null===e},n.isNumber=b,n.isObject=y,n.isRegExp=function(e){return rt.call(e)==gt},n.isString=w,n.isUndefined=function(e){return"undefined"==typeof e},n.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof
|
||||
n&&(r=(0>n?ft(0,r+n):lt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},n.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return tt.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},n.mixin=q,n.noConflict=function(){return e._=V,this},n.once=function(e){var t,n=!1;return function(){return n?t:(n=!0,t=e.apply(this,arguments),e=null,t)}},n.random=function(e,t){return null==e&&null==t&&(t=1),e=+e||0,null==t&&(t=e,e=0),e+et(ct()*((+t||0)-e+1))},n.reduce=A,n.reduceRight=
|
||||
O,n.result=function(e,t){var n=e?e[t]:null;return g(n)?e[t]():n},n.size=function(e){var t=e?e.length:0;return"number"==typeof t?t:Lt(e).length},n.some=M,n.sortedIndex=B,n.template=function(e,t,r){e||(e="");var r=p({},r,n.templateSettings),i=0,s="__p+='",u=r.variable;e.replace(RegExp((r.escape||K).source+"|"+(r.interpolate||K).source+"|"+(r.evaluate||K).source+"|$","g"),function(t,n,r,u,a){s+=e.slice(i,a).replace(G,o),s+=n?"'+_['escape']("+n+")+'":u?"';"+u+";__p+='":r?"'+((__t=("+r+"))==null?'':__t)+'"
|
||||
:"",i=a+t.length}),s+="';\n",u||(u="obj",s="with("+u+"||{}){"+s+"}"),s="function("+u+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+s+"return __p}";try{var a=Function("_","return "+s)(n)}catch(f){throw f.source=s,f}return t?a(t):(a.source=s,a)},n.throttle=function(e,t){function n(){u=new Date,o=null,i=e.apply(s,r)}var r,i,s,o,u=0;return function(){var a=new Date,f=t-(a-u);return r=arguments,s=this,0>=f?(clearTimeout(o),o=null,u=a,i=e.apply(s,r)):o||(o=setTimeout
|
||||
(n,f)),i}},n.unescape=function(e){return null==e?"":(e+"").replace($,l)},n.uniqueId=function(e){var t=++W+"";return e?e+t:t},n.wrap=function(e,t){return function(){var n=[e];return nt.apply(n,arguments),t.apply(this,n)}},n.all=x,n.any=M,n.detect=N,n.foldl=A,n.foldr=O,n.include=S,n.inject=A,n.first=_,n.last=function(e,t,n){if(e){var r=e.length;return null==t||n?e[r-1]:f(e,ft(0,r-t))}},n.take=_,n.head=_,n.VERSION="1.0.0-rc.2",q(n),n.prototype.chain=function(){return this.__chain__=!0,this},n.prototype
|
||||
.value=function(){return this.__wrapped__},At("pop push reverse shift sort splice unshift".split(" "),function(e){var t=z[e];n.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),wt&&e.length===0&&delete e[0],this}}),At(["concat","join","slice"],function(e){var t=z[e];n.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new n(e),e.__chain__=!0),e}}),R?"object"==typeof module&&module&&module.exports==R?(module.exports=n)._=n:R._=n:e._=
|
||||
n})(this);
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "lodash",
|
||||
"version": "0.8.2",
|
||||
"description": "A drop-in replacement for Underscore.js delivering performance, bug fixes, and additional features.",
|
||||
"version": "1.0.0-rc.2",
|
||||
"description": "A utility library, usable as a drop-in replacement for Underscore, delivering performance, bug fixes, and additional features.",
|
||||
"homepage": "http://lodash.com",
|
||||
"main": "./lodash",
|
||||
"keywords": [
|
||||
@@ -47,6 +47,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node build",
|
||||
"test": "node test/test && node test/test-build"
|
||||
"test": "node test/test && node test/test-build",
|
||||
"install": "node build/post-install"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,17 +13,34 @@
|
||||
position: absolute;
|
||||
left: -9999em;
|
||||
}
|
||||
#FirebugUI {
|
||||
top: 2em;
|
||||
}
|
||||
#perf-toolbar {
|
||||
background-color: #EEE;
|
||||
color: #5E740B;
|
||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||
font-size: small;
|
||||
padding: 0.5em 0 0.5em 2em;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="../lodash.min.js"></script>
|
||||
<script>
|
||||
var lodash = _.noConflict();
|
||||
</script>
|
||||
<script src="../vendor/underscore/underscore-min.js"></script>
|
||||
<div id="perf-toolbar"></div>
|
||||
<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>
|
||||
<script src="perf-ui.js"></script>
|
||||
<script>
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
</script>
|
||||
<script>
|
||||
var lodash = _.noConflict();
|
||||
</script>
|
||||
<script>
|
||||
document.write('<script src="../' + ui.otherPath + '"><\/script>');
|
||||
</script>
|
||||
<script src="perf.js"></script>
|
||||
<script>
|
||||
(function() {
|
||||
@@ -39,7 +56,12 @@
|
||||
if (!fbCommandLine) {
|
||||
return setTimeout(init, 15);
|
||||
}
|
||||
fbUI.style.height = fbDoc.body.style.height = fbDoc.documentElement.style.height = '100%';
|
||||
fbUI.style.height = (
|
||||
Math.max(document.documentElement.clientHeight, document.body.clientHeight) -
|
||||
document.getElementById('perf-toolbar').clientHeight
|
||||
) + 'px';
|
||||
|
||||
fbDoc.body.style.height = fbDoc.documentElement.style.height = '100%';
|
||||
setTimeout(run, 15);
|
||||
}
|
||||
|
||||
|
||||
130
perf/perf-ui.js
Normal file
130
perf/perf-ui.js
Normal file
@@ -0,0 +1,130 @@
|
||||
;(function(window) {
|
||||
'use strict';
|
||||
|
||||
/** The Lo-Dash build to load */
|
||||
var build = (/build=([^&]+)/.exec(location.search) || [])[1];
|
||||
|
||||
/** The other library to load */
|
||||
var other = (/other=([^&]+)/.exec(location.search) || [])[1];
|
||||
|
||||
/** The `ui` object */
|
||||
var ui = {};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Registers an event listener on an element.
|
||||
*
|
||||
* @private
|
||||
* @param {Element} element The element.
|
||||
* @param {String} eventName The name of the event.
|
||||
* @param {Function} handler The event handler.
|
||||
* @returns {Element} The element.
|
||||
*/
|
||||
function addListener(element, eventName, handler) {
|
||||
if (typeof element.addEventListener != 'undefined') {
|
||||
element.addEventListener(eventName, handler, false);
|
||||
} else if (typeof element.attachEvent != 'undefined') {
|
||||
element.attachEvent('on' + eventName, handler);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// expose Lo-Dash build file path
|
||||
ui.buildPath = (function() {
|
||||
switch (build) {
|
||||
case 'lodash-dev': return 'lodash.js';
|
||||
case 'lodash-underscore': return 'lodash.underscore.min.js';
|
||||
case 'lodash-custom': return 'lodash.custom.min.js';
|
||||
}
|
||||
return 'lodash.min.js';
|
||||
}());
|
||||
|
||||
// expose other library file path
|
||||
ui.otherPath = (function() {
|
||||
switch (other) {
|
||||
case 'lodash-dev': return 'lodash.js';
|
||||
case 'lodash-prod': return 'lodash.min.js';
|
||||
case 'lodash-underscore': return 'lodash.underscore.min.js';
|
||||
case 'lodash-custom': return 'lodash.custom.min.js';
|
||||
case 'underscore-dev': return 'vendor/underscore/underscore.js';
|
||||
}
|
||||
return 'vendor/underscore/underscore-min.js';
|
||||
}());
|
||||
|
||||
// initialize controls
|
||||
addListener(window, 'load', function() {
|
||||
function eventHandler(event) {
|
||||
var search = location.search.replace(/^\?|&?(?:build|other)=[^&]*&?/g, '');
|
||||
if (event.stopPropagation) {
|
||||
event.stopPropagation();
|
||||
} else {
|
||||
event.cancelBubble = true;
|
||||
}
|
||||
location.href =
|
||||
location.href.split('?')[0] + '?' +
|
||||
(search ? search + '&' : '') +
|
||||
'build=' + buildList[buildList.selectedIndex].value + '&' +
|
||||
'other=' + otherList[otherList.selectedIndex].value;
|
||||
}
|
||||
|
||||
var span1 = document.createElement('span');
|
||||
span1.style.cssText = 'float:right';
|
||||
span1.innerHTML =
|
||||
'<label for="perf-build">Build: </label>' +
|
||||
'<select id="perf-build">' +
|
||||
'<option value="lodash-dev">Lo-Dash</option>' +
|
||||
'<option value="lodash-prod">Lo-Dash (minified)</option>' +
|
||||
'<option value="lodash-underscore">Lo-Dash (underscore)</option>' +
|
||||
'<option value="lodash-custom">Lo-Dash (custom)</option>' +
|
||||
'</select>';
|
||||
|
||||
var span2 = document.createElement('span');
|
||||
span2.style.cssText = 'float:right';
|
||||
span2.innerHTML =
|
||||
'<label for="perf-other">Other Library: </label>' +
|
||||
'<select id="perf-other">' +
|
||||
'<option value="underscore-dev">Underscore</option>' +
|
||||
'<option value="underscore-prod">Underscore (minified)</option>' +
|
||||
'<option value="lodash-dev">Lo-Dash</option>' +
|
||||
'<option value="lodash-prod">Lo-Dash (minified)</option>' +
|
||||
'<option value="lodash-underscore">Lo-Dash (underscore)</option>' +
|
||||
'<option value="lodash-custom">Lo-Dash (custom)</option>' +
|
||||
'</select>';
|
||||
|
||||
var buildList = span1.lastChild,
|
||||
otherList = span2.lastChild,
|
||||
toolbar = document.getElementById('perf-toolbar');
|
||||
|
||||
toolbar.appendChild(span2);
|
||||
toolbar.appendChild(span1);
|
||||
|
||||
buildList.selectedIndex = (function() {
|
||||
switch (build) {
|
||||
case 'lodash-dev': return 0;
|
||||
case 'lodash-underscore': return 2;
|
||||
case 'lodash-custom': return 3;
|
||||
}
|
||||
return 1;
|
||||
}());
|
||||
|
||||
otherList.selectedIndex = (function() {
|
||||
switch (other) {
|
||||
case 'underscore-dev': return 0;
|
||||
case 'lodash-dev': return 2;
|
||||
case 'lodash-prod': return 3;
|
||||
case 'lodash-underscore': return 4;
|
||||
case 'lodash-custom': return 5;
|
||||
}
|
||||
return 1;
|
||||
}());
|
||||
|
||||
addListener(buildList, 'change', eventHandler);
|
||||
addListener(otherList, 'change', eventHandler);
|
||||
});
|
||||
|
||||
// expose `ui`
|
||||
window.ui = ui;
|
||||
|
||||
}(this));
|
||||
619
perf/perf.js
619
perf/perf.js
File diff suppressed because it is too large
Load Diff
@@ -3,14 +3,11 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Backbone Test Suite</title>
|
||||
<link rel="stylesheet" href="../vendor/backbone/test/vendor/qunit.css">
|
||||
<link rel="stylesheet" href="../vendor/qunit/qunit/qunit.css">
|
||||
<style>
|
||||
body > #qunit-header {
|
||||
display: none;
|
||||
}
|
||||
#jslitmus {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -21,9 +18,8 @@
|
||||
<h1>Test</h1>
|
||||
</div>
|
||||
</div>
|
||||
<script src="../vendor/backbone/test/vendor/json2.js"></script>
|
||||
<script src="../vendor/backbone/test/vendor/jquery-1.7.1.js"></script>
|
||||
<script src="../vendor/backbone/test/vendor/jslitmus.js"></script>
|
||||
<script src="../vendor/json3/lib/json3.js"></script>
|
||||
<script src="../vendor/jquery/jquery.js"></script>
|
||||
<script src="../vendor/platform.js/platform.js"></script>
|
||||
<script>
|
||||
// avoid syntax errors for `QUnit.throws` in older Firefoxes
|
||||
@@ -34,7 +30,7 @@
|
||||
</script>
|
||||
<script src="test-ui.js"></script>
|
||||
<script>
|
||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
</script>
|
||||
<script src="../vendor/backbone/backbone.js"></script>
|
||||
<script src="../vendor/backbone/test/environment.js"></script>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
Object.keys = function() { return []; };
|
||||
|
||||
// load Lo-Dash and expose it to the bad `Object.keys` shim
|
||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
</script>
|
||||
<script>
|
||||
// store Lo-Dash to test for bad shim detection
|
||||
@@ -33,7 +33,7 @@
|
||||
delete Object._keys;
|
||||
|
||||
// load Lo-Dash again to overwrite the existing `_` value
|
||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
|
||||
// load test.js if not using require.js
|
||||
document.write(QUnit.urlParams.norequire
|
||||
@@ -47,20 +47,24 @@
|
||||
shimmedModule,
|
||||
underscoreModule;
|
||||
|
||||
window.require && require({
|
||||
'baseUrl': '../vendor/requirejs/',
|
||||
'urlArgs': 't=' + (+new Date),
|
||||
'paths': {
|
||||
'lodash': '../../' + QUnit.config.lodashFilename,
|
||||
'shimmed': './../../' + QUnit.config.lodashFilename,
|
||||
'underscore': '../underscore/../../' + QUnit.config.lodashFilename
|
||||
},
|
||||
'shim': {
|
||||
'shimmed': {
|
||||
'exports': '_'
|
||||
window.require && require(
|
||||
(function() {
|
||||
var modulePath = ui.buildPath.replace(/\.js$/, '');
|
||||
return {
|
||||
'baseUrl': '../vendor/requirejs/',
|
||||
'urlArgs': 't=' + (+new Date),
|
||||
'paths': {
|
||||
'lodash': '../../' + modulePath,
|
||||
'shimmed': './../../' + modulePath,
|
||||
'underscore': '../underscore/../../' + modulePath
|
||||
},
|
||||
'shim': {
|
||||
'shimmed': {
|
||||
'exports': '_'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}()),
|
||||
['lodash', 'shimmed', 'underscore'], function(lodash, shimmed, underscore) {
|
||||
if (lodash && lodash.noConflict) {
|
||||
lodashModule = lodash.noConflict();
|
||||
|
||||
1
test/template/c.jst
Normal file
1
test/template/c.jst
Normal file
@@ -0,0 +1 @@
|
||||
Hello ${ name }!
|
||||
@@ -22,6 +22,7 @@
|
||||
'detect': 'find',
|
||||
'drop': 'rest',
|
||||
'each': 'forEach',
|
||||
'extend': 'assign',
|
||||
'foldl': 'reduce',
|
||||
'foldr': 'reduceRight',
|
||||
'head': 'first',
|
||||
@@ -36,6 +37,7 @@
|
||||
|
||||
/** Used to associate real names with their aliases */
|
||||
var realToAliasMap = {
|
||||
'assign': ['extend'],
|
||||
'contains': ['include'],
|
||||
'every': ['all'],
|
||||
'filter': ['select'],
|
||||
@@ -130,11 +132,11 @@
|
||||
'after',
|
||||
'bind',
|
||||
'bindAll',
|
||||
'bindKey',
|
||||
'compose',
|
||||
'debounce',
|
||||
'defer',
|
||||
'delay',
|
||||
'lateBind',
|
||||
'memoize',
|
||||
'once',
|
||||
'partial',
|
||||
@@ -144,6 +146,7 @@
|
||||
|
||||
/** List of "Objects" category methods */
|
||||
var objectsMethods = [
|
||||
'assign',
|
||||
'clone',
|
||||
'defaults',
|
||||
'extend',
|
||||
@@ -195,8 +198,11 @@
|
||||
var backboneDependencies = [
|
||||
'bind',
|
||||
'bindAll',
|
||||
'chain',
|
||||
'clone',
|
||||
'contains',
|
||||
'countBy',
|
||||
'defaults',
|
||||
'escape',
|
||||
'every',
|
||||
'extend',
|
||||
@@ -215,6 +221,7 @@
|
||||
'isFunction',
|
||||
'isObject',
|
||||
'isRegExp',
|
||||
'isString',
|
||||
'keys',
|
||||
'last',
|
||||
'lastIndexOf',
|
||||
@@ -222,6 +229,7 @@
|
||||
'max',
|
||||
'min',
|
||||
'mixin',
|
||||
'pick',
|
||||
'reduce',
|
||||
'reduceRight',
|
||||
'reject',
|
||||
@@ -234,15 +242,16 @@
|
||||
'sortedIndex',
|
||||
'toArray',
|
||||
'uniqueId',
|
||||
'value',
|
||||
'without'
|
||||
];
|
||||
|
||||
/** List of methods used by Underscore */
|
||||
var underscoreMethods = _.without.apply(_, [allMethods].concat([
|
||||
'bindKey',
|
||||
'forIn',
|
||||
'forOwn',
|
||||
'isPlainObject',
|
||||
'lateBind',
|
||||
'merge',
|
||||
'partial'
|
||||
]));
|
||||
@@ -393,7 +402,7 @@
|
||||
func(1, noop);
|
||||
} else if (methodName == 'bindAll') {
|
||||
func({ 'noop': noop });
|
||||
} else if (methodName == 'lateBind') {
|
||||
} else if (methodName == 'bindKey') {
|
||||
func(lodash, 'identity', array, string);
|
||||
} else if (/^(?:bind|partial)$/.test(methodName)) {
|
||||
func(noop, object, array, string);
|
||||
@@ -474,7 +483,8 @@
|
||||
|
||||
var data = {
|
||||
'a': { 'people': ['moe', 'larry', 'curly'] },
|
||||
'b': { 'epithet': 'stooge' }
|
||||
'b': { 'epithet': 'stooge' },
|
||||
'c': { 'name': 'ES6' }
|
||||
};
|
||||
|
||||
context._ = _;
|
||||
@@ -483,10 +493,40 @@
|
||||
|
||||
equal(templates.a(data.a).replace(/[\r\n]+/g, ''), '<ul><li>moe</li><li>larry</li><li>curly</li></ul>', basename);
|
||||
equal(templates.b(data.b), 'Hello stooge.', basename);
|
||||
equal(templates.c(data.c), 'Hello ES6!', basename);
|
||||
delete _.templates;
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
['', 'moduleId=underscore'].forEach(function(command) {
|
||||
asyncTest('`lodash template=*.jst` exports=amd' + (command ? ' ' + command : ''), function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'template=' + templatePath + '/*.jst', 'exports=amd'].concat(command || []), function(source, filePath) {
|
||||
var moduleId,
|
||||
basename = path.basename(filePath, '.js'),
|
||||
context = createContext(),
|
||||
pass = false;
|
||||
|
||||
(context.define = function(requires, factory) {
|
||||
factory(_);
|
||||
var templates = _.templates;
|
||||
moduleId = requires + '';
|
||||
pass = 'a' in templates && 'b' in templates;
|
||||
})
|
||||
.amd = {};
|
||||
|
||||
vm.runInContext(source, context);
|
||||
|
||||
equal(moduleId, command ? 'underscore' : 'lodash');
|
||||
ok(pass, basename);
|
||||
delete _.templates;
|
||||
start();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('`lodash settings=...`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
@@ -495,14 +535,14 @@
|
||||
context = createContext();
|
||||
|
||||
var data = {
|
||||
'c': { 'name': 'Mustache' }
|
||||
'd': { 'name': 'Mustache' }
|
||||
};
|
||||
|
||||
context._ = _;
|
||||
vm.runInContext(source, context);
|
||||
var templates = context._.templates;
|
||||
|
||||
equal(templates.c(data.c), 'Hello Mustache!', basename);
|
||||
equal(templates.d(data.d), 'Hello Mustache!', basename);
|
||||
start();
|
||||
});
|
||||
});
|
||||
@@ -521,7 +561,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('debug custom', function () {
|
||||
asyncTest('debug custom', function() {
|
||||
var start = _.once(QUnit.start);
|
||||
build(['-d', '-s', 'backbone'], function(source, filePath) {
|
||||
equal(path.basename(filePath, '.js'), 'lodash.custom');
|
||||
@@ -537,7 +577,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('minified custom', function () {
|
||||
asyncTest('minified custom', function() {
|
||||
var start = _.once(QUnit.start);
|
||||
build(['-m', '-s', 'backbone'], function(source, filePath) {
|
||||
equal(path.basename(filePath, '.js'), 'lodash.custom.min');
|
||||
@@ -551,9 +591,9 @@
|
||||
QUnit.module('strict modifier');
|
||||
|
||||
(function() {
|
||||
var object = Object.create(Object.prototype, {
|
||||
'a': { 'value': _.identify },
|
||||
'b': { 'value': null }
|
||||
var object = Object.freeze({
|
||||
'a': _.identity,
|
||||
'b': null
|
||||
});
|
||||
|
||||
['non-strict', 'strict'].forEach(function(strictMode, index) {
|
||||
@@ -566,20 +606,26 @@
|
||||
}
|
||||
build(commands, function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
context = createContext(),
|
||||
pass = !index;
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(source, context);
|
||||
var lodash = context._;
|
||||
|
||||
try {
|
||||
lodash.bindAll(object);
|
||||
lodash.extend(object, { 'a': 1 });
|
||||
lodash.defaults(object, { 'b': 2 });
|
||||
} catch(e) {
|
||||
pass = !!index;
|
||||
}
|
||||
equal(pass, true, basename);
|
||||
var actual = _.every([
|
||||
function() { lodash.bindAll(object); },
|
||||
function() { lodash.extend(object, { 'a': 1 }); },
|
||||
function() { lodash.defaults(object, { 'b': 2 }); }
|
||||
], function(fn) {
|
||||
var pass = !index;
|
||||
try {
|
||||
fn();
|
||||
} catch(e) {
|
||||
pass = !!index;
|
||||
}
|
||||
return pass;
|
||||
});
|
||||
|
||||
equal(actual, true, basename);
|
||||
start();
|
||||
});
|
||||
});
|
||||
@@ -596,25 +642,96 @@
|
||||
|
||||
build(['-s', 'underscore'], function(source, filePath) {
|
||||
var last,
|
||||
array = [{ 'value': 1 }, { 'value': 2 }],
|
||||
array = [{ 'a': 1, 'b': 2 }, { 'a': 2, 'b': 2 }],
|
||||
basename = path.basename(filePath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(source, context);
|
||||
var lodash = context._;
|
||||
|
||||
lodash.each(array, function(value) {
|
||||
var object = { 'fn': lodash.bind(function(foo) { return foo + this.bar; }, { 'bar': 1 }, 1) };
|
||||
equal(object.fn(), 2, '_.bind: ' + basename);
|
||||
|
||||
ok(lodash.clone(array, true)[0] === array[0], '_.clone should be shallow: ' + basename);
|
||||
equal(lodash.contains({ 'a': 1, 'b': 2 }, 1), true, '_.contains should work with objects: ' + basename);
|
||||
equal(lodash.contains([1, 2, 3], 1, 2), true, '_.contains should ignore `fromIndex`: ' + basename);
|
||||
equal(lodash.every([true, false, true]), false, '_.every: ' + basename);
|
||||
|
||||
function Foo() {}
|
||||
Foo.prototype = { 'a': 1 };
|
||||
|
||||
deepEqual(lodash.defaults({}, new Foo), Foo.prototype, '_.defaults should assign inherited `source` properties: ' + basename);
|
||||
deepEqual(lodash.extend({}, new Foo), Foo.prototype, '_.extend should assign inherited `source` properties: ' + basename);
|
||||
|
||||
actual = lodash.find(array, function(value) {
|
||||
return 'a' in value;
|
||||
});
|
||||
|
||||
equal(actual, _.first(array), '_.find: ' + basename);
|
||||
|
||||
actual = lodash.forEach(array, function(value) {
|
||||
last = value;
|
||||
return false;
|
||||
});
|
||||
|
||||
equal(last.value, 2, '_.each: ' + basename);
|
||||
equal(lodash.isEmpty('moe'), false, '_.isEmpty: ' + basename);
|
||||
equal(last, _.last(array), '_.forEach should not exit early: ' + basename);
|
||||
equal(actual, undefined, '_.forEach should return `undefined`: ' + basename);
|
||||
|
||||
var object = { 'fn': lodash.bind(function(x) { return this.x + x; }, { 'x': 1 }, 1) };
|
||||
equal(object.fn(), 2, '_.bind: ' + basename);
|
||||
object = { 'length': 0, 'splice': Array.prototype.splice };
|
||||
equal(lodash.isEmpty(object), false, '_.isEmpty should return `false` for jQuery/MooTools DOM query collections: ' + basename);
|
||||
|
||||
object = { 'a': 1, 'b': 2, 'c': 3 };
|
||||
equal(lodash.isEqual(object, { 'a': 1, 'b': 0, 'c': 3 }), false, '_.isEqual: ' + basename);
|
||||
|
||||
equal(lodash.max('abc'), -Infinity, '_.max should return `-Infinity` for strings: ' + basename);
|
||||
equal(lodash.min('abc'), Infinity, '_.min should return `Infinity` for strings: ' + basename);
|
||||
|
||||
// avoid issues comparing objects with `deepEqual`
|
||||
object = { 'a': 1, 'b': 2, 'c': 3 };
|
||||
var actual = lodash.omit(object, function(value) { return value == 3; });
|
||||
deepEqual(_.keys(actual).sort(), ['a', 'b', 'c'], '_.omit should not accept a `callback`: ' + basename);
|
||||
|
||||
actual = lodash.pick(object, function(value) { return value != 3; });
|
||||
deepEqual(_.keys(actual), [], '_.pick should not accept a `callback`: ' + basename);
|
||||
|
||||
equal(lodash.some([false, true, false]), true, '_.some: ' + basename);
|
||||
equal(lodash.template('${a}', object), '${a}', '_.template should ignore ES6 delimiters: ' + basename);
|
||||
equal(lodash.uniqueId(0), '1', '_.uniqueId should ignore a prefix of `0`: ' + basename);
|
||||
|
||||
var wrapped = lodash(1);
|
||||
equal(wrapped.clone() instanceof lodash, false, '_(...) wrapped values are not chainable by default: ' + basename);
|
||||
equal(String(wrapped) === '1', false, '_#toString should not be implemented: ' + basename);
|
||||
equal(Number(wrapped) === 1 , false, '_#valueOf should not be implemented: ' + basename);
|
||||
|
||||
wrapped.chain();
|
||||
equal(wrapped.has('x') instanceof lodash, true, '_#has returns wrapped values when chaining: ' + basename);
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('should not have any Lo-Dash-only methods', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'underscore'], function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(source, context);
|
||||
var lodash = context._;
|
||||
|
||||
_.each([
|
||||
'assign',
|
||||
'bindKey',
|
||||
'forIn',
|
||||
'forOwn',
|
||||
'isPlainObject',
|
||||
'merge',
|
||||
'partial'
|
||||
], function(methodName) {
|
||||
equal(lodash[methodName], undefined, '_.' + methodName + ' should not exist: ' + basename);
|
||||
});
|
||||
|
||||
ok(lodash.clone(array, true)[0] === array[0], '_.clone: ' + basename);
|
||||
start();
|
||||
});
|
||||
});
|
||||
@@ -904,7 +1021,9 @@
|
||||
build(['--silent'].concat(command.split(' ')), function(source, filePath) {
|
||||
var methodNames,
|
||||
basename = path.basename(filePath, '.js'),
|
||||
context = createContext();
|
||||
context = createContext(),
|
||||
isUnderscore = /underscore/.test(command),
|
||||
exposeAssign = !isUnderscore;
|
||||
|
||||
try {
|
||||
vm.runInContext(source, context);
|
||||
@@ -919,8 +1038,12 @@
|
||||
if (/backbone/.test(command) && !methodNames) {
|
||||
methodNames = backboneDependencies.slice();
|
||||
}
|
||||
if (/underscore/.test(command) && !methodNames) {
|
||||
methodNames = underscoreMethods.slice();
|
||||
if (isUnderscore) {
|
||||
if (methodNames) {
|
||||
exposeAssign = methodNames.indexOf('assign') > -1;
|
||||
} else {
|
||||
methodNames = underscoreMethods.slice();
|
||||
}
|
||||
}
|
||||
// add method names explicitly by category
|
||||
if (/category/.test(command)) {
|
||||
@@ -954,6 +1077,9 @@
|
||||
// remove nonexistent and duplicate method names
|
||||
methodNames = _.uniq(_.intersection(allMethods, expandMethodNames(methodNames)));
|
||||
|
||||
if (!exposeAssign) {
|
||||
methodNames = _.without(methodNames, 'assign');
|
||||
}
|
||||
var lodash = context._ || {};
|
||||
methodNames.forEach(function(methodName) {
|
||||
testMethod(lodash, methodName, basename);
|
||||
|
||||
@@ -10,16 +10,20 @@
|
||||
/** A flag to determine if RequireJS should be loaded */
|
||||
var norequire = /[?&]norequire=true(?:&|$)/.test(location.search);
|
||||
|
||||
/** The `ui` object */
|
||||
var ui = {};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// assign `QUnit.config` properties
|
||||
QUnit.config.lodashFilename = (function() {
|
||||
// expose Lo-Dash build file path
|
||||
ui.buildPath = (function() {
|
||||
switch (build) {
|
||||
case 'prod': return 'lodash.min';
|
||||
case 'custom': return 'lodash.custom.min';
|
||||
case 'custom-debug': return 'lodash.custom';
|
||||
case 'lodash-prod': return 'lodash.min.js';
|
||||
case 'lodash-underscore': return 'lodash.underscore.min.js';
|
||||
case 'lodash-custom': return 'lodash.custom.min.js';
|
||||
case 'lodash-custom-debug': return 'lodash.custom.js';
|
||||
}
|
||||
return 'lodash';
|
||||
return 'lodash.js';
|
||||
}());
|
||||
|
||||
// assign `QUnit.urlParams` properties
|
||||
@@ -28,7 +32,7 @@
|
||||
'norequire': norequire
|
||||
});
|
||||
|
||||
// initialize the build dropdown
|
||||
// initialize controls
|
||||
addEvent(window, 'load', function() {
|
||||
function eventHandler(event) {
|
||||
var search = location.search.replace(/^\?|&?(?:build|norequire)=[^&]*&?/g, '');
|
||||
@@ -39,8 +43,8 @@
|
||||
}
|
||||
location.href =
|
||||
location.href.split('?')[0] + '?' +
|
||||
(search ? search + '&' : '') + 'build=' +
|
||||
dropdown[dropdown.selectedIndex].value +
|
||||
(search ? search + '&' : '') +
|
||||
'build=' + buildList[buildList.selectedIndex].value +
|
||||
(checkbox.checked ? '&norequire=true' : '');
|
||||
}
|
||||
|
||||
@@ -50,18 +54,19 @@
|
||||
toolbar.appendChild(span1);
|
||||
toolbar.appendChild(span2);
|
||||
|
||||
dropdown.selectedIndex = (function() {
|
||||
buildList.selectedIndex = (function() {
|
||||
switch (build) {
|
||||
case 'prod': return 1;
|
||||
case 'custom': return 2;
|
||||
case 'custom-debug': return 3;
|
||||
case 'lodash-prod': return 1;
|
||||
case 'lodash-underscore': return 2;
|
||||
case 'lodash-custom': return 3;
|
||||
case 'lodash-custom-debug': return 4;
|
||||
}
|
||||
return 0;
|
||||
}());
|
||||
|
||||
checkbox.checked = norequire;
|
||||
addEvent(checkbox, 'click', eventHandler);
|
||||
addEvent(dropdown, 'change', eventHandler);
|
||||
addEvent(buildList, 'change', eventHandler);
|
||||
}
|
||||
else {
|
||||
setTimeout(init, 15);
|
||||
@@ -78,16 +83,20 @@
|
||||
span2.innerHTML =
|
||||
'<label for="qunit-build">Build: </label>' +
|
||||
'<select id="qunit-build">' +
|
||||
'<option value="dev">Developement</option>' +
|
||||
'<option value="prod">Production</option>' +
|
||||
'<option value="custom">Custom</option>' +
|
||||
'<option value="custom-debug">Custom (debug)</option>' +
|
||||
'<option value="lodash-dev">Developement</option>' +
|
||||
'<option value="lodash-prod">Production</option>' +
|
||||
'<option value="lodash-underscore">Underscore</option>' +
|
||||
'<option value="lodash-custom">Custom</option>' +
|
||||
'<option value="lodash-custom-debug">Custom (debug)</option>' +
|
||||
'</select>';
|
||||
|
||||
var checkbox = span1.firstChild,
|
||||
dropdown = span2.lastChild;
|
||||
buildList = span2.lastChild;
|
||||
|
||||
init();
|
||||
});
|
||||
|
||||
// expose `ui`
|
||||
window.ui = ui;
|
||||
|
||||
}(this));
|
||||
|
||||
521
test/test.js
521
test/test.js
@@ -41,6 +41,14 @@
|
||||
/** Shortcut used to make object properties immutable */
|
||||
var freeze = Object.freeze;
|
||||
|
||||
/** Used to set property descriptors */
|
||||
var setDescriptor = (function(fn) {
|
||||
try {
|
||||
var o = {};
|
||||
return fn(o, o, o) && fn;
|
||||
} catch(e) { }
|
||||
}(Object.defineProperty));
|
||||
|
||||
/** Shortcut used to convert array-like objects to arrays */
|
||||
var slice = [].slice;
|
||||
|
||||
@@ -105,16 +113,6 @@
|
||||
QUnit.module('lodash');
|
||||
|
||||
(function() {
|
||||
// ensure this test is executed before any other template tests to avoid false positives
|
||||
test('should initialize `reEvaluateDelimiter` (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');
|
||||
@@ -165,6 +163,42 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.assign');
|
||||
|
||||
(function() {
|
||||
test('should not error on `null` or `undefined` sources (test in IE < 9)', function() {
|
||||
try {
|
||||
deepEqual(_.assign({}, null, undefined, { 'a': 1 }), { 'a': 1 });
|
||||
} catch(e) {
|
||||
ok(false);
|
||||
}
|
||||
});
|
||||
|
||||
test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype.c = 3;
|
||||
|
||||
Foo.a = 1;
|
||||
Foo.b = 2;
|
||||
|
||||
var expected = { 'a': 1, 'b': 2 };
|
||||
deepEqual(_.assign({}, Foo), expected);
|
||||
|
||||
Foo.prototype = { 'c': 3 };
|
||||
deepEqual(_.assign({}, Foo), expected);
|
||||
});
|
||||
|
||||
test('should work with `_.reduce`', function() {
|
||||
var actual = { 'a': 1},
|
||||
array = [{ 'b': 2 }, { 'c': 3 }];
|
||||
|
||||
_.reduce(array, _.assign, actual);
|
||||
deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3});
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.bind');
|
||||
|
||||
(function() {
|
||||
@@ -175,6 +209,36 @@
|
||||
bound(['b'], 'c');
|
||||
deepEqual(args, ['a', ['b'], 'c']);
|
||||
});
|
||||
|
||||
test('ensure `new bound` is an instance of `func`', function() {
|
||||
var func = function() {},
|
||||
bound = _.bind(func, {});
|
||||
|
||||
ok(new bound instanceof func);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.bindKey');
|
||||
|
||||
(function() {
|
||||
test('should work when the target function is overwritten', function() {
|
||||
var object = {
|
||||
'name': 'moe',
|
||||
'greet': function(greeting) {
|
||||
return greeting + ': ' + this.name;
|
||||
}
|
||||
};
|
||||
|
||||
var func = _.bindKey(object, 'greet', 'hi');
|
||||
equal(func(), 'hi: moe');
|
||||
|
||||
object.greet = function(greeting) {
|
||||
return greeting + ' ' + this.name + '!';
|
||||
};
|
||||
equal(func(), 'hi moe!');
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -186,17 +250,17 @@
|
||||
Klass.prototype = { 'b': 1 };
|
||||
|
||||
var nonCloneable = {
|
||||
'an arguments object': arguments,
|
||||
'an element': window.document && document.body,
|
||||
'a function': Klass,
|
||||
'a Klass instance': new Klass
|
||||
'a function': Klass
|
||||
};
|
||||
|
||||
var objects = {
|
||||
'an arguments object': arguments,
|
||||
'an array': ['a', 'b', 'c', ''],
|
||||
'an array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 },
|
||||
'boolean': false,
|
||||
'boolean object': Object(false),
|
||||
'a Klass instance': new Klass,
|
||||
'an object': { 'a': 0, 'b': 1, 'c': 3 },
|
||||
'an object with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
|
||||
'an object from another document': _._object || {},
|
||||
@@ -238,6 +302,14 @@
|
||||
ok(actual != expected && actual.a == expected.a && actual.b == expected.b);
|
||||
});
|
||||
|
||||
test('should deep clone `index` and `input` array properties', function() {
|
||||
var array = /x/.exec('x'),
|
||||
actual = _.clone(array, true);
|
||||
|
||||
equal(actual.index, 0);
|
||||
equal(actual.input, 'x');
|
||||
});
|
||||
|
||||
test('should deep clone objects with circular references', function() {
|
||||
var object = {
|
||||
'foo': { 'b': { 'foo': { 'c': { } } } },
|
||||
@@ -264,6 +336,33 @@
|
||||
QUnit.module('lodash.contains');
|
||||
|
||||
(function() {
|
||||
_.each({
|
||||
'an array': [1, 2, 3, 1, 2, 3],
|
||||
'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 1, 'e': 2, 'f': 3 },
|
||||
'a string': '123123'
|
||||
},
|
||||
function(collection, key) {
|
||||
test('should work with ' + key + ' and a positive `fromIndex`', function() {
|
||||
equal(_.contains(collection, 1, 2), true);
|
||||
});
|
||||
|
||||
test('should work with ' + key + ' and a `fromIndex` >= collection\'s length', function() {
|
||||
equal(_.contains(collection, 1, 6), false);
|
||||
equal(_.contains(collection, undefined, 6), false);
|
||||
equal(_.contains(collection, 1, 8), false);
|
||||
equal(_.contains(collection, undefined, 8), false);
|
||||
});
|
||||
|
||||
test('should work with ' + key + ' and a negative `fromIndex`', function() {
|
||||
equal(_.contains(collection, 2, -3), true);
|
||||
});
|
||||
|
||||
test('should work with ' + key + ' and a negative `fromIndex` <= negative collection\'s length', function() {
|
||||
equal(_.contains(collection, 1, -6), true);
|
||||
equal(_.contains(collection, 2, -8), true);
|
||||
});
|
||||
});
|
||||
|
||||
_.each({
|
||||
'literal': 'abc',
|
||||
'object': Object('abc')
|
||||
@@ -297,17 +396,17 @@
|
||||
|
||||
(function() {
|
||||
asyncTest('subsequent debounced calls return the last `func` result', function() {
|
||||
var debounced = _.debounce(function(value) { return value; }, 100);
|
||||
var debounced = _.debounce(function(value) { return value; }, 90);
|
||||
debounced('x');
|
||||
|
||||
setTimeout(function() {
|
||||
equal(debounced('y'), 'x');
|
||||
QUnit.start();
|
||||
}, 220);
|
||||
}, 120);
|
||||
});
|
||||
|
||||
test('subsequent "immediate" debounced calls return the last `func` result', function() {
|
||||
var debounced = _.debounce(function(value) { return value; }, 100, true),
|
||||
var debounced = _.debounce(function(value) { return value; }, 90, true),
|
||||
result = [debounced('x'), debounced('y')];
|
||||
|
||||
deepEqual(result, ['x', 'x']);
|
||||
@@ -350,37 +449,33 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.extend');
|
||||
QUnit.module('lodash.every');
|
||||
|
||||
(function() {
|
||||
test('should not error on `null` or `undefined` sources (test in IE < 9)', function() {
|
||||
try {
|
||||
deepEqual(_.extend({}, null, undefined, { 'a': 1 }), { 'a': 1 });
|
||||
} catch(e) {
|
||||
ok(false);
|
||||
}
|
||||
});
|
||||
|
||||
test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype.c = 3;
|
||||
|
||||
Foo.a = 1;
|
||||
Foo.b = 2;
|
||||
|
||||
var expected = { 'a': 1, 'b': 2 };
|
||||
deepEqual(_.extend({}, Foo), expected);
|
||||
|
||||
Foo.prototype = { 'c': 3 };
|
||||
deepEqual(_.extend({}, Foo), expected);
|
||||
test('should return `false` as soon as the `callback` result is falsey', function() {
|
||||
equal(_.every([true, null, true], _.identity), false);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('source property checks');
|
||||
|
||||
_.each(['assign', 'defaults'], function(methodName) {
|
||||
var func = _[methodName];
|
||||
|
||||
test('lodash.' + methodName + ' should not assign inherited `source` properties', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype = { 'a': 1 };
|
||||
deepEqual(func({}, new Foo), {});
|
||||
});
|
||||
});
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('strict mode checks');
|
||||
|
||||
_.each(['bindAll', 'defaults', 'extend'], function(methodName) {
|
||||
_.each(['assign', 'bindAll', 'defaults'], function(methodName) {
|
||||
var func = _[methodName];
|
||||
|
||||
test('lodash.' + methodName + ' should not throw strict mode errors', function() {
|
||||
@@ -450,10 +545,10 @@
|
||||
expected.push(undefined, undefined, undefined);
|
||||
|
||||
deepEqual(actual1, expected);
|
||||
ok('4' in actual1);
|
||||
ok(4 in actual1);
|
||||
|
||||
deepEqual(actual2, expected);
|
||||
ok('4' in actual2);
|
||||
ok(4 in actual2);
|
||||
});
|
||||
}());
|
||||
|
||||
@@ -642,9 +737,9 @@
|
||||
QUnit.module('lodash.initial');
|
||||
|
||||
(function() {
|
||||
test('returns an empty collection for `n` of `0`', function() {
|
||||
test('returns a full collection for `n` of `0`', function() {
|
||||
var array = [1, 2, 3];
|
||||
deepEqual(_.initial(array, 0), []);
|
||||
deepEqual(_.initial(array, 0), [1, 2, 3]);
|
||||
});
|
||||
|
||||
test('should allow a falsey `array` argument', function() {
|
||||
@@ -766,6 +861,27 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.isFinite');
|
||||
|
||||
(function() {
|
||||
test('should return `false` for non-numeric values', function() {
|
||||
equal(_.isFinite(null), false);
|
||||
equal(_.isFinite([]), false);
|
||||
equal(_.isFinite(true), false);
|
||||
equal(_.isFinite(''), false);
|
||||
equal(_.isFinite(' '), false);
|
||||
equal(_.isFinite('2px'), false);
|
||||
});
|
||||
|
||||
test('should return `true` for numeric string values', function() {
|
||||
equal(_.isFinite('2'), true);
|
||||
equal(_.isFinite('0'), true);
|
||||
equal(_.isFinite('08'), true);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.isObject');
|
||||
|
||||
(function() {
|
||||
@@ -924,24 +1040,24 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.lateBind');
|
||||
QUnit.module('lodash.map');
|
||||
|
||||
(function() {
|
||||
test('should work when the target function is overwritten', function() {
|
||||
var object = {
|
||||
'name': 'moe',
|
||||
'greet': function(greeting) {
|
||||
return greeting + ': ' + this.name;
|
||||
}
|
||||
};
|
||||
test('should return the correct result when iterating an object', function() {
|
||||
var actual = _.map({ 'a': 1, 'b': 2, 'c': 3 }, function(value) {
|
||||
return value;
|
||||
});
|
||||
deepEqual(actual, [1, 2, 3]);
|
||||
});
|
||||
|
||||
var func = _.lateBind(object, 'greet', 'hi');
|
||||
equal(func(), 'hi: moe');
|
||||
|
||||
object.greet = function(greeting) {
|
||||
return greeting + ' ' + this.name + '!';
|
||||
};
|
||||
equal(func(), 'hi moe!');
|
||||
test('should handle object arguments with non-numeric length properties', function() {
|
||||
if (setDescriptor) {
|
||||
var object = {};
|
||||
setDescriptor(object, 'length', { 'value': 'x' });
|
||||
deepEqual(_.map(object, _.identity), []);
|
||||
} else {
|
||||
skipTest();
|
||||
}
|
||||
});
|
||||
}());
|
||||
|
||||
@@ -960,6 +1076,21 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.max and lodash.min string iteration');
|
||||
|
||||
_.each(['max', 'min'], function(methodName) {
|
||||
var func = _[methodName];
|
||||
|
||||
test('lodash.' + methodName + ' should iterate a string', function() {
|
||||
_.each(['abc', Object('abc')], function(value) {
|
||||
var actual = func(value);
|
||||
equal(actual, methodName == 'max' ? 'c' : 'a');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.merge');
|
||||
|
||||
(function() {
|
||||
@@ -1041,6 +1172,14 @@
|
||||
var expected = { 'a': 4 };
|
||||
deepEqual(_.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected), expected);
|
||||
});
|
||||
|
||||
test('should work with `_.reduce`', function() {
|
||||
var actual = { 'a': 1},
|
||||
array = [{ 'b': 2 }, { 'c': 3 }];
|
||||
|
||||
_.reduce(array, _.merge, actual);
|
||||
deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3});
|
||||
});
|
||||
}(1, 2, 3));
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1251,6 +1390,17 @@
|
||||
QUnit.module('lodash.reduce');
|
||||
|
||||
(function() {
|
||||
test('should pass the correct `callback` arguments', function() {
|
||||
var args,
|
||||
array = [1, 2, 3];
|
||||
|
||||
_.reduce(array, function() {
|
||||
args || (args = slice.call(arguments));
|
||||
});
|
||||
|
||||
deepEqual(args, [1, 2, 1, array]);
|
||||
});
|
||||
|
||||
_.each({
|
||||
'literal': 'abc',
|
||||
'object': Object('abc')
|
||||
@@ -1275,6 +1425,17 @@
|
||||
QUnit.module('lodash.reduceRight');
|
||||
|
||||
(function() {
|
||||
test('should pass the correct `callback` arguments when iterating an array', function() {
|
||||
var args,
|
||||
array = [1, 2, 3];
|
||||
|
||||
_.reduceRight(array, function() {
|
||||
args || (args = slice.call(arguments));
|
||||
});
|
||||
|
||||
deepEqual(args, [3, 2, 1, array]);
|
||||
});
|
||||
|
||||
test('should pass the correct `callback` arguments when iterating an object', function() {
|
||||
var args,
|
||||
object = { 'a': 1, 'b': 2 },
|
||||
@@ -1372,6 +1533,17 @@
|
||||
});
|
||||
}(1, 2, 3));
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.some');
|
||||
|
||||
(function() {
|
||||
test('should return `true` as soon as the `callback` result is truthy', function() {
|
||||
equal(_.some([null, true, null], _.identity), true);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.sortBy');
|
||||
@@ -1468,7 +1640,7 @@
|
||||
} catch(e) {
|
||||
var source = e.source;
|
||||
}
|
||||
ok((source + '').indexOf('__p') > -1);
|
||||
ok(/__p/.test(source));
|
||||
});
|
||||
|
||||
test('should work with complex "interpolate" delimiters', function() {
|
||||
@@ -1555,6 +1727,12 @@
|
||||
|
||||
equal(compiled({ 'value': true }), expected);
|
||||
});
|
||||
|
||||
test('should parse ES6 template delimiters', function() {
|
||||
var data = { 'value': 2 };
|
||||
equal(_.template('1${value}3', data), '123');
|
||||
equal(_.template('${"{" + value + "\\}"}', data), '{2}');
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1563,24 +1741,12 @@
|
||||
|
||||
(function() {
|
||||
test('subsequent calls should return the result of the first call', function() {
|
||||
var throttled = _.throttle(function(value) { return value; }, 100),
|
||||
var throttled = _.throttle(function(value) { return value; }, 32),
|
||||
result = [throttled('x'), throttled('y')];
|
||||
|
||||
deepEqual(result, ['x', 'x']);
|
||||
});
|
||||
|
||||
test('supports calls in a loop', function() {
|
||||
var counter = 0,
|
||||
throttled = _.throttle(function() { counter++; }, 100),
|
||||
start = new Date,
|
||||
limit = 220;
|
||||
|
||||
while ((new Date - start) < limit) {
|
||||
throttled();
|
||||
}
|
||||
ok(counter > 1);
|
||||
});
|
||||
|
||||
asyncTest('supports recursive calls', function() {
|
||||
var counter = 0;
|
||||
var throttled = _.throttle(function() {
|
||||
@@ -1588,12 +1754,12 @@
|
||||
if (counter < 4) {
|
||||
throttled();
|
||||
}
|
||||
}, 100);
|
||||
}, 90);
|
||||
|
||||
setTimeout(function() {
|
||||
ok(counter > 1);
|
||||
QUnit.start();
|
||||
}, 220);
|
||||
}, 180);
|
||||
|
||||
throttled();
|
||||
});
|
||||
@@ -1604,12 +1770,12 @@
|
||||
|
||||
var throttled = _.throttle(function() {
|
||||
times.push(new Date - now);
|
||||
}, 20);
|
||||
}, 32);
|
||||
|
||||
setTimeout(throttled, 20);
|
||||
setTimeout(throttled, 20);
|
||||
setTimeout(throttled, 40);
|
||||
setTimeout(throttled, 40);
|
||||
setTimeout(throttled, 32);
|
||||
setTimeout(throttled, 32);
|
||||
setTimeout(throttled, 64);
|
||||
setTimeout(throttled, 64);
|
||||
|
||||
setTimeout(function() {
|
||||
var actual = _.every(times, function(value, index) {
|
||||
@@ -1620,7 +1786,44 @@
|
||||
|
||||
ok(actual);
|
||||
QUnit.start();
|
||||
}, 120);
|
||||
}, 260);
|
||||
});
|
||||
|
||||
asyncTest('should not trigger a trailing call when invoked once', function() {
|
||||
var counter = 0,
|
||||
throttled = _.throttle(function() { counter++; }, 32);
|
||||
|
||||
throttled();
|
||||
equal(counter, 1);
|
||||
|
||||
setTimeout(function() {
|
||||
equal(counter, 1);
|
||||
QUnit.start();
|
||||
}, 64);
|
||||
});
|
||||
|
||||
asyncTest('should trigger trailing call when invoked repeatedly', function() {
|
||||
var actual,
|
||||
counter = 0,
|
||||
limit = 80,
|
||||
throttled = _.throttle(function() { counter++; }, 32),
|
||||
start = new Date;
|
||||
|
||||
while ((new Date - start) < limit) {
|
||||
throttled();
|
||||
}
|
||||
setTimeout(function() {
|
||||
actual = counter + 2;
|
||||
throttled();
|
||||
throttled();
|
||||
}, 64);
|
||||
|
||||
setTimeout(function() {
|
||||
equal(counter, actual);
|
||||
QUnit.start();
|
||||
}, 128);
|
||||
|
||||
ok(counter > 1);
|
||||
});
|
||||
}());
|
||||
|
||||
@@ -1631,6 +1834,17 @@
|
||||
(function() {
|
||||
var args = arguments;
|
||||
|
||||
test('should return a dense array', function() {
|
||||
var array = Array(3);
|
||||
array[1] = 2;
|
||||
|
||||
var actual = _.toArray(array);
|
||||
|
||||
ok(0 in actual);
|
||||
ok(2 in actual);
|
||||
deepEqual(actual, array);
|
||||
});
|
||||
|
||||
test('should treat array-like objects like arrays', function() {
|
||||
var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
|
||||
deepEqual(_.toArray(object), ['a', 'b', 'c']);
|
||||
@@ -1641,6 +1855,19 @@
|
||||
deepEqual(_.toArray('abc'), ['a', 'b', 'c']);
|
||||
deepEqual(_.toArray(Object('abc')), ['a', 'b', 'c']);
|
||||
});
|
||||
|
||||
test('should work with a node list for `collection` (test in IE < 9)', function() {
|
||||
if (window.document) {
|
||||
try {
|
||||
var nodeList = document.getElementsByTagName('body'),
|
||||
body = nodeList[0],
|
||||
actual = _.toArray(nodeList);
|
||||
} catch(e) { }
|
||||
deepEqual(actual, [body]);
|
||||
} else {
|
||||
skipTest();
|
||||
}
|
||||
});
|
||||
}(1, 2, 3));
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1691,6 +1918,28 @@
|
||||
|
||||
deepEqual(actual, [1, 2, 3]);
|
||||
});
|
||||
|
||||
test('should distinguish between numbers and numeric strings', function() {
|
||||
var expected = ['2', 2, Object('2'), Object(2)],
|
||||
actual = _.uniq(expected);
|
||||
|
||||
deepEqual(actual, expected);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.uniqueId');
|
||||
|
||||
(function() {
|
||||
test('should return a string value when not passing a prefix argument', function() {
|
||||
equal(typeof _.uniqueId(), 'string');
|
||||
});
|
||||
|
||||
test('should coerce the prefix argument to a string', function() {
|
||||
var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
|
||||
equal(/3\d+,2\d+,1\d+/.test(actual), true);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1715,14 +1964,13 @@
|
||||
deepEqual(_.where(array, { 'a': 1, 'b': 2 }), [{ 'a': 1, 'b': 2 }]);
|
||||
});
|
||||
|
||||
test('should filter by inherited properties', function() {
|
||||
test('should not filter by inherited properties', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype = { 'b': 2 };
|
||||
Foo.prototype = { 'a': 2 };
|
||||
|
||||
var properties = new Foo;
|
||||
properties.a = 1;
|
||||
|
||||
deepEqual(_.where(array, properties), [{ 'a': 1, 'b': 2 }]);
|
||||
properties.b = 2;
|
||||
deepEqual(_.where(array, properties), [{ 'a': 1, 'b': 2 }, { 'a': 2, 'b': 2 }]);
|
||||
});
|
||||
|
||||
test('should filter by problem JScript properties (test in IE < 9)', function() {
|
||||
@@ -1739,6 +1987,10 @@
|
||||
|
||||
deepEqual(_.where(collection, { 'a': 1 }), [{ 'a': 1 }, { 'a': 1, 'b': 2 }]);
|
||||
});
|
||||
|
||||
test('should return an empty array when passed an empty `properties` object', function() {
|
||||
deepEqual(_.where(array, {}), []);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1750,7 +2002,7 @@
|
||||
var wrapped = _({ '0': 1, 'length': 1 });
|
||||
wrapped.shift();
|
||||
|
||||
deepEqual(wrapped.keys(), ['length']);
|
||||
deepEqual(wrapped.keys().value(), ['length']);
|
||||
equal(wrapped.first(), undefined);
|
||||
});
|
||||
}());
|
||||
@@ -1764,13 +2016,107 @@
|
||||
var wrapped = _({ '0': 1, 'length': 1 });
|
||||
wrapped.splice(0, 1);
|
||||
|
||||
deepEqual(wrapped.keys(), ['length']);
|
||||
deepEqual(wrapped.keys().value(), ['length']);
|
||||
equal(wrapped.first(), undefined);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash(...).toString');
|
||||
|
||||
(function() {
|
||||
test('should return the `toString` result of the wrapped value', function() {
|
||||
var wrapped = _([1, 2, 3]);
|
||||
equal(String(wrapped), '1,2,3');
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash(...).valueOf');
|
||||
|
||||
(function() {
|
||||
test('should return the `valueOf` result of the wrapped value', function() {
|
||||
var wrapped = _(123);
|
||||
equal(Number(wrapped), 123);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash(...) methods capable of returning wrapped and unwrapped values');
|
||||
|
||||
(function() {
|
||||
var array = [1, 2, 3],
|
||||
wrapped = _(array);
|
||||
|
||||
var funcs = [
|
||||
'first',
|
||||
'last'
|
||||
];
|
||||
|
||||
_.each(funcs, function(methodName) {
|
||||
test('_.' + methodName + ' should return an unwrapped value', function() {
|
||||
equal(typeof wrapped[methodName](), 'number');
|
||||
});
|
||||
|
||||
test('_.' + methodName + ' should return a wrapped value', function() {
|
||||
ok(wrapped[methodName](1) instanceof _);
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash(...) methods that return unwrapped values');
|
||||
|
||||
(function() {
|
||||
var array = [1, 2, 3],
|
||||
wrapped = _(array);
|
||||
|
||||
var funcs = [
|
||||
'contains',
|
||||
'every',
|
||||
'find',
|
||||
'first',
|
||||
'has',
|
||||
'isArguments',
|
||||
'isArray',
|
||||
'isBoolean',
|
||||
'isDate',
|
||||
'isElement',
|
||||
'isEmpty',
|
||||
'isEqual',
|
||||
'isFinite',
|
||||
'isFunction',
|
||||
'isNaN',
|
||||
'isNull',
|
||||
'isNumber',
|
||||
'isObject',
|
||||
'isPlainObject',
|
||||
'isRegExp',
|
||||
'isString',
|
||||
'isUndefined',
|
||||
'last',
|
||||
'reduce',
|
||||
'reduceRight',
|
||||
'some'
|
||||
];
|
||||
|
||||
_.each(funcs, function(methodName) {
|
||||
test('_.' + methodName + ' should return unwrapped values', function() {
|
||||
var result = methodName == 'reduceRight'
|
||||
? wrapped[methodName](_.identity)
|
||||
: wrapped[methodName];
|
||||
|
||||
notEqual(typeof result, 'object', '_.' + methodName + ' returns unwrapped values');
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash methods');
|
||||
|
||||
(function() {
|
||||
@@ -1790,7 +2136,6 @@
|
||||
var funcs = _.without.apply(_, [_.functions(_)].concat([
|
||||
'_',
|
||||
'_iteratorTemplate',
|
||||
'_shimKeys',
|
||||
'after',
|
||||
'bind',
|
||||
'bindAll',
|
||||
@@ -1823,8 +2168,6 @@
|
||||
|
||||
if (_.indexOf(returnArrays, methodName) > -1) {
|
||||
deepEqual(actual, expected, '_.' + methodName + ' returns an array');
|
||||
} else {
|
||||
skipTest(falsey.length);
|
||||
}
|
||||
ok(pass, '_.' + methodName + ' allows falsey arguments');
|
||||
});
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Underscore Test Suite</title>
|
||||
<link rel="stylesheet" href="../vendor/underscore/test/vendor/qunit.css">
|
||||
<link rel="stylesheet" href="../vendor/qunit/qunit/qunit.css">
|
||||
<style>
|
||||
#jslitmus, iframe {
|
||||
iframe, img {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -17,10 +17,9 @@
|
||||
<div id="id1"></div>
|
||||
<div id="id2"></div>
|
||||
</div>
|
||||
<img id="chart_image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
|
||||
</div>
|
||||
<script src="../vendor/backbone/test/vendor/json2.js"></script>
|
||||
<script src="../vendor/underscore/test/vendor/jquery.js"></script>
|
||||
<script src="../vendor/underscore/test/vendor/jslitmus.js"></script>
|
||||
<script src="../vendor/jquery/jquery.js"></script>
|
||||
<script src="../vendor/platform.js/platform.js"></script>
|
||||
<script>
|
||||
// avoid syntax errors for `QUnit.throws` in older Firefoxes
|
||||
@@ -31,7 +30,7 @@
|
||||
</script>
|
||||
<script src="test-ui.js"></script>
|
||||
<script>
|
||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
</script>
|
||||
<script src="../vendor/underscore/test/collections.js"></script>
|
||||
<script src="../vendor/underscore/test/arrays.js"></script>
|
||||
|
||||
269
vendor/backbone/backbone.js
vendored
269
vendor/backbone/backbone.js
vendored
@@ -10,7 +10,7 @@
|
||||
// Initial Setup
|
||||
// -------------
|
||||
|
||||
// Save a reference to the global object (`window` in the browser, `global`
|
||||
// Save a reference to the global object (`window` in the browser, `exports`
|
||||
// on the server).
|
||||
var root = this;
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
Backbone.emulateJSON = false;
|
||||
|
||||
// Backbone.Events
|
||||
// -----------------
|
||||
// ---------------
|
||||
|
||||
// Regular expression used to split event strings
|
||||
var eventSplitter = /\s+/;
|
||||
@@ -184,22 +184,20 @@
|
||||
var Model = Backbone.Model = function(attributes, options) {
|
||||
var defaults;
|
||||
var attrs = attributes || {};
|
||||
this.cid = _.uniqueId('c');
|
||||
this.changed = {};
|
||||
this.attributes = {};
|
||||
this._escapedAttributes = {};
|
||||
this._modelState = [];
|
||||
if (options && options.collection) this.collection = options.collection;
|
||||
if (options && options.parse) attributes = this.parse(attributes);
|
||||
if (options && options.parse) attrs = this.parse(attrs);
|
||||
if (defaults = _.result(this, 'defaults')) {
|
||||
attrs = _.extend({}, defaults, attrs);
|
||||
}
|
||||
this.attributes = {};
|
||||
this._escapedAttributes = {};
|
||||
this.cid = _.uniqueId('c');
|
||||
this.changed = {};
|
||||
this._changes = {};
|
||||
this._pending = {};
|
||||
this.set(attrs, {silent: true});
|
||||
// Reset change tracking.
|
||||
this.changed = {};
|
||||
this._changes = {};
|
||||
this._pending = {};
|
||||
this._cleanChange = true;
|
||||
this._modelState = [];
|
||||
this._currentState = _.clone(this.attributes);
|
||||
this._previousAttributes = _.clone(this.attributes);
|
||||
this.initialize.apply(this, arguments);
|
||||
};
|
||||
@@ -210,17 +208,26 @@
|
||||
// A hash of attributes whose current and previous value differ.
|
||||
changed: null,
|
||||
|
||||
// A hash of attributes that have changed since the last time `change`
|
||||
// was called.
|
||||
_changes: null,
|
||||
// Whether there is a pending request to fire in the final `change` loop.
|
||||
_pending: false,
|
||||
|
||||
// A hash of attributes that have changed since the last `change` event
|
||||
// began.
|
||||
_pending: null,
|
||||
// Whether the model is in the midst of a change cycle.
|
||||
_changing: false,
|
||||
|
||||
// A hash of attributes with the current model state to determine if
|
||||
// a `change` should be recorded within a nested `change` block.
|
||||
_changing : null,
|
||||
// Whether there has been a `set` call since the last
|
||||
// calculation of the changed hash, for efficiency.
|
||||
_cleanChange: true,
|
||||
|
||||
// The model state used for comparison in determining if a
|
||||
// change should be fired.
|
||||
_currentState: null,
|
||||
|
||||
// An array queue of all changes attributed to a model
|
||||
// on the next non-silent change event.
|
||||
_modelState: null,
|
||||
|
||||
// A hash of the model's attributes when the last `change` occured.
|
||||
_previousAttributes: null,
|
||||
|
||||
// The default name for the JSON `id` attribute is `"id"`. MongoDB and
|
||||
// CouchDB users may want to set this to `"_id"`.
|
||||
@@ -261,20 +268,22 @@
|
||||
|
||||
// Set a hash of model attributes on the object, firing `"change"` unless
|
||||
// you choose to silence it.
|
||||
set: function(attrs, options) {
|
||||
var attr, key, val;
|
||||
if (attrs == null) return this;
|
||||
set: function(key, val, options) {
|
||||
var attr, attrs;
|
||||
if (key == null) return this;
|
||||
|
||||
// Handle both `"key", value` and `{key: value}` -style arguments.
|
||||
if (!_.isObject(attrs)) {
|
||||
key = attrs;
|
||||
(attrs = {})[key] = options;
|
||||
options = arguments[2];
|
||||
if (_.isObject(key)) {
|
||||
attrs = key;
|
||||
options = val;
|
||||
} else {
|
||||
(attrs = {})[key] = val;
|
||||
}
|
||||
|
||||
// Extract attributes and options.
|
||||
var silent = options && options.silent;
|
||||
var unset = options && options.unset;
|
||||
|
||||
if (attrs instanceof Model) attrs = attrs.attributes;
|
||||
if (unset) for (attr in attrs) attrs[attr] = void 0;
|
||||
|
||||
@@ -284,38 +293,26 @@
|
||||
// Check for changes of `id`.
|
||||
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
|
||||
|
||||
var changing = this._changing;
|
||||
var now = this.attributes;
|
||||
var escaped = this._escapedAttributes;
|
||||
var prev = this._previousAttributes || {};
|
||||
var esc = this._escapedAttributes;
|
||||
|
||||
// For each `set` attribute...
|
||||
for (attr in attrs) {
|
||||
val = attrs[attr];
|
||||
|
||||
// If the new and current value differ, record the change.
|
||||
if (!_.isEqual(now[attr], val) || (unset && _.has(now, attr))) {
|
||||
delete escaped[attr];
|
||||
this._changes[attr] = true;
|
||||
}
|
||||
// If an escaped attr exists, and the new and current value differ, remove the escaped attr.
|
||||
if (esc[attr] && !_.isEqual(now[attr], val) || (unset && _.has(now, attr))) delete esc[attr];
|
||||
|
||||
// Update or delete the current value.
|
||||
unset ? delete now[attr] : now[attr] = val;
|
||||
|
||||
// If the new and previous value differ, record the change. If not,
|
||||
// then remove changes for this attribute.
|
||||
if (!_.isEqual(prev[attr], val) || (_.has(now, attr) !== _.has(prev, attr))) {
|
||||
this.changed[attr] = val;
|
||||
if (!silent) this._pending[attr] = true;
|
||||
} else {
|
||||
delete this.changed[attr];
|
||||
delete this._pending[attr];
|
||||
if (!changing) delete this._changes[attr];
|
||||
}
|
||||
|
||||
if (changing && _.isEqual(now[attr], changing[attr])) delete this._changes[attr];
|
||||
// Track any action on the attribute.
|
||||
this._modelState.push(attr, val, unset);
|
||||
}
|
||||
|
||||
// Signal that the model's state has potentially changed.
|
||||
this._cleanChange = false;
|
||||
|
||||
// Fire the `"change"` events.
|
||||
if (!silent) this.change(options);
|
||||
return this;
|
||||
@@ -340,6 +337,7 @@
|
||||
// triggering a `"change"` event.
|
||||
fetch: function(options) {
|
||||
options = options ? _.clone(options) : {};
|
||||
if (options.parse === void 0) options.parse = true;
|
||||
var model = this;
|
||||
var success = options.success;
|
||||
options.success = function(resp, status, xhr) {
|
||||
@@ -352,20 +350,21 @@
|
||||
// Set a hash of model attributes, and sync the model to the server.
|
||||
// If the server returns an attributes hash that differs, the model's
|
||||
// state will be `set` again.
|
||||
save: function(attrs, options) {
|
||||
var key, current, done;
|
||||
save: function(key, val, options) {
|
||||
var attrs, current, done;
|
||||
|
||||
// Handle both `"key", value` and `{key: value}` -style arguments.
|
||||
if (attrs != null && !_.isObject(attrs)) {
|
||||
key = attrs;
|
||||
(attrs = {})[key] = options;
|
||||
options = arguments[2];
|
||||
if (key == null || _.isObject(key)) {
|
||||
attrs = key;
|
||||
options = val;
|
||||
} else if (key != null) {
|
||||
(attrs = {})[key] = val;
|
||||
}
|
||||
options = options ? _.clone(options) : {};
|
||||
|
||||
// If we're "wait"-ing to set changed attributes, validate early.
|
||||
if (options.wait) {
|
||||
if (!this._validate(attrs, options)) return false;
|
||||
if (attrs && !this._validate(attrs, options)) return false;
|
||||
current = _.clone(this.attributes);
|
||||
}
|
||||
|
||||
@@ -459,37 +458,23 @@
|
||||
// a `"change:attribute"` event for each changed attribute.
|
||||
// Calling this will cause all objects observing the model to update.
|
||||
change: function(options) {
|
||||
var changing = this._changing;
|
||||
var current = this._changing = {};
|
||||
var i, changing = this._changing;
|
||||
this._changing = true;
|
||||
|
||||
// Silent changes become pending changes.
|
||||
for (var attr in this._changes) this._pending[attr] = true;
|
||||
// Generate the changes to be triggered on the model.
|
||||
var triggers = this._changeCenter(true);
|
||||
this._pending = triggers.length;
|
||||
|
||||
// Trigger 'change:attr' for any new or silent changes.
|
||||
var changes = this._changes;
|
||||
this._changes = {};
|
||||
|
||||
// Set the correct state for this._changing values
|
||||
var triggers = [];
|
||||
for (var attr in changes) {
|
||||
current[attr] = this.get(attr);
|
||||
triggers.push(attr);
|
||||
for (i = triggers.length - 2; i >= 0; i -= 2) {
|
||||
this.trigger('change:' + triggers[i], this, triggers[i + 1], options);
|
||||
}
|
||||
|
||||
for (var i=0, l=triggers.length; i < l; i++) {
|
||||
this.trigger('change:' + triggers[i], this, current[triggers[i]], options);
|
||||
}
|
||||
if (changing) return this;
|
||||
|
||||
// Continue firing `"change"` events while there are pending changes.
|
||||
while (!_.isEmpty(this._pending)) {
|
||||
this._pending = {};
|
||||
// Trigger a `change` while there have been changes.
|
||||
while (this._pending) {
|
||||
this._pending = false;
|
||||
this.trigger('change', this, options);
|
||||
// Pending and silent changes still remain.
|
||||
for (var attr in this.changed) {
|
||||
if (this._pending[attr] || this._changes[attr]) continue;
|
||||
delete this.changed[attr];
|
||||
}
|
||||
this._previousAttributes = _.clone(this.attributes);
|
||||
}
|
||||
|
||||
@@ -500,6 +485,7 @@
|
||||
// Determine if the model has changed since the last `"change"` event.
|
||||
// If you specify an attribute name, determine if that attribute has changed.
|
||||
hasChanged: function(attr) {
|
||||
if (!this._cleanChange) this._changeCenter();
|
||||
if (attr == null) return !_.isEmpty(this.changed);
|
||||
return _.has(this.changed, attr);
|
||||
},
|
||||
@@ -520,6 +506,42 @@
|
||||
return changed;
|
||||
},
|
||||
|
||||
// Calculates and handles any changes in `this._modelState`,
|
||||
// checking against `this._currentState` to determine current changes.
|
||||
_changeCenter: function (change) {
|
||||
this.changed = {};
|
||||
var local = {};
|
||||
var triggers = [];
|
||||
var modelState = this._modelState;
|
||||
var currentState = this._currentState;
|
||||
|
||||
// Loop through the current queue of potential model changes.
|
||||
for (var i = modelState.length - 3; i >= 0; i -= 3) {
|
||||
var key = modelState[i], val = modelState[i + 1], unset = modelState[i + 2];
|
||||
|
||||
// If the item hasn't been set locally this round, proceed.
|
||||
if (!local[key]) {
|
||||
local[key] = val;
|
||||
|
||||
// Check if the attribute has been modified since the last change,
|
||||
// and update `this.changed` accordingly.
|
||||
if (currentState[key] !== val || (_.has(currentState, key) && unset)) {
|
||||
this.changed[key] = val;
|
||||
|
||||
// Triggers & modifications are only created inside a `change` call.
|
||||
if (!change) continue;
|
||||
triggers.push(key, val);
|
||||
(!unset) ? currentState[key] = val : delete currentState[key];
|
||||
}
|
||||
}
|
||||
modelState.splice(i,3);
|
||||
}
|
||||
|
||||
// Signals `this.changed` is current to prevent duplicate calls from `this.hasChanged`.
|
||||
this._cleanChange = true;
|
||||
return triggers;
|
||||
},
|
||||
|
||||
// Get the previous value of an attribute, recorded at the time the last
|
||||
// `"change"` event was fired.
|
||||
previous: function(attr) {
|
||||
@@ -597,26 +619,27 @@
|
||||
// Add a model, or list of models to the set. Pass **silent** to avoid
|
||||
// firing the `add` event for every new model.
|
||||
add: function(models, options) {
|
||||
var i, args, length, model, existing;
|
||||
var i, args, length, model, existing, sort;
|
||||
var at = options && options.at;
|
||||
models = _.isArray(models) ? models.slice() : [models];
|
||||
|
||||
// Begin by turning bare objects into model references, and preventing
|
||||
// invalid models from being added.
|
||||
for (i = 0, length = models.length; i < length; i++) {
|
||||
if (models[i] = this._prepareModel(models[i], options)) continue;
|
||||
throw new Error("Can't add an invalid model to a collection");
|
||||
}
|
||||
|
||||
// Turn bare objects into model references, and prevent invalid models
|
||||
// from being added.
|
||||
for (i = models.length - 1; i >= 0; i--) {
|
||||
model = models[i];
|
||||
existing = model.id != null && this._byId[model.id];
|
||||
if(!(model = this._prepareModel(models[i], options))) {
|
||||
this.trigger("error", this, models[i], options);
|
||||
models.splice(i, 1);
|
||||
continue;
|
||||
}
|
||||
models[i] = model;
|
||||
|
||||
// If a duplicate is found, splice it out and optionally merge it into
|
||||
// the existing model.
|
||||
existing = model.id != null && this._byId[model.id];
|
||||
// If a duplicate is found, prevent it from being added and
|
||||
// optionally merge it into the existing model.
|
||||
if (existing || this._byCid[model.cid]) {
|
||||
if (options && options.merge && existing) {
|
||||
existing.set(model, options);
|
||||
sort = true;
|
||||
}
|
||||
models.splice(i, 1);
|
||||
continue;
|
||||
@@ -629,14 +652,15 @@
|
||||
if (model.id != null) this._byId[model.id] = model;
|
||||
}
|
||||
|
||||
// Update `length` and splice in new models.
|
||||
// See if sorting is needed, update `length` and splice in new models.
|
||||
if (models.length) sort = true;
|
||||
this.length += models.length;
|
||||
args = [at != null ? at : this.models.length, 0];
|
||||
push.apply(args, models);
|
||||
splice.apply(this.models, args);
|
||||
|
||||
// Sort the collection if appropriate.
|
||||
if (this.comparator && at == null) this.sort({silent: true});
|
||||
if (sort && this.comparator && at == null) this.sort({silent: true});
|
||||
|
||||
if (options && options.silent) return this;
|
||||
|
||||
@@ -819,7 +843,7 @@
|
||||
},
|
||||
|
||||
// Reset all internal state. Called when the collection is reset.
|
||||
_reset: function(options) {
|
||||
_reset: function() {
|
||||
this.length = 0;
|
||||
this.models = [];
|
||||
this._byId = {};
|
||||
@@ -892,7 +916,7 @@
|
||||
});
|
||||
|
||||
// Backbone.Router
|
||||
// -------------------
|
||||
// ---------------
|
||||
|
||||
// Routers map faux-URLs to actions, and fire events when routes are
|
||||
// matched. Creating a new one sets its `routes` hash, if not set statically.
|
||||
@@ -946,12 +970,9 @@
|
||||
// routes can be defined at the bottom of the route map.
|
||||
_bindRoutes: function() {
|
||||
if (!this.routes) return;
|
||||
var routes = [];
|
||||
for (var route in this.routes) {
|
||||
routes.unshift([route, this.routes[route]]);
|
||||
}
|
||||
for (var i = 0, l = routes.length; i < l; i++) {
|
||||
this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
|
||||
var route, routes = _.keys(this.routes);
|
||||
while ((route = routes.pop()) != null) {
|
||||
this.route(route, this.routes[route]);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -989,8 +1010,8 @@
|
||||
}
|
||||
};
|
||||
|
||||
// Cached regex for cleaning leading hashes and slashes.
|
||||
var routeStripper = /^[#\/]/;
|
||||
// Cached regex for stripping a leading hash/slash and trailing space.
|
||||
var routeStripper = /^[#\/]|\s+$/g;
|
||||
|
||||
// Cached regex for stripping leading and trailing slashes.
|
||||
var rootStripper = /^\/+|\/+$/g;
|
||||
@@ -1205,7 +1226,7 @@
|
||||
var delegateEventSplitter = /^(\S+)\s*(.*)$/;
|
||||
|
||||
// List of view options to be merged as properties.
|
||||
var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];
|
||||
var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
|
||||
|
||||
// Set up all inheritable **Backbone.View** properties and methods.
|
||||
_.extend(View.prototype, Events, {
|
||||
@@ -1314,11 +1335,8 @@
|
||||
// Keys with special meaning *(model, collection, id, className)*, are
|
||||
// attached directly to the view.
|
||||
_configure: function(options) {
|
||||
if (this.options) options = _.extend({}, this.options, options);
|
||||
for (var i = 0, l = viewOptions.length; i < l; i++) {
|
||||
var attr = viewOptions[i];
|
||||
if (options[attr]) this[attr] = options[attr];
|
||||
}
|
||||
if (this.options) options = _.extend({}, _.result(this, 'options'), options);
|
||||
_.extend(this, _.pick(options, viewOptions));
|
||||
this.options = options;
|
||||
},
|
||||
|
||||
@@ -1369,7 +1387,10 @@
|
||||
var type = methodMap[method];
|
||||
|
||||
// Default options, unless specified.
|
||||
options || (options = {});
|
||||
_.defaults(options || (options = {}), {
|
||||
emulateHTTP: Backbone.emulateHTTP,
|
||||
emulateJSON: Backbone.emulateJSON
|
||||
});
|
||||
|
||||
// Default JSON-request options.
|
||||
var params = {type: type, dataType: 'json'};
|
||||
@@ -1382,29 +1403,29 @@
|
||||
// Ensure that we have the appropriate request data.
|
||||
if (!options.data && model && (method === 'create' || method === 'update')) {
|
||||
params.contentType = 'application/json';
|
||||
params.data = JSON.stringify(model);
|
||||
params.data = JSON.stringify(model.toJSON(options));
|
||||
}
|
||||
|
||||
// For older servers, emulate JSON by encoding the request into an HTML-form.
|
||||
if (Backbone.emulateJSON) {
|
||||
if (options.emulateJSON) {
|
||||
params.contentType = 'application/x-www-form-urlencoded';
|
||||
params.data = params.data ? {model: params.data} : {};
|
||||
}
|
||||
|
||||
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
|
||||
// And an `X-HTTP-Method-Override` header.
|
||||
if (Backbone.emulateHTTP) {
|
||||
if (type === 'PUT' || type === 'DELETE') {
|
||||
if (Backbone.emulateJSON) params.data._method = type;
|
||||
params.type = 'POST';
|
||||
params.beforeSend = function(xhr) {
|
||||
xhr.setRequestHeader('X-HTTP-Method-Override', type);
|
||||
};
|
||||
}
|
||||
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE')) {
|
||||
params.type = 'POST';
|
||||
if (options.emulateJSON) params.data._method = type;
|
||||
var beforeSend = options.beforeSend;
|
||||
options.beforeSend = function(xhr) {
|
||||
xhr.setRequestHeader('X-HTTP-Method-Override', type);
|
||||
if (beforeSend) return beforeSend.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
// Don't process data on a non-GET request.
|
||||
if (params.type !== 'GET' && !Backbone.emulateJSON) {
|
||||
if (params.type !== 'GET' && !options.emulateJSON) {
|
||||
params.processData = false;
|
||||
}
|
||||
|
||||
@@ -1468,8 +1489,8 @@
|
||||
return child;
|
||||
};
|
||||
|
||||
// Set up inheritance for the model, collection, router, and view.
|
||||
Model.extend = Collection.extend = Router.extend = View.extend = extend;
|
||||
// Set up inheritance for the model, collection, router, view and history.
|
||||
Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
|
||||
|
||||
// Throw an error when a URL is needed, and none is supplied.
|
||||
var urlError = function() {
|
||||
|
||||
57
vendor/backbone/test/collection.js
vendored
57
vendor/backbone/test/collection.js
vendored
@@ -542,8 +542,7 @@ $(document).ready(function() {
|
||||
equal(col.length, 0);
|
||||
});
|
||||
|
||||
test("#861, adding models to a collection which do not pass validation", 1, function() {
|
||||
raises(function() {
|
||||
test("#861, adding models to a collection which do not pass validation", 2, function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
if (attrs.id == 3) return "id can't be 3";
|
||||
@@ -554,26 +553,26 @@ $(document).ready(function() {
|
||||
model: Model
|
||||
});
|
||||
|
||||
var col = new Collection;
|
||||
var collection = new Collection;
|
||||
collection.on("error", function() { ok(true); });
|
||||
|
||||
col.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}]);
|
||||
}, function(e) {
|
||||
return e.message === "Can't add an invalid model to a collection";
|
||||
});
|
||||
collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}]);
|
||||
deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);
|
||||
});
|
||||
|
||||
test("throwing during add leaves consistent state", 4, function() {
|
||||
var col = new Backbone.Collection();
|
||||
col.on('test', function() { ok(false); });
|
||||
col.model = Backbone.Model.extend({
|
||||
test("Invalid models are discarded.", 5, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
collection.on('test', function() { ok(true); });
|
||||
collection.model = Backbone.Model.extend({
|
||||
validate: function(attrs){ if (!attrs.valid) return 'invalid'; }
|
||||
});
|
||||
var model = new col.model({id: 1, valid: true});
|
||||
raises(function() { col.add([model, {id: 2}]); });
|
||||
var model = new collection.model({id: 1, valid: true});
|
||||
collection.add([model, {id: 2}]);;
|
||||
model.trigger('test');
|
||||
ok(!col.getByCid(model.cid));
|
||||
ok(!col.get(1));
|
||||
equal(col.length, 0);
|
||||
ok(collection.getByCid(model.cid));
|
||||
ok(collection.get(1));
|
||||
ok(!collection.get(2));
|
||||
equal(collection.length, 1);
|
||||
});
|
||||
|
||||
test("multiple copies of the same model", 3, function() {
|
||||
@@ -701,4 +700,30 @@ $(document).ready(function() {
|
||||
collection.add([{id: 1, x: 1}, {id: 2, x: 2}]);
|
||||
deepEqual(added, [1, 2]);
|
||||
});
|
||||
|
||||
test("fetch parses models by default", 1, function() {
|
||||
var model = {};
|
||||
var Collection = Backbone.Collection.extend({
|
||||
url: 'test',
|
||||
model: Backbone.Model.extend({
|
||||
parse: function(resp) {
|
||||
strictEqual(resp, model);
|
||||
}
|
||||
})
|
||||
});
|
||||
new Collection().fetch();
|
||||
this.ajaxSettings.success([model]);
|
||||
});
|
||||
|
||||
test("`sort` shouldn't always fire on `add`", 1, function() {
|
||||
var c = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}], {
|
||||
comparator: 'id'
|
||||
});
|
||||
c.sort = function(){ ok(true); };
|
||||
c.add([]);
|
||||
c.add({id: 1});
|
||||
c.add([{id: 2}, {id: 3}]);
|
||||
c.add({id: 4});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
6
vendor/backbone/test/environment.js
vendored
6
vendor/backbone/test/environment.js
vendored
@@ -8,6 +8,10 @@
|
||||
|
||||
sync: Backbone.sync,
|
||||
|
||||
emulateHTTP: Backbone.emulateHTTP,
|
||||
|
||||
emulateJSON: Backbone.emulateJSON,
|
||||
|
||||
setup: function() {
|
||||
var env = this;
|
||||
|
||||
@@ -32,6 +36,8 @@
|
||||
this.ajaxSettings = null;
|
||||
Backbone.sync = this.sync;
|
||||
Backbone.ajax = this.ajax;
|
||||
Backbone.emulateHTTP = this.emulateHTTP;
|
||||
Backbone.emulateJSON = this.emulateJSON;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
41
vendor/backbone/test/model.js
vendored
41
vendor/backbone/test/model.js
vendored
@@ -55,6 +55,17 @@ $(document).ready(function() {
|
||||
equal(model.get('value'), 2);
|
||||
});
|
||||
|
||||
test("parse can return null", 1, function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
parse: function(obj) {
|
||||
obj.value += 1;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
var model = new Model({value: 1}, {parse: true});
|
||||
equal(JSON.stringify(model.toJSON()), "{}");
|
||||
});
|
||||
|
||||
test("url", 3, function() {
|
||||
doc.urlRoot = null;
|
||||
equal(doc.url(), '/collection/1-the-tempest');
|
||||
@@ -88,7 +99,7 @@ $(document).ready(function() {
|
||||
equal(model.url(), '/nested/1/collection/2');
|
||||
});
|
||||
|
||||
test("clone", 8, function() {
|
||||
test("clone", 10, function() {
|
||||
var a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3});
|
||||
var b = a.clone();
|
||||
equal(a.get('foo'), 1);
|
||||
@@ -100,6 +111,12 @@ $(document).ready(function() {
|
||||
a.set({foo : 100});
|
||||
equal(a.get('foo'), 100);
|
||||
equal(b.get('foo'), 1, "Changing a parent attribute does not change the clone.");
|
||||
|
||||
var foo = new Backbone.Model({p: 1});
|
||||
var bar = new Backbone.Model({p: 2});
|
||||
bar.set(foo.clone(), {unset: true});
|
||||
equal(foo.get('p'), 1);
|
||||
equal(bar.get('p'), undefined);
|
||||
});
|
||||
|
||||
test("isNew", 6, function() {
|
||||
@@ -878,4 +895,26 @@ $(document).ready(function() {
|
||||
deepEqual(changes, ['a',1,'item']);
|
||||
});
|
||||
|
||||
test("#1791 - `attributes` is available for `parse`", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
parse: function() { this.has('a'); } // shouldn't throw an error
|
||||
});
|
||||
var model = new Model(null, {parse: true});
|
||||
expect(0);
|
||||
});
|
||||
|
||||
test("silent changes in last `change` event back to original does not trigger change", 2, function() {
|
||||
var changes = [];
|
||||
var model = new Backbone.Model();
|
||||
model.on('change:a change:b change:c', function(model, val) { changes.push(val); });
|
||||
model.on('change', function() {
|
||||
model.set({a:'c'}, {silent:true});
|
||||
});
|
||||
model.set({a:'a'});
|
||||
deepEqual(changes, ['a']);
|
||||
model.set({a:'a'}, {silent:true});
|
||||
model.change();
|
||||
deepEqual(changes, ['a']);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
21
vendor/backbone/test/router.js
vendored
21
vendor/backbone/test/router.js
vendored
@@ -481,4 +481,25 @@ $(document).ready(function() {
|
||||
});
|
||||
});
|
||||
|
||||
test("#1746 - Router allows empty route.", 1, function() {
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {'': 'empty'},
|
||||
empty: function(){},
|
||||
route: function(route){
|
||||
strictEqual(route, '');
|
||||
}
|
||||
});
|
||||
new Router;
|
||||
});
|
||||
|
||||
test("#1794 - Trailing space in fragments.", 1, function() {
|
||||
var history = new Backbone.History;
|
||||
strictEqual(history.getFragment('fragment '), 'fragment');
|
||||
});
|
||||
|
||||
test("#1820 - Leading slash and trailing space.", 1, function() {
|
||||
var history = new Backbone.History;
|
||||
strictEqual(history.getFragment('/fragment '), 'fragment');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
76
vendor/backbone/test/sync.js
vendored
76
vendor/backbone/test/sync.js
vendored
@@ -17,6 +17,11 @@ $(document).ready(function() {
|
||||
Environment.prototype.setup.apply(this, arguments);
|
||||
library = new Library;
|
||||
library.create(attrs, {wait: false});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
Environment.prototype.teardown.apply(this, arguments);
|
||||
Backbone.emulateHTTP = false;
|
||||
}
|
||||
|
||||
}));
|
||||
@@ -59,8 +64,10 @@ $(document).ready(function() {
|
||||
});
|
||||
|
||||
test("update with emulateHTTP and emulateJSON", 7, function() {
|
||||
Backbone.emulateHTTP = Backbone.emulateJSON = true;
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
|
||||
emulateHTTP: true,
|
||||
emulateJSON: true
|
||||
});
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'POST');
|
||||
equal(this.ajaxSettings.dataType, 'json');
|
||||
@@ -69,12 +76,12 @@ $(document).ready(function() {
|
||||
equal(data.id, '2-the-tempest');
|
||||
equal(data.author, 'Tim Shakespeare');
|
||||
equal(data.length, 123);
|
||||
Backbone.emulateHTTP = Backbone.emulateJSON = false;
|
||||
});
|
||||
|
||||
test("update with just emulateHTTP", 6, function() {
|
||||
Backbone.emulateHTTP = true;
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
|
||||
emulateHTTP: true
|
||||
});
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'POST');
|
||||
equal(this.ajaxSettings.contentType, 'application/json');
|
||||
@@ -82,12 +89,12 @@ $(document).ready(function() {
|
||||
equal(data.id, '2-the-tempest');
|
||||
equal(data.author, 'Tim Shakespeare');
|
||||
equal(data.length, 123);
|
||||
Backbone.emulateHTTP = false;
|
||||
});
|
||||
|
||||
test("update with just emulateJSON", 6, function() {
|
||||
Backbone.emulateJSON = true;
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
|
||||
emulateJSON: true
|
||||
});
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'PUT');
|
||||
equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');
|
||||
@@ -95,7 +102,6 @@ $(document).ready(function() {
|
||||
equal(data.id, '2-the-tempest');
|
||||
equal(data.author, 'Tim Shakespeare');
|
||||
equal(data.length, 123);
|
||||
Backbone.emulateJSON = false;
|
||||
});
|
||||
|
||||
test("read model", 3, function() {
|
||||
@@ -116,12 +122,13 @@ $(document).ready(function() {
|
||||
|
||||
test("destroy with emulateHTTP", 3, function() {
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
Backbone.emulateHTTP = Backbone.emulateJSON = true;
|
||||
library.first().destroy();
|
||||
library.first().destroy({
|
||||
emulateHTTP: true,
|
||||
emulateJSON: true
|
||||
});
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'POST');
|
||||
equal(JSON.stringify(this.ajaxSettings.data), '{"_method":"DELETE"}');
|
||||
Backbone.emulateHTTP = Backbone.emulateJSON = false;
|
||||
});
|
||||
|
||||
test("urlError", 2, function() {
|
||||
@@ -157,4 +164,49 @@ $(document).ready(function() {
|
||||
this.ajaxSettings.error();
|
||||
});
|
||||
|
||||
test('Use Backbone.emulateHTTP as default.', 2, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.url = '/test';
|
||||
|
||||
Backbone.emulateHTTP = true;
|
||||
model.sync('create', model);
|
||||
strictEqual(this.ajaxSettings.emulateHTTP, true);
|
||||
|
||||
Backbone.emulateHTTP = false;
|
||||
model.sync('create', model);
|
||||
strictEqual(this.ajaxSettings.emulateHTTP, false);
|
||||
});
|
||||
|
||||
test('Use Backbone.emulateJSON as default.', 2, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.url = '/test';
|
||||
|
||||
Backbone.emulateJSON = true;
|
||||
model.sync('create', model);
|
||||
strictEqual(this.ajaxSettings.emulateJSON, true);
|
||||
|
||||
Backbone.emulateJSON = false;
|
||||
model.sync('create', model);
|
||||
strictEqual(this.ajaxSettings.emulateJSON, false);
|
||||
});
|
||||
|
||||
test("#1756 - Call user provided beforeSend function.", 4, function() {
|
||||
Backbone.emulateHTTP = true;
|
||||
var model = new Backbone.Model;
|
||||
model.url = '/test';
|
||||
var xhr = {
|
||||
setRequestHeader: function(header, value) {
|
||||
strictEqual(header, 'X-HTTP-Method-Override');
|
||||
strictEqual(value, 'DELETE');
|
||||
}
|
||||
};
|
||||
model.sync('delete', model, {
|
||||
beforeSend: function(_xhr) {
|
||||
ok(_xhr === xhr);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
strictEqual(this.ajaxSettings.beforeSend(xhr), false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
9266
vendor/backbone/test/vendor/jquery-1.7.1.js
vendored
9266
vendor/backbone/test/vendor/jquery-1.7.1.js
vendored
File diff suppressed because it is too large
Load Diff
649
vendor/backbone/test/vendor/jslitmus.js
vendored
649
vendor/backbone/test/vendor/jslitmus.js
vendored
@@ -1,649 +0,0 @@
|
||||
// JSLitmus.js
|
||||
//
|
||||
// Copyright (c) 2010, Robert Kieffer, http://broofa.com
|
||||
// Available under MIT license (http://en.wikipedia.org/wiki/MIT_License)
|
||||
|
||||
(function() {
|
||||
// Private methods and state
|
||||
|
||||
// Get platform info but don't go crazy trying to recognize everything
|
||||
// that's out there. This is just for the major platforms and OSes.
|
||||
var platform = 'unknown platform', ua = navigator.userAgent;
|
||||
|
||||
// Detect OS
|
||||
var oses = ['Windows','iPhone OS','(Intel |PPC )?Mac OS X','Linux'].join('|');
|
||||
var pOS = new RegExp('((' + oses + ') [^ \);]*)').test(ua) ? RegExp.$1 : null;
|
||||
if (!pOS) pOS = new RegExp('((' + oses + ')[^ \);]*)').test(ua) ? RegExp.$1 : null;
|
||||
|
||||
// Detect browser
|
||||
var pName = /(Chrome|MSIE|Safari|Opera|Firefox)/.test(ua) ? RegExp.$1 : null;
|
||||
|
||||
// Detect version
|
||||
var vre = new RegExp('(Version|' + pName + ')[ \/]([^ ;]*)');
|
||||
var pVersion = (pName && vre.test(ua)) ? RegExp.$2 : null;
|
||||
var platform = (pOS && pName && pVersion) ? pName + ' ' + pVersion + ' on ' + pOS : 'unknown platform';
|
||||
|
||||
/**
|
||||
* A smattering of methods that are needed to implement the JSLitmus testbed.
|
||||
*/
|
||||
var jsl = {
|
||||
/**
|
||||
* Enhanced version of escape()
|
||||
*/
|
||||
escape: function(s) {
|
||||
s = s.replace(/,/g, '\\,');
|
||||
s = escape(s);
|
||||
s = s.replace(/\+/g, '%2b');
|
||||
s = s.replace(/ /g, '+');
|
||||
return s;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an element by ID.
|
||||
*/
|
||||
$: function(id) {
|
||||
return document.getElementById(id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Null function
|
||||
*/
|
||||
F: function() {},
|
||||
|
||||
/**
|
||||
* Set the status shown in the UI
|
||||
*/
|
||||
status: function(msg) {
|
||||
var el = jsl.$('jsl_status');
|
||||
if (el) el.innerHTML = msg || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert a number to an abbreviated string like, "15K" or "10M"
|
||||
*/
|
||||
toLabel: function(n) {
|
||||
if (n == Infinity) {
|
||||
return 'Infinity';
|
||||
} else if (n > 1e9) {
|
||||
n = Math.round(n/1e8);
|
||||
return n/10 + 'B';
|
||||
} else if (n > 1e6) {
|
||||
n = Math.round(n/1e5);
|
||||
return n/10 + 'M';
|
||||
} else if (n > 1e3) {
|
||||
n = Math.round(n/1e2);
|
||||
return n/10 + 'K';
|
||||
}
|
||||
return n;
|
||||
},
|
||||
|
||||
/**
|
||||
* Copy properties from src to dst
|
||||
*/
|
||||
extend: function(dst, src) {
|
||||
for (var k in src) dst[k] = src[k]; return dst;
|
||||
},
|
||||
|
||||
/**
|
||||
* Like Array.join(), but for the key-value pairs in an object
|
||||
*/
|
||||
join: function(o, delimit1, delimit2) {
|
||||
if (o.join) return o.join(delimit1); // If it's an array
|
||||
var pairs = [];
|
||||
for (var k in o) pairs.push(k + delimit1 + o[k]);
|
||||
return pairs.join(delimit2);
|
||||
},
|
||||
|
||||
/**
|
||||
* Array#indexOf isn't supported in IE, so we use this as a cross-browser solution
|
||||
*/
|
||||
indexOf: function(arr, o) {
|
||||
if (arr.indexOf) return arr.indexOf(o);
|
||||
for (var i = 0; i < this.length; i++) if (arr[i] === o) return i;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test manages a single test (created with
|
||||
* JSLitmus.test())
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var Test = function (name, f) {
|
||||
if (!f) throw new Error('Undefined test function');
|
||||
if (!/function[^\(]*\(([^,\)]*)/.test(f.toString())) {
|
||||
throw new Error('"' + name + '" test: Test is not a valid Function object');
|
||||
}
|
||||
this.loopArg = RegExp.$1;
|
||||
this.name = name;
|
||||
this.f = f;
|
||||
};
|
||||
|
||||
jsl.extend(Test, /** @lends Test */ {
|
||||
/** Calibration tests for establishing iteration loop overhead */
|
||||
CALIBRATIONS: [
|
||||
new Test('calibrating loop', function(count) {while (count--);}),
|
||||
new Test('calibrating function', jsl.F)
|
||||
],
|
||||
|
||||
/**
|
||||
* Run calibration tests. Returns true if calibrations are not yet
|
||||
* complete (in which case calling code should run the tests yet again).
|
||||
* onCalibrated - Callback to invoke when calibrations have finished
|
||||
*/
|
||||
calibrate: function(onCalibrated) {
|
||||
for (var i = 0; i < Test.CALIBRATIONS.length; i++) {
|
||||
var cal = Test.CALIBRATIONS[i];
|
||||
if (cal.running) return true;
|
||||
if (!cal.count) {
|
||||
cal.isCalibration = true;
|
||||
cal.onStop = onCalibrated;
|
||||
//cal.MIN_TIME = .1; // Do calibrations quickly
|
||||
cal.run(2e4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
jsl.extend(Test.prototype, {/** @lends Test.prototype */
|
||||
/** Initial number of iterations */
|
||||
INIT_COUNT: 10,
|
||||
/** Max iterations allowed (i.e. used to detect bad looping functions) */
|
||||
MAX_COUNT: 1e9,
|
||||
/** Minimum time a test should take to get valid results (secs) */
|
||||
MIN_TIME: .5,
|
||||
|
||||
/** Callback invoked when test state changes */
|
||||
onChange: jsl.F,
|
||||
|
||||
/** Callback invoked when test is finished */
|
||||
onStop: jsl.F,
|
||||
|
||||
/**
|
||||
* Reset test state
|
||||
*/
|
||||
reset: function() {
|
||||
delete this.count;
|
||||
delete this.time;
|
||||
delete this.running;
|
||||
delete this.error;
|
||||
},
|
||||
|
||||
/**
|
||||
* Run the test (in a timeout). We use a timeout to make sure the browser
|
||||
* has a chance to finish rendering any UI changes we've made, like
|
||||
* updating the status message.
|
||||
*/
|
||||
run: function(count) {
|
||||
count = count || this.INIT_COUNT;
|
||||
jsl.status(this.name + ' x ' + count);
|
||||
this.running = true;
|
||||
var me = this;
|
||||
setTimeout(function() {me._run(count);}, 200);
|
||||
},
|
||||
|
||||
/**
|
||||
* The nuts and bolts code that actually runs a test
|
||||
*/
|
||||
_run: function(count) {
|
||||
var me = this;
|
||||
|
||||
// Make sure calibration tests have run
|
||||
if (!me.isCalibration && Test.calibrate(function() {me.run(count);})) return;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
var start, f = this.f, now, i = count;
|
||||
|
||||
// Start the timer
|
||||
start = new Date();
|
||||
|
||||
// Now for the money shot. If this is a looping function ...
|
||||
if (this.loopArg) {
|
||||
// ... let it do the iteration itself
|
||||
f(count);
|
||||
} else {
|
||||
// ... otherwise do the iteration for it
|
||||
while (i--) f();
|
||||
}
|
||||
|
||||
// Get time test took (in secs)
|
||||
this.time = Math.max(1,new Date() - start)/1000;
|
||||
|
||||
// Store iteration count and per-operation time taken
|
||||
this.count = count;
|
||||
this.period = this.time/count;
|
||||
|
||||
// Do we need to do another run?
|
||||
this.running = this.time <= this.MIN_TIME;
|
||||
|
||||
// ... if so, compute how many times we should iterate
|
||||
if (this.running) {
|
||||
// Bump the count to the nearest power of 2
|
||||
var x = this.MIN_TIME/this.time;
|
||||
var pow = Math.pow(2, Math.max(1, Math.ceil(Math.log(x)/Math.log(2))));
|
||||
count *= pow;
|
||||
if (count > this.MAX_COUNT) {
|
||||
throw new Error('Max count exceeded. If this test uses a looping function, make sure the iteration loop is working properly.');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Exceptions are caught and displayed in the test UI
|
||||
this.reset();
|
||||
this.error = e;
|
||||
}
|
||||
|
||||
// Figure out what to do next
|
||||
if (this.running) {
|
||||
me.run(count);
|
||||
} else {
|
||||
jsl.status('');
|
||||
me.onStop(me);
|
||||
}
|
||||
|
||||
// Finish up
|
||||
this.onChange(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the number of operations per second for this test.
|
||||
*
|
||||
* @param normalize if true, iteration loop overhead taken into account
|
||||
*/
|
||||
getHz: function(/**Boolean*/ normalize) {
|
||||
var p = this.period;
|
||||
|
||||
// Adjust period based on the calibration test time
|
||||
if (normalize && !this.isCalibration) {
|
||||
var cal = Test.CALIBRATIONS[this.loopArg ? 0 : 1];
|
||||
|
||||
// If the period is within 20% of the calibration time, then zero the
|
||||
// it out
|
||||
p = p < cal.period*1.2 ? 0 : p - cal.period;
|
||||
}
|
||||
|
||||
return Math.round(1/p);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a friendly string describing the test
|
||||
*/
|
||||
toString: function() {
|
||||
return this.name + ' - ' + this.time/this.count + ' secs';
|
||||
}
|
||||
});
|
||||
|
||||
// CSS we need for the UI
|
||||
var STYLESHEET = '<style> \
|
||||
#jslitmus {font-family:sans-serif; font-size: 12px;} \
|
||||
#jslitmus a {text-decoration: none;} \
|
||||
#jslitmus a:hover {text-decoration: underline;} \
|
||||
#jsl_status { \
|
||||
margin-top: 10px; \
|
||||
font-size: 10px; \
|
||||
color: #888; \
|
||||
} \
|
||||
A IMG {border:none} \
|
||||
#test_results { \
|
||||
margin-top: 10px; \
|
||||
font-size: 12px; \
|
||||
font-family: sans-serif; \
|
||||
border-collapse: collapse; \
|
||||
border-spacing: 0px; \
|
||||
} \
|
||||
#test_results th, #test_results td { \
|
||||
border: solid 1px #ccc; \
|
||||
vertical-align: top; \
|
||||
padding: 3px; \
|
||||
} \
|
||||
#test_results th { \
|
||||
vertical-align: bottom; \
|
||||
background-color: #ccc; \
|
||||
padding: 1px; \
|
||||
font-size: 10px; \
|
||||
} \
|
||||
#test_results #test_platform { \
|
||||
color: #444; \
|
||||
text-align:center; \
|
||||
} \
|
||||
#test_results .test_row { \
|
||||
color: #006; \
|
||||
cursor: pointer; \
|
||||
} \
|
||||
#test_results .test_nonlooping { \
|
||||
border-left-style: dotted; \
|
||||
border-left-width: 2px; \
|
||||
} \
|
||||
#test_results .test_looping { \
|
||||
border-left-style: solid; \
|
||||
border-left-width: 2px; \
|
||||
} \
|
||||
#test_results .test_name {white-space: nowrap;} \
|
||||
#test_results .test_pending { \
|
||||
} \
|
||||
#test_results .test_running { \
|
||||
font-style: italic; \
|
||||
} \
|
||||
#test_results .test_done {} \
|
||||
#test_results .test_done { \
|
||||
text-align: right; \
|
||||
font-family: monospace; \
|
||||
} \
|
||||
#test_results .test_error {color: #600;} \
|
||||
#test_results .test_error .error_head {font-weight:bold;} \
|
||||
#test_results .test_error .error_body {font-size:85%;} \
|
||||
#test_results .test_row:hover td { \
|
||||
background-color: #ffc; \
|
||||
text-decoration: underline; \
|
||||
} \
|
||||
#chart { \
|
||||
margin: 10px 0px; \
|
||||
width: 250px; \
|
||||
} \
|
||||
#chart img { \
|
||||
border: solid 1px #ccc; \
|
||||
margin-bottom: 5px; \
|
||||
} \
|
||||
#chart #tiny_url { \
|
||||
height: 40px; \
|
||||
width: 250px; \
|
||||
} \
|
||||
#jslitmus_credit { \
|
||||
font-size: 10px; \
|
||||
color: #888; \
|
||||
margin-top: 8px; \
|
||||
} \
|
||||
</style>';
|
||||
|
||||
// HTML markup for the UI
|
||||
var MARKUP = '<div id="jslitmus"> \
|
||||
<button onclick="JSLitmus.runAll(event)">Run Tests</button> \
|
||||
<button id="stop_button" disabled="disabled" onclick="JSLitmus.stop()">Stop Tests</button> \
|
||||
<br \> \
|
||||
<br \> \
|
||||
<input type="checkbox" style="vertical-align: middle" id="test_normalize" checked="checked" onchange="JSLitmus.renderAll()""> Normalize results \
|
||||
<table id="test_results"> \
|
||||
<colgroup> \
|
||||
<col /> \
|
||||
<col width="100" /> \
|
||||
</colgroup> \
|
||||
<tr><th id="test_platform" colspan="2">' + platform + '</th></tr> \
|
||||
<tr><th>Test</th><th>Ops/sec</th></tr> \
|
||||
<tr id="test_row_template" class="test_row" style="display:none"> \
|
||||
<td class="test_name"></td> \
|
||||
<td class="test_result">Ready</td> \
|
||||
</tr> \
|
||||
</table> \
|
||||
<div id="jsl_status"></div> \
|
||||
<div id="chart" style="display:none"> \
|
||||
<a id="chart_link" target="_blank"><img id="chart_image"></a> \
|
||||
TinyURL (for chart): \
|
||||
<iframe id="tiny_url" frameBorder="0" scrolling="no" src=""></iframe> \
|
||||
</div> \
|
||||
<a id="jslitmus_credit" title="JSLitmus home page" href="http://code.google.com/p/jslitmus" target="_blank">Powered by JSLitmus</a> \
|
||||
</div>';
|
||||
|
||||
/**
|
||||
* The public API for creating and running tests
|
||||
*/
|
||||
window.JSLitmus = {
|
||||
/** The list of all tests that have been registered with JSLitmus.test */
|
||||
_tests: [],
|
||||
/** The queue of tests that need to be run */
|
||||
_queue: [],
|
||||
|
||||
/**
|
||||
* The parsed query parameters the current page URL. This is provided as a
|
||||
* convenience for test functions - it's not used by JSLitmus proper
|
||||
*/
|
||||
params: {},
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
_init: function() {
|
||||
// Parse query params into JSLitmus.params[] hash
|
||||
var match = (location + '').match(/([^?#]*)(#.*)?$/);
|
||||
if (match) {
|
||||
var pairs = match[1].split('&');
|
||||
for (var i = 0; i < pairs.length; i++) {
|
||||
var pair = pairs[i].split('=');
|
||||
if (pair.length > 1) {
|
||||
var key = pair.shift();
|
||||
var value = pair.length > 1 ? pair.join('=') : pair[0];
|
||||
this.params[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the stylesheet. We have to do this here because IE
|
||||
// doesn't honor sheets written after the document has loaded.
|
||||
document.write(STYLESHEET);
|
||||
|
||||
// Setup the rest of the UI once the document is loaded
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('load', this._setup, false);
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('load', this._setup, false);
|
||||
} else if (window.attachEvent) {
|
||||
window.attachEvent('onload', this._setup);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the UI
|
||||
*/
|
||||
_setup: function() {
|
||||
var el = jsl.$('jslitmus_container');
|
||||
if (!el) document.body.appendChild(el = document.createElement('div'));
|
||||
|
||||
el.innerHTML = MARKUP;
|
||||
|
||||
// Render the UI for all our tests
|
||||
for (var i=0; i < JSLitmus._tests.length; i++)
|
||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render all the test results
|
||||
*/
|
||||
renderAll: function() {
|
||||
for (var i = 0; i < JSLitmus._tests.length; i++)
|
||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
||||
JSLitmus.renderChart();
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render the chart graphics
|
||||
*/
|
||||
renderChart: function() {
|
||||
var url = JSLitmus.chartUrl();
|
||||
jsl.$('chart_link').href = url;
|
||||
jsl.$('chart_image').src = url;
|
||||
jsl.$('chart').style.display = '';
|
||||
|
||||
// Update the tiny URL
|
||||
jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url);
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render the results for a specific test
|
||||
*/
|
||||
renderTest: function(test) {
|
||||
// Make a new row if needed
|
||||
if (!test._row) {
|
||||
var trow = jsl.$('test_row_template');
|
||||
if (!trow) return;
|
||||
|
||||
test._row = trow.cloneNode(true);
|
||||
test._row.style.display = '';
|
||||
test._row.id = '';
|
||||
test._row.onclick = function() {JSLitmus._queueTest(test);};
|
||||
test._row.title = 'Run ' + test.name + ' test';
|
||||
trow.parentNode.appendChild(test._row);
|
||||
test._row.cells[0].innerHTML = test.name;
|
||||
}
|
||||
|
||||
var cell = test._row.cells[1];
|
||||
var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping'];
|
||||
|
||||
if (test.error) {
|
||||
cns.push('test_error');
|
||||
cell.innerHTML =
|
||||
'<div class="error_head">' + test.error + '</div>' +
|
||||
'<ul class="error_body"><li>' +
|
||||
jsl.join(test.error, ': ', '</li><li>') +
|
||||
'</li></ul>';
|
||||
} else {
|
||||
if (test.running) {
|
||||
cns.push('test_running');
|
||||
cell.innerHTML = 'running';
|
||||
} else if (jsl.indexOf(JSLitmus._queue, test) >= 0) {
|
||||
cns.push('test_pending');
|
||||
cell.innerHTML = 'pending';
|
||||
} else if (test.count) {
|
||||
cns.push('test_done');
|
||||
var hz = test.getHz(jsl.$('test_normalize').checked);
|
||||
cell.innerHTML = hz != Infinity ? hz : '∞';
|
||||
cell.title = 'Looped ' + test.count + ' times in ' + test.time + ' seconds';
|
||||
} else {
|
||||
cell.innerHTML = 'ready';
|
||||
}
|
||||
}
|
||||
cell.className = cns.join(' ');
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new test
|
||||
*/
|
||||
test: function(name, f) {
|
||||
// Create the Test object
|
||||
var test = new Test(name, f);
|
||||
JSLitmus._tests.push(test);
|
||||
|
||||
// Re-render if the test state changes
|
||||
test.onChange = JSLitmus.renderTest;
|
||||
|
||||
// Run the next test if this one finished
|
||||
test.onStop = function(test) {
|
||||
if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test);
|
||||
JSLitmus.currentTest = null;
|
||||
JSLitmus._nextTest();
|
||||
};
|
||||
|
||||
// Render the new test
|
||||
this.renderTest(test);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add all tests to the run queue
|
||||
*/
|
||||
runAll: function(e) {
|
||||
e = e || window.event;
|
||||
var reverse = e && e.shiftKey, len = JSLitmus._tests.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all tests from the run queue. The current test has to finish on
|
||||
* it's own though
|
||||
*/
|
||||
stop: function() {
|
||||
while (JSLitmus._queue.length) {
|
||||
var test = JSLitmus._queue.shift();
|
||||
JSLitmus.renderTest(test);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Run the next test in the run queue
|
||||
*/
|
||||
_nextTest: function() {
|
||||
if (!JSLitmus.currentTest) {
|
||||
var test = JSLitmus._queue.shift();
|
||||
if (test) {
|
||||
jsl.$('stop_button').disabled = false;
|
||||
JSLitmus.currentTest = test;
|
||||
test.run();
|
||||
JSLitmus.renderTest(test);
|
||||
if (JSLitmus.onTestStart) JSLitmus.onTestStart(test);
|
||||
} else {
|
||||
jsl.$('stop_button').disabled = true;
|
||||
JSLitmus.renderChart();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a test to the run queue
|
||||
*/
|
||||
_queueTest: function(test) {
|
||||
if (jsl.indexOf(JSLitmus._queue, test) >= 0) return;
|
||||
JSLitmus._queue.push(test);
|
||||
JSLitmus.renderTest(test);
|
||||
JSLitmus._nextTest();
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate a Google Chart URL that shows the data for all tests
|
||||
*/
|
||||
chartUrl: function() {
|
||||
var n = JSLitmus._tests.length, markers = [], data = [];
|
||||
var d, min = 0, max = -1e10;
|
||||
var normalize = jsl.$('test_normalize').checked;
|
||||
|
||||
// Gather test data
|
||||
for (var i=0; i < JSLitmus._tests.length; i++) {
|
||||
var test = JSLitmus._tests[i];
|
||||
if (test.count) {
|
||||
var hz = test.getHz(normalize);
|
||||
var v = hz != Infinity ? hz : 0;
|
||||
data.push(v);
|
||||
markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' +
|
||||
markers.length + ',10');
|
||||
max = Math.max(v, max);
|
||||
}
|
||||
}
|
||||
if (markers.length <= 0) return null;
|
||||
|
||||
// Build chart title
|
||||
var title = document.getElementsByTagName('title');
|
||||
title = (title && title.length) ? title[0].innerHTML : null;
|
||||
var chart_title = [];
|
||||
if (title) chart_title.push(title);
|
||||
chart_title.push('Ops/sec (' + platform + ')');
|
||||
|
||||
// Build labels
|
||||
var labels = [jsl.toLabel(min), jsl.toLabel(max)];
|
||||
|
||||
var w = 250, bw = 15;
|
||||
var bs = 5;
|
||||
var h = markers.length*(bw + bs) + 30 + chart_title.length*20;
|
||||
|
||||
var params = {
|
||||
chtt: escape(chart_title.join('|')),
|
||||
chts: '000000,10',
|
||||
cht: 'bhg', // chart type
|
||||
chd: 't:' + data.join(','), // data set
|
||||
chds: min + ',' + max, // max/min of data
|
||||
chxt: 'x', // label axes
|
||||
chxl: '0:|' + labels.join('|'), // labels
|
||||
chsp: '0,1',
|
||||
chm: markers.join('|'), // test names
|
||||
chbh: [bw, 0, bs].join(','), // bar widths
|
||||
// chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient
|
||||
chs: w + 'x' + h
|
||||
};
|
||||
return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&');
|
||||
}
|
||||
};
|
||||
|
||||
JSLitmus._init();
|
||||
})();
|
||||
481
vendor/backbone/test/vendor/json2.js
vendored
481
vendor/backbone/test/vendor/json2.js
vendored
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
http://www.JSON.org/json2.js
|
||||
2009-09-29
|
||||
|
||||
Public Domain.
|
||||
|
||||
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
See http://www.JSON.org/js.html
|
||||
|
||||
|
||||
This code should be minified before deployment.
|
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
|
||||
|
||||
This file creates a global JSON object containing two methods: stringify
|
||||
and parse.
|
||||
|
||||
JSON.stringify(value, replacer, space)
|
||||
value any JavaScript value, usually an object or array.
|
||||
|
||||
replacer an optional parameter that determines how object
|
||||
values are stringified for objects. It can be a
|
||||
function or an array of strings.
|
||||
|
||||
space an optional parameter that specifies the indentation
|
||||
of nested structures. If it is omitted, the text will
|
||||
be packed without extra whitespace. If it is a number,
|
||||
it will specify the number of spaces to indent at each
|
||||
level. If it is a string (such as '\t' or ' '),
|
||||
it contains the characters used to indent at each level.
|
||||
|
||||
This method produces a JSON text from a JavaScript value.
|
||||
|
||||
When an object value is found, if the object contains a toJSON
|
||||
method, its toJSON method will be called and the result will be
|
||||
stringified. A toJSON method does not serialize: it returns the
|
||||
value represented by the name/value pair that should be serialized,
|
||||
or undefined if nothing should be serialized. The toJSON method
|
||||
will be passed the key associated with the value, and this will be
|
||||
bound to the value
|
||||
|
||||
For example, this would serialize Dates as ISO strings.
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
return this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z';
|
||||
};
|
||||
|
||||
You can provide an optional replacer method. It will be passed the
|
||||
key and value of each member, with this bound to the containing
|
||||
object. The value that is returned from your method will be
|
||||
serialized. If your method returns undefined, then the member will
|
||||
be excluded from the serialization.
|
||||
|
||||
If the replacer parameter is an array of strings, then it will be
|
||||
used to select the members to be serialized. It filters the results
|
||||
such that only members with keys listed in the replacer array are
|
||||
stringified.
|
||||
|
||||
Values that do not have JSON representations, such as undefined or
|
||||
functions, will not be serialized. Such values in objects will be
|
||||
dropped; in arrays they will be replaced with null. You can use
|
||||
a replacer function to replace those with JSON values.
|
||||
JSON.stringify(undefined) returns undefined.
|
||||
|
||||
The optional space parameter produces a stringification of the
|
||||
value that is filled with line breaks and indentation to make it
|
||||
easier to read.
|
||||
|
||||
If the space parameter is a non-empty string, then that string will
|
||||
be used for indentation. If the space parameter is a number, then
|
||||
the indentation will be that many spaces.
|
||||
|
||||
Example:
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||||
// text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
|
||||
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
text = JSON.stringify([new Date()], function (key, value) {
|
||||
return this[key] instanceof Date ?
|
||||
'Date(' + this[key] + ')' : value;
|
||||
});
|
||||
// text is '["Date(---current time---)"]'
|
||||
|
||||
|
||||
JSON.parse(text, reviver)
|
||||
This method parses a JSON text to produce an object or array.
|
||||
It can throw a SyntaxError exception.
|
||||
|
||||
The optional reviver parameter is a function that can filter and
|
||||
transform the results. It receives each of the keys and values,
|
||||
and its return value is used instead of the original value.
|
||||
If it returns what it received, then the structure is not modified.
|
||||
If it returns undefined then the member is deleted.
|
||||
|
||||
Example:
|
||||
|
||||
// Parse the text. Values that look like ISO date strings will
|
||||
// be converted to Date objects.
|
||||
|
||||
myData = JSON.parse(text, function (key, value) {
|
||||
var a;
|
||||
if (typeof value === 'string') {
|
||||
a =
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||
if (a) {
|
||||
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||||
+a[5], +a[6]));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||||
var d;
|
||||
if (typeof value === 'string' &&
|
||||
value.slice(0, 5) === 'Date(' &&
|
||||
value.slice(-1) === ')') {
|
||||
d = new Date(value.slice(5, -1));
|
||||
if (d) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or
|
||||
redistribute.
|
||||
*/
|
||||
|
||||
/*jslint evil: true, strict: false */
|
||||
|
||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
|
||||
if (!this.JSON) {
|
||||
this.JSON = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') {
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
|
||||
return isFinite(this.valueOf()) ?
|
||||
this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z' : null;
|
||||
};
|
||||
|
||||
String.prototype.toJSON =
|
||||
Number.prototype.toJSON =
|
||||
Boolean.prototype.toJSON = function (key) {
|
||||
return this.valueOf();
|
||||
};
|
||||
}
|
||||
|
||||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
gap,
|
||||
indent,
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"' : '\\"',
|
||||
'\\': '\\\\'
|
||||
},
|
||||
rep;
|
||||
|
||||
|
||||
function quote(string) {
|
||||
|
||||
// If the string contains no control characters, no quote characters, and no
|
||||
// backslash characters, then we can safely slap some quotes around it.
|
||||
// Otherwise we must also replace the offending characters with safe escape
|
||||
// sequences.
|
||||
|
||||
escapable.lastIndex = 0;
|
||||
return escapable.test(string) ?
|
||||
'"' + string.replace(escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === 'string' ? c :
|
||||
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + '"' :
|
||||
'"' + string + '"';
|
||||
}
|
||||
|
||||
|
||||
function str(key, holder) {
|
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i, // The loop counter.
|
||||
k, // The member key.
|
||||
v, // The member value.
|
||||
length,
|
||||
mind = gap,
|
||||
partial,
|
||||
value = holder[key];
|
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
|
||||
if (value && typeof value === 'object' &&
|
||||
typeof value.toJSON === 'function') {
|
||||
value = value.toJSON(key);
|
||||
}
|
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === 'function') {
|
||||
value = rep.call(holder, key, value);
|
||||
}
|
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return quote(value);
|
||||
|
||||
case 'number':
|
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return isFinite(value) ? String(value) : 'null';
|
||||
|
||||
case 'boolean':
|
||||
case 'null':
|
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce 'null'. The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value);
|
||||
|
||||
// If the type is 'object', we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case 'object':
|
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent;
|
||||
partial = [];
|
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value) || 'null';
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0 ? '[]' :
|
||||
gap ? '[\n' + gap +
|
||||
partial.join(',\n' + gap) + '\n' +
|
||||
mind + ']' :
|
||||
'[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
k = rep[i];
|
||||
if (typeof k === 'string') {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0 ? '{}' :
|
||||
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
|
||||
mind + '}' : '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') {
|
||||
JSON.stringify = function (value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i;
|
||||
gap = '';
|
||||
indent = '';
|
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === 'number') {
|
||||
for (i = 0; i < space; i += 1) {
|
||||
indent += ' ';
|
||||
}
|
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === 'string') {
|
||||
indent = space;
|
||||
}
|
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' &&
|
||||
(typeof replacer !== 'object' ||
|
||||
typeof replacer.length !== 'number')) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
// Make a fake root object containing our value under the key of ''.
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str('', {'': value});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') {
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
// a JavaScript value if the text is a valid JSON text.
|
||||
|
||||
var j;
|
||||
|
||||
function walk(holder, key) {
|
||||
|
||||
// The walk method is used to recursively walk the resulting structure so
|
||||
// that modifications can be made.
|
||||
|
||||
var k, v, value = holder[key];
|
||||
if (value && typeof value === 'object') {
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
} else {
|
||||
delete value[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return reviver.call(holder, key, value);
|
||||
}
|
||||
|
||||
|
||||
// Parsing happens in four stages. In the first stage, we replace certain
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
cx.lastIndex = 0;
|
||||
if (cx.test(text)) {
|
||||
text = text.replace(cx, function (a) {
|
||||
return '\\u' +
|
||||
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
});
|
||||
}
|
||||
|
||||
// In the second stage, we run the text against regular expressions that look
|
||||
// for non-JSON patterns. We are especially concerned with '()' and 'new'
|
||||
// because they can cause invocation, and '=' because it can cause mutation.
|
||||
// But just to be safe, we want to reject all unexpected forms.
|
||||
|
||||
// We split the second stage into 4 regexp operations in order to work around
|
||||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
|
||||
// replace all simple value tokens with ']' characters. Third, we delete all
|
||||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||
// we look to see that the remaining characters are only whitespace or ']' or
|
||||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||
|
||||
if (/^[\],:{}\s]*$/.
|
||||
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
|
||||
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
|
||||
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||
// in parens to eliminate the ambiguity.
|
||||
|
||||
j = eval('(' + text + ')');
|
||||
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return typeof reviver === 'function' ?
|
||||
walk({'': j}, '') : j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
throw new SyntaxError('JSON.parse');
|
||||
};
|
||||
}
|
||||
}());
|
||||
235
vendor/backbone/test/vendor/qunit.css
vendored
235
vendor/backbone/test/vendor/qunit.css
vendored
@@ -1,235 +0,0 @@
|
||||
/**
|
||||
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://qunitjs.com
|
||||
*
|
||||
* Copyright 2012 jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*/
|
||||
|
||||
/** Font Family and Sizes */
|
||||
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
||||
#qunit-tests { font-size: smaller; }
|
||||
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/** Header */
|
||||
|
||||
#qunit-header {
|
||||
padding: 0.5em 0 0.5em 1em;
|
||||
|
||||
color: #8699a4;
|
||||
background-color: #0d3349;
|
||||
|
||||
font-size: 1.5em;
|
||||
line-height: 1em;
|
||||
font-weight: normal;
|
||||
|
||||
border-radius: 5px 5px 0 0;
|
||||
-moz-border-radius: 5px 5px 0 0;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
-webkit-border-top-left-radius: 5px;
|
||||
}
|
||||
|
||||
#qunit-header a {
|
||||
text-decoration: none;
|
||||
color: #c2ccd1;
|
||||
}
|
||||
|
||||
#qunit-header a:hover,
|
||||
#qunit-header a:focus {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar label {
|
||||
display: inline-block;
|
||||
padding: 0 .5em 0 .1em;
|
||||
}
|
||||
|
||||
#qunit-banner {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar {
|
||||
padding: 0.5em 0 0.5em 2em;
|
||||
color: #5E740B;
|
||||
background-color: #eee;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#qunit-userAgent {
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
background-color: #2b81af;
|
||||
color: #fff;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
|
||||
#qunit-modulefilter-container {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/** Tests: Pass/Fail */
|
||||
|
||||
#qunit-tests {
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests li {
|
||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
||||
border-bottom: 1px solid #fff;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests li strong {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#qunit-tests li a {
|
||||
padding: 0.5em;
|
||||
color: #c2ccd1;
|
||||
text-decoration: none;
|
||||
}
|
||||
#qunit-tests li a:hover,
|
||||
#qunit-tests li a:focus {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qunit-tests ol {
|
||||
margin-top: 0.5em;
|
||||
padding: 0.5em;
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
}
|
||||
|
||||
#qunit-tests table {
|
||||
border-collapse: collapse;
|
||||
margin-top: .2em;
|
||||
}
|
||||
|
||||
#qunit-tests th {
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
padding: 0 .5em 0 0;
|
||||
}
|
||||
|
||||
#qunit-tests td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#qunit-tests pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#qunit-tests del {
|
||||
background-color: #e0f2be;
|
||||
color: #374e0c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#qunit-tests ins {
|
||||
background-color: #ffcaca;
|
||||
color: #500;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*** Test Counts */
|
||||
|
||||
#qunit-tests b.counts { color: black; }
|
||||
#qunit-tests b.passed { color: #5E740B; }
|
||||
#qunit-tests b.failed { color: #710909; }
|
||||
|
||||
#qunit-tests li li {
|
||||
padding: 5px;
|
||||
background-color: #fff;
|
||||
border-bottom: none;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
/*** Passing Styles */
|
||||
|
||||
#qunit-tests li li.pass {
|
||||
color: #3c510c;
|
||||
background-color: #fff;
|
||||
border-left: 10px solid #C6E746;
|
||||
}
|
||||
|
||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
||||
#qunit-tests .pass .test-name { color: #366097; }
|
||||
|
||||
#qunit-tests .pass .test-actual,
|
||||
#qunit-tests .pass .test-expected { color: #999999; }
|
||||
|
||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
||||
|
||||
/*** Failing Styles */
|
||||
|
||||
#qunit-tests li li.fail {
|
||||
color: #710909;
|
||||
background-color: #fff;
|
||||
border-left: 10px solid #EE5757;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#qunit-tests > li:last-child {
|
||||
border-radius: 0 0 5px 5px;
|
||||
-moz-border-radius: 0 0 5px 5px;
|
||||
-webkit-border-bottom-right-radius: 5px;
|
||||
-webkit-border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
||||
#qunit-tests .fail .test-name,
|
||||
#qunit-tests .fail .module-name { color: #000000; }
|
||||
|
||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
||||
#qunit-tests .fail .test-expected { color: green; }
|
||||
|
||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
||||
|
||||
|
||||
/** Result */
|
||||
|
||||
#qunit-testresult {
|
||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
||||
|
||||
color: #2b81af;
|
||||
background-color: #D2E0E6;
|
||||
|
||||
border-bottom: 1px solid white;
|
||||
}
|
||||
#qunit-testresult .module-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/** Fixture */
|
||||
|
||||
#qunit-fixture {
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
left: -10000px;
|
||||
width: 1000px;
|
||||
height: 1000px;
|
||||
}
|
||||
1977
vendor/backbone/test/vendor/qunit.js
vendored
1977
vendor/backbone/test/vendor/qunit.js
vendored
File diff suppressed because it is too large
Load Diff
55
vendor/backbone/test/view.js
vendored
55
vendor/backbone/test/view.js
vendored
@@ -7,17 +7,20 @@ $(document).ready(function() {
|
||||
setup: function() {
|
||||
view = new Backbone.View({
|
||||
id : 'test-view',
|
||||
className : 'test-view'
|
||||
className : 'test-view',
|
||||
other : 'non-special-option'
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
test("constructor", 4, function() {
|
||||
test("constructor", 6, function() {
|
||||
equal(view.el.id, 'test-view');
|
||||
equal(view.el.className, 'test-view');
|
||||
equal(view.el.other, void 0);
|
||||
equal(view.options.id, 'test-view');
|
||||
equal(view.options.className, 'test-view');
|
||||
equal(view.options.other, 'non-special-option');
|
||||
});
|
||||
|
||||
test("jQuery", 1, function() {
|
||||
@@ -162,6 +165,30 @@ $(document).ready(function() {
|
||||
strictEqual(new View().el.id, 'id');
|
||||
});
|
||||
|
||||
test("with options function", 3, function() {
|
||||
var View1 = Backbone.View.extend({
|
||||
options: function() {
|
||||
return {
|
||||
title: 'title1',
|
||||
acceptText: 'confirm'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var View2 = View1.extend({
|
||||
options: function() {
|
||||
return _.extend(View1.prototype.options.call(this), {
|
||||
title: 'title2',
|
||||
fixed: true
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
strictEqual(new View2().options.title, 'title2');
|
||||
strictEqual(new View2().options.acceptText, 'confirm');
|
||||
strictEqual(new View2().options.fixed, true);
|
||||
});
|
||||
|
||||
test("with attributes", 2, function() {
|
||||
var View = Backbone.View.extend({
|
||||
attributes: {
|
||||
@@ -328,4 +355,28 @@ $(document).ready(function() {
|
||||
ok(view.$el.is('p:has(a)'));
|
||||
});
|
||||
|
||||
test("events passed in options", 2, function() {
|
||||
var counter = 0;
|
||||
|
||||
var View = Backbone.View.extend({
|
||||
el: '<p><a id="test"></a></p>',
|
||||
increment: function() {
|
||||
counter++;
|
||||
}
|
||||
});
|
||||
|
||||
var view = new View({events:{'click #test':'increment'}});
|
||||
var view2 = new View({events:function(){
|
||||
return {'click #test':'increment'};
|
||||
}});
|
||||
|
||||
view.$('#test').trigger('click');
|
||||
view2.$('#test').trigger('click');
|
||||
equal(counter, 2);
|
||||
|
||||
view.$('#test').trigger('click');
|
||||
view2.$('#test').trigger('click');
|
||||
equal(counter, 4);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
41
vendor/benchmark.js/benchmark.js
vendored
41
vendor/benchmark.js/benchmark.js
vendored
@@ -320,6 +320,7 @@
|
||||
/** Math shortcuts */
|
||||
var abs = Math.abs,
|
||||
floor = Math.floor,
|
||||
log = Math.log,
|
||||
max = Math.max,
|
||||
min = Math.min,
|
||||
pow = Math.pow,
|
||||
@@ -945,6 +946,20 @@
|
||||
(/^[\s(]*function[^(]*\(([^\s,)]+)/.exec(fn) || 0)[1]) || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the geometric mean (log-average) of a sample.
|
||||
* See http://en.wikipedia.org/wiki/Geometric_mean#Relationship_with_arithmetic_mean_of_logarithms.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} sample The sample.
|
||||
* @returns {Number} The geometric mean.
|
||||
*/
|
||||
function getGeometricMean(sample) {
|
||||
return pow(Math.E, reduce(sample, function(sum, x) {
|
||||
return sum + log(x);
|
||||
}) / sample.length) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the arithmetic mean of a sample.
|
||||
*
|
||||
@@ -953,9 +968,9 @@
|
||||
* @returns {Number} The mean.
|
||||
*/
|
||||
function getMean(sample) {
|
||||
return reduce(sample, function(sum, x) {
|
||||
return (reduce(sample, function(sum, x) {
|
||||
return sum + x;
|
||||
}) / sample.length || 0;
|
||||
}) / sample.length) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2076,6 +2091,10 @@
|
||||
event.aborted = me.aborted;
|
||||
},
|
||||
'onComplete': function(event) {
|
||||
me.score = getGeometricMean(map(me, function(bench) {
|
||||
return bench.reference / (bench.times.period * 1e6);
|
||||
})) || 0;
|
||||
|
||||
me.running = false;
|
||||
me.emit(event);
|
||||
}
|
||||
@@ -3169,7 +3188,15 @@
|
||||
* @memberOf Benchmark.options
|
||||
* @type Function
|
||||
*/
|
||||
'onStart': undefined
|
||||
'onStart': undefined,
|
||||
|
||||
/**
|
||||
* The reference time taken to execute the test once (usecs).
|
||||
*
|
||||
* @memberOf Benchmark.options
|
||||
* @type Number
|
||||
*/
|
||||
'reference': 0
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -3726,6 +3753,14 @@
|
||||
*/
|
||||
'length': 0,
|
||||
|
||||
/**
|
||||
* A score computed using the normalized result of each benchmark in the suite.
|
||||
*
|
||||
* @memberOf Benchmark.Suite
|
||||
* @type Number
|
||||
*/
|
||||
'score': 0,
|
||||
|
||||
/**
|
||||
* A flag to indicate if the suite is aborted.
|
||||
*
|
||||
|
||||
1049
vendor/firebug-lite/changelog.txt
vendored
1049
vendor/firebug-lite/changelog.txt
vendored
File diff suppressed because it is too large
Load Diff
662
vendor/firebug-lite/skin/xp/debugger.css
vendored
662
vendor/firebug-lite/skin/xp/debugger.css
vendored
@@ -1,331 +1,331 @@
|
||||
/* See license.txt for terms of usage */
|
||||
|
||||
.panelNode-script {
|
||||
overflow: hidden;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.scriptTooltip {
|
||||
position: fixed;
|
||||
z-index: 2147483647;
|
||||
padding: 2px 3px;
|
||||
border: 1px solid #CBE087;
|
||||
background: LightYellow;
|
||||
font-family: monospace;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.sourceBox {
|
||||
/* TODO: xxxpedro problem with sourceBox and scrolling elements */
|
||||
/*overflow: scroll; /* see issue 1479 */
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sourceRow {
|
||||
white-space: nowrap;
|
||||
-moz-user-select: text;
|
||||
}
|
||||
|
||||
.sourceRow.hovered {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.sourceLine {
|
||||
-moz-user-select: none;
|
||||
margin-right: 10px;
|
||||
border-right: 1px solid #CCCCCC;
|
||||
padding: 0px 4px 0 20px;
|
||||
background: #EEEEEE no-repeat 2px 0px;
|
||||
color: #888888;
|
||||
white-space: pre;
|
||||
font-family: monospace; /* see issue 2953 */
|
||||
}
|
||||
|
||||
.noteInToolTip { /* below sourceLine, so it overrides it */
|
||||
background-color: #FFD472;
|
||||
}
|
||||
|
||||
.useA11y .sourceBox .sourceViewport:focus .sourceLine {
|
||||
background-color: #FFFFC0;
|
||||
color: navy;
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
|
||||
.useA11y .sourceBox .sourceViewport:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.a11y1emSize {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.useA11y .panelStatusLabel:focus {
|
||||
outline-offset: -2px !important;
|
||||
}
|
||||
|
||||
.sourceBox > .sourceRow > .sourceLine {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sourceLine:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sourceRowText {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.sourceRow[exe_line="true"] {
|
||||
outline: 1px solid #D9D9B6;
|
||||
margin-right: 1px;
|
||||
background-color: lightgoldenrodyellow;
|
||||
}
|
||||
|
||||
.sourceRow[executable="true"] > .sourceLine {
|
||||
content: "-";
|
||||
color: #4AA02C; /* Spring Green */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sourceRow[exe_line="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/exe.png);
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpoint.png);
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"][condition="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpointCondition.png);
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"][disabledBreakpoint="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpointDisabled.png);
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"][exe_line="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpointExe.png);
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"][exe_line="true"][disabledBreakpoint="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpointDisabledExe.png);
|
||||
}
|
||||
|
||||
.sourceLine.editing {
|
||||
background-image: url(chrome://firebug/skin/breakpoint.png);
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.conditionEditor {
|
||||
z-index: 2147483647;
|
||||
position: absolute;
|
||||
margin-top: 0;
|
||||
left: 2px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.conditionEditorInner {
|
||||
position: relative;
|
||||
top: -26px;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.conditionCaption {
|
||||
margin-bottom: 2px;
|
||||
font-family: Lucida Grande, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
color: #226679;
|
||||
}
|
||||
|
||||
.conditionInput {
|
||||
width: 100%;
|
||||
border: 1px solid #0096C0;
|
||||
font-family: monospace;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.conditionEditorInner1 {
|
||||
padding-left: 37px;
|
||||
background: url(condBorders.png) repeat-y;
|
||||
}
|
||||
|
||||
.conditionEditorInner2 {
|
||||
padding-right: 25px;
|
||||
background: url(condBorders.png) repeat-y 100% 0;
|
||||
}
|
||||
|
||||
.conditionEditorTop1 {
|
||||
background: url(condCorners.png) no-repeat 100% 0;
|
||||
margin-left: 37px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.conditionEditorTop2 {
|
||||
position: relative;
|
||||
left: -37px;
|
||||
width: 37px;
|
||||
height: 35px;
|
||||
background: url(condCorners.png) no-repeat;
|
||||
}
|
||||
|
||||
.conditionEditorBottom1 {
|
||||
background: url(condCorners.png) no-repeat 100% 100%;
|
||||
margin-left: 37px;
|
||||
height: 33px;
|
||||
}
|
||||
|
||||
.conditionEditorBottom2 {
|
||||
position: relative; left: -37px;
|
||||
width: 37px;
|
||||
height: 33px;
|
||||
background: url(condCorners.png) no-repeat 0 100%;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.upsideDown {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorInner {
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorInner1 {
|
||||
padding-left: 33px;
|
||||
background: url(condBordersUps.png) repeat-y;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorInner2 {
|
||||
padding-right: 25px;
|
||||
background: url(condBordersUps.png) repeat-y 100% 0;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorTop1 {
|
||||
background: url(condCornersUps.png) no-repeat 100% 0;
|
||||
margin-left: 33px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorTop2 {
|
||||
position: relative;
|
||||
left: -33px;
|
||||
width: 33px;
|
||||
height: 25px;
|
||||
background: url(condCornersUps.png) no-repeat;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorBottom1 {
|
||||
background: url(condCornersUps.png) no-repeat 100% 100%;
|
||||
margin-left: 33px;
|
||||
height: 43px;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorBottom2 {
|
||||
position: relative;
|
||||
left: -33px;
|
||||
width: 33px;
|
||||
height: 43px;
|
||||
background: url(condCornersUps.png) no-repeat 0 100%;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.breakpointsGroupListBox {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.breakpointBlockHead {
|
||||
position: relative;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.breakpointBlockHead > .checkbox {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.breakpointBlockHead > .objectLink-sourceLink {
|
||||
top: 4px;
|
||||
right: 20px;
|
||||
background-color: #FFFFFF; /* issue 3308 */
|
||||
}
|
||||
|
||||
.breakpointBlockHead > .closeButton {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
.breakpointCheckbox {
|
||||
margin-top: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.breakpointName {
|
||||
margin-left: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.breakpointRow[aria-checked="false"] > .breakpointBlockHead > *,
|
||||
.breakpointRow[aria-checked="false"] > .breakpointCode {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.breakpointRow[aria-checked="false"] .breakpointCheckbox,
|
||||
.breakpointRow[aria-checked="false"] .objectLink-sourceLink,
|
||||
.breakpointRow[aria-checked="false"] .closeButton,
|
||||
.breakpointRow[aria-checked="false"] .breakpointMutationType {
|
||||
opacity: 1.0 !important;
|
||||
}
|
||||
|
||||
.breakpointCode {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
padding-left: 24px;
|
||||
padding-bottom: 2px;
|
||||
border-bottom: 1px solid #D7D7D7;
|
||||
font-family: monospace;
|
||||
color: DarkGreen;
|
||||
}
|
||||
|
||||
.breakpointCondition {
|
||||
white-space: nowrap;
|
||||
padding-left: 24px;
|
||||
padding-bottom: 2px;
|
||||
border-bottom: 1px solid #D7D7D7;
|
||||
font-family: monospace;
|
||||
color: Gray;
|
||||
}
|
||||
|
||||
.breakpointBlock-breakpoints > .groupHeader {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.breakpointBlock-monitors > .breakpointCode {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.breakpointBlock-errorBreakpoints .breakpointCheckbox,
|
||||
.breakpointBlock-monitors .breakpointCheckbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.breakpointHeader {
|
||||
margin: 0 !important;
|
||||
border-top: none !important;
|
||||
}
|
||||
/* See license.txt for terms of usage */
|
||||
|
||||
.panelNode-script {
|
||||
overflow: hidden;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.scriptTooltip {
|
||||
position: fixed;
|
||||
z-index: 2147483647;
|
||||
padding: 2px 3px;
|
||||
border: 1px solid #CBE087;
|
||||
background: LightYellow;
|
||||
font-family: monospace;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.sourceBox {
|
||||
/* TODO: xxxpedro problem with sourceBox and scrolling elements */
|
||||
/*overflow: scroll; /* see issue 1479 */
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sourceRow {
|
||||
white-space: nowrap;
|
||||
-moz-user-select: text;
|
||||
}
|
||||
|
||||
.sourceRow.hovered {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.sourceLine {
|
||||
-moz-user-select: none;
|
||||
margin-right: 10px;
|
||||
border-right: 1px solid #CCCCCC;
|
||||
padding: 0px 4px 0 20px;
|
||||
background: #EEEEEE no-repeat 2px 0px;
|
||||
color: #888888;
|
||||
white-space: pre;
|
||||
font-family: monospace; /* see issue 2953 */
|
||||
}
|
||||
|
||||
.noteInToolTip { /* below sourceLine, so it overrides it */
|
||||
background-color: #FFD472;
|
||||
}
|
||||
|
||||
.useA11y .sourceBox .sourceViewport:focus .sourceLine {
|
||||
background-color: #FFFFC0;
|
||||
color: navy;
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
|
||||
.useA11y .sourceBox .sourceViewport:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.a11y1emSize {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.useA11y .panelStatusLabel:focus {
|
||||
outline-offset: -2px !important;
|
||||
}
|
||||
|
||||
.sourceBox > .sourceRow > .sourceLine {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sourceLine:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sourceRowText {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.sourceRow[exe_line="true"] {
|
||||
outline: 1px solid #D9D9B6;
|
||||
margin-right: 1px;
|
||||
background-color: lightgoldenrodyellow;
|
||||
}
|
||||
|
||||
.sourceRow[executable="true"] > .sourceLine {
|
||||
content: "-";
|
||||
color: #4AA02C; /* Spring Green */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sourceRow[exe_line="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/exe.png);
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpoint.png);
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"][condition="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpointCondition.png);
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"][disabledBreakpoint="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpointDisabled.png);
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"][exe_line="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpointExe.png);
|
||||
}
|
||||
|
||||
.sourceRow[breakpoint="true"][exe_line="true"][disabledBreakpoint="true"] > .sourceLine {
|
||||
background-image: url(chrome://firebug/skin/breakpointDisabledExe.png);
|
||||
}
|
||||
|
||||
.sourceLine.editing {
|
||||
background-image: url(chrome://firebug/skin/breakpoint.png);
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.conditionEditor {
|
||||
z-index: 2147483647;
|
||||
position: absolute;
|
||||
margin-top: 0;
|
||||
left: 2px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.conditionEditorInner {
|
||||
position: relative;
|
||||
top: -26px;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.conditionCaption {
|
||||
margin-bottom: 2px;
|
||||
font-family: Lucida Grande, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
color: #226679;
|
||||
}
|
||||
|
||||
.conditionInput {
|
||||
width: 100%;
|
||||
border: 1px solid #0096C0;
|
||||
font-family: monospace;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.conditionEditorInner1 {
|
||||
padding-left: 37px;
|
||||
background: url(condBorders.png) repeat-y;
|
||||
}
|
||||
|
||||
.conditionEditorInner2 {
|
||||
padding-right: 25px;
|
||||
background: url(condBorders.png) repeat-y 100% 0;
|
||||
}
|
||||
|
||||
.conditionEditorTop1 {
|
||||
background: url(condCorners.png) no-repeat 100% 0;
|
||||
margin-left: 37px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.conditionEditorTop2 {
|
||||
position: relative;
|
||||
left: -37px;
|
||||
width: 37px;
|
||||
height: 35px;
|
||||
background: url(condCorners.png) no-repeat;
|
||||
}
|
||||
|
||||
.conditionEditorBottom1 {
|
||||
background: url(condCorners.png) no-repeat 100% 100%;
|
||||
margin-left: 37px;
|
||||
height: 33px;
|
||||
}
|
||||
|
||||
.conditionEditorBottom2 {
|
||||
position: relative; left: -37px;
|
||||
width: 37px;
|
||||
height: 33px;
|
||||
background: url(condCorners.png) no-repeat 0 100%;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.upsideDown {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorInner {
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorInner1 {
|
||||
padding-left: 33px;
|
||||
background: url(condBordersUps.png) repeat-y;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorInner2 {
|
||||
padding-right: 25px;
|
||||
background: url(condBordersUps.png) repeat-y 100% 0;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorTop1 {
|
||||
background: url(condCornersUps.png) no-repeat 100% 0;
|
||||
margin-left: 33px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorTop2 {
|
||||
position: relative;
|
||||
left: -33px;
|
||||
width: 33px;
|
||||
height: 25px;
|
||||
background: url(condCornersUps.png) no-repeat;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorBottom1 {
|
||||
background: url(condCornersUps.png) no-repeat 100% 100%;
|
||||
margin-left: 33px;
|
||||
height: 43px;
|
||||
}
|
||||
|
||||
.upsideDown .conditionEditorBottom2 {
|
||||
position: relative;
|
||||
left: -33px;
|
||||
width: 33px;
|
||||
height: 43px;
|
||||
background: url(condCornersUps.png) no-repeat 0 100%;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.breakpointsGroupListBox {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.breakpointBlockHead {
|
||||
position: relative;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.breakpointBlockHead > .checkbox {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.breakpointBlockHead > .objectLink-sourceLink {
|
||||
top: 4px;
|
||||
right: 20px;
|
||||
background-color: #FFFFFF; /* issue 3308 */
|
||||
}
|
||||
|
||||
.breakpointBlockHead > .closeButton {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
.breakpointCheckbox {
|
||||
margin-top: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.breakpointName {
|
||||
margin-left: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.breakpointRow[aria-checked="false"] > .breakpointBlockHead > *,
|
||||
.breakpointRow[aria-checked="false"] > .breakpointCode {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.breakpointRow[aria-checked="false"] .breakpointCheckbox,
|
||||
.breakpointRow[aria-checked="false"] .objectLink-sourceLink,
|
||||
.breakpointRow[aria-checked="false"] .closeButton,
|
||||
.breakpointRow[aria-checked="false"] .breakpointMutationType {
|
||||
opacity: 1.0 !important;
|
||||
}
|
||||
|
||||
.breakpointCode {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
padding-left: 24px;
|
||||
padding-bottom: 2px;
|
||||
border-bottom: 1px solid #D7D7D7;
|
||||
font-family: monospace;
|
||||
color: DarkGreen;
|
||||
}
|
||||
|
||||
.breakpointCondition {
|
||||
white-space: nowrap;
|
||||
padding-left: 24px;
|
||||
padding-bottom: 2px;
|
||||
border-bottom: 1px solid #D7D7D7;
|
||||
font-family: monospace;
|
||||
color: Gray;
|
||||
}
|
||||
|
||||
.breakpointBlock-breakpoints > .groupHeader {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.breakpointBlock-monitors > .breakpointCode {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.breakpointBlock-errorBreakpoints .breakpointCheckbox,
|
||||
.breakpointBlock-monitors .breakpointCheckbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.breakpointHeader {
|
||||
margin: 0 !important;
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
1634
vendor/firebug-lite/skin/xp/firebug-1.3a2.css
vendored
1634
vendor/firebug-lite/skin/xp/firebug-1.3a2.css
vendored
File diff suppressed because it is too large
Load Diff
40
vendor/firebug-lite/skin/xp/firebug.IE6.css
vendored
40
vendor/firebug-lite/skin/xp/firebug.IE6.css
vendored
@@ -1,20 +1,20 @@
|
||||
/************************************************************************************************/
|
||||
#fbToolbarSearch {
|
||||
background-image: url(search.gif) !important;
|
||||
}
|
||||
/************************************************************************************************/
|
||||
.fbErrors {
|
||||
background-image: url(errorIcon.gif) !important;
|
||||
}
|
||||
/************************************************************************************************/
|
||||
.logRow-info {
|
||||
background-image: url(infoIcon.gif) !important;
|
||||
}
|
||||
|
||||
.logRow-warning {
|
||||
background-image: url(warningIcon.gif) !important;
|
||||
}
|
||||
|
||||
.logRow-error {
|
||||
background-image: url(errorIcon.gif) !important;
|
||||
}
|
||||
/************************************************************************************************/
|
||||
#fbToolbarSearch {
|
||||
background-image: url(search.gif) !important;
|
||||
}
|
||||
/************************************************************************************************/
|
||||
.fbErrors {
|
||||
background-image: url(errorIcon.gif) !important;
|
||||
}
|
||||
/************************************************************************************************/
|
||||
.logRow-info {
|
||||
background-image: url(infoIcon.gif) !important;
|
||||
}
|
||||
|
||||
.logRow-warning {
|
||||
background-image: url(warningIcon.gif) !important;
|
||||
}
|
||||
|
||||
.logRow-error {
|
||||
background-image: url(errorIcon.gif) !important;
|
||||
}
|
||||
|
||||
6294
vendor/firebug-lite/skin/xp/firebug.css
vendored
6294
vendor/firebug-lite/skin/xp/firebug.css
vendored
File diff suppressed because it is too large
Load Diff
428
vendor/firebug-lite/skin/xp/firebug.html
vendored
428
vendor/firebug-lite/skin/xp/firebug.html
vendored
@@ -1,215 +1,215 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<title>Firebug Lite</title>
|
||||
<!-- An empty script to avoid FOUC when loading the stylesheet -->
|
||||
<script type="text/javascript"></script>
|
||||
<style type="text/css" media="screen">@import "firebug.css";</style>
|
||||
<style>html,body{margin:0;padding:0;overflow:hidden;}</style>
|
||||
</head>
|
||||
<body class="fbBody">
|
||||
<table id="fbChrome" cellpadding="0" cellspacing="0" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<!-- Interface - Top Area -->
|
||||
<td id="fbTop" colspan="2">
|
||||
|
||||
<!--
|
||||
<div>
|
||||
--><!-- <span id="fbToolbarErrors" class="fbErrors">2 errors</span> --><!--
|
||||
<input type="text" id="fbToolbarSearch" />
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!-- Window Buttons -->
|
||||
<div id="fbWindowButtons">
|
||||
<a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page"> </a>
|
||||
<a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window"> </a>
|
||||
<a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug"> </a>
|
||||
</div>
|
||||
|
||||
<!-- Toolbar buttons and Status Bar -->
|
||||
<div id="fbToolbar">
|
||||
<div id="fbToolbarContent">
|
||||
|
||||
<!-- Firebug Button -->
|
||||
<span id="fbToolbarIcon">
|
||||
<a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank"> </a>
|
||||
</span>
|
||||
|
||||
<!--
|
||||
<span id="fbLeftToolbarErrors" class="fbErrors">2 errors</span>
|
||||
-->
|
||||
|
||||
<!-- Toolbar Buttons -->
|
||||
<span id="fbToolbarButtons">
|
||||
<!-- Fixed Toolbar Buttons -->
|
||||
<span id="fbFixedButtons">
|
||||
<a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a>
|
||||
</span>
|
||||
|
||||
<!-- Console Panel Toolbar Buttons -->
|
||||
<span id="fbConsoleButtons" class="fbToolbarButtons">
|
||||
<a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a>
|
||||
</span>
|
||||
|
||||
<!-- HTML Panel Toolbar Buttons -->
|
||||
<!--
|
||||
<span id="fbHTMLButtons" class="fbToolbarButtons">
|
||||
<a id="fbHTML_btEdit" class="fbHover" title="Edit this HTML">Edit</a>
|
||||
</span>
|
||||
-->
|
||||
</span>
|
||||
|
||||
<!-- Status Bar -->
|
||||
<span id="fbStatusBarBox">
|
||||
<span class="fbToolbarSeparator"></span>
|
||||
<!-- HTML Panel Status Bar -->
|
||||
<!--
|
||||
<span id="fbHTMLStatusBar" class="fbStatusBar fbToolbarButtons">
|
||||
</span>
|
||||
-->
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- PanelBars -->
|
||||
<div id="fbPanelBarBox">
|
||||
|
||||
<!-- Main PanelBar -->
|
||||
<div id="fbPanelBar1" class="fbPanelBar">
|
||||
<a id="fbConsoleTab" class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">Console</span>
|
||||
<span class="fbTabMenuTarget"></span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a id="fbHTMLTab" class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">HTML</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">CSS</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">Script</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">DOM</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Side PanelBars -->
|
||||
<div id="fbPanelBar2Box" class="hide">
|
||||
<div id="fbPanelBar2" class="fbPanelBar">
|
||||
<!--
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">Style</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">Layout</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">DOM</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Horizontal Splitter -->
|
||||
<div id="fbHSplitter"> </div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Interface - Main Area -->
|
||||
<tr id="fbContent">
|
||||
|
||||
<!-- Panels -->
|
||||
<td id="fbPanelBox1">
|
||||
<div id="fbPanel1" class="fbFitHeight">
|
||||
<div id="fbConsole" class="fbPanel"></div>
|
||||
<div id="fbHTML" class="fbPanel"></div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- Side Panel Box -->
|
||||
<td id="fbPanelBox2" class="hide">
|
||||
|
||||
<!-- VerticalSplitter -->
|
||||
<div id="fbVSplitter" class="fbVSplitter"> </div>
|
||||
|
||||
<!-- Side Panels -->
|
||||
<div id="fbPanel2" class="fbFitHeight">
|
||||
|
||||
<!-- HTML Side Panels -->
|
||||
<div id="fbHTML_Style" class="fbPanel"></div>
|
||||
<div id="fbHTML_Layout" class="fbPanel"></div>
|
||||
<div id="fbHTML_DOM" class="fbPanel"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Large Command Line -->
|
||||
<textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea>
|
||||
|
||||
<!-- Large Command Line Buttons -->
|
||||
<div id="fbLargeCommandButtons">
|
||||
<a id="fbCommand_btRun" class="fbButton fbHover">Run</a>
|
||||
<a id="fbCommand_btClear" class="fbButton fbHover">Clear</a>
|
||||
|
||||
<a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<!-- Interface - Bottom Area -->
|
||||
<tr id="fbBottom" class="hide">
|
||||
|
||||
<!-- Command Line -->
|
||||
<td id="fbCommand" colspan="2">
|
||||
<div id="fbCommandBox">
|
||||
<div id="fbCommandIcon">>>></div>
|
||||
<input id="fbCommandLine" name="fbCommandLine" type="text" />
|
||||
<a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<span id="fbMiniChrome">
|
||||
<span id="fbMiniContent">
|
||||
<span id="fbMiniIcon" title="Open Firebug Lite"></span>
|
||||
<span id="fbMiniErrors" class="fbErrors"><!-- 2 errors --></span>
|
||||
</span>
|
||||
</span>
|
||||
<!--
|
||||
<div id="fbErrorPopup">
|
||||
<div id="fbErrorPopupContent">
|
||||
<div id="fbErrorIndicator" class="fbErrors">2 errors</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</body>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<title>Firebug Lite</title>
|
||||
<!-- An empty script to avoid FOUC when loading the stylesheet -->
|
||||
<script type="text/javascript"></script>
|
||||
<style type="text/css" media="screen">@import "firebug.css";</style>
|
||||
<style>html,body{margin:0;padding:0;overflow:hidden;}</style>
|
||||
</head>
|
||||
<body class="fbBody">
|
||||
<table id="fbChrome" cellpadding="0" cellspacing="0" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<!-- Interface - Top Area -->
|
||||
<td id="fbTop" colspan="2">
|
||||
|
||||
<!--
|
||||
<div>
|
||||
--><!-- <span id="fbToolbarErrors" class="fbErrors">2 errors</span> --><!--
|
||||
<input type="text" id="fbToolbarSearch" />
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!-- Window Buttons -->
|
||||
<div id="fbWindowButtons">
|
||||
<a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page"> </a>
|
||||
<a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window"> </a>
|
||||
<a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug"> </a>
|
||||
</div>
|
||||
|
||||
<!-- Toolbar buttons and Status Bar -->
|
||||
<div id="fbToolbar">
|
||||
<div id="fbToolbarContent">
|
||||
|
||||
<!-- Firebug Button -->
|
||||
<span id="fbToolbarIcon">
|
||||
<a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank"> </a>
|
||||
</span>
|
||||
|
||||
<!--
|
||||
<span id="fbLeftToolbarErrors" class="fbErrors">2 errors</span>
|
||||
-->
|
||||
|
||||
<!-- Toolbar Buttons -->
|
||||
<span id="fbToolbarButtons">
|
||||
<!-- Fixed Toolbar Buttons -->
|
||||
<span id="fbFixedButtons">
|
||||
<a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a>
|
||||
</span>
|
||||
|
||||
<!-- Console Panel Toolbar Buttons -->
|
||||
<span id="fbConsoleButtons" class="fbToolbarButtons">
|
||||
<a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a>
|
||||
</span>
|
||||
|
||||
<!-- HTML Panel Toolbar Buttons -->
|
||||
<!--
|
||||
<span id="fbHTMLButtons" class="fbToolbarButtons">
|
||||
<a id="fbHTML_btEdit" class="fbHover" title="Edit this HTML">Edit</a>
|
||||
</span>
|
||||
-->
|
||||
</span>
|
||||
|
||||
<!-- Status Bar -->
|
||||
<span id="fbStatusBarBox">
|
||||
<span class="fbToolbarSeparator"></span>
|
||||
<!-- HTML Panel Status Bar -->
|
||||
<!--
|
||||
<span id="fbHTMLStatusBar" class="fbStatusBar fbToolbarButtons">
|
||||
</span>
|
||||
-->
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- PanelBars -->
|
||||
<div id="fbPanelBarBox">
|
||||
|
||||
<!-- Main PanelBar -->
|
||||
<div id="fbPanelBar1" class="fbPanelBar">
|
||||
<a id="fbConsoleTab" class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">Console</span>
|
||||
<span class="fbTabMenuTarget"></span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a id="fbHTMLTab" class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">HTML</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">CSS</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">Script</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">DOM</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Side PanelBars -->
|
||||
<div id="fbPanelBar2Box" class="hide">
|
||||
<div id="fbPanelBar2" class="fbPanelBar">
|
||||
<!--
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">Style</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">Layout</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
<a class="fbTab fbHover">
|
||||
<span class="fbTabL"></span>
|
||||
<span class="fbTabText">DOM</span>
|
||||
<span class="fbTabR"></span>
|
||||
</a>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Horizontal Splitter -->
|
||||
<div id="fbHSplitter"> </div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Interface - Main Area -->
|
||||
<tr id="fbContent">
|
||||
|
||||
<!-- Panels -->
|
||||
<td id="fbPanelBox1">
|
||||
<div id="fbPanel1" class="fbFitHeight">
|
||||
<div id="fbConsole" class="fbPanel"></div>
|
||||
<div id="fbHTML" class="fbPanel"></div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- Side Panel Box -->
|
||||
<td id="fbPanelBox2" class="hide">
|
||||
|
||||
<!-- VerticalSplitter -->
|
||||
<div id="fbVSplitter" class="fbVSplitter"> </div>
|
||||
|
||||
<!-- Side Panels -->
|
||||
<div id="fbPanel2" class="fbFitHeight">
|
||||
|
||||
<!-- HTML Side Panels -->
|
||||
<div id="fbHTML_Style" class="fbPanel"></div>
|
||||
<div id="fbHTML_Layout" class="fbPanel"></div>
|
||||
<div id="fbHTML_DOM" class="fbPanel"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Large Command Line -->
|
||||
<textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea>
|
||||
|
||||
<!-- Large Command Line Buttons -->
|
||||
<div id="fbLargeCommandButtons">
|
||||
<a id="fbCommand_btRun" class="fbButton fbHover">Run</a>
|
||||
<a id="fbCommand_btClear" class="fbButton fbHover">Clear</a>
|
||||
|
||||
<a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<!-- Interface - Bottom Area -->
|
||||
<tr id="fbBottom" class="hide">
|
||||
|
||||
<!-- Command Line -->
|
||||
<td id="fbCommand" colspan="2">
|
||||
<div id="fbCommandBox">
|
||||
<div id="fbCommandIcon">>>></div>
|
||||
<input id="fbCommandLine" name="fbCommandLine" type="text" />
|
||||
<a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<span id="fbMiniChrome">
|
||||
<span id="fbMiniContent">
|
||||
<span id="fbMiniIcon" title="Open Firebug Lite"></span>
|
||||
<span id="fbMiniErrors" class="fbErrors"><!-- 2 errors --></span>
|
||||
</span>
|
||||
</span>
|
||||
<!--
|
||||
<div id="fbErrorPopup">
|
||||
<div id="fbErrorPopupContent">
|
||||
<div id="fbErrorIndicator" class="fbErrors">2 errors</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
542
vendor/firebug-lite/skin/xp/html.css
vendored
542
vendor/firebug-lite/skin/xp/html.css
vendored
@@ -1,272 +1,272 @@
|
||||
/* See license.txt for terms of usage */
|
||||
|
||||
.panelNode-html {
|
||||
-moz-box-sizing: padding-box;
|
||||
padding: 4px 0 0 2px;
|
||||
}
|
||||
|
||||
.nodeBox {
|
||||
position: relative;
|
||||
font-family: Monaco, monospace;
|
||||
padding-left: 13px;
|
||||
-moz-user-select: -moz-none;
|
||||
}
|
||||
.nodeBox.search-selection {
|
||||
-moz-user-select: text;
|
||||
}
|
||||
.twisty {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.nodeChildBox {
|
||||
margin-left: 12px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nodeLabel,
|
||||
.nodeCloseLabel {
|
||||
margin: -2px 2px 0 2px;
|
||||
border: 2px solid transparent;
|
||||
-moz-border-radius: 3px;
|
||||
padding: 0 2px;
|
||||
color: #000088;
|
||||
}
|
||||
|
||||
.nodeCloseLabel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nodeTag {
|
||||
cursor: pointer;
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.nodeValue {
|
||||
color: #FF0000;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.nodeText,
|
||||
.nodeComment {
|
||||
margin: 0 2px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.nodeText {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.nodeWhiteSpace {
|
||||
border: 1px solid LightGray;
|
||||
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
|
||||
margin-left: 1px;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
|
||||
.nodeWhiteSpace_Space {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.nodeTextEntity {
|
||||
border: 1px solid gray;
|
||||
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.nodeComment {
|
||||
color: DarkGreen;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.highlightOpen > .nodeLabel {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
.nodeBox.highlightOpen > .nodeCloseLabel,
|
||||
.nodeBox.highlightOpen > .nodeChildBox,
|
||||
.nodeBox.open > .nodeCloseLabel,
|
||||
.nodeBox.open > .nodeChildBox {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.selected > .nodeLabel {
|
||||
border-color: Highlight;
|
||||
background-color: Highlight;
|
||||
color: HighlightText !important;
|
||||
}
|
||||
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.highlighted > .nodeLabel {
|
||||
border-color: Highlight !important;
|
||||
background-color: cyan !important;
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.nodeHidden .nodeCloseLabel,
|
||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
|
||||
.nodeBox.nodeHidden .nodeText {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||
.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
|
||||
color: #5F82D9;
|
||||
}
|
||||
|
||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
|
||||
color: #D86060;
|
||||
}
|
||||
|
||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
|
||||
color: SkyBlue !important;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.mutated > .nodeLabel,
|
||||
.nodeAttr.mutated,
|
||||
.nodeValue.mutated,
|
||||
.nodeText.mutated,
|
||||
.nodeBox.mutated > .nodeText {
|
||||
background-color: #EFFF79;
|
||||
color: #FF0000 !important;
|
||||
}
|
||||
|
||||
.nodeBox.selected.mutated > .nodeLabel,
|
||||
.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
|
||||
background-color: #EFFF79;
|
||||
border-color: #EFFF79;
|
||||
color: #FF0000 !important;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.logRow-dirxml {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.soloElement > .nodeBox {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.useA11y .nodeLabel.focused {
|
||||
outline: 2px solid #FF9933;
|
||||
-moz-outline-radius: 3px;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.useA11y .nodeLabelBox:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.breakpointCode .twisty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.breakpointCode .nodeBox.containerNodeBox,
|
||||
.breakpointCode .nodeLabel {
|
||||
padding-left: 0px;
|
||||
margin-left: 0px;
|
||||
font-family: Monaco, monospace !important;
|
||||
}
|
||||
|
||||
.breakpointCode .nodeTag,
|
||||
.breakpointCode .nodeAttr,
|
||||
.breakpointCode .nodeText,
|
||||
.breakpointCode .nodeValue,
|
||||
.breakpointCode .nodeLabel {
|
||||
color: DarkGreen !important;
|
||||
}
|
||||
|
||||
.breakpointMutationType {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 20px;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
/************************************************************************************************/
|
||||
/* Twisties */
|
||||
|
||||
.twisty,
|
||||
.logRow-errorMessage > .hasTwisty > .errorTitle,
|
||||
.logRow-log > .objectBox-array.hasTwisty,
|
||||
.logRow-spy .spyHead .spyTitle,
|
||||
.logGroup > .logRow,
|
||||
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
|
||||
.hasHeaders .netHrefLabel,
|
||||
.netPageRow > .netCol > .netPageTitle {
|
||||
background-image: url(twistyClosed.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 2px 2px;
|
||||
min-height: 12px;
|
||||
}
|
||||
|
||||
.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
|
||||
.logRow-log > .objectBox-array.hasTwisty.opened,
|
||||
.logRow-spy.opened .spyHead .spyTitle,
|
||||
.logGroup.opened > .logRow,
|
||||
.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
|
||||
.nodeBox.highlightOpen > .nodeLabel > .twisty,
|
||||
.nodeBox.open > .nodeLabel > .twisty,
|
||||
.netRow.opened > .netCol > .netHrefLabel,
|
||||
.netPageRow.opened > .netCol > .netPageTitle {
|
||||
background-image: url(twistyOpen.png);
|
||||
}
|
||||
|
||||
.twisty {
|
||||
background-position: 4px 4px;
|
||||
/* See license.txt for terms of usage */
|
||||
|
||||
.panelNode-html {
|
||||
-moz-box-sizing: padding-box;
|
||||
padding: 4px 0 0 2px;
|
||||
}
|
||||
|
||||
.nodeBox {
|
||||
position: relative;
|
||||
font-family: Monaco, monospace;
|
||||
padding-left: 13px;
|
||||
-moz-user-select: -moz-none;
|
||||
}
|
||||
.nodeBox.search-selection {
|
||||
-moz-user-select: text;
|
||||
}
|
||||
.twisty {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.nodeChildBox {
|
||||
margin-left: 12px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nodeLabel,
|
||||
.nodeCloseLabel {
|
||||
margin: -2px 2px 0 2px;
|
||||
border: 2px solid transparent;
|
||||
-moz-border-radius: 3px;
|
||||
padding: 0 2px;
|
||||
color: #000088;
|
||||
}
|
||||
|
||||
.nodeCloseLabel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nodeTag {
|
||||
cursor: pointer;
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.nodeValue {
|
||||
color: #FF0000;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.nodeText,
|
||||
.nodeComment {
|
||||
margin: 0 2px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.nodeText {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.nodeWhiteSpace {
|
||||
border: 1px solid LightGray;
|
||||
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
|
||||
margin-left: 1px;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
|
||||
.nodeWhiteSpace_Space {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.nodeTextEntity {
|
||||
border: 1px solid gray;
|
||||
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.nodeComment {
|
||||
color: DarkGreen;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.highlightOpen > .nodeLabel {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
.nodeBox.highlightOpen > .nodeCloseLabel,
|
||||
.nodeBox.highlightOpen > .nodeChildBox,
|
||||
.nodeBox.open > .nodeCloseLabel,
|
||||
.nodeBox.open > .nodeChildBox {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.selected > .nodeLabel {
|
||||
border-color: Highlight;
|
||||
background-color: Highlight;
|
||||
color: HighlightText !important;
|
||||
}
|
||||
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.highlighted > .nodeLabel {
|
||||
border-color: Highlight !important;
|
||||
background-color: cyan !important;
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.nodeHidden .nodeCloseLabel,
|
||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
|
||||
.nodeBox.nodeHidden .nodeText {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||
.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
|
||||
color: #5F82D9;
|
||||
}
|
||||
|
||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
|
||||
color: #D86060;
|
||||
}
|
||||
|
||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
|
||||
color: SkyBlue !important;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
.nodeBox.mutated > .nodeLabel,
|
||||
.nodeAttr.mutated,
|
||||
.nodeValue.mutated,
|
||||
.nodeText.mutated,
|
||||
.nodeBox.mutated > .nodeText {
|
||||
background-color: #EFFF79;
|
||||
color: #FF0000 !important;
|
||||
}
|
||||
|
||||
.nodeBox.selected.mutated > .nodeLabel,
|
||||
.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
|
||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
|
||||
background-color: #EFFF79;
|
||||
border-color: #EFFF79;
|
||||
color: #FF0000 !important;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.logRow-dirxml {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.soloElement > .nodeBox {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.useA11y .nodeLabel.focused {
|
||||
outline: 2px solid #FF9933;
|
||||
-moz-outline-radius: 3px;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.useA11y .nodeLabelBox:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
.breakpointCode .twisty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.breakpointCode .nodeBox.containerNodeBox,
|
||||
.breakpointCode .nodeLabel {
|
||||
padding-left: 0px;
|
||||
margin-left: 0px;
|
||||
font-family: Monaco, monospace !important;
|
||||
}
|
||||
|
||||
.breakpointCode .nodeTag,
|
||||
.breakpointCode .nodeAttr,
|
||||
.breakpointCode .nodeText,
|
||||
.breakpointCode .nodeValue,
|
||||
.breakpointCode .nodeLabel {
|
||||
color: DarkGreen !important;
|
||||
}
|
||||
|
||||
.breakpointMutationType {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 20px;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
/************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
/************************************************************************************************/
|
||||
/* Twisties */
|
||||
|
||||
.twisty,
|
||||
.logRow-errorMessage > .hasTwisty > .errorTitle,
|
||||
.logRow-log > .objectBox-array.hasTwisty,
|
||||
.logRow-spy .spyHead .spyTitle,
|
||||
.logGroup > .logRow,
|
||||
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
|
||||
.hasHeaders .netHrefLabel,
|
||||
.netPageRow > .netCol > .netPageTitle {
|
||||
background-image: url(twistyClosed.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 2px 2px;
|
||||
min-height: 12px;
|
||||
}
|
||||
|
||||
.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
|
||||
.logRow-log > .objectBox-array.hasTwisty.opened,
|
||||
.logRow-spy.opened .spyHead .spyTitle,
|
||||
.logGroup.opened > .logRow,
|
||||
.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
|
||||
.nodeBox.highlightOpen > .nodeLabel > .twisty,
|
||||
.nodeBox.open > .nodeLabel > .twisty,
|
||||
.netRow.opened > .netCol > .netHrefLabel,
|
||||
.netPageRow.opened > .netCol > .netPageTitle {
|
||||
background-image: url(twistyOpen.png);
|
||||
}
|
||||
|
||||
.twisty {
|
||||
background-position: 4px 4px;
|
||||
}
|
||||
12
vendor/firebug-lite/skin/xp/roundCorner.svg
vendored
12
vendor/firebug-lite/skin/xp/roundCorner.svg
vendored
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="white" x="0" y="0" width="100%" height="100%" />
|
||||
<rect fill="highlight" x="0" y="0" width="100%" height="100%" rx="2px"/>
|
||||
</svg>
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="white" x="0" y="0" width="100%" height="100%" />
|
||||
<rect fill="highlight" x="0" y="0" width="100%" height="100%" rx="2px"/>
|
||||
</svg>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 228 B |
21
vendor/jquery/MIT-LICENSE.txt
vendored
Normal file
21
vendor/jquery/MIT-LICENSE.txt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
Copyright 2012 jQuery Foundation and other contributors
|
||||
http://jquery.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
417
vendor/jquery/README.md
vendored
Normal file
417
vendor/jquery/README.md
vendored
Normal file
@@ -0,0 +1,417 @@
|
||||
[jQuery](http://jquery.com/) - New Wave JavaScript
|
||||
==================================================
|
||||
|
||||
Contribution Guides
|
||||
--------------------------------------
|
||||
|
||||
In the spirit of open source software development, jQuery always encourages community code contribution. To help you get started and before you jump into writing code, be sure to read these important contribution guidelines thoroughly:
|
||||
|
||||
1. [Getting Involved](http://docs.jquery.com/Getting_Involved)
|
||||
2. [Core Style Guide](http://docs.jquery.com/JQuery_Core_Style_Guidelines)
|
||||
3. [Tips For Bug Patching](http://docs.jquery.com/Tips_for_jQuery_Bug_Patching)
|
||||
|
||||
|
||||
What you need to build your own jQuery
|
||||
--------------------------------------
|
||||
|
||||
In order to build jQuery, you need to have GNU make 3.8 or later, Node.js/npm latest, and git 1.7 or later.
|
||||
(Earlier versions might work OK, but are not tested.)
|
||||
|
||||
Windows users have two options:
|
||||
|
||||
1. Install [msysgit](https://code.google.com/p/msysgit/) (Full installer for official Git),
|
||||
[GNU make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm), and a
|
||||
[binary version of Node.js](http://node-js.prcn.co.cc/). Make sure all three packages are installed to the same
|
||||
location (by default, this is C:\Program Files\Git).
|
||||
2. Install [Cygwin](http://cygwin.com/) (make sure you install the git, make, and which packages), then either follow
|
||||
the [Node.js build instructions](https://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29) or install
|
||||
the [binary version of Node.js](http://node-js.prcn.co.cc/).
|
||||
|
||||
Mac OS users should install Xcode (comes on your Mac OS install DVD, or downloadable from
|
||||
[Apple's Xcode site](http://developer.apple.com/technologies/xcode.html)) and
|
||||
[Homebrew](http://mxcl.github.com/homebrew/). Once Homebrew is installed, run `brew install git` to install git,
|
||||
and `brew install node` to install Node.js.
|
||||
|
||||
Linux/BSD users should use their appropriate package managers to install make, git, and node, or build from source
|
||||
if you swing that way. Easy-peasy.
|
||||
|
||||
|
||||
How to build your own jQuery
|
||||
----------------------------
|
||||
|
||||
First, clone a copy of the main jQuery git repo by running:
|
||||
|
||||
```bash
|
||||
git clone git://github.com/jquery/jquery.git
|
||||
```
|
||||
|
||||
Enter the directory and install the Node dependencies:
|
||||
|
||||
```bash
|
||||
cd jquery && npm install
|
||||
```
|
||||
|
||||
|
||||
Make sure you have `grunt` installed by testing:
|
||||
|
||||
```bash
|
||||
grunt -version
|
||||
```
|
||||
|
||||
|
||||
|
||||
Then, to get a complete, minified (w/ Uglify.js), linted (w/ JSHint) version of jQuery, type the following:
|
||||
|
||||
```bash
|
||||
grunt
|
||||
```
|
||||
|
||||
|
||||
The built version of jQuery will be put in the `dist/` subdirectory.
|
||||
|
||||
|
||||
### Modules (new in 1.8)
|
||||
|
||||
Starting in jQuery 1.8, special builds can now be created that optionally exclude or include any of the following modules:
|
||||
|
||||
- ajax
|
||||
- css
|
||||
- dimensions
|
||||
- effects
|
||||
- offset
|
||||
|
||||
|
||||
Before creating a custom build for use in production, be sure to check out the latest stable version:
|
||||
|
||||
```bash
|
||||
git pull; git checkout $(git describe --abbrev=0 --tags)
|
||||
```
|
||||
|
||||
Then, make sure all Node dependencies are installed and all Git submodules are checked out:
|
||||
|
||||
```bash
|
||||
npm install && grunt
|
||||
```
|
||||
|
||||
To create a custom build, use the following special `grunt` commands:
|
||||
|
||||
Exclude **ajax**:
|
||||
|
||||
```bash
|
||||
grunt custom:-ajax
|
||||
```
|
||||
|
||||
Exclude **css**:
|
||||
|
||||
```bash
|
||||
grunt custom:-css
|
||||
```
|
||||
|
||||
Exclude **deprecated**:
|
||||
|
||||
```bash
|
||||
grunt custom:-deprecated
|
||||
```
|
||||
|
||||
Exclude **dimensions**:
|
||||
|
||||
```bash
|
||||
grunt custom:-dimensions
|
||||
```
|
||||
|
||||
Exclude **effects**:
|
||||
|
||||
```bash
|
||||
grunt custom:-effects
|
||||
```
|
||||
|
||||
Exclude **offset**:
|
||||
|
||||
```bash
|
||||
grunt custom:-offset
|
||||
```
|
||||
|
||||
Exclude **all** optional modules:
|
||||
|
||||
```bash
|
||||
grunt custom:-ajax,-css,-deprecated,-dimensions,-effects,-offset
|
||||
```
|
||||
|
||||
|
||||
Note: dependencies will be handled internally, by the build process.
|
||||
|
||||
|
||||
Running the Unit Tests
|
||||
--------------------------------------
|
||||
|
||||
|
||||
Start grunt to auto-build jQuery as you work:
|
||||
|
||||
```bash
|
||||
cd jquery && grunt watch
|
||||
```
|
||||
|
||||
|
||||
Run the unit tests with a local server that supports PHP. No database is required. Pre-configured php local servers are available for Windows and Mac. Here are some options:
|
||||
|
||||
- Windows: [WAMP download](http://www.wampserver.com/en/)
|
||||
- Mac: [MAMP download](http://www.mamp.info/en/index.html)
|
||||
- Linux: [Setting up LAMP](https://www.linux.com/learn/tutorials/288158-easy-lamp-server-installation)
|
||||
- [Mongoose (most platforms)](http://code.google.com/p/mongoose/)
|
||||
|
||||
|
||||
|
||||
|
||||
Building to a different directory
|
||||
---------------------------------
|
||||
|
||||
If you want to build jQuery to a directory that is different from the default location:
|
||||
|
||||
```bash
|
||||
grunt && grunt dist:/path/to/special/location/
|
||||
```
|
||||
With this example, the output files would be:
|
||||
|
||||
```bash
|
||||
/path/to/special/location/jquery.js
|
||||
/path/to/special/location/jquery.min.js
|
||||
```
|
||||
|
||||
If you want to add a permanent copy destination, create a file in `dist/` called ".destination.json". Inside the file, paste and customize the following:
|
||||
|
||||
```json
|
||||
|
||||
{
|
||||
"/Absolute/path/to/other/destination": true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Additionally, both methods can be combined.
|
||||
|
||||
|
||||
|
||||
Updating Submodules
|
||||
-------------------
|
||||
|
||||
Update the submodules to what is probably the latest upstream code.
|
||||
|
||||
```bash
|
||||
grunt update_submodules
|
||||
```
|
||||
|
||||
Note: This task will also be run any time the default `grunt` command is used.
|
||||
|
||||
|
||||
|
||||
Git for dummies
|
||||
---------------
|
||||
|
||||
As the source code is handled by the version control system Git, it's useful to know some features used.
|
||||
|
||||
### Submodules ###
|
||||
|
||||
The repository uses submodules, which normally are handled directly by the Makefile, but sometimes you want to
|
||||
be able to work with them manually.
|
||||
|
||||
Following are the steps to manually get the submodules:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/jquery/jquery.git
|
||||
cd jquery
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/jquery/jquery.git
|
||||
cd jquery
|
||||
git submodule update --init
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```bash
|
||||
git clone --recursive https://github.com/jquery/jquery.git
|
||||
cd jquery
|
||||
```
|
||||
|
||||
If you want to work inside a submodule, it is possible, but first you need to checkout a branch:
|
||||
|
||||
```bash
|
||||
cd src/sizzle
|
||||
git checkout master
|
||||
```
|
||||
|
||||
After you've committed your changes to the submodule, you'll update the jquery project to point to the new commit,
|
||||
but remember to push the submodule changes before pushing the new jquery commit:
|
||||
|
||||
```bash
|
||||
cd src/sizzle
|
||||
git push origin master
|
||||
cd ..
|
||||
git add src/sizzle
|
||||
git commit
|
||||
```
|
||||
|
||||
|
||||
### cleaning ###
|
||||
|
||||
If you want to purge your working directory back to the status of upstream, following commands can be used (remember everything you've worked on is gone after these):
|
||||
|
||||
```bash
|
||||
git reset --hard upstream/master
|
||||
git clean -fdx
|
||||
```
|
||||
|
||||
### rebasing ###
|
||||
|
||||
For feature/topic branches, you should always used the `--rebase` flag to `git pull`, or if you are usually handling many temporary "to be in a github pull request" branches, run following to automate this:
|
||||
|
||||
```bash
|
||||
git config branch.autosetuprebase local
|
||||
```
|
||||
(see `man git-config` for more information)
|
||||
|
||||
### handling merge conflicts ###
|
||||
|
||||
If you're getting merge conflicts when merging, instead of editing the conflicted files manually, you can use the feature
|
||||
`git mergetool`. Even though the default tool `xxdiff` looks awful/old, it's rather useful.
|
||||
|
||||
Following are some commands that can be used there:
|
||||
|
||||
* `Ctrl + Alt + M` - automerge as much as possible
|
||||
* `b` - jump to next merge conflict
|
||||
* `s` - change the order of the conflicted lines
|
||||
* `u` - undo an merge
|
||||
* `left mouse button` - mark a block to be the winner
|
||||
* `middle mouse button` - mark a line to be the winner
|
||||
* `Ctrl + S` - save
|
||||
* `Ctrl + Q` - quit
|
||||
|
||||
[QUnit](http://docs.jquery.com/QUnit) Reference
|
||||
-----------------
|
||||
|
||||
### Test methods ###
|
||||
|
||||
```js
|
||||
expect( numAssertions );
|
||||
stop();
|
||||
start();
|
||||
```
|
||||
|
||||
|
||||
note: QUnit's eventual addition of an argument to stop/start is ignored in this test suite so that start and stop can be passed as callbacks without worrying about their parameters
|
||||
|
||||
### Test assertions ###
|
||||
|
||||
|
||||
```js
|
||||
ok( value, [message] );
|
||||
equal( actual, expected, [message] );
|
||||
notEqual( actual, expected, [message] );
|
||||
deepEqual( actual, expected, [message] );
|
||||
notDeepEqual( actual, expected, [message] );
|
||||
strictEqual( actual, expected, [message] );
|
||||
notStrictEqual( actual, expected, [message] );
|
||||
raises( block, [expected], [message] );
|
||||
```
|
||||
|
||||
|
||||
Test Suite Convenience Methods Reference (See [test/data/testinit.js](https://github.com/jquery/jquery/blob/master/test/data/testinit.js))
|
||||
------------------------------
|
||||
|
||||
### Returns an array of elements with the given IDs ###
|
||||
|
||||
```js
|
||||
q( ... );
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
q("main", "foo", "bar");
|
||||
|
||||
=> [ div#main, span#foo, input#bar ]
|
||||
```
|
||||
|
||||
### Asserts that a selection matches the given IDs ###
|
||||
|
||||
```js
|
||||
t( testName, selector, [ "array", "of", "ids" ] );
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
t("Check for something", "//[a]", ["foo", "baar"]);
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Fires a native DOM event without going through jQuery ###
|
||||
|
||||
```js
|
||||
fireNative( node, eventType )
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
fireNative( jQuery("#elem")[0], "click" );
|
||||
```
|
||||
|
||||
### Add random number to url to stop caching ###
|
||||
|
||||
```js
|
||||
url( "some/url.php" );
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
url("data/test.html");
|
||||
|
||||
=> "data/test.html?10538358428943"
|
||||
|
||||
|
||||
url("data/test.php?foo=bar");
|
||||
|
||||
=> "data/test.php?foo=bar&10538358345554"
|
||||
```
|
||||
|
||||
|
||||
### Load tests in an iframe ###
|
||||
|
||||
Loads a given page constructing a url with fileName: `"./data/" + fileName + ".html"`
|
||||
and fires the given callback on jQuery ready (using the jQuery loading from that page)
|
||||
and passes the iFrame's jQuery to the callback.
|
||||
|
||||
```js
|
||||
testIframe( fileName, testName, callback );
|
||||
```
|
||||
|
||||
Callback arguments:
|
||||
|
||||
```js
|
||||
callback( jQueryFromIFrame, iFrameWindow, iFrameDocument );
|
||||
```
|
||||
|
||||
### Load tests in an iframe (window.iframeCallback) ###
|
||||
|
||||
Loads a given page constructing a url with fileName: `"./data/" + fileName + ".html"`
|
||||
The given callback is fired when window.iframeCallback is called by the page
|
||||
The arguments passed to the callback are the same as the
|
||||
arguments passed to window.iframeCallback, whatever that may be
|
||||
|
||||
```js
|
||||
testIframeWithCallback( testName, fileName, callback );
|
||||
```
|
||||
|
||||
Questions?
|
||||
----------
|
||||
|
||||
If you have any questions, please feel free to ask on the
|
||||
[Developing jQuery Core forum](http://forum.jquery.com/developing-jquery-core) or in #jquery on irc.freenode.net.
|
||||
File diff suppressed because it is too large
Load Diff
20
vendor/json3/LICENSE
vendored
Normal file
20
vendor/json3/LICENSE
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2012 Kit Cambridge.
|
||||
http://kitcambridge.github.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
124
vendor/json3/README.md
vendored
Normal file
124
vendor/json3/README.md
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
# JSON 3 #
|
||||
|
||||

|
||||
|
||||
**JSON 3** is a modern JSON implementation compatible with a variety of JavaScript platforms, including Internet Explorer 6, Opera 7, Safari 2, and Netscape 6. The current version is **3.2.4**.
|
||||
|
||||
- [Development Version](http://cdnjs.cloudflare.com/ajax/libs/json3/3.2.4/json3.js) *(36.5 KB; uncompressed with comments)*
|
||||
- [Production Version](http://cdnjs.cloudflare.com/ajax/libs/json3/3.2.4/json3.min.js) *(3.0 KB; compressed and `gzip`-ped)*
|
||||
|
||||
[JSON](http://json.org/) is a language-independent data interchange format based on a loose subset of the JavaScript grammar. Originally popularized by [Douglas Crockford](http://www.crockford.com/), the format was standardized in the [fifth edition](http://es5.github.com/) of the ECMAScript specification. The 5.1 edition, ratified in June 2011, incorporates several modifications to the grammar pertaining to the serialization of dates.
|
||||
|
||||
JSON 3 exposes two functions: `stringify()` for [serializing](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify) a JavaScript value to JSON, and `parse()` for [producing](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/parse) a JavaScript value from a JSON source string. It is a **drop-in replacement** for [JSON 2](http://json.org/js). The functions behave exactly as described in the ECMAScript spec, **except** for the date serialization discrepancy noted below.
|
||||
|
||||
The JSON 3 parser does **not** use `eval` or regular expressions. This provides security and performance benefits in obsolete and mobile environments, where the margin is particularly significant. The complete [benchmark suite](http://jsperf.com/json3) is available on [jsPerf](http://jsperf.com/).
|
||||
|
||||
The project is [hosted on GitHub](http://git.io/json3), along with the [unit tests](http://bestiejs.github.com/json3/test/test_browser.html). It is part of the [BestieJS](https://github.com/bestiejs) family, a collection of best-in-class JavaScript libraries that promote cross-platform support, specification precedents, unit testing, and plenty of documentation.
|
||||
|
||||
# Changes from JSON 2 #
|
||||
|
||||
JSON 3...
|
||||
|
||||
* Correctly serializes primitive wrapper objects.
|
||||
* Throws a `TypeError` when serializing cyclic structures (JSON 2 recurses until the call stack overflows).
|
||||
* Utilizes **feature tests** to detect broken or incomplete *native* JSON implementations (JSON 2 only checks for the presence of the native functions). The tests are only executed once at runtime, so there is no additional performance cost when parsing or serializing values.
|
||||
|
||||
**As of v3.2.3**, JSON 3 is compatible with [Prototype](http://prototypejs.org) 1.6.1 and older.
|
||||
|
||||
In contrast to JSON 2, JSON 3 **does not**...
|
||||
|
||||
* Add `toJSON()` methods to the `Boolean`, `Number`, and `String` prototypes. These are not part of any standard, and are made redundant by the design of the `stringify()` implementation.
|
||||
* Add `toJSON()` or `toISOString()` methods to `Date.prototype`. See the note about date serialization below.
|
||||
|
||||
## Date Serialization
|
||||
|
||||
**JSON 3 deviates from the specification in one important way**: it does not define `Date#toISOString()` or `Date#toJSON()`. This preserves CommonJS compatibility and avoids polluting native prototypes. Instead, date serialization is performed internally by the `stringify()` implementation: if a date object does not define a custom `toJSON()` method, it is serialized as a [simplified ISO 8601 date-time string](http://es5.github.com/#x15.9.1.15).
|
||||
|
||||
**Several native `Date#toJSON()` implementations produce date time strings that do *not* conform to the grammar outlined in the spec**. For instance, all versions of Safari 4, as well as JSON 2, fail to serialize extended years correctly. Furthermore, JSON 2 and older implementations omit the milliseconds from the date-time string (optional in ES 5, but required in 5.1). Finally, in all versions of Safari 4 and 5, serializing an invalid date will produce the string `"Invalid Date"`, rather than `null`. Because these environments exhibit other serialization bugs, however, JSON 3 will override the native `stringify()` implementation.
|
||||
|
||||
Portions of the date serialization code are adapted from the [`date-shim`](https://github.com/Yaffle/date-shim) project.
|
||||
|
||||
# Usage #
|
||||
|
||||
## Web Browsers
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/json3/3.2.4/json3.min.js"></script>
|
||||
<script>
|
||||
JSON.stringify({"Hello": 123});
|
||||
// => '{"Hello":123}'
|
||||
JSON.parse("[[1, 2, 3], 1, 2, 3, 4]", function (key, value) {
|
||||
if (typeof value == "number") {
|
||||
value = value % 2 ? "Odd" : "Even";
|
||||
}
|
||||
return value;
|
||||
});
|
||||
// => [["Odd", "Even", "Odd"], "Odd", "Even", "Odd", "Even"]
|
||||
</script>
|
||||
|
||||
## CommonJS Environments
|
||||
|
||||
var JSON3 = require("./path/to/json3");
|
||||
JSON3.parse("[1, 2, 3]");
|
||||
// => [1, 2, 3]
|
||||
|
||||
## JavaScript Engines
|
||||
|
||||
load("path/to/json3.js");
|
||||
JSON.stringify({"Hello": 123, "Good-bye": 456}, ["Hello"], "\t");
|
||||
// => '{\n\t"Hello": 123\n}'
|
||||
|
||||
# Compatibility #
|
||||
|
||||
JSON 3 has been **tested** with the following web browsers, CommonJS environments, and JavaScript engines.
|
||||
|
||||
## Web Browsers
|
||||
|
||||
- Windows [Internet Explorer](http://www.microsoft.com/windows/internet-explorer), version 6.0 and higher
|
||||
- Mozilla [Firefox](http://www.mozilla.com/firefox), version 1.0 and higher
|
||||
- Apple [Safari](http://www.apple.com/safari), version 2.0 and higher
|
||||
- [Opera](http://www.opera.com) 7.02 and higher
|
||||
- [Mozilla](http://sillydog.org/narchive/gecko.php) 1.0, [Netscape](http://sillydog.org/narchive/) 6.2.3, and [SeaMonkey](http://www.seamonkey-project.org/) 1.0 and higher
|
||||
|
||||
## CommonJS Environments
|
||||
|
||||
- [Node](http://nodejs.org/) 0.2.6 and higher
|
||||
- [RingoJS](http://ringojs.org/) 0.4 and higher
|
||||
- [Narwhal](http://narwhaljs.org/) 0.3.2 and higher
|
||||
|
||||
## JavaScript Engines
|
||||
|
||||
- Mozilla [Rhino](http://www.mozilla.org/rhino) 1.5R5 and higher
|
||||
- WebKit [JSC](https://trac.webkit.org/wiki/JSC)
|
||||
- Google [V8](http://code.google.com/p/v8)
|
||||
|
||||
## Known Incompatibilities
|
||||
|
||||
* Attempting to serialize the `arguments` object may produce inconsistent results across environments due to specification version differences. As a workaround, please convert the `arguments` object to an array first: `JSON.stringify([].slice.call(arguments, 0))`.
|
||||
|
||||
## Required Native Methods
|
||||
|
||||
JSON 3 assumes that the following methods exist and function as described in the ECMAScript specification:
|
||||
|
||||
- The `Number`, `String`, `Array`, `Object`, `Date`, `SyntaxError`, and `TypeError` constructors.
|
||||
- `String.fromCharCode`
|
||||
- `Object#toString`
|
||||
- `Function#call`
|
||||
- `Math.floor`
|
||||
- `Number#toString`
|
||||
- `Date#valueOf`
|
||||
- `String.prototype`: `indexOf`, `charCodeAt`, `charAt`, `slice`.
|
||||
- `Array.prototype`: `push`, `pop`, `join`.
|
||||
|
||||
# Contribute #
|
||||
|
||||
Check out a working copy of the JSON 3 source code with [Git](http://git-scm.com/):
|
||||
|
||||
$ git clone git://github.com/bestiejs/json3.git
|
||||
$ cd json3
|
||||
$ git submodule update --init
|
||||
|
||||
If you'd like to contribute a feature or bug fix, you can [fork](http://help.github.com/fork-a-repo/) JSON 3, commit your changes, and [send a pull request](http://help.github.com/send-pull-requests/). Please make sure to update the unit tests in the `test` directory as well.
|
||||
|
||||
Alternatively, you can use the [GitHub issue tracker](https://github.com/bestiejs/json3/issues) to submit bug reports, feature requests, and questions, or send tweets to [@kitcambridge](http://twitter.com/kitcambridge).
|
||||
|
||||
JSON 3 is released under the [MIT License](http://kit.mit-license.org/).
|
||||
783
vendor/json3/lib/json3.js
vendored
Normal file
783
vendor/json3/lib/json3.js
vendored
Normal file
@@ -0,0 +1,783 @@
|
||||
/*! JSON v3.2.4 | http://bestiejs.github.com/json3 | Copyright 2012, Kit Cambridge | http://kit.mit-license.org */
|
||||
;(function () {
|
||||
// Convenience aliases.
|
||||
var getClass = {}.toString, isProperty, forEach, undef;
|
||||
|
||||
// Detect the `define` function exposed by asynchronous module loaders. The
|
||||
// strict `define` check is necessary for compatibility with `r.js`.
|
||||
var isLoader = typeof define === "function" && define.amd, JSON3 = !isLoader && typeof exports == "object" && exports;
|
||||
|
||||
if (JSON3 || isLoader) {
|
||||
if (typeof JSON == "object" && JSON) {
|
||||
// Delegate to the native `stringify` and `parse` implementations in
|
||||
// asynchronous module loaders and CommonJS environments.
|
||||
if (isLoader) {
|
||||
JSON3 = JSON;
|
||||
} else {
|
||||
JSON3.stringify = JSON.stringify;
|
||||
JSON3.parse = JSON.parse;
|
||||
}
|
||||
} else if (isLoader) {
|
||||
JSON3 = this.JSON = {};
|
||||
}
|
||||
} else {
|
||||
// Export for web browsers and JavaScript engines.
|
||||
JSON3 = this.JSON || (this.JSON = {});
|
||||
}
|
||||
|
||||
// Local variables.
|
||||
var Escapes, toPaddedString, quote, serialize;
|
||||
var fromCharCode, Unescapes, abort, lex, get, walk, update, Index, Source;
|
||||
|
||||
// Test the `Date#getUTC*` methods. Based on work by @Yaffle.
|
||||
var isExtended = new Date(-3509827334573292), floor, Months, getDay;
|
||||
|
||||
try {
|
||||
// The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical
|
||||
// results for certain dates in Opera >= 10.53.
|
||||
isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() == 1 &&
|
||||
// Safari < 2.0.2 stores the internal millisecond time value correctly,
|
||||
// but clips the values returned by the date methods to the range of
|
||||
// signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).
|
||||
isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;
|
||||
} catch (exception) {}
|
||||
|
||||
// Internal: Determines whether the native `JSON.stringify` and `parse`
|
||||
// implementations are spec-compliant. Based on work by Ken Snyder.
|
||||
function has(name) {
|
||||
var stringifySupported, parseSupported, value, serialized = '{"A":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}', all = name == "json";
|
||||
if (all || name == "json-stringify" || name == "json-parse") {
|
||||
// Test `JSON.stringify`.
|
||||
if (name == "json-stringify" || all) {
|
||||
if ((stringifySupported = typeof JSON3.stringify == "function" && isExtended)) {
|
||||
// A test function object with a custom `toJSON` method.
|
||||
(value = function () {
|
||||
return 1;
|
||||
}).toJSON = value;
|
||||
try {
|
||||
stringifySupported =
|
||||
// Firefox 3.1b1 and b2 serialize string, number, and boolean
|
||||
// primitives as object literals.
|
||||
JSON3.stringify(0) === "0" &&
|
||||
// FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
|
||||
// literals.
|
||||
JSON3.stringify(new Number()) === "0" &&
|
||||
JSON3.stringify(new String()) == '""' &&
|
||||
// FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
|
||||
// does not define a canonical JSON representation (this applies to
|
||||
// objects with `toJSON` properties as well, *unless* they are nested
|
||||
// within an object or array).
|
||||
JSON3.stringify(getClass) === undef &&
|
||||
// IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
|
||||
// FF 3.1b3 pass this test.
|
||||
JSON3.stringify(undef) === undef &&
|
||||
// Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
|
||||
// respectively, if the value is omitted entirely.
|
||||
JSON3.stringify() === undef &&
|
||||
// FF 3.1b1, 2 throw an error if the given value is not a number,
|
||||
// string, array, object, Boolean, or `null` literal. This applies to
|
||||
// objects with custom `toJSON` methods as well, unless they are nested
|
||||
// inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
|
||||
// methods entirely.
|
||||
JSON3.stringify(value) === "1" &&
|
||||
JSON3.stringify([value]) == "[1]" &&
|
||||
// Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
|
||||
// `"[null]"`.
|
||||
JSON3.stringify([undef]) == "[null]" &&
|
||||
// YUI 3.0.0b1 fails to serialize `null` literals.
|
||||
JSON3.stringify(null) == "null" &&
|
||||
// FF 3.1b1, 2 halts serialization if an array contains a function:
|
||||
// `[1, true, getClass, 1]` serializes as "[1,true,],". These versions
|
||||
// of Firefox also allow trailing commas in JSON objects and arrays.
|
||||
// FF 3.1b3 elides non-JSON values from objects and arrays, unless they
|
||||
// define custom `toJSON` methods.
|
||||
JSON3.stringify([undef, getClass, null]) == "[null,null,null]" &&
|
||||
// Simple serialization test. FF 3.1b1 uses Unicode escape sequences
|
||||
// where character escape codes are expected (e.g., `\b` => `\u0008`).
|
||||
JSON3.stringify({ "A": [value, true, false, null, "\0\b\n\f\r\t"] }) == serialized &&
|
||||
// FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
|
||||
JSON3.stringify(null, value) === "1" &&
|
||||
JSON3.stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
|
||||
// JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
|
||||
// serialize extended years.
|
||||
JSON3.stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
|
||||
// The milliseconds are optional in ES 5, but required in 5.1.
|
||||
JSON3.stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
|
||||
// Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
|
||||
// four-digit years instead of six-digit years. Credits: @Yaffle.
|
||||
JSON3.stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
|
||||
// Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
|
||||
// values less than 1000. Credits: @Yaffle.
|
||||
JSON3.stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
|
||||
} catch (exception) {
|
||||
stringifySupported = false;
|
||||
}
|
||||
}
|
||||
if (!all) {
|
||||
return stringifySupported;
|
||||
}
|
||||
}
|
||||
// Test `JSON.parse`.
|
||||
if (name == "json-parse" || all) {
|
||||
if (typeof JSON3.parse == "function") {
|
||||
try {
|
||||
// FF 3.1b1, b2 will throw an exception if a bare literal is provided.
|
||||
// Conforming implementations should also coerce the initial argument to
|
||||
// a string prior to parsing.
|
||||
if (JSON3.parse("0") === 0 && !JSON3.parse(false)) {
|
||||
// Simple parsing test.
|
||||
value = JSON3.parse(serialized);
|
||||
if ((parseSupported = value.A.length == 5 && value.A[0] == 1)) {
|
||||
try {
|
||||
// Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
|
||||
parseSupported = !JSON3.parse('"\t"');
|
||||
} catch (exception) {}
|
||||
if (parseSupported) {
|
||||
try {
|
||||
// FF 4.0 and 4.0.1 allow leading `+` signs, and leading and
|
||||
// trailing decimal points. FF 4.0, 4.0.1, and IE 9-10 also
|
||||
// allow certain octal literals.
|
||||
parseSupported = JSON3.parse("01") != 1;
|
||||
} catch (exception) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (exception) {
|
||||
parseSupported = false;
|
||||
}
|
||||
}
|
||||
if (!all) {
|
||||
return parseSupported;
|
||||
}
|
||||
}
|
||||
return stringifySupported && parseSupported;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has("json")) {
|
||||
// Define additional utility methods if the `Date` methods are buggy.
|
||||
if (!isExtended) {
|
||||
floor = Math.floor;
|
||||
// A mapping between the months of the year and the number of days between
|
||||
// January 1st and the first of the respective month.
|
||||
Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||||
// Internal: Calculates the number of days between the Unix epoch and the
|
||||
// first day of the given month.
|
||||
getDay = function (year, month) {
|
||||
return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);
|
||||
};
|
||||
}
|
||||
|
||||
// Internal: Determines if a property is a direct property of the given
|
||||
// object. Delegates to the native `Object#hasOwnProperty` method.
|
||||
if (!(isProperty = {}.hasOwnProperty)) {
|
||||
isProperty = function (property) {
|
||||
var members = {}, constructor;
|
||||
if ((members.__proto__ = null, members.__proto__ = {
|
||||
// The *proto* property cannot be set multiple times in recent
|
||||
// versions of Firefox and SeaMonkey.
|
||||
"toString": 1
|
||||
}, members).toString != getClass) {
|
||||
// Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but
|
||||
// supports the mutable *proto* property.
|
||||
isProperty = function (property) {
|
||||
// Capture and break the object's prototype chain (see section 8.6.2
|
||||
// of the ES 5.1 spec). The parenthesized expression prevents an
|
||||
// unsafe transformation by the Closure Compiler.
|
||||
var original = this.__proto__, result = property in (this.__proto__ = null, this);
|
||||
// Restore the original prototype chain.
|
||||
this.__proto__ = original;
|
||||
return result;
|
||||
};
|
||||
} else {
|
||||
// Capture a reference to the top-level `Object` constructor.
|
||||
constructor = members.constructor;
|
||||
// Use the `constructor` property to simulate `Object#hasOwnProperty` in
|
||||
// other environments.
|
||||
isProperty = function (property) {
|
||||
var parent = (this.constructor || constructor).prototype;
|
||||
return property in this && !(property in parent && this[property] === parent[property]);
|
||||
};
|
||||
}
|
||||
members = null;
|
||||
return isProperty.call(this, property);
|
||||
};
|
||||
}
|
||||
|
||||
// Internal: Normalizes the `for...in` iteration algorithm across
|
||||
// environments. Each enumerated key is yielded to a `callback` function.
|
||||
forEach = function (object, callback) {
|
||||
var size = 0, Properties, members, property, forEach;
|
||||
|
||||
// Tests for bugs in the current environment's `for...in` algorithm. The
|
||||
// `valueOf` property inherits the non-enumerable flag from
|
||||
// `Object.prototype` in older versions of IE, Netscape, and Mozilla.
|
||||
(Properties = function () {
|
||||
this.valueOf = 0;
|
||||
}).prototype.valueOf = 0;
|
||||
|
||||
// Iterate over a new instance of the `Properties` class.
|
||||
members = new Properties();
|
||||
for (property in members) {
|
||||
// Ignore all properties inherited from `Object.prototype`.
|
||||
if (isProperty.call(members, property)) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
Properties = members = null;
|
||||
|
||||
// Normalize the iteration algorithm.
|
||||
if (!size) {
|
||||
// A list of non-enumerable properties inherited from `Object.prototype`.
|
||||
members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"];
|
||||
// IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable
|
||||
// properties.
|
||||
forEach = function (object, callback) {
|
||||
var isFunction = getClass.call(object) == "[object Function]", property, length;
|
||||
for (property in object) {
|
||||
// Gecko <= 1.0 enumerates the `prototype` property of functions under
|
||||
// certain conditions; IE does not.
|
||||
if (!(isFunction && property == "prototype") && isProperty.call(object, property)) {
|
||||
callback(property);
|
||||
}
|
||||
}
|
||||
// Manually invoke the callback for each non-enumerable property.
|
||||
for (length = members.length; property = members[--length]; isProperty.call(object, property) && callback(property));
|
||||
};
|
||||
} else if (size == 2) {
|
||||
// Safari <= 2.0.4 enumerates shadowed properties twice.
|
||||
forEach = function (object, callback) {
|
||||
// Create a set of iterated properties.
|
||||
var members = {}, isFunction = getClass.call(object) == "[object Function]", property;
|
||||
for (property in object) {
|
||||
// Store each property name to prevent double enumeration. The
|
||||
// `prototype` property of functions is not enumerated due to cross-
|
||||
// environment inconsistencies.
|
||||
if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {
|
||||
callback(property);
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
// No bugs detected; use the standard `for...in` algorithm.
|
||||
forEach = function (object, callback) {
|
||||
var isFunction = getClass.call(object) == "[object Function]", property, isConstructor;
|
||||
for (property in object) {
|
||||
if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) {
|
||||
callback(property);
|
||||
}
|
||||
}
|
||||
// Manually invoke the callback for the `constructor` property due to
|
||||
// cross-environment inconsistencies.
|
||||
if (isConstructor || isProperty.call(object, (property = "constructor"))) {
|
||||
callback(property);
|
||||
}
|
||||
};
|
||||
}
|
||||
return forEach(object, callback);
|
||||
};
|
||||
|
||||
// Public: Serializes a JavaScript `value` as a JSON string. The optional
|
||||
// `filter` argument may specify either a function that alters how object and
|
||||
// array members are serialized, or an array of strings and numbers that
|
||||
// indicates which properties should be serialized. The optional `width`
|
||||
// argument may be either a string or number that specifies the indentation
|
||||
// level of the output.
|
||||
if (!has("json-stringify")) {
|
||||
// Internal: A map of control characters and their escaped equivalents.
|
||||
Escapes = {
|
||||
"\\": "\\\\",
|
||||
'"': '\\"',
|
||||
"\b": "\\b",
|
||||
"\f": "\\f",
|
||||
"\n": "\\n",
|
||||
"\r": "\\r",
|
||||
"\t": "\\t"
|
||||
};
|
||||
|
||||
// Internal: Converts `value` into a zero-padded string such that its
|
||||
// length is at least equal to `width`. The `width` must be <= 6.
|
||||
toPaddedString = function (width, value) {
|
||||
// The `|| 0` expression is necessary to work around a bug in
|
||||
// Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`.
|
||||
return ("000000" + (value || 0)).slice(-width);
|
||||
};
|
||||
|
||||
// Internal: Double-quotes a string `value`, replacing all ASCII control
|
||||
// characters (characters with code unit values between 0 and 31) with
|
||||
// their escaped equivalents. This is an implementation of the
|
||||
// `Quote(value)` operation defined in ES 5.1 section 15.12.3.
|
||||
quote = function (value) {
|
||||
var result = '"', index = 0, symbol;
|
||||
for (; symbol = value.charAt(index); index++) {
|
||||
// Escape the reverse solidus, double quote, backspace, form feed, line
|
||||
// feed, carriage return, and tab characters.
|
||||
result += '\\"\b\f\n\r\t'.indexOf(symbol) > -1 ? Escapes[symbol] :
|
||||
// If the character is a control character, append its Unicode escape
|
||||
// sequence; otherwise, append the character as-is.
|
||||
(Escapes[symbol] = symbol < " " ? "\\u00" + toPaddedString(2, symbol.charCodeAt(0).toString(16)) : symbol);
|
||||
}
|
||||
return result + '"';
|
||||
};
|
||||
|
||||
// Internal: Recursively serializes an object. Implements the
|
||||
// `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.
|
||||
serialize = function (property, object, callback, properties, whitespace, indentation, stack) {
|
||||
var value = object[property], className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, any, result;
|
||||
if (typeof value == "object" && value) {
|
||||
className = getClass.call(value);
|
||||
if (className == "[object Date]" && !isProperty.call(value, "toJSON")) {
|
||||
if (value > -1 / 0 && value < 1 / 0) {
|
||||
// Dates are serialized according to the `Date#toJSON` method
|
||||
// specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15
|
||||
// for the ISO 8601 date time string format.
|
||||
if (getDay) {
|
||||
// Manually compute the year, month, date, hours, minutes,
|
||||
// seconds, and milliseconds if the `getUTC*` methods are
|
||||
// buggy. Adapted from @Yaffle's `date-shim` project.
|
||||
date = floor(value / 864e5);
|
||||
for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);
|
||||
for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);
|
||||
date = 1 + date - getDay(year, month);
|
||||
// The `time` value specifies the time within the day (see ES
|
||||
// 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used
|
||||
// to compute `A modulo B`, as the `%` operator does not
|
||||
// correspond to the `modulo` operation for negative numbers.
|
||||
time = (value % 864e5 + 864e5) % 864e5;
|
||||
// The hours, minutes, seconds, and milliseconds are obtained by
|
||||
// decomposing the time within the day. See section 15.9.1.10.
|
||||
hours = floor(time / 36e5) % 24;
|
||||
minutes = floor(time / 6e4) % 60;
|
||||
seconds = floor(time / 1e3) % 60;
|
||||
milliseconds = time % 1e3;
|
||||
} else {
|
||||
year = value.getUTCFullYear();
|
||||
month = value.getUTCMonth();
|
||||
date = value.getUTCDate();
|
||||
hours = value.getUTCHours();
|
||||
minutes = value.getUTCMinutes();
|
||||
seconds = value.getUTCSeconds();
|
||||
milliseconds = value.getUTCMilliseconds();
|
||||
}
|
||||
// Serialize extended years correctly.
|
||||
value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +
|
||||
"-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) +
|
||||
// Months, dates, hours, minutes, and seconds should have two
|
||||
// digits; milliseconds should have three.
|
||||
"T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) +
|
||||
// Milliseconds are optional in ES 5.0, but required in 5.1.
|
||||
"." + toPaddedString(3, milliseconds) + "Z";
|
||||
} else {
|
||||
value = null;
|
||||
}
|
||||
} else if (typeof value.toJSON == "function" && ((className != "[object Number]" && className != "[object String]" && className != "[object Array]") || isProperty.call(value, "toJSON"))) {
|
||||
// Prototype <= 1.6.1 adds non-standard `toJSON` methods to the
|
||||
// `Number`, `String`, `Date`, and `Array` prototypes. JSON 3
|
||||
// ignores all `toJSON` methods on these objects unless they are
|
||||
// defined directly on an instance.
|
||||
value = value.toJSON(property);
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
// If a replacement function was provided, call it to obtain the value
|
||||
// for serialization.
|
||||
value = callback.call(object, property, value);
|
||||
}
|
||||
if (value === null) {
|
||||
return "null";
|
||||
}
|
||||
className = getClass.call(value);
|
||||
if (className == "[object Boolean]") {
|
||||
// Booleans are represented literally.
|
||||
return "" + value;
|
||||
} else if (className == "[object Number]") {
|
||||
// JSON numbers must be finite. `Infinity` and `NaN` are serialized as
|
||||
// `"null"`.
|
||||
return value > -1 / 0 && value < 1 / 0 ? "" + value : "null";
|
||||
} else if (className == "[object String]") {
|
||||
// Strings are double-quoted and escaped.
|
||||
return quote(value);
|
||||
}
|
||||
// Recursively serialize objects and arrays.
|
||||
if (typeof value == "object") {
|
||||
// Check for cyclic structures. This is a linear search; performance
|
||||
// is inversely proportional to the number of unique nested objects.
|
||||
for (length = stack.length; length--;) {
|
||||
if (stack[length] === value) {
|
||||
// Cyclic structures cannot be serialized by `JSON.stringify`.
|
||||
throw TypeError();
|
||||
}
|
||||
}
|
||||
// Add the object to the stack of traversed objects.
|
||||
stack.push(value);
|
||||
results = [];
|
||||
// Save the current indentation level and indent one additional level.
|
||||
prefix = indentation;
|
||||
indentation += whitespace;
|
||||
if (className == "[object Array]") {
|
||||
// Recursively serialize array elements.
|
||||
for (index = 0, length = value.length; index < length; any || (any = true), index++) {
|
||||
element = serialize(index, value, callback, properties, whitespace, indentation, stack);
|
||||
results.push(element === undef ? "null" : element);
|
||||
}
|
||||
result = any ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]";
|
||||
} else {
|
||||
// Recursively serialize object members. Members are selected from
|
||||
// either a user-specified list of property names, or the object
|
||||
// itself.
|
||||
forEach(properties || value, function (property) {
|
||||
var element = serialize(property, value, callback, properties, whitespace, indentation, stack);
|
||||
if (element !== undef) {
|
||||
// According to ES 5.1 section 15.12.3: "If `gap` {whitespace}
|
||||
// is not the empty string, let `member` {quote(property) + ":"}
|
||||
// be the concatenation of `member` and the `space` character."
|
||||
// The "`space` character" refers to the literal space
|
||||
// character, not the `space` {width} argument provided to
|
||||
// `JSON.stringify`.
|
||||
results.push(quote(property) + ":" + (whitespace ? " " : "") + element);
|
||||
}
|
||||
any || (any = true);
|
||||
});
|
||||
result = any ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}";
|
||||
}
|
||||
// Remove the object from the traversed object stack.
|
||||
stack.pop();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// Public: `JSON.stringify`. See ES 5.1 section 15.12.3.
|
||||
JSON3.stringify = function (source, filter, width) {
|
||||
var whitespace, callback, properties, index, length, value;
|
||||
if (typeof filter == "function" || typeof filter == "object" && filter) {
|
||||
if (getClass.call(filter) == "[object Function]") {
|
||||
callback = filter;
|
||||
} else if (getClass.call(filter) == "[object Array]") {
|
||||
// Convert the property names array into a makeshift set.
|
||||
properties = {};
|
||||
for (index = 0, length = filter.length; index < length; value = filter[index++], ((getClass.call(value) == "[object String]" || getClass.call(value) == "[object Number]") && (properties[value] = 1)));
|
||||
}
|
||||
}
|
||||
if (width) {
|
||||
if (getClass.call(width) == "[object Number]") {
|
||||
// Convert the `width` to an integer and create a string containing
|
||||
// `width` number of space characters.
|
||||
if ((width -= width % 1) > 0) {
|
||||
for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " ");
|
||||
}
|
||||
} else if (getClass.call(width) == "[object String]") {
|
||||
whitespace = width.length <= 10 ? width : width.slice(0, 10);
|
||||
}
|
||||
}
|
||||
// Opera <= 7.54u2 discards the values associated with empty string keys
|
||||
// (`""`) only if they are used directly within an object member list
|
||||
// (e.g., `!("" in { "": 1})`).
|
||||
return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []);
|
||||
};
|
||||
}
|
||||
|
||||
// Public: Parses a JSON source string.
|
||||
if (!has("json-parse")) {
|
||||
fromCharCode = String.fromCharCode;
|
||||
// Internal: A map of escaped control characters and their unescaped
|
||||
// equivalents.
|
||||
Unescapes = {
|
||||
"\\": "\\",
|
||||
'"': '"',
|
||||
"/": "/",
|
||||
"b": "\b",
|
||||
"t": "\t",
|
||||
"n": "\n",
|
||||
"f": "\f",
|
||||
"r": "\r"
|
||||
};
|
||||
|
||||
// Internal: Resets the parser state and throws a `SyntaxError`.
|
||||
abort = function() {
|
||||
Index = Source = null;
|
||||
throw SyntaxError();
|
||||
};
|
||||
|
||||
// Internal: Returns the next token, or `"$"` if the parser has reached
|
||||
// the end of the source string. A token may be a string, number, `null`
|
||||
// literal, or Boolean literal.
|
||||
lex = function () {
|
||||
var source = Source, length = source.length, symbol, value, begin, position, sign;
|
||||
while (Index < length) {
|
||||
symbol = source.charAt(Index);
|
||||
if ("\t\r\n ".indexOf(symbol) > -1) {
|
||||
// Skip whitespace tokens, including tabs, carriage returns, line
|
||||
// feeds, and space characters.
|
||||
Index++;
|
||||
} else if ("{}[]:,".indexOf(symbol) > -1) {
|
||||
// Parse a punctuator token at the current position.
|
||||
Index++;
|
||||
return symbol;
|
||||
} else if (symbol == '"') {
|
||||
// Advance to the next character and parse a JSON string at the
|
||||
// current position. String tokens are prefixed with the sentinel
|
||||
// `@` character to distinguish them from punctuators.
|
||||
for (value = "@", Index++; Index < length;) {
|
||||
symbol = source.charAt(Index);
|
||||
if (symbol < " ") {
|
||||
// Unescaped ASCII control characters are not permitted.
|
||||
abort();
|
||||
} else if (symbol == "\\") {
|
||||
// Parse escaped JSON control characters, `"`, `\`, `/`, and
|
||||
// Unicode escape sequences.
|
||||
symbol = source.charAt(++Index);
|
||||
if ('\\"/btnfr'.indexOf(symbol) > -1) {
|
||||
// Revive escaped control characters.
|
||||
value += Unescapes[symbol];
|
||||
Index++;
|
||||
} else if (symbol == "u") {
|
||||
// Advance to the first character of the escape sequence.
|
||||
begin = ++Index;
|
||||
// Validate the Unicode escape sequence.
|
||||
for (position = Index + 4; Index < position; Index++) {
|
||||
symbol = source.charAt(Index);
|
||||
// A valid sequence comprises four hexdigits that form a
|
||||
// single hexadecimal value.
|
||||
if (!(symbol >= "0" && symbol <= "9" || symbol >= "a" && symbol <= "f" || symbol >= "A" && symbol <= "F")) {
|
||||
// Invalid Unicode escape sequence.
|
||||
abort();
|
||||
}
|
||||
}
|
||||
// Revive the escaped character.
|
||||
value += fromCharCode("0x" + source.slice(begin, Index));
|
||||
} else {
|
||||
// Invalid escape sequence.
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
if (symbol == '"') {
|
||||
// An unescaped double-quote character marks the end of the
|
||||
// string.
|
||||
break;
|
||||
}
|
||||
// Append the original character as-is.
|
||||
value += symbol;
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
if (source.charAt(Index) == '"') {
|
||||
Index++;
|
||||
// Return the revived string.
|
||||
return value;
|
||||
}
|
||||
// Unterminated string.
|
||||
abort();
|
||||
} else {
|
||||
// Parse numbers and literals.
|
||||
begin = Index;
|
||||
// Advance the scanner's position past the sign, if one is
|
||||
// specified.
|
||||
if (symbol == "-") {
|
||||
sign = true;
|
||||
symbol = source.charAt(++Index);
|
||||
}
|
||||
// Parse an integer or floating-point value.
|
||||
if (symbol >= "0" && symbol <= "9") {
|
||||
// Leading zeroes are interpreted as octal literals.
|
||||
if (symbol == "0" && (symbol = source.charAt(Index + 1), symbol >= "0" && symbol <= "9")) {
|
||||
// Illegal octal literal.
|
||||
abort();
|
||||
}
|
||||
sign = false;
|
||||
// Parse the integer component.
|
||||
for (; Index < length && (symbol = source.charAt(Index), symbol >= "0" && symbol <= "9"); Index++);
|
||||
// Floats cannot contain a leading decimal point; however, this
|
||||
// case is already accounted for by the parser.
|
||||
if (source.charAt(Index) == ".") {
|
||||
position = ++Index;
|
||||
// Parse the decimal component.
|
||||
for (; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position++);
|
||||
if (position == Index) {
|
||||
// Illegal trailing decimal.
|
||||
abort();
|
||||
}
|
||||
Index = position;
|
||||
}
|
||||
// Parse exponents.
|
||||
symbol = source.charAt(Index);
|
||||
if (symbol == "e" || symbol == "E") {
|
||||
// Skip past the sign following the exponent, if one is
|
||||
// specified.
|
||||
symbol = source.charAt(++Index);
|
||||
if (symbol == "+" || symbol == "-") {
|
||||
Index++;
|
||||
}
|
||||
// Parse the exponential component.
|
||||
for (position = Index; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position++);
|
||||
if (position == Index) {
|
||||
// Illegal empty exponent.
|
||||
abort();
|
||||
}
|
||||
Index = position;
|
||||
}
|
||||
// Coerce the parsed value to a JavaScript number.
|
||||
return +source.slice(begin, Index);
|
||||
}
|
||||
// A negative sign may only precede numbers.
|
||||
if (sign) {
|
||||
abort();
|
||||
}
|
||||
// `true`, `false`, and `null` literals.
|
||||
if (source.slice(Index, Index + 4) == "true") {
|
||||
Index += 4;
|
||||
return true;
|
||||
} else if (source.slice(Index, Index + 5) == "false") {
|
||||
Index += 5;
|
||||
return false;
|
||||
} else if (source.slice(Index, Index + 4) == "null") {
|
||||
Index += 4;
|
||||
return null;
|
||||
}
|
||||
// Unrecognized token.
|
||||
abort();
|
||||
}
|
||||
}
|
||||
// Return the sentinel `$` character if the parser has reached the end
|
||||
// of the source string.
|
||||
return "$";
|
||||
};
|
||||
|
||||
// Internal: Parses a JSON `value` token.
|
||||
get = function (value) {
|
||||
var results, any, key;
|
||||
if (value == "$") {
|
||||
// Unexpected end of input.
|
||||
abort();
|
||||
}
|
||||
if (typeof value == "string") {
|
||||
if (value.charAt(0) == "@") {
|
||||
// Remove the sentinel `@` character.
|
||||
return value.slice(1);
|
||||
}
|
||||
// Parse object and array literals.
|
||||
if (value == "[") {
|
||||
// Parses a JSON array, returning a new JavaScript array.
|
||||
results = [];
|
||||
for (;; any || (any = true)) {
|
||||
value = lex();
|
||||
// A closing square bracket marks the end of the array literal.
|
||||
if (value == "]") {
|
||||
break;
|
||||
}
|
||||
// If the array literal contains elements, the current token
|
||||
// should be a comma separating the previous element from the
|
||||
// next.
|
||||
if (any) {
|
||||
if (value == ",") {
|
||||
value = lex();
|
||||
if (value == "]") {
|
||||
// Unexpected trailing `,` in array literal.
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
// A `,` must separate each array element.
|
||||
abort();
|
||||
}
|
||||
}
|
||||
// Elisions and leading commas are not permitted.
|
||||
if (value == ",") {
|
||||
abort();
|
||||
}
|
||||
results.push(get(value));
|
||||
}
|
||||
return results;
|
||||
} else if (value == "{") {
|
||||
// Parses a JSON object, returning a new JavaScript object.
|
||||
results = {};
|
||||
for (;; any || (any = true)) {
|
||||
value = lex();
|
||||
// A closing curly brace marks the end of the object literal.
|
||||
if (value == "}") {
|
||||
break;
|
||||
}
|
||||
// If the object literal contains members, the current token
|
||||
// should be a comma separator.
|
||||
if (any) {
|
||||
if (value == ",") {
|
||||
value = lex();
|
||||
if (value == "}") {
|
||||
// Unexpected trailing `,` in object literal.
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
// A `,` must separate each object member.
|
||||
abort();
|
||||
}
|
||||
}
|
||||
// Leading commas are not permitted, object property names must be
|
||||
// double-quoted strings, and a `:` must separate each property
|
||||
// name and value.
|
||||
if (value == "," || typeof value != "string" || value.charAt(0) != "@" || lex() != ":") {
|
||||
abort();
|
||||
}
|
||||
results[value.slice(1)] = get(lex());
|
||||
}
|
||||
return results;
|
||||
}
|
||||
// Unexpected token encountered.
|
||||
abort();
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
// Internal: Updates a traversed object member.
|
||||
update = function(source, property, callback) {
|
||||
var element = walk(source, property, callback);
|
||||
if (element === undef) {
|
||||
delete source[property];
|
||||
} else {
|
||||
source[property] = element;
|
||||
}
|
||||
};
|
||||
|
||||
// Internal: Recursively traverses a parsed JSON object, invoking the
|
||||
// `callback` function for each value. This is an implementation of the
|
||||
// `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.
|
||||
walk = function (source, property, callback) {
|
||||
var value = source[property], length;
|
||||
if (typeof value == "object" && value) {
|
||||
if (getClass.call(value) == "[object Array]") {
|
||||
for (length = value.length; length--;) {
|
||||
update(value, length, callback);
|
||||
}
|
||||
} else {
|
||||
// `forEach` can't be used to traverse an array in Opera <= 8.54,
|
||||
// as `Object#hasOwnProperty` returns `false` for array indices
|
||||
// (e.g., `![1, 2, 3].hasOwnProperty("0")`).
|
||||
forEach(value, function (property) {
|
||||
update(value, property, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
return callback.call(source, property, value);
|
||||
};
|
||||
|
||||
// Public: `JSON.parse`. See ES 5.1 section 15.12.2.
|
||||
JSON3.parse = function (source, callback) {
|
||||
var result, value;
|
||||
Index = 0;
|
||||
Source = source;
|
||||
result = get(lex());
|
||||
// If a JSON string contains multiple tokens, it is invalid.
|
||||
if (lex() != "$") {
|
||||
abort();
|
||||
}
|
||||
// Reset the parser state.
|
||||
Index = Source = null;
|
||||
return callback && getClass.call(callback) == "[object Function]" ? walk((value = {}, value[""] = result, value), "", callback) : result;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Export for asynchronous module loaders.
|
||||
if (isLoader) {
|
||||
define(function () {
|
||||
return JSON3;
|
||||
});
|
||||
}
|
||||
}).call(this);
|
||||
14
vendor/qunit/README.md
vendored
14
vendor/qunit/README.md
vendored
@@ -1,4 +1,4 @@
|
||||
[QUnit](http://docs.jquery.com/QUnit) - A JavaScript Unit Testing framework.
|
||||
[QUnit](http://qunitjs.com) - A JavaScript Unit Testing framework.
|
||||
================================
|
||||
|
||||
QUnit is a powerful, easy-to-use, JavaScript test suite. It's used by the jQuery
|
||||
@@ -35,7 +35,8 @@ the change, run `grunt` to lint and test it, then commit, push and create a pull
|
||||
Include some background for the change in the commit message and `Fixes #nnn`, referring
|
||||
to the issue number you're addressing.
|
||||
|
||||
To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`.
|
||||
To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`. That gives you a global
|
||||
grunt binary. For additional grunt tasks, also run `npm install`.
|
||||
|
||||
Releases
|
||||
--------
|
||||
@@ -47,3 +48,12 @@ tag, update them again to the next version, commit and push commits and tags
|
||||
|
||||
Put the 'v' in front of the tag, e.g. `v1.8.0`. Clean up the changelog, removing merge commits
|
||||
or whitespace cleanups.
|
||||
|
||||
To upload to code.jquery.com (replace $version accordingly):
|
||||
|
||||
scp -q qunit/qunit.js jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/qunit/qunit-$version.js
|
||||
scp -q qunit/qunit.css jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/qunit/qunit-$version.css
|
||||
|
||||
Then update /var/www/html/code.jquery.com/index.html and purge it with:
|
||||
|
||||
curl -s http://code.origin.jquery.com/?reload
|
||||
16
vendor/qunit/qunit/qunit.css
vendored
16
vendor/qunit/qunit/qunit.css
vendored
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* QUnit v1.9.0 - A JavaScript Unit Testing Framework
|
||||
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://docs.jquery.com/QUnit
|
||||
* http://qunitjs.com
|
||||
*
|
||||
* Copyright (c) 2012 John Resig, Jörn Zaefferer
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* or GPL (GPL-LICENSE.txt) licenses.
|
||||
* Copyright 2012 jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*/
|
||||
|
||||
/** Font Family and Sizes */
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
|
||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -67,6 +67,7 @@
|
||||
padding: 0.5em 0 0.5em 2em;
|
||||
color: #5E740B;
|
||||
background-color: #eee;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#qunit-userAgent {
|
||||
@@ -76,6 +77,9 @@
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
|
||||
#qunit-modulefilter-container {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/** Tests: Pass/Fail */
|
||||
|
||||
|
||||
89
vendor/qunit/qunit/qunit.js
vendored
89
vendor/qunit/qunit/qunit.js
vendored
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* QUnit v1.9.0 - A JavaScript Unit Testing Framework
|
||||
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://docs.jquery.com/QUnit
|
||||
* http://qunitjs.com
|
||||
*
|
||||
* Copyright (c) 2012 John Resig, Jörn Zaefferer
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* or GPL (GPL-LICENSE.txt) licenses.
|
||||
* Copyright 2012 jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*/
|
||||
|
||||
(function( window ) {
|
||||
@@ -17,6 +17,8 @@ var QUnit,
|
||||
fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
|
||||
toString = Object.prototype.toString,
|
||||
hasOwn = Object.prototype.hasOwnProperty,
|
||||
// Keep a local reference to Date (GH-283)
|
||||
Date = window.Date,
|
||||
defined = {
|
||||
setTimeout: typeof window.setTimeout !== "undefined",
|
||||
sessionStorage: (function() {
|
||||
@@ -304,7 +306,8 @@ QUnit = {
|
||||
// call on start of module test to prepend name to all tests
|
||||
module: function( name, testEnvironment ) {
|
||||
config.currentModule = name;
|
||||
config.currentModuleTestEnviroment = testEnvironment;
|
||||
config.currentModuleTestEnvironment = testEnvironment;
|
||||
config.modules[name] = true;
|
||||
},
|
||||
|
||||
asyncTest: function( testName, expected, callback ) {
|
||||
@@ -336,7 +339,7 @@ QUnit = {
|
||||
async: async,
|
||||
callback: callback,
|
||||
module: config.currentModule,
|
||||
moduleTestEnvironment: config.currentModuleTestEnviroment,
|
||||
moduleTestEnvironment: config.currentModuleTestEnvironment,
|
||||
stack: sourceFromStacktrace( 2 )
|
||||
});
|
||||
|
||||
@@ -349,7 +352,11 @@ QUnit = {
|
||||
|
||||
// Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
|
||||
expect: function( asserts ) {
|
||||
config.current.expected = asserts;
|
||||
if (arguments.length === 1) {
|
||||
config.current.expected = asserts;
|
||||
} else {
|
||||
return config.current.expected;
|
||||
}
|
||||
},
|
||||
|
||||
start: function( count ) {
|
||||
@@ -415,6 +422,8 @@ QUnit.assert = {
|
||||
|
||||
var source,
|
||||
details = {
|
||||
module: config.current.module,
|
||||
name: config.current.testName,
|
||||
result: result,
|
||||
message: msg
|
||||
};
|
||||
@@ -600,6 +609,9 @@ config = {
|
||||
}
|
||||
],
|
||||
|
||||
// Set of all modules.
|
||||
modules: {},
|
||||
|
||||
// logging callback queues
|
||||
begin: [],
|
||||
done: [],
|
||||
@@ -710,17 +722,10 @@ extend( QUnit, {
|
||||
},
|
||||
|
||||
// Resets the test setup. Useful for tests that modify the DOM.
|
||||
// If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
|
||||
reset: function() {
|
||||
var fixture;
|
||||
|
||||
if ( window.jQuery ) {
|
||||
jQuery( "#qunit-fixture" ).html( config.fixture );
|
||||
} else {
|
||||
fixture = id( "qunit-fixture" );
|
||||
if ( fixture ) {
|
||||
fixture.innerHTML = config.fixture;
|
||||
}
|
||||
var fixture = id( "qunit-fixture" );
|
||||
if ( fixture ) {
|
||||
fixture.innerHTML = config.fixture;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -781,6 +786,8 @@ extend( QUnit, {
|
||||
|
||||
var output, source,
|
||||
details = {
|
||||
module: config.current.module,
|
||||
name: config.current.testName,
|
||||
result: result,
|
||||
message: message,
|
||||
actual: actual,
|
||||
@@ -826,6 +833,8 @@ extend( QUnit, {
|
||||
|
||||
var output,
|
||||
details = {
|
||||
module: config.current.module,
|
||||
name: config.current.testName,
|
||||
result: false,
|
||||
message: message
|
||||
};
|
||||
@@ -916,7 +925,9 @@ QUnit.load = function() {
|
||||
runLoggingCallbacks( "begin", QUnit, {} );
|
||||
|
||||
// Initialize the config, saving the execution queue
|
||||
var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes,
|
||||
var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, moduleFilter,
|
||||
numModules = 0,
|
||||
moduleFilterHtml = "",
|
||||
urlConfigHtml = "",
|
||||
oldconfig = extend( {}, config );
|
||||
|
||||
@@ -940,6 +951,15 @@ QUnit.load = function() {
|
||||
urlConfigHtml += "<input id='qunit-urlconfig-" + val.id + "' name='" + val.id + "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) + " title='" + val.tooltip + "'><label for='qunit-urlconfig-" + val.id + "' title='" + val.tooltip + "'>" + val.label + "</label>";
|
||||
}
|
||||
|
||||
moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " + ( config.module === undefined ? "selected" : "" ) + ">< All Modules ></option>";
|
||||
for ( i in config.modules ) {
|
||||
if ( config.modules.hasOwnProperty( i ) ) {
|
||||
numModules += 1;
|
||||
moduleFilterHtml += "<option value='" + encodeURIComponent(i) + "' " + ( config.module === i ? "selected" : "" ) + ">" + i + "</option>";
|
||||
}
|
||||
}
|
||||
moduleFilterHtml += "</select>";
|
||||
|
||||
// `userAgent` initialized at top of scope
|
||||
userAgent = id( "qunit-userAgent" );
|
||||
if ( userAgent ) {
|
||||
@@ -1002,6 +1022,19 @@ QUnit.load = function() {
|
||||
window.location = QUnit.url( params );
|
||||
});
|
||||
toolbar.appendChild( urlConfigCheckboxes );
|
||||
|
||||
if (numModules > 1) {
|
||||
moduleFilter = document.createElement( 'span' );
|
||||
moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
|
||||
moduleFilter.innerHTML = moduleFilterHtml;
|
||||
addEvent( moduleFilter, "change", function() {
|
||||
var selectBox = moduleFilter.getElementsByTagName("select")[0],
|
||||
selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
|
||||
|
||||
window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
|
||||
});
|
||||
toolbar.appendChild(moduleFilter);
|
||||
}
|
||||
}
|
||||
|
||||
// `main` initialized at top of scope
|
||||
@@ -1039,9 +1072,9 @@ window.onerror = function ( error, filePath, linerNr ) {
|
||||
}
|
||||
QUnit.pushFailure( error, filePath + ":" + linerNr );
|
||||
} else {
|
||||
QUnit.test( "global failure", function() {
|
||||
QUnit.test( "global failure", extend( function() {
|
||||
QUnit.pushFailure( error, filePath + ":" + linerNr );
|
||||
});
|
||||
}, { validTest: validTest } ) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1108,6 +1141,11 @@ function done() {
|
||||
}
|
||||
}
|
||||
|
||||
// scroll back to top to show results
|
||||
if ( window.scrollTo ) {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
runLoggingCallbacks( "done", QUnit, {
|
||||
failed: config.stats.bad,
|
||||
passed: passed,
|
||||
@@ -1123,6 +1161,12 @@ function validTest( test ) {
|
||||
module = config.module && config.module.toLowerCase(),
|
||||
fullName = (test.module + ": " + test.testName).toLowerCase();
|
||||
|
||||
// Internally-generated tests are always valid
|
||||
if ( test.callback && test.callback.validTest === validTest ) {
|
||||
delete test.callback.validTest;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( config.testNumber ) {
|
||||
return test.testNumber === config.testNumber;
|
||||
}
|
||||
@@ -1404,7 +1448,8 @@ QUnit.equiv = (function() {
|
||||
a.global === b.global &&
|
||||
// (gmi) ...
|
||||
a.ignoreCase === b.ignoreCase &&
|
||||
a.multiline === b.multiline;
|
||||
a.multiline === b.multiline &&
|
||||
a.sticky === b.sticky;
|
||||
},
|
||||
|
||||
// - skip when the property is a method of an instance (OOP)
|
||||
|
||||
169
vendor/requirejs/require.js
vendored
169
vendor/requirejs/require.js
vendored
@@ -1,5 +1,5 @@
|
||||
/** vim: et:ts=4:sw=4:sts=4
|
||||
* @license RequireJS 2.1.0 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
* @license RequireJS 2.1.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
* Available via the MIT or new BSD license.
|
||||
* see: http://github.com/jrburke/requirejs for details
|
||||
*/
|
||||
@@ -12,7 +12,7 @@ var requirejs, require, define;
|
||||
(function (global) {
|
||||
var req, s, head, baseElement, dataMain, src,
|
||||
interactiveScript, currentlyAddingScript, mainScript, subPath,
|
||||
version = '2.1.0',
|
||||
version = '2.1.2',
|
||||
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
|
||||
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
|
||||
jsSuffixRegExp = /\.js$/,
|
||||
@@ -81,6 +81,10 @@ var requirejs, require, define;
|
||||
return hasOwn.call(obj, prop);
|
||||
}
|
||||
|
||||
function getOwn(obj, prop) {
|
||||
return hasProp(obj, prop) && obj[prop];
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycles over properties in an object and calls a function for each
|
||||
* property value. If the function returns a truthy value, then the
|
||||
@@ -89,7 +93,7 @@ var requirejs, require, define;
|
||||
function eachProp(obj, func) {
|
||||
var prop;
|
||||
for (prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
if (hasProp(obj, prop)) {
|
||||
if (func(obj[prop], prop)) {
|
||||
break;
|
||||
}
|
||||
@@ -100,9 +104,6 @@ var requirejs, require, define;
|
||||
/**
|
||||
* Simple function to mix in properties from source into target,
|
||||
* but only if target does not already have a property of the same name.
|
||||
* This is not robust in IE for transferring methods that match
|
||||
* Object.prototype names, but the uses of mixin here seem unlikely to
|
||||
* trigger a problem related to that.
|
||||
*/
|
||||
function mixin(target, source, force, deepStringMixin) {
|
||||
if (source) {
|
||||
@@ -195,7 +196,9 @@ var requirejs, require, define;
|
||||
baseUrl: './',
|
||||
paths: {},
|
||||
pkgs: {},
|
||||
shim: {}
|
||||
shim: {},
|
||||
map: {},
|
||||
config: {}
|
||||
},
|
||||
registry = {},
|
||||
undefEvents = {},
|
||||
@@ -262,7 +265,7 @@ var requirejs, require, define;
|
||||
//otherwise, assume it is a top-level require that will
|
||||
//be relative to baseUrl in the end.
|
||||
if (baseName) {
|
||||
if (config.pkgs[baseName]) {
|
||||
if (getOwn(config.pkgs, baseName)) {
|
||||
//If the baseName is a package name, then just treat it as one
|
||||
//name to concat the name with.
|
||||
normalizedBaseParts = baseParts = [baseName];
|
||||
@@ -280,7 +283,7 @@ var requirejs, require, define;
|
||||
|
||||
//Some use of packages may use a . path to reference the
|
||||
//'main' module name, so normalize for that.
|
||||
pkgConfig = config.pkgs[(pkgName = name[0])];
|
||||
pkgConfig = getOwn(config.pkgs, (pkgName = name[0]));
|
||||
name = name.join('/');
|
||||
if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {
|
||||
name = pkgName;
|
||||
@@ -303,12 +306,12 @@ var requirejs, require, define;
|
||||
//Find the longest baseName segment match in the config.
|
||||
//So, do joins on the biggest to smallest lengths of baseParts.
|
||||
for (j = baseParts.length; j > 0; j -= 1) {
|
||||
mapValue = map[baseParts.slice(0, j).join('/')];
|
||||
mapValue = getOwn(map, baseParts.slice(0, j).join('/'));
|
||||
|
||||
//baseName segment has config, find if it has one for
|
||||
//this name.
|
||||
if (mapValue) {
|
||||
mapValue = mapValue[nameSegment];
|
||||
mapValue = getOwn(mapValue, nameSegment);
|
||||
if (mapValue) {
|
||||
//Match, update name to the new value.
|
||||
foundMap = mapValue;
|
||||
@@ -326,8 +329,8 @@ var requirejs, require, define;
|
||||
//Check for a star map match, but just hold on to it,
|
||||
//if there is a shorter segment match later in a matching
|
||||
//config, then favor over this star map.
|
||||
if (!foundStarMap && starMap && starMap[nameSegment]) {
|
||||
foundStarMap = starMap[nameSegment];
|
||||
if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {
|
||||
foundStarMap = getOwn(starMap, nameSegment);
|
||||
starI = i;
|
||||
}
|
||||
}
|
||||
@@ -359,7 +362,7 @@ var requirejs, require, define;
|
||||
}
|
||||
|
||||
function hasPathFallback(id) {
|
||||
var pathConfig = config.paths[id];
|
||||
var pathConfig = getOwn(config.paths, id);
|
||||
if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
|
||||
removeScript(id);
|
||||
//Pop off the first array value, since it failed, and
|
||||
@@ -420,7 +423,7 @@ var requirejs, require, define;
|
||||
|
||||
if (prefix) {
|
||||
prefix = normalize(prefix, parentName, applyMap);
|
||||
pluginModule = defined[prefix];
|
||||
pluginModule = getOwn(defined, prefix);
|
||||
}
|
||||
|
||||
//Account for relative paths if there is a base name.
|
||||
@@ -473,7 +476,7 @@ var requirejs, require, define;
|
||||
|
||||
function getModule(depMap) {
|
||||
var id = depMap.id,
|
||||
mod = registry[id];
|
||||
mod = getOwn(registry, id);
|
||||
|
||||
if (!mod) {
|
||||
mod = registry[id] = new context.Module(depMap);
|
||||
@@ -484,7 +487,7 @@ var requirejs, require, define;
|
||||
|
||||
function on(depMap, name, fn) {
|
||||
var id = depMap.id,
|
||||
mod = registry[id];
|
||||
mod = getOwn(registry, id);
|
||||
|
||||
if (hasProp(defined, id) &&
|
||||
(!mod || mod.defineEmitComplete)) {
|
||||
@@ -504,7 +507,7 @@ var requirejs, require, define;
|
||||
errback(err);
|
||||
} else {
|
||||
each(ids, function (id) {
|
||||
var mod = registry[id];
|
||||
var mod = getOwn(registry, id);
|
||||
if (mod) {
|
||||
//Set error on module, so it skips timeout checks.
|
||||
mod.error = err;
|
||||
@@ -563,7 +566,7 @@ var requirejs, require, define;
|
||||
id: mod.map.id,
|
||||
uri: mod.map.url,
|
||||
config: function () {
|
||||
return (config.config && config.config[mod.map.id]) || {};
|
||||
return (config.config && getOwn(config.config, mod.map.id)) || {};
|
||||
},
|
||||
exports: defined[mod.map.id]
|
||||
});
|
||||
@@ -585,14 +588,14 @@ var requirejs, require, define;
|
||||
traced[id] = true;
|
||||
each(mod.depMaps, function (depMap, i) {
|
||||
var depId = depMap.id,
|
||||
dep = registry[depId];
|
||||
dep = getOwn(registry, depId);
|
||||
|
||||
//Only force things that have not completed
|
||||
//being defined, so still in the registry,
|
||||
//and only if it has not been matched up
|
||||
//in the module already.
|
||||
if (dep && !mod.depMatched[i] && !processed[depId]) {
|
||||
if (traced[depId]) {
|
||||
if (getOwn(traced, depId)) {
|
||||
mod.defineDep(i, defined[depId]);
|
||||
mod.check(); //pass false?
|
||||
} else {
|
||||
@@ -692,9 +695,9 @@ var requirejs, require, define;
|
||||
}
|
||||
|
||||
Module = function (map) {
|
||||
this.events = undefEvents[map.id] || {};
|
||||
this.events = getOwn(undefEvents, map.id) || {};
|
||||
this.map = map;
|
||||
this.shim = config.shim[map.id];
|
||||
this.shim = getOwn(config.shim, map.id);
|
||||
this.depExports = [];
|
||||
this.depMaps = [];
|
||||
this.depMatched = [];
|
||||
@@ -941,7 +944,7 @@ var requirejs, require, define;
|
||||
});
|
||||
}));
|
||||
|
||||
normalizedMod = registry[normalizedMap.id];
|
||||
normalizedMod = getOwn(registry, normalizedMap.id);
|
||||
if (normalizedMod) {
|
||||
//Mark this as a dependency for this plugin, so it
|
||||
//can be traced for cycles.
|
||||
@@ -1006,6 +1009,11 @@ var requirejs, require, define;
|
||||
//it.
|
||||
getModule(moduleMap);
|
||||
|
||||
//Transfer any config to this other module.
|
||||
if (hasProp(config.config, id)) {
|
||||
config.config[moduleName] = config.config[id];
|
||||
}
|
||||
|
||||
try {
|
||||
req.exec(text);
|
||||
} catch (e) {
|
||||
@@ -1061,7 +1069,7 @@ var requirejs, require, define;
|
||||
!this.skipMap);
|
||||
this.depMaps[i] = depMap;
|
||||
|
||||
handler = handlers[depMap.id];
|
||||
handler = getOwn(handlers, depMap.id);
|
||||
|
||||
if (handler) {
|
||||
this.depExports[i] = handler(this);
|
||||
@@ -1086,7 +1094,7 @@ var requirejs, require, define;
|
||||
//Skip special modules like 'require', 'exports', 'module'
|
||||
//Also, don't call enable if it is already enabled,
|
||||
//important in circular dependency cases.
|
||||
if (!handlers[id] && mod && !mod.enabled) {
|
||||
if (!hasProp(handlers, id) && mod && !mod.enabled) {
|
||||
context.enable(depMap, this);
|
||||
}
|
||||
}));
|
||||
@@ -1094,7 +1102,7 @@ var requirejs, require, define;
|
||||
//Enable each plugin that is used in
|
||||
//a dependency
|
||||
eachProp(this.pluginMaps, bind(this, function (pluginMap) {
|
||||
var mod = registry[pluginMap.id];
|
||||
var mod = getOwn(registry, pluginMap.id);
|
||||
if (mod && !mod.enabled) {
|
||||
context.enable(pluginMap, this);
|
||||
}
|
||||
@@ -1127,7 +1135,10 @@ var requirejs, require, define;
|
||||
};
|
||||
|
||||
function callGetModule(args) {
|
||||
getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
|
||||
//Skip modules already defined.
|
||||
if (!hasProp(defined, args[0])) {
|
||||
getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
|
||||
}
|
||||
}
|
||||
|
||||
function removeListener(node, func, name, ieName) {
|
||||
@@ -1167,6 +1178,25 @@ var requirejs, require, define;
|
||||
};
|
||||
}
|
||||
|
||||
function intakeDefines() {
|
||||
var args;
|
||||
|
||||
//Any defined modules in the global queue, intake them now.
|
||||
takeGlobalQueue();
|
||||
|
||||
//Make sure any remaining defQueue items get properly processed.
|
||||
while (defQueue.length) {
|
||||
args = defQueue.shift();
|
||||
if (args[0] === null) {
|
||||
return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
|
||||
} else {
|
||||
//args are id, deps, factory. Should be normalized by the
|
||||
//define() function.
|
||||
callGetModule(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context = {
|
||||
config: config,
|
||||
contextName: contextName,
|
||||
@@ -1194,20 +1224,23 @@ var requirejs, require, define;
|
||||
//they are additive.
|
||||
var pkgs = config.pkgs,
|
||||
shim = config.shim,
|
||||
paths = config.paths,
|
||||
map = config.map;
|
||||
objs = {
|
||||
paths: true,
|
||||
config: true,
|
||||
map: true
|
||||
};
|
||||
|
||||
//Mix in the config values, favoring the new values over
|
||||
//existing ones in context.config.
|
||||
mixin(config, cfg, true);
|
||||
|
||||
//Merge paths.
|
||||
config.paths = mixin(paths, cfg.paths, true);
|
||||
|
||||
//Merge map
|
||||
if (cfg.map) {
|
||||
config.map = mixin(map || {}, cfg.map, true, true);
|
||||
}
|
||||
eachProp(cfg, function (value, prop) {
|
||||
if (objs[prop]) {
|
||||
if (prop === 'map') {
|
||||
mixin(config[prop], value, true, true);
|
||||
} else {
|
||||
mixin(config[prop], value, true);
|
||||
}
|
||||
} else {
|
||||
config[prop] = value;
|
||||
}
|
||||
});
|
||||
|
||||
//Merge shim
|
||||
if (cfg.shim) {
|
||||
@@ -1218,7 +1251,7 @@ var requirejs, require, define;
|
||||
deps: value
|
||||
};
|
||||
}
|
||||
if (value.exports && !value.exportsFn) {
|
||||
if ((value.exports || value.init) && !value.exportsFn) {
|
||||
value.exportsFn = context.makeShimExports(value);
|
||||
}
|
||||
shim[id] = value;
|
||||
@@ -1280,7 +1313,7 @@ var requirejs, require, define;
|
||||
if (value.init) {
|
||||
ret = value.init.apply(global, arguments);
|
||||
}
|
||||
return ret || getGlobal(value.exports);
|
||||
return ret || (value.exports && getGlobal(value.exports));
|
||||
}
|
||||
return fn;
|
||||
},
|
||||
@@ -1288,8 +1321,8 @@ var requirejs, require, define;
|
||||
makeRequire: function (relMap, options) {
|
||||
options = options || {};
|
||||
|
||||
function require(deps, callback, errback) {
|
||||
var id, map, requireMod, args;
|
||||
function localRequire(deps, callback, errback) {
|
||||
var id, map, requireMod;
|
||||
|
||||
if (options.enableBuildCallback && callback && isFunction(callback)) {
|
||||
callback.__requireJsBuild = true;
|
||||
@@ -1304,7 +1337,7 @@ var requirejs, require, define;
|
||||
//If require|exports|module are requested, get the
|
||||
//value for them from the special handlers. Caveat:
|
||||
//this only works while module is being defined.
|
||||
if (relMap && handlers[deps]) {
|
||||
if (relMap && hasProp(handlers, deps)) {
|
||||
return handlers[deps](registry[relMap.id]);
|
||||
}
|
||||
|
||||
@@ -1328,23 +1361,15 @@ var requirejs, require, define;
|
||||
return defined[id];
|
||||
}
|
||||
|
||||
//Any defined modules in the global queue, intake them now.
|
||||
takeGlobalQueue();
|
||||
|
||||
//Make sure any remaining defQueue items get properly processed.
|
||||
while (defQueue.length) {
|
||||
args = defQueue.shift();
|
||||
if (args[0] === null) {
|
||||
return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
|
||||
} else {
|
||||
//args are id, deps, factory. Should be normalized by the
|
||||
//define() function.
|
||||
callGetModule(args);
|
||||
}
|
||||
}
|
||||
//Grab defines waiting in the global queue.
|
||||
intakeDefines();
|
||||
|
||||
//Mark all the dependencies as needing to be loaded.
|
||||
context.nextTick(function () {
|
||||
//Some defines could have been added since the
|
||||
//require call, collect them.
|
||||
intakeDefines();
|
||||
|
||||
requireMod = getModule(makeModuleMap(null, relMap));
|
||||
|
||||
//Store if map config should be applied to this require
|
||||
@@ -1358,10 +1383,10 @@ var requirejs, require, define;
|
||||
checkLoaded();
|
||||
});
|
||||
|
||||
return require;
|
||||
return localRequire;
|
||||
}
|
||||
|
||||
mixin(require, {
|
||||
mixin(localRequire, {
|
||||
isBrowser: isBrowser,
|
||||
|
||||
/**
|
||||
@@ -1394,13 +1419,13 @@ var requirejs, require, define;
|
||||
|
||||
//Only allow undef on top level require calls
|
||||
if (!relMap) {
|
||||
require.undef = function (id) {
|
||||
localRequire.undef = function (id) {
|
||||
//Bind any waiting define() calls to this context,
|
||||
//fix for #408
|
||||
takeGlobalQueue();
|
||||
|
||||
var map = makeModuleMap(id, relMap, true),
|
||||
mod = registry[id];
|
||||
mod = getOwn(registry, id);
|
||||
|
||||
delete defined[id];
|
||||
delete urlFetched[map.url];
|
||||
@@ -1419,7 +1444,7 @@ var requirejs, require, define;
|
||||
};
|
||||
}
|
||||
|
||||
return require;
|
||||
return localRequire;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1428,7 +1453,7 @@ var requirejs, require, define;
|
||||
* used by the optimizer.
|
||||
*/
|
||||
enable: function (depMap, parent) {
|
||||
var mod = registry[depMap.id];
|
||||
var mod = getOwn(registry, depMap.id);
|
||||
if (mod) {
|
||||
getModule(depMap).enable();
|
||||
}
|
||||
@@ -1442,7 +1467,7 @@ var requirejs, require, define;
|
||||
*/
|
||||
completeLoad: function (moduleName) {
|
||||
var found, args, mod,
|
||||
shim = config.shim[moduleName] || {},
|
||||
shim = getOwn(config.shim, moduleName) || {},
|
||||
shExports = shim.exports;
|
||||
|
||||
takeGlobalQueue();
|
||||
@@ -1468,9 +1493,9 @@ var requirejs, require, define;
|
||||
|
||||
//Do this after the cycle of callGetModule in case the result
|
||||
//of those calls/init calls changes the registry.
|
||||
mod = registry[moduleName];
|
||||
mod = getOwn(registry, moduleName);
|
||||
|
||||
if (!found && !defined[moduleName] && mod && !mod.inited) {
|
||||
if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {
|
||||
if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
|
||||
if (hasPathFallback(moduleName)) {
|
||||
return;
|
||||
@@ -1521,8 +1546,8 @@ var requirejs, require, define;
|
||||
//and work up from it.
|
||||
for (i = syms.length; i > 0; i -= 1) {
|
||||
parentModule = syms.slice(0, i).join('/');
|
||||
pkg = pkgs[parentModule];
|
||||
parentPath = paths[parentModule];
|
||||
pkg = getOwn(pkgs, parentModule);
|
||||
parentPath = getOwn(paths, parentModule);
|
||||
if (parentPath) {
|
||||
//If an array, it means there are a few choices,
|
||||
//Choose the one that is desired
|
||||
@@ -1647,7 +1672,7 @@ var requirejs, require, define;
|
||||
contextName = config.context;
|
||||
}
|
||||
|
||||
context = contexts[contextName];
|
||||
context = getOwn(contexts, contextName);
|
||||
if (!context) {
|
||||
context = contexts[contextName] = req.s.newContext(contextName);
|
||||
}
|
||||
|
||||
16
vendor/underscore/test/arrays.js
vendored
16
vendor/underscore/test/arrays.js
vendored
@@ -55,18 +55,16 @@ $(document).ready(function() {
|
||||
|
||||
test("compact", function() {
|
||||
equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values');
|
||||
var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3);
|
||||
var result = (function(){ return _.compact(arguments).length; })(0, 1, false, 2, false, 3);
|
||||
equal(result, 3, 'works on an arguments object');
|
||||
});
|
||||
|
||||
test("flatten", function() {
|
||||
if (window.JSON) {
|
||||
var list = [1, [2], [3, [[[4]]]]];
|
||||
equal(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays');
|
||||
equal(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays');
|
||||
var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
|
||||
equal(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object');
|
||||
}
|
||||
var list = [1, [2], [3, [[[4]]]]];
|
||||
deepEqual(_.flatten(list), [1,2,3,4], 'can flatten nested arrays');
|
||||
deepEqual(_.flatten(list, true), [1,2,3,[[[4]]]], 'can shallowly flatten nested arrays');
|
||||
var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
|
||||
deepEqual(result, [1,2,3,4], 'works on an arguments object');
|
||||
});
|
||||
|
||||
test("without", function() {
|
||||
@@ -91,6 +89,8 @@ $(document).ready(function() {
|
||||
var iterator = function(value) { return value.name; };
|
||||
equal(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator');
|
||||
|
||||
equal(_.map(_.uniq(list, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator without specifying whether array is sorted');
|
||||
|
||||
var iterator = function(value) { return value +1; };
|
||||
var list = [1, 2, 2, 3, 4, 4];
|
||||
equal(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array');
|
||||
|
||||
27
vendor/underscore/test/collections.js
vendored
27
vendor/underscore/test/collections.js
vendored
@@ -171,6 +171,14 @@ $(document).ready(function() {
|
||||
test('reject', function() {
|
||||
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
|
||||
equal(odds.join(', '), '1, 3, 5', 'rejected each even number');
|
||||
|
||||
var context = "obj";
|
||||
|
||||
var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){
|
||||
equal(context, "obj");
|
||||
return num % 2 != 0;
|
||||
}, context);
|
||||
equal(evens.join(', '), '2, 4, 6', 'rejected each odd number');
|
||||
});
|
||||
|
||||
test('all', function() {
|
||||
@@ -260,6 +268,7 @@ $(document).ready(function() {
|
||||
|
||||
equal(-Infinity, _.max({}), 'Maximum value of an empty object');
|
||||
equal(-Infinity, _.max([]), 'Maximum value of an empty array');
|
||||
equal(_.max({'a': 'a'}), -Infinity, 'Maximum value of a non-numeric collection');
|
||||
|
||||
equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array");
|
||||
});
|
||||
@@ -272,6 +281,7 @@ $(document).ready(function() {
|
||||
|
||||
equal(Infinity, _.min({}), 'Minimum value of an empty object');
|
||||
equal(Infinity, _.min([]), 'Minimum value of an empty array');
|
||||
equal(_.min({'a': 'a'}), Infinity, 'Minimum value of a non-numeric collection');
|
||||
|
||||
var now = new Date(9999999999);
|
||||
var then = new Date(0);
|
||||
@@ -338,6 +348,11 @@ $(document).ready(function() {
|
||||
|
||||
var array = [{}];
|
||||
_.groupBy(array, function(value, index, obj){ ok(obj === array); });
|
||||
|
||||
var array = [1, 2, 1, 2, 3];
|
||||
var grouped = _.groupBy(array);
|
||||
equal(grouped['1'].length, 2);
|
||||
equal(grouped['3'].length, 1);
|
||||
});
|
||||
|
||||
test('countBy', function() {
|
||||
@@ -362,6 +377,11 @@ $(document).ready(function() {
|
||||
|
||||
var array = [{}];
|
||||
_.countBy(array, function(value, index, obj){ ok(obj === array); });
|
||||
|
||||
var array = [1, 2, 1, 2, 3];
|
||||
var grouped = _.countBy(array);
|
||||
equal(grouped['1'], 2);
|
||||
equal(grouped['3'], 1);
|
||||
});
|
||||
|
||||
test('sortedIndex', function() {
|
||||
@@ -398,6 +418,13 @@ $(document).ready(function() {
|
||||
|
||||
var numbers = _.toArray({one : 1, two : 2, three : 3});
|
||||
equal(numbers.join(', '), '1, 2, 3', 'object flattened into array');
|
||||
|
||||
// test in IE < 9
|
||||
try {
|
||||
var actual = _.toArray(document.childNodes);
|
||||
} catch(ex) { }
|
||||
|
||||
ok(_.isArray(actual), 'should not throw converting a node list');
|
||||
});
|
||||
|
||||
test('size', function() {
|
||||
|
||||
29
vendor/underscore/test/functions.js
vendored
29
vendor/underscore/test/functions.js
vendored
@@ -34,8 +34,10 @@ $(document).ready(function() {
|
||||
// To test this with a modern browser, set underscore's nativeBind to undefined
|
||||
var F = function () { return this; };
|
||||
var Boundf = _.bind(F, {hello: "moe curly"});
|
||||
equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5");
|
||||
var newBoundf = new Boundf();
|
||||
equal(newBoundf.hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5");
|
||||
equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context");
|
||||
ok(newBoundf instanceof F, "a bound instance is an instance of the original function");
|
||||
});
|
||||
|
||||
test("bindAll", function() {
|
||||
@@ -163,6 +165,31 @@ $(document).ready(function() {
|
||||
}, 400);
|
||||
});
|
||||
|
||||
asyncTest("throttle triggers trailing call after repeatedly invoked", 2, function() {
|
||||
var actual;
|
||||
var counter = 0;
|
||||
var limit = 80;
|
||||
var incr = function(){ counter++; };
|
||||
var throttledIncr = _.throttle(incr, 32);
|
||||
|
||||
var stamp = new Date;
|
||||
while ((new Date - stamp) < limit) {
|
||||
throttledIncr();
|
||||
}
|
||||
_.delay(function() {
|
||||
actual = counter + 2;
|
||||
throttledIncr();
|
||||
throttledIncr();
|
||||
}, 64);
|
||||
|
||||
_.delay(function() {
|
||||
equal(counter, actual);
|
||||
start();
|
||||
}, 128);
|
||||
|
||||
ok(counter > 1);
|
||||
});
|
||||
|
||||
asyncTest("debounce", 1, function() {
|
||||
var counter = 0;
|
||||
var incr = function(){ counter++; };
|
||||
|
||||
30
vendor/underscore/test/objects.js
vendored
30
vendor/underscore/test/objects.js
vendored
@@ -53,6 +53,13 @@ $(document).ready(function() {
|
||||
ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps');
|
||||
result = _.extend({}, {a: void 0, b: null});
|
||||
equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values');
|
||||
|
||||
try {
|
||||
result = {};
|
||||
_.extend(result, null, undefined, {a:1});
|
||||
} catch(ex) {}
|
||||
|
||||
equal(result.a, 1, 'should not error on `null` or `undefined` sources');
|
||||
});
|
||||
|
||||
test("pick", function() {
|
||||
@@ -96,6 +103,13 @@ $(document).ready(function() {
|
||||
equal(options.empty, "", 'value exists');
|
||||
ok(_.isNaN(options.nan), "NaN isn't overridden");
|
||||
equal(options.word, "word", 'new value is added, first one wins');
|
||||
|
||||
try {
|
||||
options = {};
|
||||
_.defaults(options, null, undefined, {a:1});
|
||||
} catch(ex) {}
|
||||
|
||||
equal(options.a, 1, 'should not error on `null` or `undefined` sources');
|
||||
});
|
||||
|
||||
test("clone", function() {
|
||||
@@ -337,16 +351,10 @@ $(document).ready(function() {
|
||||
|
||||
// Chaining.
|
||||
ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal');
|
||||
equal(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained');
|
||||
|
||||
// Custom `isEqual` methods.
|
||||
var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}};
|
||||
var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}};
|
||||
|
||||
ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods');
|
||||
ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods');
|
||||
ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal');
|
||||
ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods');
|
||||
a = _({x: 1, y: 2}).chain();
|
||||
b = _({x: 1, y: 2}).chain();
|
||||
equal(_.isEqual(a.isEqual(b), _(true)), true, '`isEqual` can be chained');
|
||||
|
||||
// Objects from another frame.
|
||||
ok(_.isEqual({}, iObject));
|
||||
@@ -485,7 +493,9 @@ $(document).ready(function() {
|
||||
ok(!_.isFinite(NaN), 'NaN is not Finite');
|
||||
ok(!_.isFinite(Infinity), 'Infinity is not Finite');
|
||||
ok(!_.isFinite(-Infinity), '-Infinity is not Finite');
|
||||
ok(!_.isFinite('12'), 'Strings are not numbers');
|
||||
ok(_.isFinite('12'), 'Numeric strings are numbers');
|
||||
ok(!_.isFinite('1a'), 'Non numeric strings are not numbers');
|
||||
ok(!_.isFinite(''), 'Empty strings are not numbers');
|
||||
var obj = new Number(5);
|
||||
ok(_.isFinite(obj), 'Number instances can be finite');
|
||||
ok(_.isFinite(0), '0 is Finite');
|
||||
|
||||
11
vendor/underscore/test/utility.js
vendored
11
vendor/underscore/test/utility.js
vendored
@@ -37,8 +37,10 @@ $(document).ready(function() {
|
||||
ok(_.isEqual(vals, [0,1,2]), "is 0 indexed");
|
||||
//
|
||||
vals = [];
|
||||
_(3).times(function (i) { vals.push(i); });
|
||||
_(3).times(function(i) { vals.push(i); });
|
||||
ok(_.isEqual(vals, [0,1,2]), "works as a wrapper");
|
||||
// collects return values
|
||||
ok(_.isEqual([0, 1, 2], _.times(3, function(i) { return i; })), "collects return values");
|
||||
});
|
||||
|
||||
test("mixin", function() {
|
||||
@@ -173,10 +175,11 @@ $(document).ready(function() {
|
||||
|
||||
test('_.template provides the generated function source, when a SyntaxError occurs', function() {
|
||||
try {
|
||||
_.template('<b><%= if %></b>');
|
||||
} catch (e) {
|
||||
ok(e.source.indexOf('( if )') > 0);
|
||||
_.template('<b><%= if x %></b>');
|
||||
} catch (ex) {
|
||||
var source = ex.source;
|
||||
}
|
||||
ok(/__p/.test(source));
|
||||
});
|
||||
|
||||
test('_.template handles \\u2028 & \\u2029', function() {
|
||||
|
||||
670
vendor/underscore/test/vendor/jslitmus.js
vendored
670
vendor/underscore/test/vendor/jslitmus.js
vendored
@@ -1,670 +0,0 @@
|
||||
// JSLitmus.js
|
||||
//
|
||||
// History:
|
||||
// 2008-10-27: Initial release
|
||||
// 2008-11-09: Account for iteration loop overhead
|
||||
// 2008-11-13: Added OS detection
|
||||
// 2009-02-25: Create tinyURL automatically, shift-click runs tests in reverse
|
||||
//
|
||||
// Copyright (c) 2008-2009, Robert Kieffer
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the
|
||||
// Software), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
(function() {
|
||||
// Private methods and state
|
||||
|
||||
// Get platform info but don't go crazy trying to recognize everything
|
||||
// that's out there. This is just for the major platforms and OSes.
|
||||
var platform = 'unknown platform', ua = navigator.userAgent;
|
||||
|
||||
// Detect OS
|
||||
var oses = ['Windows','iPhone OS','(Intel |PPC )?Mac OS X','Linux'].join('|');
|
||||
var pOS = new RegExp('((' + oses + ') [^ \);]*)').test(ua) ? RegExp.$1 : null;
|
||||
if (!pOS) pOS = new RegExp('((' + oses + ')[^ \);]*)').test(ua) ? RegExp.$1 : null;
|
||||
|
||||
// Detect browser
|
||||
var pName = /(Chrome|MSIE|Safari|Opera|Firefox)/.test(ua) ? RegExp.$1 : null;
|
||||
|
||||
// Detect version
|
||||
var vre = new RegExp('(Version|' + pName + ')[ \/]([^ ;]*)');
|
||||
var pVersion = (pName && vre.test(ua)) ? RegExp.$2 : null;
|
||||
var platform = (pOS && pName && pVersion) ? pName + ' ' + pVersion + ' on ' + pOS : 'unknown platform';
|
||||
|
||||
/**
|
||||
* A smattering of methods that are needed to implement the JSLitmus testbed.
|
||||
*/
|
||||
var jsl = {
|
||||
/**
|
||||
* Enhanced version of escape()
|
||||
*/
|
||||
escape: function(s) {
|
||||
s = s.replace(/,/g, '\\,');
|
||||
s = escape(s);
|
||||
s = s.replace(/\+/g, '%2b');
|
||||
s = s.replace(/ /g, '+');
|
||||
return s;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an element by ID.
|
||||
*/
|
||||
$: function(id) {
|
||||
return document.getElementById(id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Null function
|
||||
*/
|
||||
F: function() {},
|
||||
|
||||
/**
|
||||
* Set the status shown in the UI
|
||||
*/
|
||||
status: function(msg) {
|
||||
var el = jsl.$('jsl_status');
|
||||
if (el) el.innerHTML = msg || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert a number to an abbreviated string like, "15K" or "10M"
|
||||
*/
|
||||
toLabel: function(n) {
|
||||
if (n == Infinity) {
|
||||
return 'Infinity';
|
||||
} else if (n > 1e9) {
|
||||
n = Math.round(n/1e8);
|
||||
return n/10 + 'B';
|
||||
} else if (n > 1e6) {
|
||||
n = Math.round(n/1e5);
|
||||
return n/10 + 'M';
|
||||
} else if (n > 1e3) {
|
||||
n = Math.round(n/1e2);
|
||||
return n/10 + 'K';
|
||||
}
|
||||
return n;
|
||||
},
|
||||
|
||||
/**
|
||||
* Copy properties from src to dst
|
||||
*/
|
||||
extend: function(dst, src) {
|
||||
for (var k in src) dst[k] = src[k]; return dst;
|
||||
},
|
||||
|
||||
/**
|
||||
* Like Array.join(), but for the key-value pairs in an object
|
||||
*/
|
||||
join: function(o, delimit1, delimit2) {
|
||||
if (o.join) return o.join(delimit1); // If it's an array
|
||||
var pairs = [];
|
||||
for (var k in o) pairs.push(k + delimit1 + o[k]);
|
||||
return pairs.join(delimit2);
|
||||
},
|
||||
|
||||
/**
|
||||
* Array#indexOf isn't supported in IE, so we use this as a cross-browser solution
|
||||
*/
|
||||
indexOf: function(arr, o) {
|
||||
if (arr.indexOf) return arr.indexOf(o);
|
||||
for (var i = 0; i < this.length; i++) if (arr[i] === o) return i;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test manages a single test (created with
|
||||
* JSLitmus.test())
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var Test = function (name, f) {
|
||||
if (!f) throw new Error('Undefined test function');
|
||||
if (!(/function[^\(]*\(([^,\)]*)/).test(f.toString())) {
|
||||
throw new Error('"' + name + '" test: Test is not a valid Function object');
|
||||
}
|
||||
this.loopArg = RegExp.$1;
|
||||
this.name = name;
|
||||
this.f = f;
|
||||
};
|
||||
|
||||
jsl.extend(Test, /** @lends Test */ {
|
||||
/** Calibration tests for establishing iteration loop overhead */
|
||||
CALIBRATIONS: [
|
||||
new Test('calibrating loop', function(count) {while (count--);}),
|
||||
new Test('calibrating function', jsl.F)
|
||||
],
|
||||
|
||||
/**
|
||||
* Run calibration tests. Returns true if calibrations are not yet
|
||||
* complete (in which case calling code should run the tests yet again).
|
||||
* onCalibrated - Callback to invoke when calibrations have finished
|
||||
*/
|
||||
calibrate: function(onCalibrated) {
|
||||
for (var i = 0; i < Test.CALIBRATIONS.length; i++) {
|
||||
var cal = Test.CALIBRATIONS[i];
|
||||
if (cal.running) return true;
|
||||
if (!cal.count) {
|
||||
cal.isCalibration = true;
|
||||
cal.onStop = onCalibrated;
|
||||
//cal.MIN_TIME = .1; // Do calibrations quickly
|
||||
cal.run(2e4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
jsl.extend(Test.prototype, {/** @lends Test.prototype */
|
||||
/** Initial number of iterations */
|
||||
INIT_COUNT: 10,
|
||||
/** Max iterations allowed (i.e. used to detect bad looping functions) */
|
||||
MAX_COUNT: 1e9,
|
||||
/** Minimum time a test should take to get valid results (secs) */
|
||||
MIN_TIME: .5,
|
||||
|
||||
/** Callback invoked when test state changes */
|
||||
onChange: jsl.F,
|
||||
|
||||
/** Callback invoked when test is finished */
|
||||
onStop: jsl.F,
|
||||
|
||||
/**
|
||||
* Reset test state
|
||||
*/
|
||||
reset: function() {
|
||||
delete this.count;
|
||||
delete this.time;
|
||||
delete this.running;
|
||||
delete this.error;
|
||||
},
|
||||
|
||||
/**
|
||||
* Run the test (in a timeout). We use a timeout to make sure the browser
|
||||
* has a chance to finish rendering any UI changes we've made, like
|
||||
* updating the status message.
|
||||
*/
|
||||
run: function(count) {
|
||||
count = count || this.INIT_COUNT;
|
||||
jsl.status(this.name + ' x ' + count);
|
||||
this.running = true;
|
||||
var me = this;
|
||||
setTimeout(function() {me._run(count);}, 200);
|
||||
},
|
||||
|
||||
/**
|
||||
* The nuts and bolts code that actually runs a test
|
||||
*/
|
||||
_run: function(count) {
|
||||
var me = this;
|
||||
|
||||
// Make sure calibration tests have run
|
||||
if (!me.isCalibration && Test.calibrate(function() {me.run(count);})) return;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
var start, f = this.f, now, i = count;
|
||||
|
||||
// Start the timer
|
||||
start = new Date();
|
||||
|
||||
// Now for the money shot. If this is a looping function ...
|
||||
if (this.loopArg) {
|
||||
// ... let it do the iteration itself
|
||||
f(count);
|
||||
} else {
|
||||
// ... otherwise do the iteration for it
|
||||
while (i--) f();
|
||||
}
|
||||
|
||||
// Get time test took (in secs)
|
||||
this.time = Math.max(1,new Date() - start)/1000;
|
||||
|
||||
// Store iteration count and per-operation time taken
|
||||
this.count = count;
|
||||
this.period = this.time/count;
|
||||
|
||||
// Do we need to do another run?
|
||||
this.running = this.time <= this.MIN_TIME;
|
||||
|
||||
// ... if so, compute how many times we should iterate
|
||||
if (this.running) {
|
||||
// Bump the count to the nearest power of 2
|
||||
var x = this.MIN_TIME/this.time;
|
||||
var pow = Math.pow(2, Math.max(1, Math.ceil(Math.log(x)/Math.log(2))));
|
||||
count *= pow;
|
||||
if (count > this.MAX_COUNT) {
|
||||
throw new Error('Max count exceeded. If this test uses a looping function, make sure the iteration loop is working properly.');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Exceptions are caught and displayed in the test UI
|
||||
this.reset();
|
||||
this.error = e;
|
||||
}
|
||||
|
||||
// Figure out what to do next
|
||||
if (this.running) {
|
||||
me.run(count);
|
||||
} else {
|
||||
jsl.status('');
|
||||
me.onStop(me);
|
||||
}
|
||||
|
||||
// Finish up
|
||||
this.onChange(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the number of operations per second for this test.
|
||||
*
|
||||
* @param normalize if true, iteration loop overhead taken into account
|
||||
*/
|
||||
getHz: function(/**Boolean*/ normalize) {
|
||||
var p = this.period;
|
||||
|
||||
// Adjust period based on the calibration test time
|
||||
if (normalize && !this.isCalibration) {
|
||||
var cal = Test.CALIBRATIONS[this.loopArg ? 0 : 1];
|
||||
|
||||
// If the period is within 20% of the calibration time, then zero the
|
||||
// it out
|
||||
p = p < cal.period*1.2 ? 0 : p - cal.period;
|
||||
}
|
||||
|
||||
return Math.round(1/p);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a friendly string describing the test
|
||||
*/
|
||||
toString: function() {
|
||||
return this.name + ' - ' + this.time/this.count + ' secs';
|
||||
}
|
||||
});
|
||||
|
||||
// CSS we need for the UI
|
||||
var STYLESHEET = '<style> \
|
||||
#jslitmus {font-family:sans-serif; font-size: 12px;} \
|
||||
#jslitmus a {text-decoration: none;} \
|
||||
#jslitmus a:hover {text-decoration: underline;} \
|
||||
#jsl_status { \
|
||||
margin-top: 10px; \
|
||||
font-size: 10px; \
|
||||
color: #888; \
|
||||
} \
|
||||
A IMG {border:none} \
|
||||
#test_results { \
|
||||
margin-top: 10px; \
|
||||
font-size: 12px; \
|
||||
font-family: sans-serif; \
|
||||
border-collapse: collapse; \
|
||||
border-spacing: 0px; \
|
||||
} \
|
||||
#test_results th, #test_results td { \
|
||||
border: solid 1px #ccc; \
|
||||
vertical-align: top; \
|
||||
padding: 3px; \
|
||||
} \
|
||||
#test_results th { \
|
||||
vertical-align: bottom; \
|
||||
background-color: #ccc; \
|
||||
padding: 1px; \
|
||||
font-size: 10px; \
|
||||
} \
|
||||
#test_results #test_platform { \
|
||||
color: #444; \
|
||||
text-align:center; \
|
||||
} \
|
||||
#test_results .test_row { \
|
||||
color: #006; \
|
||||
cursor: pointer; \
|
||||
} \
|
||||
#test_results .test_nonlooping { \
|
||||
border-left-style: dotted; \
|
||||
border-left-width: 2px; \
|
||||
} \
|
||||
#test_results .test_looping { \
|
||||
border-left-style: solid; \
|
||||
border-left-width: 2px; \
|
||||
} \
|
||||
#test_results .test_name {white-space: nowrap;} \
|
||||
#test_results .test_pending { \
|
||||
} \
|
||||
#test_results .test_running { \
|
||||
font-style: italic; \
|
||||
} \
|
||||
#test_results .test_done {} \
|
||||
#test_results .test_done { \
|
||||
text-align: right; \
|
||||
font-family: monospace; \
|
||||
} \
|
||||
#test_results .test_error {color: #600;} \
|
||||
#test_results .test_error .error_head {font-weight:bold;} \
|
||||
#test_results .test_error .error_body {font-size:85%;} \
|
||||
#test_results .test_row:hover td { \
|
||||
background-color: #ffc; \
|
||||
text-decoration: underline; \
|
||||
} \
|
||||
#chart { \
|
||||
margin: 10px 0px; \
|
||||
width: 250px; \
|
||||
} \
|
||||
#chart img { \
|
||||
border: solid 1px #ccc; \
|
||||
margin-bottom: 5px; \
|
||||
} \
|
||||
#chart #tiny_url { \
|
||||
height: 40px; \
|
||||
width: 250px; \
|
||||
} \
|
||||
#jslitmus_credit { \
|
||||
font-size: 10px; \
|
||||
color: #888; \
|
||||
margin-top: 8px; \
|
||||
} \
|
||||
</style>';
|
||||
|
||||
// HTML markup for the UI
|
||||
var MARKUP = '<div id="jslitmus"> \
|
||||
<button onclick="JSLitmus.runAll(event)">Run Tests</button> \
|
||||
<button id="stop_button" disabled="disabled" onclick="JSLitmus.stop()">Stop Tests</button> \
|
||||
<br \> \
|
||||
<br \> \
|
||||
<input type="checkbox" style="vertical-align: middle" id="test_normalize" checked="checked" onchange="JSLitmus.renderAll()""> Normalize results \
|
||||
<table id="test_results"> \
|
||||
<colgroup> \
|
||||
<col /> \
|
||||
<col width="100" /> \
|
||||
</colgroup> \
|
||||
<tr><th id="test_platform" colspan="2">' + platform + '</th></tr> \
|
||||
<tr><th>Test</th><th>Ops/sec</th></tr> \
|
||||
<tr id="test_row_template" class="test_row" style="display:none"> \
|
||||
<td class="test_name"></td> \
|
||||
<td class="test_result">Ready</td> \
|
||||
</tr> \
|
||||
</table> \
|
||||
<div id="jsl_status"></div> \
|
||||
<div id="chart" style="display:none"> \
|
||||
<a id="chart_link" target="_blank"><img id="chart_image"></a> \
|
||||
TinyURL (for chart): \
|
||||
<iframe id="tiny_url" frameBorder="0" scrolling="no" src=""></iframe> \
|
||||
</div> \
|
||||
<a id="jslitmus_credit" title="JSLitmus home page" href="http://code.google.com/p/jslitmus" target="_blank">Powered by JSLitmus</a> \
|
||||
</div>';
|
||||
|
||||
/**
|
||||
* The public API for creating and running tests
|
||||
*/
|
||||
window.JSLitmus = {
|
||||
/** The list of all tests that have been registered with JSLitmus.test */
|
||||
_tests: [],
|
||||
/** The queue of tests that need to be run */
|
||||
_queue: [],
|
||||
|
||||
/**
|
||||
* The parsed query parameters the current page URL. This is provided as a
|
||||
* convenience for test functions - it's not used by JSLitmus proper
|
||||
*/
|
||||
params: {},
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
_init: function() {
|
||||
// Parse query params into JSLitmus.params[] hash
|
||||
var match = (location + '').match(/([^?#]*)(#.*)?$/);
|
||||
if (match) {
|
||||
var pairs = match[1].split('&');
|
||||
for (var i = 0; i < pairs.length; i++) {
|
||||
var pair = pairs[i].split('=');
|
||||
if (pair.length > 1) {
|
||||
var key = pair.shift();
|
||||
var value = pair.length > 1 ? pair.join('=') : pair[0];
|
||||
this.params[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the stylesheet. We have to do this here because IE
|
||||
// doesn't honor sheets written after the document has loaded.
|
||||
document.write(STYLESHEET);
|
||||
|
||||
// Setup the rest of the UI once the document is loaded
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('load', this._setup, false);
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('load', this._setup, false);
|
||||
} else if (window.attachEvent) {
|
||||
window.attachEvent('onload', this._setup);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the UI
|
||||
*/
|
||||
_setup: function() {
|
||||
var el = jsl.$('jslitmus_container');
|
||||
if (!el) document.body.appendChild(el = document.createElement('div'));
|
||||
|
||||
el.innerHTML = MARKUP;
|
||||
|
||||
// Render the UI for all our tests
|
||||
for (var i=0; i < JSLitmus._tests.length; i++)
|
||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render all the test results
|
||||
*/
|
||||
renderAll: function() {
|
||||
for (var i = 0; i < JSLitmus._tests.length; i++)
|
||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
||||
JSLitmus.renderChart();
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render the chart graphics
|
||||
*/
|
||||
renderChart: function() {
|
||||
var url = JSLitmus.chartUrl();
|
||||
jsl.$('chart_link').href = url;
|
||||
jsl.$('chart_image').src = url;
|
||||
jsl.$('chart').style.display = '';
|
||||
|
||||
// Update the tiny URL
|
||||
jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url);
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render the results for a specific test
|
||||
*/
|
||||
renderTest: function(test) {
|
||||
// Make a new row if needed
|
||||
if (!test._row) {
|
||||
var trow = jsl.$('test_row_template');
|
||||
if (!trow) return;
|
||||
|
||||
test._row = trow.cloneNode(true);
|
||||
test._row.style.display = '';
|
||||
test._row.id = '';
|
||||
test._row.onclick = function() {JSLitmus._queueTest(test);};
|
||||
test._row.title = 'Run ' + test.name + ' test';
|
||||
trow.parentNode.appendChild(test._row);
|
||||
test._row.cells[0].innerHTML = test.name;
|
||||
}
|
||||
|
||||
var cell = test._row.cells[1];
|
||||
var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping'];
|
||||
|
||||
if (test.error) {
|
||||
cns.push('test_error');
|
||||
cell.innerHTML =
|
||||
'<div class="error_head">' + test.error + '</div>' +
|
||||
'<ul class="error_body"><li>' +
|
||||
jsl.join(test.error, ': ', '</li><li>') +
|
||||
'</li></ul>';
|
||||
} else {
|
||||
if (test.running) {
|
||||
cns.push('test_running');
|
||||
cell.innerHTML = 'running';
|
||||
} else if (jsl.indexOf(JSLitmus._queue, test) >= 0) {
|
||||
cns.push('test_pending');
|
||||
cell.innerHTML = 'pending';
|
||||
} else if (test.count) {
|
||||
cns.push('test_done');
|
||||
var hz = test.getHz(jsl.$('test_normalize').checked);
|
||||
cell.innerHTML = hz != Infinity ? hz : '∞';
|
||||
} else {
|
||||
cell.innerHTML = 'ready';
|
||||
}
|
||||
}
|
||||
cell.className = cns.join(' ');
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new test
|
||||
*/
|
||||
test: function(name, f) {
|
||||
// Create the Test object
|
||||
var test = new Test(name, f);
|
||||
JSLitmus._tests.push(test);
|
||||
|
||||
// Re-render if the test state changes
|
||||
test.onChange = JSLitmus.renderTest;
|
||||
|
||||
// Run the next test if this one finished
|
||||
test.onStop = function(test) {
|
||||
if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test);
|
||||
JSLitmus.currentTest = null;
|
||||
JSLitmus._nextTest();
|
||||
};
|
||||
|
||||
// Render the new test
|
||||
this.renderTest(test);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add all tests to the run queue
|
||||
*/
|
||||
runAll: function(e) {
|
||||
e = e || window.event;
|
||||
var reverse = e && e.shiftKey, len = JSLitmus._tests.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all tests from the run queue. The current test has to finish on
|
||||
* it's own though
|
||||
*/
|
||||
stop: function() {
|
||||
while (JSLitmus._queue.length) {
|
||||
var test = JSLitmus._queue.shift();
|
||||
JSLitmus.renderTest(test);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Run the next test in the run queue
|
||||
*/
|
||||
_nextTest: function() {
|
||||
if (!JSLitmus.currentTest) {
|
||||
var test = JSLitmus._queue.shift();
|
||||
if (test) {
|
||||
jsl.$('stop_button').disabled = false;
|
||||
JSLitmus.currentTest = test;
|
||||
test.run();
|
||||
JSLitmus.renderTest(test);
|
||||
if (JSLitmus.onTestStart) JSLitmus.onTestStart(test);
|
||||
} else {
|
||||
jsl.$('stop_button').disabled = true;
|
||||
JSLitmus.renderChart();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a test to the run queue
|
||||
*/
|
||||
_queueTest: function(test) {
|
||||
if (jsl.indexOf(JSLitmus._queue, test) >= 0) return;
|
||||
JSLitmus._queue.push(test);
|
||||
JSLitmus.renderTest(test);
|
||||
JSLitmus._nextTest();
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate a Google Chart URL that shows the data for all tests
|
||||
*/
|
||||
chartUrl: function() {
|
||||
var n = JSLitmus._tests.length, markers = [], data = [];
|
||||
var d, min = 0, max = -1e10;
|
||||
var normalize = jsl.$('test_normalize').checked;
|
||||
|
||||
// Gather test data
|
||||
for (var i=0; i < JSLitmus._tests.length; i++) {
|
||||
var test = JSLitmus._tests[i];
|
||||
if (test.count) {
|
||||
var hz = test.getHz(normalize);
|
||||
var v = hz != Infinity ? hz : 0;
|
||||
data.push(v);
|
||||
markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' +
|
||||
markers.length + ',10');
|
||||
max = Math.max(v, max);
|
||||
}
|
||||
}
|
||||
if (markers.length <= 0) return null;
|
||||
|
||||
// Build chart title
|
||||
var title = document.getElementsByTagName('title');
|
||||
title = (title && title.length) ? title[0].innerHTML : null;
|
||||
var chart_title = [];
|
||||
if (title) chart_title.push(title);
|
||||
chart_title.push('Ops/sec (' + platform + ')');
|
||||
|
||||
// Build labels
|
||||
var labels = [jsl.toLabel(min), jsl.toLabel(max)];
|
||||
|
||||
var w = 250, bw = 15;
|
||||
var bs = 5;
|
||||
var h = markers.length*(bw + bs) + 30 + chart_title.length*20;
|
||||
|
||||
var params = {
|
||||
chtt: escape(chart_title.join('|')),
|
||||
chts: '000000,10',
|
||||
cht: 'bhg', // chart type
|
||||
chd: 't:' + data.join(','), // data set
|
||||
chds: min + ',' + max, // max/min of data
|
||||
chxt: 'x', // label axes
|
||||
chxl: '0:|' + labels.join('|'), // labels
|
||||
chsp: '0,1',
|
||||
chm: markers.join('|'), // test names
|
||||
chbh: [bw, 0, bs].join(','), // bar widths
|
||||
// chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient
|
||||
chs: w + 'x' + h
|
||||
};
|
||||
return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&');
|
||||
}
|
||||
};
|
||||
|
||||
JSLitmus._init();
|
||||
})();
|
||||
235
vendor/underscore/test/vendor/qunit.css
vendored
235
vendor/underscore/test/vendor/qunit.css
vendored
@@ -1,235 +0,0 @@
|
||||
/**
|
||||
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://qunitjs.com
|
||||
*
|
||||
* Copyright 2012 jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*/
|
||||
|
||||
/** Font Family and Sizes */
|
||||
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
||||
#qunit-tests { font-size: smaller; }
|
||||
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/** Header */
|
||||
|
||||
#qunit-header {
|
||||
padding: 0.5em 0 0.5em 1em;
|
||||
|
||||
color: #8699a4;
|
||||
background-color: #0d3349;
|
||||
|
||||
font-size: 1.5em;
|
||||
line-height: 1em;
|
||||
font-weight: normal;
|
||||
|
||||
border-radius: 5px 5px 0 0;
|
||||
-moz-border-radius: 5px 5px 0 0;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
-webkit-border-top-left-radius: 5px;
|
||||
}
|
||||
|
||||
#qunit-header a {
|
||||
text-decoration: none;
|
||||
color: #c2ccd1;
|
||||
}
|
||||
|
||||
#qunit-header a:hover,
|
||||
#qunit-header a:focus {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar label {
|
||||
display: inline-block;
|
||||
padding: 0 .5em 0 .1em;
|
||||
}
|
||||
|
||||
#qunit-banner {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar {
|
||||
padding: 0.5em 0 0.5em 2em;
|
||||
color: #5E740B;
|
||||
background-color: #eee;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#qunit-userAgent {
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
background-color: #2b81af;
|
||||
color: #fff;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
|
||||
#qunit-modulefilter-container {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/** Tests: Pass/Fail */
|
||||
|
||||
#qunit-tests {
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests li {
|
||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
||||
border-bottom: 1px solid #fff;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests li strong {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#qunit-tests li a {
|
||||
padding: 0.5em;
|
||||
color: #c2ccd1;
|
||||
text-decoration: none;
|
||||
}
|
||||
#qunit-tests li a:hover,
|
||||
#qunit-tests li a:focus {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qunit-tests ol {
|
||||
margin-top: 0.5em;
|
||||
padding: 0.5em;
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
}
|
||||
|
||||
#qunit-tests table {
|
||||
border-collapse: collapse;
|
||||
margin-top: .2em;
|
||||
}
|
||||
|
||||
#qunit-tests th {
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
padding: 0 .5em 0 0;
|
||||
}
|
||||
|
||||
#qunit-tests td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#qunit-tests pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#qunit-tests del {
|
||||
background-color: #e0f2be;
|
||||
color: #374e0c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#qunit-tests ins {
|
||||
background-color: #ffcaca;
|
||||
color: #500;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*** Test Counts */
|
||||
|
||||
#qunit-tests b.counts { color: black; }
|
||||
#qunit-tests b.passed { color: #5E740B; }
|
||||
#qunit-tests b.failed { color: #710909; }
|
||||
|
||||
#qunit-tests li li {
|
||||
padding: 5px;
|
||||
background-color: #fff;
|
||||
border-bottom: none;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
/*** Passing Styles */
|
||||
|
||||
#qunit-tests li li.pass {
|
||||
color: #3c510c;
|
||||
background-color: #fff;
|
||||
border-left: 10px solid #C6E746;
|
||||
}
|
||||
|
||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
||||
#qunit-tests .pass .test-name { color: #366097; }
|
||||
|
||||
#qunit-tests .pass .test-actual,
|
||||
#qunit-tests .pass .test-expected { color: #999999; }
|
||||
|
||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
||||
|
||||
/*** Failing Styles */
|
||||
|
||||
#qunit-tests li li.fail {
|
||||
color: #710909;
|
||||
background-color: #fff;
|
||||
border-left: 10px solid #EE5757;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#qunit-tests > li:last-child {
|
||||
border-radius: 0 0 5px 5px;
|
||||
-moz-border-radius: 0 0 5px 5px;
|
||||
-webkit-border-bottom-right-radius: 5px;
|
||||
-webkit-border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
||||
#qunit-tests .fail .test-name,
|
||||
#qunit-tests .fail .module-name { color: #000000; }
|
||||
|
||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
||||
#qunit-tests .fail .test-expected { color: green; }
|
||||
|
||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
||||
|
||||
|
||||
/** Result */
|
||||
|
||||
#qunit-testresult {
|
||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
||||
|
||||
color: #2b81af;
|
||||
background-color: #D2E0E6;
|
||||
|
||||
border-bottom: 1px solid white;
|
||||
}
|
||||
#qunit-testresult .module-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/** Fixture */
|
||||
|
||||
#qunit-fixture {
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
left: -10000px;
|
||||
width: 1000px;
|
||||
height: 1000px;
|
||||
}
|
||||
1977
vendor/underscore/test/vendor/qunit.js
vendored
1977
vendor/underscore/test/vendor/qunit.js
vendored
File diff suppressed because it is too large
Load Diff
4
vendor/underscore/underscore-min.js
vendored
4
vendor/underscore/underscore-min.js
vendored
File diff suppressed because one or more lines are too long
89
vendor/underscore/underscore.js
vendored
89
vendor/underscore/underscore.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Underscore.js 1.4.2
|
||||
// Underscore.js 1.4.3
|
||||
// http://underscorejs.org
|
||||
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Underscore may be freely distributed under the MIT license.
|
||||
@@ -24,7 +24,6 @@
|
||||
var push = ArrayProto.push,
|
||||
slice = ArrayProto.slice,
|
||||
concat = ArrayProto.concat,
|
||||
unshift = ArrayProto.unshift,
|
||||
toString = ObjProto.toString,
|
||||
hasOwnProperty = ObjProto.hasOwnProperty;
|
||||
|
||||
@@ -61,11 +60,11 @@
|
||||
}
|
||||
exports._ = _;
|
||||
} else {
|
||||
root['_'] = _;
|
||||
root._ = _;
|
||||
}
|
||||
|
||||
// Current version.
|
||||
_.VERSION = '1.4.2';
|
||||
_.VERSION = '1.4.3';
|
||||
|
||||
// Collection Functions
|
||||
// --------------------
|
||||
@@ -102,6 +101,8 @@
|
||||
return results;
|
||||
};
|
||||
|
||||
var reduceError = 'Reduce of empty array with no initial value';
|
||||
|
||||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
||||
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
||||
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
|
||||
@@ -119,7 +120,7 @@
|
||||
memo = iterator.call(context, memo, value, index, list);
|
||||
}
|
||||
});
|
||||
if (!initial) throw new TypeError('Reduce of empty array with no initial value');
|
||||
if (!initial) throw new TypeError(reduceError);
|
||||
return memo;
|
||||
};
|
||||
|
||||
@@ -130,7 +131,7 @@
|
||||
if (obj == null) obj = [];
|
||||
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
|
||||
if (context) iterator = _.bind(iterator, context);
|
||||
return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
|
||||
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
|
||||
}
|
||||
var length = obj.length;
|
||||
if (length !== +length) {
|
||||
@@ -146,7 +147,7 @@
|
||||
memo = iterator.call(context, memo, obj[index], index, list);
|
||||
}
|
||||
});
|
||||
if (!initial) throw new TypeError('Reduce of empty array with no initial value');
|
||||
if (!initial) throw new TypeError(reduceError);
|
||||
return memo;
|
||||
};
|
||||
|
||||
@@ -177,12 +178,9 @@
|
||||
|
||||
// Return all the elements for which a truth test fails.
|
||||
_.reject = function(obj, iterator, context) {
|
||||
var results = [];
|
||||
if (obj == null) return results;
|
||||
each(obj, function(value, index, list) {
|
||||
if (!iterator.call(context, value, index, list)) results[results.length] = value;
|
||||
});
|
||||
return results;
|
||||
return _.filter(obj, function(value, index, list) {
|
||||
return !iterator.call(context, value, index, list);
|
||||
}, context);
|
||||
};
|
||||
|
||||
// Determine whether all of the elements match a truth test.
|
||||
@@ -216,13 +214,11 @@
|
||||
// Determine if the array or object contains a given value (using `===`).
|
||||
// Aliased as `include`.
|
||||
_.contains = _.include = function(obj, target) {
|
||||
var found = false;
|
||||
if (obj == null) return found;
|
||||
if (obj == null) return false;
|
||||
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
||||
found = any(obj, function(value) {
|
||||
return any(obj, function(value) {
|
||||
return value === target;
|
||||
});
|
||||
return found;
|
||||
};
|
||||
|
||||
// Invoke a method (with arguments) on every item in a collection.
|
||||
@@ -258,7 +254,7 @@
|
||||
return Math.max.apply(Math, obj);
|
||||
}
|
||||
if (!iterator && _.isEmpty(obj)) return -Infinity;
|
||||
var result = {computed : -Infinity};
|
||||
var result = {computed : -Infinity, value: -Infinity};
|
||||
each(obj, function(value, index, list) {
|
||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||
computed >= result.computed && (result = {value : value, computed : computed});
|
||||
@@ -272,7 +268,7 @@
|
||||
return Math.min.apply(Math, obj);
|
||||
}
|
||||
if (!iterator && _.isEmpty(obj)) return Infinity;
|
||||
var result = {computed : Infinity};
|
||||
var result = {computed : Infinity, value: Infinity};
|
||||
each(obj, function(value, index, list) {
|
||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||
computed < result.computed && (result = {value : value, computed : computed});
|
||||
@@ -321,7 +317,7 @@
|
||||
// An internal function used for aggregate "group by" operations.
|
||||
var group = function(obj, value, context, behavior) {
|
||||
var result = {};
|
||||
var iterator = lookupIterator(value);
|
||||
var iterator = lookupIterator(value || _.identity);
|
||||
each(obj, function(value, index) {
|
||||
var key = iterator.call(context, value, index, obj);
|
||||
behavior(result, key, value);
|
||||
@@ -341,7 +337,7 @@
|
||||
// either a string attribute to count by, or a function that returns the
|
||||
// criterion.
|
||||
_.countBy = function(obj, value, context) {
|
||||
return group(obj, value, context, function(result, key, value) {
|
||||
return group(obj, value, context, function(result, key) {
|
||||
if (!_.has(result, key)) result[key] = 0;
|
||||
result[key]++;
|
||||
});
|
||||
@@ -363,7 +359,8 @@
|
||||
// Safely convert anything iterable into a real, live array.
|
||||
_.toArray = function(obj) {
|
||||
if (!obj) return [];
|
||||
if (obj.length === +obj.length) return slice.call(obj);
|
||||
if (_.isArray(obj)) return slice.call(obj);
|
||||
if (obj.length === +obj.length) return _.map(obj, _.identity);
|
||||
return _.values(obj);
|
||||
};
|
||||
|
||||
@@ -413,7 +410,7 @@
|
||||
|
||||
// Trim out all falsy values from an array.
|
||||
_.compact = function(array) {
|
||||
return _.filter(array, function(value){ return !!value; });
|
||||
return _.filter(array, _.identity);
|
||||
};
|
||||
|
||||
// Internal implementation of a recursive `flatten` function.
|
||||
@@ -442,6 +439,11 @@
|
||||
// been sorted, you have the option of using a faster algorithm.
|
||||
// Aliased as `unique`.
|
||||
_.uniq = _.unique = function(array, isSorted, iterator, context) {
|
||||
if (_.isFunction(isSorted)) {
|
||||
context = iterator;
|
||||
iterator = isSorted;
|
||||
isSorted = false;
|
||||
}
|
||||
var initial = iterator ? _.map(array, iterator, context) : array;
|
||||
var results = [];
|
||||
var seen = [];
|
||||
@@ -572,8 +574,8 @@
|
||||
// optionally). Binding with arguments is also known as `curry`.
|
||||
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
||||
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
||||
_.bind = function bind(func, context) {
|
||||
var bound, args;
|
||||
_.bind = function(func, context) {
|
||||
var args, bound;
|
||||
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||||
if (!_.isFunction(func)) throw new TypeError;
|
||||
args = slice.call(arguments, 2);
|
||||
@@ -581,6 +583,7 @@
|
||||
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
||||
ctor.prototype = func.prototype;
|
||||
var self = new ctor;
|
||||
ctor.prototype = null;
|
||||
var result = func.apply(self, args.concat(slice.call(arguments)));
|
||||
if (Object(result) === result) return result;
|
||||
return self;
|
||||
@@ -636,6 +639,7 @@
|
||||
args = arguments;
|
||||
if (remaining <= 0) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
previous = now;
|
||||
result = func.apply(context, args);
|
||||
} else if (!timeout) {
|
||||
@@ -758,8 +762,10 @@
|
||||
// Extend a given object with all the properties in passed-in object(s).
|
||||
_.extend = function(obj) {
|
||||
each(slice.call(arguments, 1), function(source) {
|
||||
for (var prop in source) {
|
||||
obj[prop] = source[prop];
|
||||
if (source) {
|
||||
for (var prop in source) {
|
||||
obj[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
@@ -788,8 +794,10 @@
|
||||
// Fill in a given object with default properties.
|
||||
_.defaults = function(obj) {
|
||||
each(slice.call(arguments, 1), function(source) {
|
||||
for (var prop in source) {
|
||||
if (obj[prop] == null) obj[prop] = source[prop];
|
||||
if (source) {
|
||||
for (var prop in source) {
|
||||
if (obj[prop] == null) obj[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
@@ -954,7 +962,7 @@
|
||||
|
||||
// Is a given object a finite number?
|
||||
_.isFinite = function(obj) {
|
||||
return _.isNumber(obj) && isFinite(obj);
|
||||
return isFinite(obj) && !isNaN(parseFloat(obj));
|
||||
};
|
||||
|
||||
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
|
||||
@@ -1000,7 +1008,9 @@
|
||||
|
||||
// Run a function **n** times.
|
||||
_.times = function(n, iterator, context) {
|
||||
for (var i = 0; i < n; i++) iterator.call(context, i);
|
||||
var accum = Array(n);
|
||||
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
|
||||
return accum;
|
||||
};
|
||||
|
||||
// Return a random integer between min and max (inclusive).
|
||||
@@ -1065,7 +1075,7 @@
|
||||
// Useful for temporary DOM ids.
|
||||
var idCounter = 0;
|
||||
_.uniqueId = function(prefix) {
|
||||
var id = idCounter++;
|
||||
var id = '' + ++idCounter;
|
||||
return prefix ? prefix + id : id;
|
||||
};
|
||||
|
||||
@@ -1115,11 +1125,18 @@
|
||||
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
||||
source += text.slice(index, offset)
|
||||
.replace(escaper, function(match) { return '\\' + escapes[match]; });
|
||||
source +=
|
||||
escape ? "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'" :
|
||||
interpolate ? "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" :
|
||||
evaluate ? "';\n" + evaluate + "\n__p+='" : '';
|
||||
|
||||
if (escape) {
|
||||
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
||||
}
|
||||
if (interpolate) {
|
||||
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
||||
}
|
||||
if (evaluate) {
|
||||
source += "';\n" + evaluate + "\n__p+='";
|
||||
}
|
||||
index = offset + match.length;
|
||||
return match;
|
||||
});
|
||||
source += "';\n";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user