├── .eslintrc.js
├── .gitignore
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── bower.json
├── jquery.serializejson.js
├── jquery.serializejson.min.js
├── package-lock.json
├── package.json
└── spec
├── lib
├── jasmine-2.0.0
│ ├── boot.js
│ ├── console.js
│ ├── jasmine-html.js
│ ├── jasmine.css
│ ├── jasmine.js
│ └── jasmine_favicon.png
├── jquery-2.1.3.js
└── zepto-1.1.6.js
├── spec.js
├── spec_runner_jquery.html
└── spec_runner_zepto.html
/.eslintrc.js:
--------------------------------------------------------------------------------
1 |
2 | /* global module */
3 | module.exports = {
4 | "env": {
5 | "browser": true,
6 | "jquery": true
7 | },
8 | "extends": "eslint:recommended",
9 | "parserOptions": {
10 | "ecmaVersion": 5
11 | },
12 | "rules": {
13 | "indent": [
14 | "error",
15 | 4
16 | ],
17 | "linebreak-style": [
18 | "error",
19 | "unix"
20 | ],
21 | "quotes": [
22 | "error",
23 | "double"
24 | ],
25 | "semi": [
26 | "error",
27 | "always"
28 | ]
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Changelog
2 | ---------
3 |
4 | * *3.2.1* (Feb 24, 2021): Fix sync issue between Github tag and npm.
5 | * *3.2.0* (Feb 24, 2021): Reimplement jQuery's serializeArray function, with the ability to include unchecked checkboxes, and returning the DOM element. This allows to simplify the code, fixing an issue with repeated input names used for arrays (Fixes #67), and allows custom type functions to receive the DOM elemnt (Fixes #109).
6 | * *3.1.1* (Dec 30, 2020): Update #114 (Allow to use new versions of jQuery by avoiding calls to the deprecated method `jQuery.isArray`).
7 | * *3.1.1* (Nov 09, 2020): Bugfix #110 (Allow unindexed arrays with multiple levels of nested objects).
8 | * *3.1.0* (Sep 13, 2020): Rename option `disableColonTypes` that was mistakenly named `disableSemicolonTypes`. Fix typos in README.
9 | * *3.0.0* (Sep 06, 2020): Improve types (PR #105) and remove parsing options (PR #104). The type system with `:type` suffixes, `data-value-type` attributes, and a combination of the options `customTypes`, `disableColonTypes` and `defaultType`, are safer and easier to use than the previous options `parseNumbers`, `parseAll`, etc. Thanks [Laykou](https://github.com/Laykou) for suggesting [PR #102] that pointed the problems of inputs with colons in their names.
10 | * *2.9.0* (Jan 12, 2018): Overrides to `customTypes.string` function now also apply to fields with no type, because `:string` is the default implicit type. Thanks [JocaPC](https://github.com/JocaPC) for reporting the [issue #83](https://github.com/marioizquierdo/jquery.serializeJSON/issues/83).
11 | * *2.8.1* (Dec 09, 2016): Identify issue #67 and throw a descriptive error with a link to the issue, that explains why nested arrays of objects with checkboxes with unchecked values are not supported.
12 | * *2.8.0* (Dec 09, 2016): Add options `skipFalsyValuesForFields`, `skipFalsyValuesForTypes` and attr `data-skip-falsy` to easily skip falsy values (which includes empty strings). Thanks to [milkaknap](https://github.com/milkaknap).
13 | * *2.7.2* (Dec 19, 2015): Bugfix #55 (Allow data types with the `data-value-type` attribute to use brackets in names). Thanks to [stricte](https://github.com/stricte).
14 | * *2.7.1* (Dec 12, 2015): Bugfix #54 (`data-value-type` attribute only works with input elements). Thanks to [madrabaz](https://github.com/madrabaz).
15 | * *2.7.0* (Nov 28, 2015): Allow to define custom types with the `data-value-type` attribute. Thanks to [madrabaz](https://github.com/madrabaz).
16 | * *2.6.2* (Oct 24, 2015): Add support for AMD/CommonJS/Browserify modules. Thanks to [jisaacks](https://github.com/jisaacks).
17 | * *2.6.1* (May 13, 2015): Bugfix #43 (Fix IE 8 compatibility). Thanks to [rywall](https://github.com/rywall).
18 | * *2.6.0* (Apr 24, 2015): Allow to define custom types with the option `customTypes` and inspect/override default types with the option `defaultTypes`. Thanks to [tygriffin](https://github.com/tygriffin) for the [pull request](https://github.com/marioizquierdo/jquery.serializeJSON/pull/40).
19 | * *2.5.0* (Mar 11, 2015): Override serialized properties if using the same name, even for nested values, instead of crashing the script, fixing issue#29. Also fix a crash when using Zepto and the data-unchecked-value option.
20 | * *2.4.2* (Feb 04, 2015): Ignore disabled checkboxes with "data-unchecked-value". Thanks to [skarr](https://github.com/skarr) for the [pull request](https://github.com/marioizquierdo/jquery.serializeJSON/pull/33).
21 | * *2.4.1* (Oct 12, 2014): Add `:auto` type, that works like the `parseAll` option, but targeted to a single input.
22 | * *2.4.0* (Oct 12, 2014): Implement :types. Types allow to easily specify how to parse each input.
23 | * *2.3.2* (Oct 11, 2014): Bugfix #27 (parsing error on nested keys like name="foo[inn[bar]]"). Thanks to [danlo](https://github.com/danlo) for finding the issue.
24 | * *2.3.1* (Oct 06, 2014): Bugfix #22 (ignore checkboxes with no name when doing `checkboxUncheckedValue`). Thanks to [KATT](https://github.com/KATT) for finding and fixing the issue.
25 | * *2.3.0* (Sep 25, 2014): Properly spell "data-unckecked-value", change for "data-unchecked-value"
26 | * *2.2.0* (Sep 17, 2014): Add option `checkboxUncheckedValue` and attribute `data-unckecked-value` to allow parsing unchecked checkboxes.
27 | * *2.1.0* (Jun 08, 2014): Add option `parseWithFunction` to allow custom parsers. And fix issue #14: empty strings were parsed as a zero when `parseNumbers` option was true.
28 | * *2.0.0* (May 04, 2014): Nested keys are always object attributes by default (discussed on issue #12). Set option `$.serializeJSON.defaultOptions.useIntKeysAsArrayIndex = true;` for backwards compatibility (see **Options** section). Thanks to [joshuajabbour](https://github.com/joshuajabbour) for finding the issue.
29 | * *1.3.0* (May 03, 2014): Accept options {parseBooleans, parseNumbers, parseNulls, parseAll} to modify what type to values are interpreted from the strings. Thanks to [diaswrd](https://github.com/diaswrd) for finding the issue.
30 | * *1.2.3* (Apr 12, 2014): Lowercase filenames.
31 | * *1.2.2* (Apr 03, 2014): Now also works with [Zepto.js](http://zeptojs.com/).
32 | * *1.2.1* (Mar 17, 2014): Refactor, cleanup, lint code and improve test coverage.
33 | * *1.2.0* (Mar 11, 2014): Arrays with empty index and objects with empty values are added and not overriden. Thanks to [kotas](https://github.com/kotas).
34 | * *1.1.1* (Feb 16, 2014): Only unsigned integers are used to create arrays. Alphanumeric keys are always for objects. Thanks to [Nicocin](https://github.com/Nicocin).
35 | * *1.0.2* (Jan 07, 2014): Tag to be on the jQuery plugin registry.
36 | * *1.0.1* (Aug 20, 2012): Bugfix: ensure that generated arrays are being displayed when parsed with JSON.stringify
37 | * *1.0.0* (Aug 20, 2012): Initial release
38 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2012-2021 Mario Izquierdo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | jquery.serializeJSON
2 | ====================
3 |
4 | Adds the method `.serializeJSON()` to [jQuery](http://jquery.com/) to serializes a form into a JavaScript Object. Supports the same format for nested parameters that is used in Ruby on Rails.
5 |
6 | Install
7 | -------
8 |
9 | Install with [bower](http://bower.io/) `bower install jquery.serializeJSON`, or [npm](https://www.npmjs.com/) `npm install jquery-serializejson`, or just download the [jquery.serializejson.js](https://raw.githubusercontent.com/marioizquierdo/jquery.serializeJSON/master/jquery.serializejson.js) script.
10 |
11 | And make sure it is included after jQuery, for example:
12 | ```html
13 |
14 |
15 | ```
16 |
17 | Usage Example
18 | -------------
19 |
20 | HTML form:
21 | ```html
22 |
27 | ```
28 |
29 | JavaScript:
30 | ```javascript
31 | $('form').serializeJSON();
32 |
33 | // returns =>
34 | {
35 | title: "Dune",
36 | author: {
37 | name: "Frank Herbert",
38 | period: "1945–1986"
39 | }
40 | }
41 | ```
42 |
43 | Nested attributes and arrays can be specified by naming fields with the syntax: `name="attr[nested][nested]"`.
44 |
45 | HTML form:
46 | ```html
47 |
85 |
86 | ```
87 |
88 | JavaScript:
89 |
90 | ```javascript
91 | $('#my-profile').serializeJSON();
92 |
93 | // returns =>
94 | {
95 | fullName: "Mario",
96 |
97 | address: {
98 | city: "San Francisco",
99 | state: {
100 | name: "California",
101 | abbr: "CA"
102 | }
103 | },
104 |
105 | jobbies: ["code", "climbing"],
106 |
107 | projects: {
108 | '0': { name: "serializeJSON", language: "javascript", popular: "1" },
109 | '1': { name: "tinytest.js", language: "javascript", popular: "0" }
110 | },
111 |
112 | selectOne: "rock",
113 | selectMultiple: ["red", "blue"]
114 | }
115 | ```
116 |
117 | The `serializeJSON` function returns a JavaScript object, not a JSON String. The plugin should probably have been called `serializeObject` or similar, but that plugin name was already taken.
118 |
119 | To convert into a JSON String, use the `JSON.stringify` method, that is available on all major [new browsers](http://caniuse.com/json).
120 | If you need to support very old browsers, just include the [json2.js](https://github.com/douglascrockford/JSON-js) polyfill (as described on [stackoverfow](http://stackoverflow.com/questions/191881/serializing-to-json-in-jquery)).
121 |
122 | ```javascript
123 | var obj = $('form').serializeJSON();
124 | var jsonString = JSON.stringify(obj);
125 | ```
126 |
127 | The plugin serializes the same inputs supported by [.serializeArray()](https://api.jquery.com/serializeArray/), following the standard W3C rules for [successful controls](http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2). In particular, the included elements **cannot be disabled** and must contain a **name attribute**. No submit button value is serialized since the form was not submitted using a button. And data from file select elements is not serialized.
128 |
129 |
130 | Parse values with :types
131 | ------------------------
132 |
133 | Fields values are `:string` by default. But can be parsed with types by appending a `:type` suffix to the field name:
134 |
135 | ```html
136 |
158 | ```
159 |
160 | ```javascript
161 | $('form').serializeJSON();
162 |
163 | // returns =>
164 | {
165 | "default": ":string is the default",
166 | "text": "some text string",
167 | // excluded:skip is ignored in the output
168 |
169 | "numbers": {
170 | "1": 1,
171 | "1.1": 1.1,
172 | "other": NaN, // <-- "other" is parsed as NaN
173 | },
174 | "bools": {
175 | "true": true,
176 | "false": false,
177 | "0": false, // <-- "false", "null", "undefined", "", "0" are parsed as false
178 | },
179 | "nulls": {
180 | "null": null, // <-- "false", "null", "undefined", "", "0" are parsed as null
181 | "other": "other" // <-- if not null, the type is a string
182 | },
183 | "arrays": { // <-- uses JSON.parse
184 | "empty": [],
185 | "not empty": [1,2,3]
186 | },
187 | "objects": { // <-- uses JSON.parse
188 | "empty": {},
189 | "not empty": {"my": "stuff"}
190 | }
191 | }
192 | ```
193 |
194 | Types can also be specified with the attribute `data-value-type`, instead of adding the `:type` suffix in the field name:
195 |
196 | ```html
197 |
203 | ```
204 |
205 | If your field names contain colons (e.g. `name="article[my::key][active]"`) the last part after the colon will be confused as an invalid type. One way to avoid that is to explicitly append the type `:string` (e.g. `name="article[my::key][active]:string"`), or to use the attribute `data-value-type="string"`. Data attributes have precedence over `:type` name suffixes. It is also possible to disable parsing `:type` suffixes with the option `{ disableColonTypes: true }`.
206 |
207 |
208 | ### Custom Types
209 |
210 | Use the `customTypes` option to provide your own parsing functions. The parsing functions receive the input name as a string, and the DOM elment of the serialized input.
211 |
212 | ```html
213 |
218 | ```
219 |
220 | ```javascript
221 | $('form').serializeJSON({
222 | customTypes: {
223 | alwaysBoo: (strVal, el) => {
224 | // strVal: is the input value as a string
225 | // el: is the dom element. $(el) would be the jQuery element
226 | return "boo"; // value returned in the serialization of this type
227 | },
228 | }
229 | });
230 |
231 | // returns =>
232 | {
233 | "scary": "boo", // <-- parsed with custom type "alwaysBoo"
234 | "str": "str",
235 | "five": 5,
236 | }
237 | ```
238 |
239 | The provided `customTypes` can include one of the `detaultTypes` to override the default behavior:
240 |
241 | ```javascript
242 | $('form').serializeJSON({
243 | customTypes: {
244 | alwaysBoo: (strVal) => { return "boo"; },
245 | string: (strVal) => { return strVal + "-OVERDRIVE"; },
246 | }
247 | });
248 |
249 | // returns =>
250 | {
251 | "scary": "boo", // <-- parsed with custom type "alwaysBoo"
252 | "str": "str-OVERDRIVE", // <-- parsed with custom override "string"
253 | "five": 5, // <-- parsed with default type "number"
254 | }
255 | ```
256 |
257 | Default types used by the plugin are defined in `$.serializeJSON.defaultOptions.defaultTypes`.
258 |
259 |
260 | Options
261 | -------
262 |
263 | With no options, `.serializeJSON()` returns the same as a regular HTML form submission when serialized as Rack/Rails params. In particular:
264 |
265 | * Values are **strings** (unless appending a `:type` to the input name)
266 | * Unchecked checkboxes are ignored (as defined in the W3C rules for [successful controls](http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2)).
267 | * Disabled elements are ignored (W3C rules)
268 | * Keys (input names) are always **strings** (nested params are objects by default)
269 |
270 | Available options:
271 |
272 | * **checkboxUncheckedValue: string**, return this value on checkboxes that are not checked. Without this option, they would be ignored. For example: `{checkboxUncheckedValue: ""}` returns an empty string. If the field has a `:type`, the returned value will be properly parsed; for example if the field type is `:boolean`, it returns `false` instead of an empty string.
273 | * **useIntKeysAsArrayIndex: true**, when using integers as keys (i.e. ``), serialize as an array (`{"foods": ["banana"]}`) instead of an object (`{"foods": {"0": "banana"}`).
274 | * **skipFalsyValuesForFields: []**, skip given fields (by name) with falsy values. You can use `data-skip-falsy="true"` input attribute as well. Falsy values are determined after converting to a given type, note that `"0"` as `:string` (default) is still truthy, but `0` as `:number` is falsy.
275 | * **skipFalsyValuesForTypes: []**, skip given fields (by :type) with falsy values (i.e. `skipFalsyValuesForTypes: ["string", "number"]` would skip `""` for `:string` fields, and `0` for `:number` fields).
276 | * **customTypes: {}**, define your own `:type` functions. Defined as an object like `{ type: function(value){...} }`. For example: `{customTypes: {nullable: function(str){ return str || null; }}`. Custom types extend defaultTypes.
277 | * **defaultTypes: {defaults}**, contains the orignal type functions `string`, `number`, `boolean`, `null`, `array`, `object` and `skip`.
278 | * **defaultType: "string"**, fields that have no `:type` suffix and no `data-value-type` attribute are parsed with the `string` type function by default, but it could be changed to use a different type function instead.
279 | * **disableColonTypes: true**, do not parse input names as types, allowing field names to use colons. If this option is used, types can still be specified with the `data-value-type` attribute. For example `` will be parsed as a number.
280 |
281 | More details about these options in the sections below.
282 |
283 | ## Include unchecked checkboxes
284 |
285 | One of the most confusing details when serializing a form is the input type checkbox, because it includes the value if checked, but nothing if unchecked.
286 |
287 | To deal with this, a common practice in HTML forms is to use hidden fields for the "unchecked" values:
288 |
289 | ```html
290 |
291 |
292 |
293 | ```
294 |
295 | This solution is somehow verbose, but ensures progressive enhancement, it works even when JavaScript is disabled.
296 |
297 | But, to make things easier, `serializeJSON` includes the option `checkboxUncheckedValue` and the possibility to add the attribute `data-unchecked-value` to the checkboxes:
298 |
299 | ```html
300 |
305 | ```
306 |
307 | Serializes like this by default:
308 |
309 | ```javascript
310 | $('form').serializeJSON();
311 |
312 | // returns =>
313 | {check1: 'true'} // check2 and check3 are ignored
314 | ```
315 |
316 | To include all checkboxes, use the `checkboxUncheckedValue` option:
317 |
318 | ```javascript
319 | $('form').serializeJSON({checkboxUncheckedValue: "false"});
320 |
321 | // returns =>
322 | {check1: "true", check2: "false", check3: "false"}
323 | ```
324 |
325 | The `data-unchecked-value` HTML attribute can be used to targed specific values per field:
326 |
327 | ```html
328 |
337 | ```
338 |
339 | ```javascript
340 | $('form#checkboxes').serializeJSON(); // No option is needed if the data attribute is used
341 |
342 | // returns =>
343 | {
344 | 'checked': {
345 | 'b': true,
346 | 'numb': '1',
347 | 'cool': 'YUP'
348 | },
349 | 'unchecked': {
350 | 'bool': false,
351 | 'bin': '0'
352 | // 'cool' is not included, because it doesn't use data-unchecked-value
353 | }
354 | }
355 | ```
356 |
357 | You can use both the option `checkboxUncheckedValue` and the attribute `data-unchecked-value` at the same time, in which case the option is used as default value (the data attribute has precedence).
358 |
359 | ```javascript
360 | $('form#checkboxes').serializeJSON({checkboxUncheckedValue: 'NOPE'});
361 |
362 | // returns =>
363 | {
364 | 'checked': {
365 | 'b': true,
366 | 'numb': '1',
367 | 'cool': 'YUP'
368 | },
369 | 'unchecked': {
370 | 'bool': false, // value from data-unchecked-value attribute, and parsed with type "boolean"
371 | 'bin': '0', // value from data-unchecked-value attribute
372 | 'cool': 'NOPE' // value from checkboxUncheckedValue option
373 | }
374 | }
375 | ```
376 |
377 | ## Ignore Empty Form Fields
378 |
379 | You can use the option `.serializeJSON({skipFalsyValuesForTypes: ["string"]})`, which ignores any string field with an empty value (default type is :string, and empty strings are falsy).
380 |
381 | Another option, since `serializeJSON()` is called on a jQuery object, is to just use the proper jQuery selector to skip empty values (see [Issue #28](https://github.com/marioizquierdo/jquery.serializeJSON/issues/28) for more info):
382 |
383 | ```javascript
384 | // Select only imputs that have a non-empty value
385 | $('form :input[value!=""]').serializeJSON();
386 |
387 | // Or filter them from the form
388 | obj = $('form').find('input').not('[value=""]').serializeJSON();
389 |
390 | // For more complicated filtering, you can use a function
391 | obj = $form.find(':input').filter(function () {
392 | return $.trim(this.value).length > 0
393 | }).serializeJSON();
394 | ```
395 |
396 |
397 | ## Ignore Fields With Falsy Values
398 |
399 | When using :types, you can also skip falsy values (`false, "", 0, null, undefined, NaN`) by using the option `skipFalsyValuesForFields: ["fullName", "address[city]"]` or `skipFalsyValuesForTypes: ["string", "null"]`.
400 |
401 | Or setting a data attribute `data-skip-falsy="true"` on the inputs that should be ignored. Note that `data-skip-falsy` is aware of field :types, so it knows how to skip a non-empty input like this `` (Note that `"0"` as a string is not falsy, but `0` as number is falsy)).
402 |
403 |
404 | ## Use integer keys as array indexes
405 |
406 | By default, all serialized keys are **strings**, this includes keys that look like numbers like this:
407 |
408 | ```html
409 |
414 | ```
415 |
416 | ```javascript
417 | $('form').serializeJSON();
418 |
419 | // arr is an object =>
420 | {'arr': {'0': 'foo', '1': 'var', '5': 'inn' }}
421 | ```
422 |
423 | Which is how Rack [parse_nested_query](http://codefol.io/posts/How-Does-Rack-Parse-Query-Params-With-parse-nested-query) behaves. Remember that serializeJSON input name format is fully compatible with Rails parameters, that are parsed using this Rack method.
424 |
425 | Use the option `useIntKeysAsArrayIndex` to interpret integers as array indexes:
426 |
427 | ```javascript
428 | $('form').serializeJSON({useIntKeysAsArrayIndex: true});
429 |
430 | // arr is an array =>
431 | {'arr': ['foo', 'var', undefined, undefined, undefined, 'inn']}
432 | ```
433 |
434 | **Note**: this was the default behavior of serializeJSON before version 2. You can use this option for backwards compatibility.
435 |
436 |
437 | ## Option Defaults
438 |
439 | All options defaults are defined in `$.serializeJSON.defaultOptions`. You can just modify it to avoid setting the option on every call to `serializeJSON`. For example:
440 |
441 | ```javascript
442 | $.serializeJSON.defaultOptions.checkboxUncheckedValue = ""; // include unckecked checkboxes as empty strings
443 | $.serializeJSON.defaultOptions.customTypes.foo = (str) => { return str + "-foo"; }; // define global custom type ":foo"
444 | ```
445 |
446 |
447 | Alternatives
448 | ------------
449 |
450 | Other plugins solve the same problem in similar ways:
451 |
452 | * https://github.com/macek/jquery-serialize-object
453 | * https://github.com/hongymagic/jQuery.serializeObject
454 | * https://github.com/danheberden/jquery-serializeForm
455 | * https://github.com/maxatwork/form2js (plain js, no jQuery)
456 | * https://github.com/serbanghita/formToObject.js (plain js, no jQuery)
457 | * https://gist.github.com/shiawuen/2634143 (simpler but small)
458 |
459 | None of them did what I needed at the time `serializeJSON` was created. Factors that differentiate `serializeJSON` from the alternatives:
460 |
461 | * Simple and small code base. The minimified version is < 1Kb.
462 | * Yet flexible enough with features like nested objects, unchecked-checkboxes and custom types.
463 | * Implementation follows the same rules as the jQuery method `serializeArray`, that creates a JavaScript array of objects, ready to be encoded as a JSON string. Taking into account the W3C rules for [successful controls](http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2) for better compatibility.
464 | * The format for the input field names is the same used by Rails (from [Rack::Utils.parse_nested_query](http://codefol.io/posts/How-Does-Rack-Parse-Query-Params-With-parse-nested-query)), that is successfully used by many backend systems and already well understood by many front end developers.
465 | * Exaustive test suite helps iterate on new releases and bugfixes with confidence.
466 | * Compatible with [bower](https://github.com/bower/bower), [zepto.js](http://zeptojs.com/) and pretty much every version of [jQuery](https://jquery.com/).
467 |
468 |
469 | Contributions
470 | -------------
471 |
472 | Contributions are awesome. Feature branch *pull requests* are the preferred method. Just make sure to add tests for it. To run the jasmine specs, just open `spec/spec_runner_jquery.html` in your browser.
473 |
474 | Changelog
475 | ---------
476 |
477 | See [CHANGELOG.md](./CHANGELOG.md)
478 |
479 | Author
480 | -------
481 |
482 | Written and maintained by [Mario Izquierdo](https://github.com/marioizquierdo)
483 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery.serializeJSON",
3 | "main": "jquery.serializejson.js",
4 | "version": "3.2.1",
5 | "description": "jQuery or Zepto plugin to serialize a form into a JavaScript Object, using the same format as the default Ruby on Rails request params",
6 | "homepage": "https://github.com/marioizquierdo/jquery.serializeJSON",
7 | "authors": ["Mario Izquierdo "],
8 | "keywords": ["form", "serialize", "json", "helper", "jquery"],
9 | "license": "MIT",
10 | "ignore": ["**/.*", "node_modules", "bower_components", "test", "tests"],
11 | "dependencies": {
12 | "jquery": "*"
13 | },
14 | "devDependencies": {
15 | "jasmine": "2.0.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/jquery.serializejson.js:
--------------------------------------------------------------------------------
1 | /*!
2 | SerializeJSON jQuery plugin.
3 | https://github.com/marioizquierdo/jquery.serializeJSON
4 | version 3.2.1 (Feb, 2021)
5 |
6 | Copyright (c) 2012-2021 Mario Izquierdo
7 | Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
8 | and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
9 | */
10 | (function (factory) {
11 | /* global define, require, module */
12 | if (typeof define === "function" && define.amd) { // AMD. Register as an anonymous module.
13 | define(["jquery"], factory);
14 | } else if (typeof exports === "object") { // Node/CommonJS
15 | var jQuery = require("jquery");
16 | module.exports = factory(jQuery);
17 | } else { // Browser globals (zepto supported)
18 | factory(window.jQuery || window.Zepto || window.$); // Zepto supported on browsers as well
19 | }
20 |
21 | }(function ($) {
22 | "use strict";
23 |
24 | var rCRLF = /\r?\n/g;
25 | var rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i;
26 | var rsubmittable = /^(?:input|select|textarea|keygen)/i;
27 | var rcheckableType = /^(?:checkbox|radio)$/i;
28 |
29 | $.fn.serializeJSON = function (options) {
30 | var f = $.serializeJSON;
31 | var $form = this; // NOTE: the set of matched elements is most likely a form, but it could also be a group of inputs
32 | var opts = f.setupOpts(options); // validate options and apply defaults
33 | var typeFunctions = $.extend({}, opts.defaultTypes, opts.customTypes);
34 |
35 | // Make a list with {name, value, el} for each input element
36 | var serializedArray = f.serializeArray($form, opts);
37 |
38 | // Convert the serializedArray into a serializedObject with nested keys
39 | var serializedObject = {};
40 | $.each(serializedArray, function (_i, obj) {
41 |
42 | var nameSansType = obj.name;
43 | var type = $(obj.el).attr("data-value-type");
44 |
45 | if (!type && !opts.disableColonTypes) { // try getting the type from the input name
46 | var p = f.splitType(obj.name); // "foo:string" => ["foo", "string"]
47 | nameSansType = p[0];
48 | type = p[1];
49 | }
50 | if (type === "skip") {
51 | return; // ignore fields with type skip
52 | }
53 | if (!type) {
54 | type = opts.defaultType; // "string" by default
55 | }
56 |
57 | var typedValue = f.applyTypeFunc(obj.name, obj.value, type, obj.el, typeFunctions); // Parse type as string, number, etc.
58 |
59 | if (!typedValue && f.shouldSkipFalsy(obj.name, nameSansType, type, obj.el, opts)) {
60 | return; // ignore falsy inputs if specified in the options
61 | }
62 |
63 | var keys = f.splitInputNameIntoKeysArray(nameSansType);
64 | f.deepSet(serializedObject, keys, typedValue, opts);
65 | });
66 | return serializedObject;
67 | };
68 |
69 | // Use $.serializeJSON as namespace for the auxiliar functions
70 | // and to define defaults
71 | $.serializeJSON = {
72 | defaultOptions: {}, // reassign to override option defaults for all serializeJSON calls
73 |
74 | defaultBaseOptions: { // do not modify, use defaultOptions instead
75 | checkboxUncheckedValue: undefined, // to include that value for unchecked checkboxes (instead of ignoring them)
76 | useIntKeysAsArrayIndex: false, // name="foo[2]" value="v" => {foo: [null, null, "v"]}, instead of {foo: ["2": "v"]}
77 |
78 | skipFalsyValuesForTypes: [], // skip serialization of falsy values for listed value types
79 | skipFalsyValuesForFields: [], // skip serialization of falsy values for listed field names
80 |
81 | disableColonTypes: false, // do not interpret ":type" suffix as a type
82 | customTypes: {}, // extends defaultTypes
83 | defaultTypes: {
84 | "string": function(str) { return String(str); },
85 | "number": function(str) { return Number(str); },
86 | "boolean": function(str) { var falses = ["false", "null", "undefined", "", "0"]; return falses.indexOf(str) === -1; },
87 | "null": function(str) { var falses = ["false", "null", "undefined", "", "0"]; return falses.indexOf(str) === -1 ? str : null; },
88 | "array": function(str) { return JSON.parse(str); },
89 | "object": function(str) { return JSON.parse(str); },
90 | "skip": null // skip is a special type used to ignore fields
91 | },
92 | defaultType: "string",
93 | },
94 |
95 | // Validate and set defaults
96 | setupOpts: function(options) {
97 | if (options == null) options = {};
98 | var f = $.serializeJSON;
99 |
100 | // Validate
101 | var validOpts = [
102 | "checkboxUncheckedValue",
103 | "useIntKeysAsArrayIndex",
104 |
105 | "skipFalsyValuesForTypes",
106 | "skipFalsyValuesForFields",
107 |
108 | "disableColonTypes",
109 | "customTypes",
110 | "defaultTypes",
111 | "defaultType"
112 | ];
113 | for (var opt in options) {
114 | if (validOpts.indexOf(opt) === -1) {
115 | throw new Error("serializeJSON ERROR: invalid option '" + opt + "'. Please use one of " + validOpts.join(", "));
116 | }
117 | }
118 |
119 | // Helper to get options or defaults
120 | return $.extend({}, f.defaultBaseOptions, f.defaultOptions, options);
121 | },
122 |
123 | // Just like jQuery's serializeArray method, returns an array of objects with name and value.
124 | // but also includes the dom element (el) and is handles unchecked checkboxes if the option or data attribute are provided.
125 | serializeArray: function($form, opts) {
126 | if (opts == null) { opts = {}; }
127 | var f = $.serializeJSON;
128 |
129 | return $form.map(function() {
130 | var elements = $.prop(this, "elements"); // handle propHook "elements" to filter or add form elements
131 | return elements ? $.makeArray(elements) : this;
132 |
133 | }).filter(function() {
134 | var $el = $(this);
135 | var type = this.type;
136 |
137 | // Filter with the standard W3C rules for successful controls: http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2
138 | return this.name && // must contain a name attribute
139 | !$el.is(":disabled") && // must not be disable (use .is(":disabled") so that fieldset[disabled] works)
140 | rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && // only serialize submittable fields (and not buttons)
141 | (this.checked || !rcheckableType.test(type) || f.getCheckboxUncheckedValue($el, opts) != null); // skip unchecked checkboxes (unless using opts)
142 |
143 | }).map(function(_i, el) {
144 | var $el = $(this);
145 | var val = $el.val();
146 | var type = this.type; // "input", "select", "textarea", "checkbox", etc.
147 |
148 | if (val == null) {
149 | return null;
150 | }
151 |
152 | if (rcheckableType.test(type) && !this.checked) {
153 | val = f.getCheckboxUncheckedValue($el, opts);
154 | }
155 |
156 | if (isArray(val)) {
157 | return $.map(val, function(val) {
158 | return { name: el.name, value: val.replace(rCRLF, "\r\n"), el: el };
159 | } );
160 | }
161 |
162 | return { name: el.name, value: val.replace(rCRLF, "\r\n"), el: el };
163 |
164 | }).get();
165 | },
166 |
167 | getCheckboxUncheckedValue: function($el, opts) {
168 | var val = $el.attr("data-unchecked-value");
169 | if (val == null) {
170 | val = opts.checkboxUncheckedValue;
171 | }
172 | return val;
173 | },
174 |
175 | // Parse value with type function
176 | applyTypeFunc: function(name, strVal, type, el, typeFunctions) {
177 | var typeFunc = typeFunctions[type];
178 | if (!typeFunc) { // quick feedback to user if there is a typo or missconfiguration
179 | throw new Error("serializeJSON ERROR: Invalid type " + type + " found in input name '" + name + "', please use one of " + objectKeys(typeFunctions).join(", "));
180 | }
181 | return typeFunc(strVal, el);
182 | },
183 |
184 | // Splits a field name into the name and the type. Examples:
185 | // "foo" => ["foo", ""]
186 | // "foo:boolean" => ["foo", "boolean"]
187 | // "foo[bar]:null" => ["foo[bar]", "null"]
188 | splitType : function(name) {
189 | var parts = name.split(":");
190 | if (parts.length > 1) {
191 | var t = parts.pop();
192 | return [parts.join(":"), t];
193 | } else {
194 | return [name, ""];
195 | }
196 | },
197 |
198 | // Check if this input should be skipped when it has a falsy value,
199 | // depending on the options to skip values by name or type, and the data-skip-falsy attribute.
200 | shouldSkipFalsy: function(name, nameSansType, type, el, opts) {
201 | var skipFromDataAttr = $(el).attr("data-skip-falsy");
202 | if (skipFromDataAttr != null) {
203 | return skipFromDataAttr !== "false"; // any value is true, except the string "false"
204 | }
205 |
206 | var optForFields = opts.skipFalsyValuesForFields;
207 | if (optForFields && (optForFields.indexOf(nameSansType) !== -1 || optForFields.indexOf(name) !== -1)) {
208 | return true;
209 | }
210 |
211 | var optForTypes = opts.skipFalsyValuesForTypes;
212 | if (optForTypes && optForTypes.indexOf(type) !== -1) {
213 | return true;
214 | }
215 |
216 | return false;
217 | },
218 |
219 | // Split the input name in programatically readable keys.
220 | // Examples:
221 | // "foo" => ["foo"]
222 | // "[foo]" => ["foo"]
223 | // "foo[inn][bar]" => ["foo", "inn", "bar"]
224 | // "foo[inn[bar]]" => ["foo", "inn", "bar"]
225 | // "foo[inn][arr][0]" => ["foo", "inn", "arr", "0"]
226 | // "arr[][val]" => ["arr", "", "val"]
227 | splitInputNameIntoKeysArray: function(nameWithNoType) {
228 | var keys = nameWithNoType.split("["); // split string into array
229 | keys = $.map(keys, function (key) { return key.replace(/\]/g, ""); }); // remove closing brackets
230 | if (keys[0] === "") { keys.shift(); } // ensure no opening bracket ("[foo][inn]" should be same as "foo[inn]")
231 | return keys;
232 | },
233 |
234 | // Set a value in an object or array, using multiple keys to set in a nested object or array.
235 | // This is the main function of the script, that allows serializeJSON to use nested keys.
236 | // Examples:
237 | //
238 | // deepSet(obj, ["foo"], v) // obj["foo"] = v
239 | // deepSet(obj, ["foo", "inn"], v) // obj["foo"]["inn"] = v // Create the inner obj["foo"] object, if needed
240 | // deepSet(obj, ["foo", "inn", "123"], v) // obj["foo"]["arr"]["123"] = v //
241 | //
242 | // deepSet(obj, ["0"], v) // obj["0"] = v
243 | // deepSet(arr, ["0"], v, {useIntKeysAsArrayIndex: true}) // arr[0] = v
244 | // deepSet(arr, [""], v) // arr.push(v)
245 | // deepSet(obj, ["arr", ""], v) // obj["arr"].push(v)
246 | //
247 | // arr = [];
248 | // deepSet(arr, ["", v] // arr => [v]
249 | // deepSet(arr, ["", "foo"], v) // arr => [v, {foo: v}]
250 | // deepSet(arr, ["", "bar"], v) // arr => [v, {foo: v, bar: v}]
251 | // deepSet(arr, ["", "bar"], v) // arr => [v, {foo: v, bar: v}, {bar: v}]
252 | //
253 | deepSet: function (o, keys, value, opts) {
254 | if (opts == null) { opts = {}; }
255 | var f = $.serializeJSON;
256 | if (isUndefined(o)) { throw new Error("ArgumentError: param 'o' expected to be an object or array, found undefined"); }
257 | if (!keys || keys.length === 0) { throw new Error("ArgumentError: param 'keys' expected to be an array with least one element"); }
258 |
259 | var key = keys[0];
260 |
261 | // Only one key, then it's not a deepSet, just assign the value in the object or add it to the array.
262 | if (keys.length === 1) {
263 | if (key === "") { // push values into an array (o must be an array)
264 | o.push(value);
265 | } else {
266 | o[key] = value; // keys can be object keys (strings) or array indexes (numbers)
267 | }
268 | return;
269 | }
270 |
271 | var nextKey = keys[1]; // nested key
272 | var tailKeys = keys.slice(1); // list of all other nested keys (nextKey is first)
273 |
274 | if (key === "") { // push nested objects into an array (o must be an array)
275 | var lastIdx = o.length - 1;
276 | var lastVal = o[lastIdx];
277 |
278 | // if the last value is an object or array, and the new key is not set yet
279 | if (isObject(lastVal) && isUndefined(f.deepGet(lastVal, tailKeys))) {
280 | key = lastIdx; // then set the new value as a new attribute of the same object
281 | } else {
282 | key = lastIdx + 1; // otherwise, add a new element in the array
283 | }
284 | }
285 |
286 | if (nextKey === "") { // "" is used to push values into the nested array "array[]"
287 | if (isUndefined(o[key]) || !isArray(o[key])) {
288 | o[key] = []; // define (or override) as array to push values
289 | }
290 | } else {
291 | if (opts.useIntKeysAsArrayIndex && isValidArrayIndex(nextKey)) { // if 1, 2, 3 ... then use an array, where nextKey is the index
292 | if (isUndefined(o[key]) || !isArray(o[key])) {
293 | o[key] = []; // define (or override) as array, to insert values using int keys as array indexes
294 | }
295 | } else { // nextKey is going to be the nested object's attribute
296 | if (isUndefined(o[key]) || !isObject(o[key])) {
297 | o[key] = {}; // define (or override) as object, to set nested properties
298 | }
299 | }
300 | }
301 |
302 | // Recursively set the inner object
303 | f.deepSet(o[key], tailKeys, value, opts);
304 | },
305 |
306 | deepGet: function (o, keys) {
307 | var f = $.serializeJSON;
308 | if (isUndefined(o) || isUndefined(keys) || keys.length === 0 || (!isObject(o) && !isArray(o))) {
309 | return o;
310 | }
311 | var key = keys[0];
312 | if (key === "") { // "" means next array index (used by deepSet)
313 | return undefined;
314 | }
315 | if (keys.length === 1) {
316 | return o[key];
317 | }
318 | var tailKeys = keys.slice(1);
319 | return f.deepGet(o[key], tailKeys);
320 | }
321 | };
322 |
323 | // polyfill Object.keys to get option keys in IE<9
324 | var objectKeys = function(obj) {
325 | if (Object.keys) {
326 | return Object.keys(obj);
327 | } else {
328 | var key, keys = [];
329 | for (key in obj) { keys.push(key); }
330 | return keys;
331 | }
332 | };
333 |
334 | var isObject = function(obj) { return obj === Object(obj); }; // true for Objects and Arrays
335 | var isUndefined = function(obj) { return obj === void 0; }; // safe check for undefined values
336 | var isValidArrayIndex = function(val) { return /^[0-9]+$/.test(String(val)); }; // 1,2,3,4 ... are valid array indexes
337 | var isArray = Array.isArray || function(obj) { return Object.prototype.toString.call(obj) === "[object Array]"; };
338 | }));
339 |
--------------------------------------------------------------------------------
/jquery.serializejson.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | SerializeJSON jQuery plugin.
3 | https://github.com/marioizquierdo/jquery.serializeJSON
4 | version 3.2.1 (Feb, 2021)
5 |
6 | Copyright (c) 2012-2021 Mario Izquierdo
7 | Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
8 | and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
9 | */
10 | !function(e){if("function"==typeof define&&define.amd)define(["jquery"],e);else if("object"==typeof exports){var n=require("jquery");module.exports=e(n)}else e(window.jQuery||window.Zepto||window.$)}(function(e){"use strict";var n=/\r?\n/g,r=/^(?:submit|button|image|reset|file)$/i,t=/^(?:input|select|textarea|keygen)/i,i=/^(?:checkbox|radio)$/i;e.fn.serializeJSON=function(n){var r=e.serializeJSON,t=r.setupOpts(n),i=e.extend({},t.defaultTypes,t.customTypes),a=r.serializeArray(this,t),u={};return e.each(a,function(n,a){var s=a.name,l=e(a.el).attr("data-value-type");if(!l&&!t.disableColonTypes){var o=r.splitType(a.name);s=o[0],l=o[1]}if("skip"!==l){l||(l=t.defaultType);var p=r.applyTypeFunc(a.name,a.value,l,a.el,i);if(p||!r.shouldSkipFalsy(a.name,s,l,a.el,t)){var f=r.splitInputNameIntoKeysArray(s);r.deepSet(u,f,p,t)}}}),u},e.serializeJSON={defaultOptions:{},defaultBaseOptions:{checkboxUncheckedValue:void 0,useIntKeysAsArrayIndex:!1,skipFalsyValuesForTypes:[],skipFalsyValuesForFields:[],disableColonTypes:!1,customTypes:{},defaultTypes:{string:function(e){return String(e)},number:function(e){return Number(e)},boolean:function(e){return-1===["false","null","undefined","","0"].indexOf(e)},null:function(e){return-1===["false","null","undefined","","0"].indexOf(e)?e:null},array:function(e){return JSON.parse(e)},object:function(e){return JSON.parse(e)},skip:null},defaultType:"string"},setupOpts:function(n){null==n&&(n={});var r=e.serializeJSON,t=["checkboxUncheckedValue","useIntKeysAsArrayIndex","skipFalsyValuesForTypes","skipFalsyValuesForFields","disableColonTypes","customTypes","defaultTypes","defaultType"];for(var i in n)if(-1===t.indexOf(i))throw new Error("serializeJSON ERROR: invalid option '"+i+"'. Please use one of "+t.join(", "));return e.extend({},r.defaultBaseOptions,r.defaultOptions,n)},serializeArray:function(a,u){null==u&&(u={});var s=e.serializeJSON;return a.map(function(){var n=e.prop(this,"elements");return n?e.makeArray(n):this}).filter(function(){var n=e(this),a=this.type;return this.name&&!n.is(":disabled")&&t.test(this.nodeName)&&!r.test(a)&&(this.checked||!i.test(a)||null!=s.getCheckboxUncheckedValue(n,u))}).map(function(r,t){var a=e(this),l=a.val(),p=this.type;return null==l?null:(i.test(p)&&!this.checked&&(l=s.getCheckboxUncheckedValue(a,u)),o(l)?e.map(l,function(e){return{name:t.name,value:e.replace(n,"\r\n"),el:t}}):{name:t.name,value:l.replace(n,"\r\n"),el:t})}).get()},getCheckboxUncheckedValue:function(e,n){var r=e.attr("data-unchecked-value");return null==r&&(r=n.checkboxUncheckedValue),r},applyTypeFunc:function(e,n,r,t,i){var u=i[r];if(!u)throw new Error("serializeJSON ERROR: Invalid type "+r+" found in input name '"+e+"', please use one of "+a(i).join(", "));return u(n,t)},splitType:function(e){var n=e.split(":");if(n.length>1){var r=n.pop();return[n.join(":"),r]}return[e,""]},shouldSkipFalsy:function(n,r,t,i,a){var u=e(i).attr("data-skip-falsy");if(null!=u)return"false"!==u;var s=a.skipFalsyValuesForFields;if(s&&(-1!==s.indexOf(r)||-1!==s.indexOf(n)))return!0;var l=a.skipFalsyValuesForTypes;return!(!l||-1===l.indexOf(t))},splitInputNameIntoKeysArray:function(n){var r=n.split("[");return""===(r=e.map(r,function(e){return e.replace(/\]/g,"")}))[0]&&r.shift(),r},deepSet:function(n,r,t,i){null==i&&(i={});var a=e.serializeJSON;if(s(n))throw new Error("ArgumentError: param 'o' expected to be an object or array, found undefined");if(!r||0===r.length)throw new Error("ArgumentError: param 'keys' expected to be an array with least one element");var p=r[0];if(1!==r.length){var f=r[1],c=r.slice(1);if(""===p){var d=n.length-1,y=n[d];p=u(y)&&s(a.deepGet(y,c))?d:d+1}""===f?!s(n[p])&&o(n[p])||(n[p]=[]):i.useIntKeysAsArrayIndex&&l(f)?!s(n[p])&&o(n[p])||(n[p]=[]):!s(n[p])&&u(n[p])||(n[p]={}),a.deepSet(n[p],c,t,i)}else""===p?n.push(t):n[p]=t},deepGet:function(n,r){var t=e.serializeJSON;if(s(n)||s(r)||0===r.length||!u(n)&&!o(n))return n;var i=r[0];if(""!==i){if(1===r.length)return n[i];var a=r.slice(1);return t.deepGet(n[i],a)}}};var a=function(e){if(Object.keys)return Object.keys(e);var n,r=[];for(n in e)r.push(n);return r},u=function(e){return e===Object(e)},s=function(e){return void 0===e},l=function(e){return/^[0-9]+$/.test(String(e))},o=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}});
11 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-serializejson",
3 | "version": "3.1.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@babel/code-frame": {
8 | "version": "7.10.4",
9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
10 | "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
11 | "dev": true,
12 | "requires": {
13 | "@babel/highlight": "^7.10.4"
14 | }
15 | },
16 | "@babel/helper-validator-identifier": {
17 | "version": "7.10.4",
18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
19 | "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
20 | "dev": true
21 | },
22 | "@babel/highlight": {
23 | "version": "7.10.4",
24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
25 | "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
26 | "dev": true,
27 | "requires": {
28 | "@babel/helper-validator-identifier": "^7.10.4",
29 | "chalk": "^2.0.0",
30 | "js-tokens": "^4.0.0"
31 | },
32 | "dependencies": {
33 | "chalk": {
34 | "version": "2.4.2",
35 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
36 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
37 | "dev": true,
38 | "requires": {
39 | "ansi-styles": "^3.2.1",
40 | "escape-string-regexp": "^1.0.5",
41 | "supports-color": "^5.3.0"
42 | }
43 | }
44 | }
45 | },
46 | "@eslint/eslintrc": {
47 | "version": "0.1.3",
48 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz",
49 | "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==",
50 | "dev": true,
51 | "requires": {
52 | "ajv": "^6.12.4",
53 | "debug": "^4.1.1",
54 | "espree": "^7.3.0",
55 | "globals": "^12.1.0",
56 | "ignore": "^4.0.6",
57 | "import-fresh": "^3.2.1",
58 | "js-yaml": "^3.13.1",
59 | "lodash": "^4.17.19",
60 | "minimatch": "^3.0.4",
61 | "strip-json-comments": "^3.1.1"
62 | }
63 | },
64 | "@types/color-name": {
65 | "version": "1.1.1",
66 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
67 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
68 | "dev": true
69 | },
70 | "acorn": {
71 | "version": "7.4.0",
72 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
73 | "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
74 | "dev": true
75 | },
76 | "acorn-jsx": {
77 | "version": "5.2.0",
78 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
79 | "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==",
80 | "dev": true
81 | },
82 | "ajv": {
83 | "version": "6.12.4",
84 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz",
85 | "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==",
86 | "dev": true,
87 | "requires": {
88 | "fast-deep-equal": "^3.1.1",
89 | "fast-json-stable-stringify": "^2.0.0",
90 | "json-schema-traverse": "^0.4.1",
91 | "uri-js": "^4.2.2"
92 | }
93 | },
94 | "ansi-colors": {
95 | "version": "4.1.1",
96 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
97 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
98 | "dev": true
99 | },
100 | "ansi-regex": {
101 | "version": "5.0.0",
102 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
103 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
104 | "dev": true
105 | },
106 | "ansi-styles": {
107 | "version": "3.2.1",
108 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
109 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
110 | "dev": true,
111 | "requires": {
112 | "color-convert": "^1.9.0"
113 | }
114 | },
115 | "argparse": {
116 | "version": "1.0.10",
117 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
118 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
119 | "dev": true,
120 | "requires": {
121 | "sprintf-js": "~1.0.2"
122 | }
123 | },
124 | "astral-regex": {
125 | "version": "1.0.0",
126 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
127 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
128 | "dev": true
129 | },
130 | "balanced-match": {
131 | "version": "1.0.0",
132 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
133 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
134 | "dev": true
135 | },
136 | "brace-expansion": {
137 | "version": "1.1.11",
138 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
139 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
140 | "dev": true,
141 | "requires": {
142 | "balanced-match": "^1.0.0",
143 | "concat-map": "0.0.1"
144 | }
145 | },
146 | "callsites": {
147 | "version": "3.1.0",
148 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
149 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
150 | "dev": true
151 | },
152 | "chalk": {
153 | "version": "4.1.0",
154 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
155 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
156 | "dev": true,
157 | "requires": {
158 | "ansi-styles": "^4.1.0",
159 | "supports-color": "^7.1.0"
160 | },
161 | "dependencies": {
162 | "ansi-styles": {
163 | "version": "4.2.1",
164 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
165 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
166 | "dev": true,
167 | "requires": {
168 | "@types/color-name": "^1.1.1",
169 | "color-convert": "^2.0.1"
170 | }
171 | },
172 | "color-convert": {
173 | "version": "2.0.1",
174 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
175 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
176 | "dev": true,
177 | "requires": {
178 | "color-name": "~1.1.4"
179 | }
180 | },
181 | "color-name": {
182 | "version": "1.1.4",
183 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
184 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
185 | "dev": true
186 | },
187 | "has-flag": {
188 | "version": "4.0.0",
189 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
190 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
191 | "dev": true
192 | },
193 | "supports-color": {
194 | "version": "7.2.0",
195 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
196 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
197 | "dev": true,
198 | "requires": {
199 | "has-flag": "^4.0.0"
200 | }
201 | }
202 | }
203 | },
204 | "color-convert": {
205 | "version": "1.9.3",
206 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
207 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
208 | "dev": true,
209 | "requires": {
210 | "color-name": "1.1.3"
211 | }
212 | },
213 | "color-name": {
214 | "version": "1.1.3",
215 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
216 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
217 | "dev": true
218 | },
219 | "concat-map": {
220 | "version": "0.0.1",
221 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
222 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
223 | "dev": true
224 | },
225 | "cross-spawn": {
226 | "version": "7.0.3",
227 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
228 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
229 | "dev": true,
230 | "requires": {
231 | "path-key": "^3.1.0",
232 | "shebang-command": "^2.0.0",
233 | "which": "^2.0.1"
234 | }
235 | },
236 | "debug": {
237 | "version": "4.1.1",
238 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
239 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
240 | "dev": true,
241 | "requires": {
242 | "ms": "^2.1.1"
243 | }
244 | },
245 | "deep-is": {
246 | "version": "0.1.3",
247 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
248 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
249 | "dev": true
250 | },
251 | "doctrine": {
252 | "version": "3.0.0",
253 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
254 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
255 | "dev": true,
256 | "requires": {
257 | "esutils": "^2.0.2"
258 | }
259 | },
260 | "emoji-regex": {
261 | "version": "7.0.3",
262 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
263 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
264 | "dev": true
265 | },
266 | "enquirer": {
267 | "version": "2.3.6",
268 | "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
269 | "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
270 | "dev": true,
271 | "requires": {
272 | "ansi-colors": "^4.1.1"
273 | }
274 | },
275 | "escape-string-regexp": {
276 | "version": "1.0.5",
277 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
278 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
279 | "dev": true
280 | },
281 | "eslint": {
282 | "version": "7.8.1",
283 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.8.1.tgz",
284 | "integrity": "sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w==",
285 | "dev": true,
286 | "requires": {
287 | "@babel/code-frame": "^7.0.0",
288 | "@eslint/eslintrc": "^0.1.3",
289 | "ajv": "^6.10.0",
290 | "chalk": "^4.0.0",
291 | "cross-spawn": "^7.0.2",
292 | "debug": "^4.0.1",
293 | "doctrine": "^3.0.0",
294 | "enquirer": "^2.3.5",
295 | "eslint-scope": "^5.1.0",
296 | "eslint-utils": "^2.1.0",
297 | "eslint-visitor-keys": "^1.3.0",
298 | "espree": "^7.3.0",
299 | "esquery": "^1.2.0",
300 | "esutils": "^2.0.2",
301 | "file-entry-cache": "^5.0.1",
302 | "functional-red-black-tree": "^1.0.1",
303 | "glob-parent": "^5.0.0",
304 | "globals": "^12.1.0",
305 | "ignore": "^4.0.6",
306 | "import-fresh": "^3.0.0",
307 | "imurmurhash": "^0.1.4",
308 | "is-glob": "^4.0.0",
309 | "js-yaml": "^3.13.1",
310 | "json-stable-stringify-without-jsonify": "^1.0.1",
311 | "levn": "^0.4.1",
312 | "lodash": "^4.17.19",
313 | "minimatch": "^3.0.4",
314 | "natural-compare": "^1.4.0",
315 | "optionator": "^0.9.1",
316 | "progress": "^2.0.0",
317 | "regexpp": "^3.1.0",
318 | "semver": "^7.2.1",
319 | "strip-ansi": "^6.0.0",
320 | "strip-json-comments": "^3.1.0",
321 | "table": "^5.2.3",
322 | "text-table": "^0.2.0",
323 | "v8-compile-cache": "^2.0.3"
324 | }
325 | },
326 | "eslint-scope": {
327 | "version": "5.1.0",
328 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
329 | "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
330 | "dev": true,
331 | "requires": {
332 | "esrecurse": "^4.1.0",
333 | "estraverse": "^4.1.1"
334 | }
335 | },
336 | "eslint-utils": {
337 | "version": "2.1.0",
338 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
339 | "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
340 | "dev": true,
341 | "requires": {
342 | "eslint-visitor-keys": "^1.1.0"
343 | }
344 | },
345 | "eslint-visitor-keys": {
346 | "version": "1.3.0",
347 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
348 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
349 | "dev": true
350 | },
351 | "espree": {
352 | "version": "7.3.0",
353 | "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz",
354 | "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==",
355 | "dev": true,
356 | "requires": {
357 | "acorn": "^7.4.0",
358 | "acorn-jsx": "^5.2.0",
359 | "eslint-visitor-keys": "^1.3.0"
360 | }
361 | },
362 | "esprima": {
363 | "version": "4.0.1",
364 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
365 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
366 | "dev": true
367 | },
368 | "esquery": {
369 | "version": "1.3.1",
370 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
371 | "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
372 | "dev": true,
373 | "requires": {
374 | "estraverse": "^5.1.0"
375 | },
376 | "dependencies": {
377 | "estraverse": {
378 | "version": "5.2.0",
379 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
380 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
381 | "dev": true
382 | }
383 | }
384 | },
385 | "esrecurse": {
386 | "version": "4.3.0",
387 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
388 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
389 | "dev": true,
390 | "requires": {
391 | "estraverse": "^5.2.0"
392 | },
393 | "dependencies": {
394 | "estraverse": {
395 | "version": "5.2.0",
396 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
397 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
398 | "dev": true
399 | }
400 | }
401 | },
402 | "estraverse": {
403 | "version": "4.3.0",
404 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
405 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
406 | "dev": true
407 | },
408 | "esutils": {
409 | "version": "2.0.3",
410 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
411 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
412 | "dev": true
413 | },
414 | "fast-deep-equal": {
415 | "version": "3.1.3",
416 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
417 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
418 | "dev": true
419 | },
420 | "fast-json-stable-stringify": {
421 | "version": "2.1.0",
422 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
423 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
424 | "dev": true
425 | },
426 | "fast-levenshtein": {
427 | "version": "2.0.6",
428 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
429 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
430 | "dev": true
431 | },
432 | "file-entry-cache": {
433 | "version": "5.0.1",
434 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
435 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
436 | "dev": true,
437 | "requires": {
438 | "flat-cache": "^2.0.1"
439 | }
440 | },
441 | "flat-cache": {
442 | "version": "2.0.1",
443 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
444 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
445 | "dev": true,
446 | "requires": {
447 | "flatted": "^2.0.0",
448 | "rimraf": "2.6.3",
449 | "write": "1.0.3"
450 | }
451 | },
452 | "flatted": {
453 | "version": "2.0.2",
454 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
455 | "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
456 | "dev": true
457 | },
458 | "fs.realpath": {
459 | "version": "1.0.0",
460 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
461 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
462 | "dev": true
463 | },
464 | "functional-red-black-tree": {
465 | "version": "1.0.1",
466 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
467 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
468 | "dev": true
469 | },
470 | "glob": {
471 | "version": "7.1.6",
472 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
473 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
474 | "dev": true,
475 | "requires": {
476 | "fs.realpath": "^1.0.0",
477 | "inflight": "^1.0.4",
478 | "inherits": "2",
479 | "minimatch": "^3.0.4",
480 | "once": "^1.3.0",
481 | "path-is-absolute": "^1.0.0"
482 | }
483 | },
484 | "glob-parent": {
485 | "version": "5.1.1",
486 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
487 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
488 | "dev": true,
489 | "requires": {
490 | "is-glob": "^4.0.1"
491 | }
492 | },
493 | "globals": {
494 | "version": "12.4.0",
495 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
496 | "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
497 | "dev": true,
498 | "requires": {
499 | "type-fest": "^0.8.1"
500 | }
501 | },
502 | "has-flag": {
503 | "version": "3.0.0",
504 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
505 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
506 | "dev": true
507 | },
508 | "ignore": {
509 | "version": "4.0.6",
510 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
511 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
512 | "dev": true
513 | },
514 | "import-fresh": {
515 | "version": "3.2.1",
516 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
517 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
518 | "dev": true,
519 | "requires": {
520 | "parent-module": "^1.0.0",
521 | "resolve-from": "^4.0.0"
522 | }
523 | },
524 | "imurmurhash": {
525 | "version": "0.1.4",
526 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
527 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
528 | "dev": true
529 | },
530 | "inflight": {
531 | "version": "1.0.6",
532 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
533 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
534 | "dev": true,
535 | "requires": {
536 | "once": "^1.3.0",
537 | "wrappy": "1"
538 | }
539 | },
540 | "inherits": {
541 | "version": "2.0.4",
542 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
543 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
544 | "dev": true
545 | },
546 | "is-extglob": {
547 | "version": "2.1.1",
548 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
549 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
550 | "dev": true
551 | },
552 | "is-fullwidth-code-point": {
553 | "version": "2.0.0",
554 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
555 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
556 | "dev": true
557 | },
558 | "is-glob": {
559 | "version": "4.0.1",
560 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
561 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
562 | "dev": true,
563 | "requires": {
564 | "is-extglob": "^2.1.1"
565 | }
566 | },
567 | "isexe": {
568 | "version": "2.0.0",
569 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
570 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
571 | "dev": true
572 | },
573 | "js-tokens": {
574 | "version": "4.0.0",
575 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
576 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
577 | "dev": true
578 | },
579 | "js-yaml": {
580 | "version": "3.14.0",
581 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
582 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
583 | "dev": true,
584 | "requires": {
585 | "argparse": "^1.0.7",
586 | "esprima": "^4.0.0"
587 | }
588 | },
589 | "json-schema-traverse": {
590 | "version": "0.4.1",
591 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
592 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
593 | "dev": true
594 | },
595 | "json-stable-stringify-without-jsonify": {
596 | "version": "1.0.1",
597 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
598 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
599 | "dev": true
600 | },
601 | "levn": {
602 | "version": "0.4.1",
603 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
604 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
605 | "dev": true,
606 | "requires": {
607 | "prelude-ls": "^1.2.1",
608 | "type-check": "~0.4.0"
609 | }
610 | },
611 | "lodash": {
612 | "version": "4.17.20",
613 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
614 | "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
615 | "dev": true
616 | },
617 | "minimatch": {
618 | "version": "3.0.4",
619 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
620 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
621 | "dev": true,
622 | "requires": {
623 | "brace-expansion": "^1.1.7"
624 | }
625 | },
626 | "minimist": {
627 | "version": "1.2.5",
628 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
629 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
630 | "dev": true
631 | },
632 | "mkdirp": {
633 | "version": "0.5.5",
634 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
635 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
636 | "dev": true,
637 | "requires": {
638 | "minimist": "^1.2.5"
639 | }
640 | },
641 | "ms": {
642 | "version": "2.1.2",
643 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
644 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
645 | "dev": true
646 | },
647 | "natural-compare": {
648 | "version": "1.4.0",
649 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
650 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
651 | "dev": true
652 | },
653 | "once": {
654 | "version": "1.4.0",
655 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
656 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
657 | "dev": true,
658 | "requires": {
659 | "wrappy": "1"
660 | }
661 | },
662 | "optionator": {
663 | "version": "0.9.1",
664 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
665 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
666 | "dev": true,
667 | "requires": {
668 | "deep-is": "^0.1.3",
669 | "fast-levenshtein": "^2.0.6",
670 | "levn": "^0.4.1",
671 | "prelude-ls": "^1.2.1",
672 | "type-check": "^0.4.0",
673 | "word-wrap": "^1.2.3"
674 | }
675 | },
676 | "parent-module": {
677 | "version": "1.0.1",
678 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
679 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
680 | "dev": true,
681 | "requires": {
682 | "callsites": "^3.0.0"
683 | }
684 | },
685 | "path-is-absolute": {
686 | "version": "1.0.1",
687 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
688 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
689 | "dev": true
690 | },
691 | "path-key": {
692 | "version": "3.1.1",
693 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
694 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
695 | "dev": true
696 | },
697 | "prelude-ls": {
698 | "version": "1.2.1",
699 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
700 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
701 | "dev": true
702 | },
703 | "progress": {
704 | "version": "2.0.3",
705 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
706 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
707 | "dev": true
708 | },
709 | "punycode": {
710 | "version": "2.1.1",
711 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
712 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
713 | "dev": true
714 | },
715 | "regexpp": {
716 | "version": "3.1.0",
717 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
718 | "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
719 | "dev": true
720 | },
721 | "resolve-from": {
722 | "version": "4.0.0",
723 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
724 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
725 | "dev": true
726 | },
727 | "rimraf": {
728 | "version": "2.6.3",
729 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
730 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
731 | "dev": true,
732 | "requires": {
733 | "glob": "^7.1.3"
734 | }
735 | },
736 | "semver": {
737 | "version": "7.3.2",
738 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
739 | "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
740 | "dev": true
741 | },
742 | "shebang-command": {
743 | "version": "2.0.0",
744 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
745 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
746 | "dev": true,
747 | "requires": {
748 | "shebang-regex": "^3.0.0"
749 | }
750 | },
751 | "shebang-regex": {
752 | "version": "3.0.0",
753 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
754 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
755 | "dev": true
756 | },
757 | "slice-ansi": {
758 | "version": "2.1.0",
759 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
760 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
761 | "dev": true,
762 | "requires": {
763 | "ansi-styles": "^3.2.0",
764 | "astral-regex": "^1.0.0",
765 | "is-fullwidth-code-point": "^2.0.0"
766 | }
767 | },
768 | "sprintf-js": {
769 | "version": "1.0.3",
770 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
771 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
772 | "dev": true
773 | },
774 | "string-width": {
775 | "version": "3.1.0",
776 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
777 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
778 | "dev": true,
779 | "requires": {
780 | "emoji-regex": "^7.0.1",
781 | "is-fullwidth-code-point": "^2.0.0",
782 | "strip-ansi": "^5.1.0"
783 | },
784 | "dependencies": {
785 | "ansi-regex": {
786 | "version": "4.1.0",
787 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
788 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
789 | "dev": true
790 | },
791 | "strip-ansi": {
792 | "version": "5.2.0",
793 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
794 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
795 | "dev": true,
796 | "requires": {
797 | "ansi-regex": "^4.1.0"
798 | }
799 | }
800 | }
801 | },
802 | "strip-ansi": {
803 | "version": "6.0.0",
804 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
805 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
806 | "dev": true,
807 | "requires": {
808 | "ansi-regex": "^5.0.0"
809 | }
810 | },
811 | "strip-json-comments": {
812 | "version": "3.1.1",
813 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
814 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
815 | "dev": true
816 | },
817 | "supports-color": {
818 | "version": "5.5.0",
819 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
820 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
821 | "dev": true,
822 | "requires": {
823 | "has-flag": "^3.0.0"
824 | }
825 | },
826 | "table": {
827 | "version": "5.4.6",
828 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
829 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
830 | "dev": true,
831 | "requires": {
832 | "ajv": "^6.10.2",
833 | "lodash": "^4.17.14",
834 | "slice-ansi": "^2.1.0",
835 | "string-width": "^3.0.0"
836 | }
837 | },
838 | "text-table": {
839 | "version": "0.2.0",
840 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
841 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
842 | "dev": true
843 | },
844 | "type-check": {
845 | "version": "0.4.0",
846 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
847 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
848 | "dev": true,
849 | "requires": {
850 | "prelude-ls": "^1.2.1"
851 | }
852 | },
853 | "type-fest": {
854 | "version": "0.8.1",
855 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
856 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
857 | "dev": true
858 | },
859 | "uri-js": {
860 | "version": "4.4.0",
861 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
862 | "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
863 | "dev": true,
864 | "requires": {
865 | "punycode": "^2.1.0"
866 | }
867 | },
868 | "v8-compile-cache": {
869 | "version": "2.1.1",
870 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
871 | "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
872 | "dev": true
873 | },
874 | "which": {
875 | "version": "2.0.2",
876 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
877 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
878 | "dev": true,
879 | "requires": {
880 | "isexe": "^2.0.0"
881 | }
882 | },
883 | "word-wrap": {
884 | "version": "1.2.3",
885 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
886 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
887 | "dev": true
888 | },
889 | "wrappy": {
890 | "version": "1.0.2",
891 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
892 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
893 | "dev": true
894 | },
895 | "write": {
896 | "version": "1.0.3",
897 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
898 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
899 | "dev": true,
900 | "requires": {
901 | "mkdirp": "^0.5.1"
902 | }
903 | }
904 | }
905 | }
906 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-serializejson",
3 | "main": "jquery.serializejson.js",
4 | "version": "3.2.1",
5 | "description": "jQuery or Zepto plugin to serialize a form into a JavaScript Object, using the same format as the default Ruby on Rails request params",
6 | "homepage": "https://github.com/marioizquierdo/jquery.serializeJSON",
7 | "author": "Mario Izquierdo",
8 | "license": "MIT",
9 | "scripts": {
10 | "test": "echo \"Open /spec/spec_runner_jquery.html or /spec/spec_runner_zepto.html to run the jasmine specs in your browser\" && exit 1"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "https://github.com/marioizquierdo/jquery.serializeJSON.git"
15 | },
16 | "keywords": [
17 | "jquery-plugin",
18 | "ecosystem:jquery",
19 | "form-serialization",
20 | "form-to-json",
21 | "html-to-json",
22 | "form",
23 | "json"
24 | ],
25 | "bugs": {
26 | "url": "https://github.com/marioizquierdo/jquery.serializeJSON/issues"
27 | },
28 | "dependencies": {},
29 | "devDependencies": {
30 | "eslint": "^7.8.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/spec/lib/jasmine-2.0.0/boot.js:
--------------------------------------------------------------------------------
1 | /**
2 | Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
3 |
4 | If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
5 |
6 | The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
7 |
8 | [jasmine-gem]: http://github.com/pivotal/jasmine-gem
9 | */
10 |
11 | (function() {
12 |
13 | /**
14 | * ## Require & Instantiate
15 | *
16 | * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
17 | */
18 | window.jasmine = jasmineRequire.core(jasmineRequire);
19 |
20 | /**
21 | * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
22 | */
23 | jasmineRequire.html(jasmine);
24 |
25 | /**
26 | * Create the Jasmine environment. This is used to run all specs in a project.
27 | */
28 | var env = jasmine.getEnv();
29 |
30 | /**
31 | * ## The Global Interface
32 | *
33 | * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
34 | */
35 | var jasmineInterface = {
36 | describe: function(description, specDefinitions) {
37 | return env.describe(description, specDefinitions);
38 | },
39 |
40 | xdescribe: function(description, specDefinitions) {
41 | return env.xdescribe(description, specDefinitions);
42 | },
43 |
44 | it: function(desc, func) {
45 | return env.it(desc, func);
46 | },
47 |
48 | xit: function(desc, func) {
49 | return env.xit(desc, func);
50 | },
51 |
52 | beforeEach: function(beforeEachFunction) {
53 | return env.beforeEach(beforeEachFunction);
54 | },
55 |
56 | afterEach: function(afterEachFunction) {
57 | return env.afterEach(afterEachFunction);
58 | },
59 |
60 | expect: function(actual) {
61 | return env.expect(actual);
62 | },
63 |
64 | pending: function() {
65 | return env.pending();
66 | },
67 |
68 | spyOn: function(obj, methodName) {
69 | return env.spyOn(obj, methodName);
70 | },
71 |
72 | jsApiReporter: new jasmine.JsApiReporter({
73 | timer: new jasmine.Timer()
74 | })
75 | };
76 |
77 | /**
78 | * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
79 | */
80 | if (typeof window == "undefined" && typeof exports == "object") {
81 | extend(exports, jasmineInterface);
82 | } else {
83 | extend(window, jasmineInterface);
84 | }
85 |
86 | /**
87 | * Expose the interface for adding custom equality testers.
88 | */
89 | jasmine.addCustomEqualityTester = function(tester) {
90 | env.addCustomEqualityTester(tester);
91 | };
92 |
93 | /**
94 | * Expose the interface for adding custom expectation matchers
95 | */
96 | jasmine.addMatchers = function(matchers) {
97 | return env.addMatchers(matchers);
98 | };
99 |
100 | /**
101 | * Expose the mock interface for the JavaScript timeout functions
102 | */
103 | jasmine.clock = function() {
104 | return env.clock;
105 | };
106 |
107 | /**
108 | * ## Runner Parameters
109 | *
110 | * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
111 | */
112 |
113 | var queryString = new jasmine.QueryString({
114 | getWindowLocation: function() { return window.location; }
115 | });
116 |
117 | var catchingExceptions = queryString.getParam("catch");
118 | env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
119 |
120 | /**
121 | * ## Reporters
122 | * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
123 | */
124 | var htmlReporter = new jasmine.HtmlReporter({
125 | env: env,
126 | onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
127 | getContainer: function() { return document.body; },
128 | createElement: function() { return document.createElement.apply(document, arguments); },
129 | createTextNode: function() { return document.createTextNode.apply(document, arguments); },
130 | timer: new jasmine.Timer()
131 | });
132 |
133 | /**
134 | * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
135 | */
136 | env.addReporter(jasmineInterface.jsApiReporter);
137 | env.addReporter(htmlReporter);
138 |
139 | /**
140 | * Filter which specs will be run by matching the start of the full name against the `spec` query param.
141 | */
142 | var specFilter = new jasmine.HtmlSpecFilter({
143 | filterString: function() { return queryString.getParam("spec"); }
144 | });
145 |
146 | env.specFilter = function(spec) {
147 | return specFilter.matches(spec.getFullName());
148 | };
149 |
150 | /**
151 | * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
152 | */
153 | window.setTimeout = window.setTimeout;
154 | window.setInterval = window.setInterval;
155 | window.clearTimeout = window.clearTimeout;
156 | window.clearInterval = window.clearInterval;
157 |
158 | /**
159 | * ## Execution
160 | *
161 | * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
162 | */
163 | var currentWindowOnload = window.onload;
164 |
165 | window.onload = function() {
166 | if (currentWindowOnload) {
167 | currentWindowOnload();
168 | }
169 | htmlReporter.initialize();
170 | env.execute();
171 | };
172 |
173 | /**
174 | * Helper function for readability above.
175 | */
176 | function extend(destination, source) {
177 | for (var property in source) destination[property] = source[property];
178 | return destination;
179 | }
180 |
181 | }());
182 |
--------------------------------------------------------------------------------
/spec/lib/jasmine-2.0.0/console.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2013 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | function getJasmineRequireObj() {
24 | if (typeof module !== "undefined" && module.exports) {
25 | return exports;
26 | } else {
27 | window.jasmineRequire = window.jasmineRequire || {};
28 | return window.jasmineRequire;
29 | }
30 | }
31 |
32 | getJasmineRequireObj().console = function(jRequire, j$) {
33 | j$.ConsoleReporter = jRequire.ConsoleReporter();
34 | };
35 |
36 | getJasmineRequireObj().ConsoleReporter = function() {
37 |
38 | var noopTimer = {
39 | start: function(){},
40 | elapsed: function(){ return 0; }
41 | };
42 |
43 | function ConsoleReporter(options) {
44 | var print = options.print,
45 | showColors = options.showColors || false,
46 | onComplete = options.onComplete || function() {},
47 | timer = options.timer || noopTimer,
48 | specCount,
49 | failureCount,
50 | failedSpecs = [],
51 | pendingCount,
52 | ansi = {
53 | green: '\x1B[32m',
54 | red: '\x1B[31m',
55 | yellow: '\x1B[33m',
56 | none: '\x1B[0m'
57 | };
58 |
59 | this.jasmineStarted = function() {
60 | specCount = 0;
61 | failureCount = 0;
62 | pendingCount = 0;
63 | print("Started");
64 | printNewline();
65 | timer.start();
66 | };
67 |
68 | this.jasmineDone = function() {
69 | printNewline();
70 | for (var i = 0; i < failedSpecs.length; i++) {
71 | specFailureDetails(failedSpecs[i]);
72 | }
73 |
74 | printNewline();
75 | var specCounts = specCount + " " + plural("spec", specCount) + ", " +
76 | failureCount + " " + plural("failure", failureCount);
77 |
78 | if (pendingCount) {
79 | specCounts += ", " + pendingCount + " pending " + plural("spec", pendingCount);
80 | }
81 |
82 | print(specCounts);
83 |
84 | printNewline();
85 | var seconds = timer.elapsed() / 1000;
86 | print("Finished in " + seconds + " " + plural("second", seconds));
87 |
88 | printNewline();
89 |
90 | onComplete(failureCount === 0);
91 | };
92 |
93 | this.specDone = function(result) {
94 | specCount++;
95 |
96 | if (result.status == "pending") {
97 | pendingCount++;
98 | print(colored("yellow", "*"));
99 | return;
100 | }
101 |
102 | if (result.status == "passed") {
103 | print(colored("green", '.'));
104 | return;
105 | }
106 |
107 | if (result.status == "failed") {
108 | failureCount++;
109 | failedSpecs.push(result);
110 | print(colored("red", 'F'));
111 | }
112 | };
113 |
114 | return this;
115 |
116 | function printNewline() {
117 | print("\n");
118 | }
119 |
120 | function colored(color, str) {
121 | return showColors ? (ansi[color] + str + ansi.none) : str;
122 | }
123 |
124 | function plural(str, count) {
125 | return count == 1 ? str : str + "s";
126 | }
127 |
128 | function repeat(thing, times) {
129 | var arr = [];
130 | for (var i = 0; i < times; i++) {
131 | arr.push(thing);
132 | }
133 | return arr;
134 | }
135 |
136 | function indent(str, spaces) {
137 | var lines = (str || '').split("\n");
138 | var newArr = [];
139 | for (var i = 0; i < lines.length; i++) {
140 | newArr.push(repeat(" ", spaces).join("") + lines[i]);
141 | }
142 | return newArr.join("\n");
143 | }
144 |
145 | function specFailureDetails(result) {
146 | printNewline();
147 | print(result.fullName);
148 |
149 | for (var i = 0; i < result.failedExpectations.length; i++) {
150 | var failedExpectation = result.failedExpectations[i];
151 | printNewline();
152 | print(indent(failedExpectation.stack, 2));
153 | }
154 |
155 | printNewline();
156 | }
157 | }
158 |
159 | return ConsoleReporter;
160 | };
161 |
--------------------------------------------------------------------------------
/spec/lib/jasmine-2.0.0/jasmine-html.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2013 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | jasmineRequire.html = function(j$) {
24 | j$.ResultsNode = jasmineRequire.ResultsNode();
25 | j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
26 | j$.QueryString = jasmineRequire.QueryString();
27 | j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
28 | };
29 |
30 | jasmineRequire.HtmlReporter = function(j$) {
31 |
32 | var noopTimer = {
33 | start: function() {},
34 | elapsed: function() { return 0; }
35 | };
36 |
37 | function HtmlReporter(options) {
38 | var env = options.env || {},
39 | getContainer = options.getContainer,
40 | createElement = options.createElement,
41 | createTextNode = options.createTextNode,
42 | onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
43 | timer = options.timer || noopTimer,
44 | results = [],
45 | specsExecuted = 0,
46 | failureCount = 0,
47 | pendingSpecCount = 0,
48 | htmlReporterMain,
49 | symbols;
50 |
51 | this.initialize = function() {
52 | htmlReporterMain = createDom("div", {className: "html-reporter"},
53 | createDom("div", {className: "banner"},
54 | createDom("span", {className: "title"}, "Jasmine"),
55 | createDom("span", {className: "version"}, j$.version)
56 | ),
57 | createDom("ul", {className: "symbol-summary"}),
58 | createDom("div", {className: "alert"}),
59 | createDom("div", {className: "results"},
60 | createDom("div", {className: "failures"})
61 | )
62 | );
63 | getContainer().appendChild(htmlReporterMain);
64 |
65 | symbols = find(".symbol-summary");
66 | };
67 |
68 | var totalSpecsDefined;
69 | this.jasmineStarted = function(options) {
70 | totalSpecsDefined = options.totalSpecsDefined || 0;
71 | timer.start();
72 | };
73 |
74 | var summary = createDom("div", {className: "summary"});
75 |
76 | var topResults = new j$.ResultsNode({}, "", null),
77 | currentParent = topResults;
78 |
79 | this.suiteStarted = function(result) {
80 | currentParent.addChild(result, "suite");
81 | currentParent = currentParent.last();
82 | };
83 |
84 | this.suiteDone = function(result) {
85 | if (currentParent == topResults) {
86 | return;
87 | }
88 |
89 | currentParent = currentParent.parent;
90 | };
91 |
92 | this.specStarted = function(result) {
93 | currentParent.addChild(result, "spec");
94 | };
95 |
96 | var failures = [];
97 | this.specDone = function(result) {
98 | if (result.status != "disabled") {
99 | specsExecuted++;
100 | }
101 |
102 | symbols.appendChild(createDom("li", {
103 | className: result.status,
104 | id: "spec_" + result.id,
105 | title: result.fullName
106 | }
107 | ));
108 |
109 | if (result.status == "failed") {
110 | failureCount++;
111 |
112 | var failure =
113 | createDom("div", {className: "spec-detail failed"},
114 | createDom("div", {className: "description"},
115 | createDom("a", {title: result.fullName, href: specHref(result)}, result.fullName)
116 | ),
117 | createDom("div", {className: "messages"})
118 | );
119 | var messages = failure.childNodes[1];
120 |
121 | for (var i = 0; i < result.failedExpectations.length; i++) {
122 | var expectation = result.failedExpectations[i];
123 | messages.appendChild(createDom("div", {className: "result-message"}, expectation.message));
124 | messages.appendChild(createDom("div", {className: "stack-trace"}, expectation.stack));
125 | }
126 |
127 | failures.push(failure);
128 | }
129 |
130 | if (result.status == "pending") {
131 | pendingSpecCount++;
132 | }
133 | };
134 |
135 | this.jasmineDone = function() {
136 | var banner = find(".banner");
137 | banner.appendChild(createDom("span", {className: "duration"}, "finished in " + timer.elapsed() / 1000 + "s"));
138 |
139 | var alert = find(".alert");
140 |
141 | alert.appendChild(createDom("span", { className: "exceptions" },
142 | createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"),
143 | createDom("input", {
144 | className: "raise",
145 | id: "raise-exceptions",
146 | type: "checkbox"
147 | })
148 | ));
149 | var checkbox = find("input");
150 |
151 | checkbox.checked = !env.catchingExceptions();
152 | checkbox.onclick = onRaiseExceptionsClick;
153 |
154 | if (specsExecuted < totalSpecsDefined) {
155 | var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all";
156 | alert.appendChild(
157 | createDom("span", {className: "bar skipped"},
158 | createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
159 | )
160 | );
161 | }
162 | var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount);
163 | if (pendingSpecCount) { statusBarMessage += ", " + pluralize("pending spec", pendingSpecCount); }
164 |
165 | var statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
166 | alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
167 |
168 | var results = find(".results");
169 | results.appendChild(summary);
170 |
171 | summaryList(topResults, summary);
172 |
173 | function summaryList(resultsTree, domParent) {
174 | var specListNode;
175 | for (var i = 0; i < resultsTree.children.length; i++) {
176 | var resultNode = resultsTree.children[i];
177 | if (resultNode.type == "suite") {
178 | var suiteListNode = createDom("ul", {className: "suite", id: "suite-" + resultNode.result.id},
179 | createDom("li", {className: "suite-detail"},
180 | createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
181 | )
182 | );
183 |
184 | summaryList(resultNode, suiteListNode);
185 | domParent.appendChild(suiteListNode);
186 | }
187 | if (resultNode.type == "spec") {
188 | if (domParent.getAttribute("class") != "specs") {
189 | specListNode = createDom("ul", {className: "specs"});
190 | domParent.appendChild(specListNode);
191 | }
192 | specListNode.appendChild(
193 | createDom("li", {
194 | className: resultNode.result.status,
195 | id: "spec-" + resultNode.result.id
196 | },
197 | createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
198 | )
199 | );
200 | }
201 | }
202 | }
203 |
204 | if (failures.length) {
205 | alert.appendChild(
206 | createDom('span', {className: "menu bar spec-list"},
207 | createDom("span", {}, "Spec List | "),
208 | createDom('a', {className: "failures-menu", href: "#"}, "Failures")));
209 | alert.appendChild(
210 | createDom('span', {className: "menu bar failure-list"},
211 | createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"),
212 | createDom("span", {}, " | Failures ")));
213 |
214 | find(".failures-menu").onclick = function() {
215 | setMenuModeTo('failure-list');
216 | };
217 | find(".spec-list-menu").onclick = function() {
218 | setMenuModeTo('spec-list');
219 | };
220 |
221 | setMenuModeTo('failure-list');
222 |
223 | var failureNode = find(".failures");
224 | for (var i = 0; i < failures.length; i++) {
225 | failureNode.appendChild(failures[i]);
226 | }
227 | }
228 | };
229 |
230 | return this;
231 |
232 | function find(selector) {
233 | return getContainer().querySelector(selector);
234 | }
235 |
236 | function createDom(type, attrs, childrenVarArgs) {
237 | var el = createElement(type);
238 |
239 | for (var i = 2; i < arguments.length; i++) {
240 | var child = arguments[i];
241 |
242 | if (typeof child === 'string') {
243 | el.appendChild(createTextNode(child));
244 | } else {
245 | if (child) {
246 | el.appendChild(child);
247 | }
248 | }
249 | }
250 |
251 | for (var attr in attrs) {
252 | if (attr == "className") {
253 | el[attr] = attrs[attr];
254 | } else {
255 | el.setAttribute(attr, attrs[attr]);
256 | }
257 | }
258 |
259 | return el;
260 | }
261 |
262 | function pluralize(singular, count) {
263 | var word = (count == 1 ? singular : singular + "s");
264 |
265 | return "" + count + " " + word;
266 | }
267 |
268 | function specHref(result) {
269 | return "?spec=" + encodeURIComponent(result.fullName);
270 | }
271 |
272 | function setMenuModeTo(mode) {
273 | htmlReporterMain.setAttribute("class", "html-reporter " + mode);
274 | }
275 | }
276 |
277 | return HtmlReporter;
278 | };
279 |
280 | jasmineRequire.HtmlSpecFilter = function() {
281 | function HtmlSpecFilter(options) {
282 | var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
283 | var filterPattern = new RegExp(filterString);
284 |
285 | this.matches = function(specName) {
286 | return filterPattern.test(specName);
287 | };
288 | }
289 |
290 | return HtmlSpecFilter;
291 | };
292 |
293 | jasmineRequire.ResultsNode = function() {
294 | function ResultsNode(result, type, parent) {
295 | this.result = result;
296 | this.type = type;
297 | this.parent = parent;
298 |
299 | this.children = [];
300 |
301 | this.addChild = function(result, type) {
302 | this.children.push(new ResultsNode(result, type, this));
303 | };
304 |
305 | this.last = function() {
306 | return this.children[this.children.length - 1];
307 | };
308 | }
309 |
310 | return ResultsNode;
311 | };
312 |
313 | jasmineRequire.QueryString = function() {
314 | function QueryString(options) {
315 |
316 | this.setParam = function(key, value) {
317 | var paramMap = queryStringToParamMap();
318 | paramMap[key] = value;
319 | options.getWindowLocation().search = toQueryString(paramMap);
320 | };
321 |
322 | this.getParam = function(key) {
323 | return queryStringToParamMap()[key];
324 | };
325 |
326 | return this;
327 |
328 | function toQueryString(paramMap) {
329 | var qStrPairs = [];
330 | for (var prop in paramMap) {
331 | qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop]));
332 | }
333 | return "?" + qStrPairs.join('&');
334 | }
335 |
336 | function queryStringToParamMap() {
337 | var paramStr = options.getWindowLocation().search.substring(1),
338 | params = [],
339 | paramMap = {};
340 |
341 | if (paramStr.length > 0) {
342 | params = paramStr.split('&');
343 | for (var i = 0; i < params.length; i++) {
344 | var p = params[i].split('=');
345 | var value = decodeURIComponent(p[1]);
346 | if (value === "true" || value === "false") {
347 | value = JSON.parse(value);
348 | }
349 | paramMap[decodeURIComponent(p[0])] = value;
350 | }
351 | }
352 |
353 | return paramMap;
354 | }
355 |
356 | }
357 |
358 | return QueryString;
359 | };
360 |
--------------------------------------------------------------------------------
/spec/lib/jasmine-2.0.0/jasmine.css:
--------------------------------------------------------------------------------
1 | body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
2 |
3 | .html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
4 | .html-reporter a { text-decoration: none; }
5 | .html-reporter a:hover { text-decoration: underline; }
6 | .html-reporter p, .html-reporter h1, .html-reporter h2, .html-reporter h3, .html-reporter h4, .html-reporter h5, .html-reporter h6 { margin: 0; line-height: 14px; }
7 | .html-reporter .banner, .html-reporter .symbol-summary, .html-reporter .summary, .html-reporter .result-message, .html-reporter .spec .description, .html-reporter .spec-detail .description, .html-reporter .alert .bar, .html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }
8 | .html-reporter .banner .version { margin-left: 14px; }
9 | .html-reporter #jasmine_content { position: fixed; right: 100%; }
10 | .html-reporter .version { color: #aaaaaa; }
11 | .html-reporter .banner { margin-top: 14px; }
12 | .html-reporter .duration { color: #aaaaaa; float: right; }
13 | .html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
14 | .html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; }
15 | .html-reporter .symbol-summary li.passed { font-size: 14px; }
16 | .html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: "\02022"; }
17 | .html-reporter .symbol-summary li.failed { line-height: 9px; }
18 | .html-reporter .symbol-summary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
19 | .html-reporter .symbol-summary li.disabled { font-size: 14px; }
20 | .html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; }
21 | .html-reporter .symbol-summary li.pending { line-height: 17px; }
22 | .html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; }
23 | .html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
24 | .html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
25 | .html-reporter .bar.failed { background-color: #b03911; }
26 | .html-reporter .bar.passed { background-color: #a6b779; }
27 | .html-reporter .bar.skipped { background-color: #bababa; }
28 | .html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }
29 | .html-reporter .bar.menu a { color: #333333; }
30 | .html-reporter .bar a { color: white; }
31 | .html-reporter.spec-list .bar.menu.failure-list, .html-reporter.spec-list .results .failures { display: none; }
32 | .html-reporter.failure-list .bar.menu.spec-list, .html-reporter.failure-list .summary { display: none; }
33 | .html-reporter .running-alert { background-color: #666666; }
34 | .html-reporter .results { margin-top: 14px; }
35 | .html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
36 | .html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
37 | .html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
38 | .html-reporter.showDetails .summary { display: none; }
39 | .html-reporter.showDetails #details { display: block; }
40 | .html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
41 | .html-reporter .summary { margin-top: 14px; }
42 | .html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
43 | .html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }
44 | .html-reporter .summary li.passed a { color: #5e7d00; }
45 | .html-reporter .summary li.failed a { color: #b03911; }
46 | .html-reporter .summary li.pending a { color: #ba9d37; }
47 | .html-reporter .description + .suite { margin-top: 0; }
48 | .html-reporter .suite { margin-top: 14px; }
49 | .html-reporter .suite a { color: #333333; }
50 | .html-reporter .failures .spec-detail { margin-bottom: 28px; }
51 | .html-reporter .failures .spec-detail .description { background-color: #b03911; }
52 | .html-reporter .failures .spec-detail .description a { color: white; }
53 | .html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; }
54 | .html-reporter .result-message span.result { display: block; }
55 | .html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
56 |
--------------------------------------------------------------------------------
/spec/lib/jasmine-2.0.0/jasmine_favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marioizquierdo/jquery.serializeJSON/8a2f2cfebd928b65509181bcdf01f8de243ed573/spec/lib/jasmine-2.0.0/jasmine_favicon.png
--------------------------------------------------------------------------------
/spec/lib/zepto-1.1.6.js:
--------------------------------------------------------------------------------
1 | /* Zepto v1.1.6 - zepto event ajax form ie - zeptojs.com/license */
2 |
3 | var Zepto = (function() {
4 | var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice, filter = emptyArray.filter,
5 | document = window.document,
6 | elementDisplay = {}, classCache = {},
7 | cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 },
8 | fragmentRE = /^\s*<(\w+|!)[^>]*>/,
9 | singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
10 | tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
11 | rootNodeRE = /^(?:body|html)$/i,
12 | capitalRE = /([A-Z])/g,
13 |
14 | // special attributes that should be get/set via method calls
15 | methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
16 |
17 | adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ],
18 | table = document.createElement('table'),
19 | tableRow = document.createElement('tr'),
20 | containers = {
21 | 'tr': document.createElement('tbody'),
22 | 'tbody': table, 'thead': table, 'tfoot': table,
23 | 'td': tableRow, 'th': tableRow,
24 | '*': document.createElement('div')
25 | },
26 | readyRE = /complete|loaded|interactive/,
27 | simpleSelectorRE = /^[\w-]*$/,
28 | class2type = {},
29 | toString = class2type.toString,
30 | zepto = {},
31 | camelize, uniq,
32 | tempParent = document.createElement('div'),
33 | propMap = {
34 | 'tabindex': 'tabIndex',
35 | 'readonly': 'readOnly',
36 | 'for': 'htmlFor',
37 | 'class': 'className',
38 | 'maxlength': 'maxLength',
39 | 'cellspacing': 'cellSpacing',
40 | 'cellpadding': 'cellPadding',
41 | 'rowspan': 'rowSpan',
42 | 'colspan': 'colSpan',
43 | 'usemap': 'useMap',
44 | 'frameborder': 'frameBorder',
45 | 'contenteditable': 'contentEditable'
46 | },
47 | isArray = Array.isArray ||
48 | function(object){ return object instanceof Array }
49 |
50 | zepto.matches = function(element, selector) {
51 | if (!selector || !element || element.nodeType !== 1) return false
52 | var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector ||
53 | element.oMatchesSelector || element.matchesSelector
54 | if (matchesSelector) return matchesSelector.call(element, selector)
55 | // fall back to performing a selector:
56 | var match, parent = element.parentNode, temp = !parent
57 | if (temp) (parent = tempParent).appendChild(element)
58 | match = ~zepto.qsa(parent, selector).indexOf(element)
59 | temp && tempParent.removeChild(element)
60 | return match
61 | }
62 |
63 | function type(obj) {
64 | return obj == null ? String(obj) :
65 | class2type[toString.call(obj)] || "object"
66 | }
67 |
68 | function isFunction(value) { return type(value) == "function" }
69 | function isWindow(obj) { return obj != null && obj == obj.window }
70 | function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }
71 | function isObject(obj) { return type(obj) == "object" }
72 | function isPlainObject(obj) {
73 | return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype
74 | }
75 | function likeArray(obj) { return typeof obj.length == 'number' }
76 |
77 | function compact(array) { return filter.call(array, function(item){ return item != null }) }
78 | function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }
79 | camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
80 | function dasherize(str) {
81 | return str.replace(/::/g, '/')
82 | .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
83 | .replace(/([a-z\d])([A-Z])/g, '$1_$2')
84 | .replace(/_/g, '-')
85 | .toLowerCase()
86 | }
87 | uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }
88 |
89 | function classRE(name) {
90 | return name in classCache ?
91 | classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'))
92 | }
93 |
94 | function maybeAddPx(name, value) {
95 | return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value
96 | }
97 |
98 | function defaultDisplay(nodeName) {
99 | var element, display
100 | if (!elementDisplay[nodeName]) {
101 | element = document.createElement(nodeName)
102 | document.body.appendChild(element)
103 | display = getComputedStyle(element, '').getPropertyValue("display")
104 | element.parentNode.removeChild(element)
105 | display == "none" && (display = "block")
106 | elementDisplay[nodeName] = display
107 | }
108 | return elementDisplay[nodeName]
109 | }
110 |
111 | function children(element) {
112 | return 'children' in element ?
113 | slice.call(element.children) :
114 | $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })
115 | }
116 |
117 | // `$.zepto.fragment` takes a html string and an optional tag name
118 | // to generate DOM nodes nodes from the given html string.
119 | // The generated DOM nodes are returned as an array.
120 | // This function can be overriden in plugins for example to make
121 | // it compatible with browsers that don't support the DOM fully.
122 | zepto.fragment = function(html, name, properties) {
123 | var dom, nodes, container
124 |
125 | // A special case optimization for a single tag
126 | if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))
127 |
128 | if (!dom) {
129 | if (html.replace) html = html.replace(tagExpanderRE, "<$1>$2>")
130 | if (name === undefined) name = fragmentRE.test(html) && RegExp.$1
131 | if (!(name in containers)) name = '*'
132 |
133 | container = containers[name]
134 | container.innerHTML = '' + html
135 | dom = $.each(slice.call(container.childNodes), function(){
136 | container.removeChild(this)
137 | })
138 | }
139 |
140 | if (isPlainObject(properties)) {
141 | nodes = $(dom)
142 | $.each(properties, function(key, value) {
143 | if (methodAttributes.indexOf(key) > -1) nodes[key](value)
144 | else nodes.attr(key, value)
145 | })
146 | }
147 |
148 | return dom
149 | }
150 |
151 | // `$.zepto.Z` swaps out the prototype of the given `dom` array
152 | // of nodes with `$.fn` and thus supplying all the Zepto functions
153 | // to the array. Note that `__proto__` is not supported on Internet
154 | // Explorer. This method can be overriden in plugins.
155 | zepto.Z = function(dom, selector) {
156 | dom = dom || []
157 | dom.__proto__ = $.fn
158 | dom.selector = selector || ''
159 | return dom
160 | }
161 |
162 | // `$.zepto.isZ` should return `true` if the given object is a Zepto
163 | // collection. This method can be overriden in plugins.
164 | zepto.isZ = function(object) {
165 | return object instanceof zepto.Z
166 | }
167 |
168 | // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and
169 | // takes a CSS selector and an optional context (and handles various
170 | // special cases).
171 | // This method can be overriden in plugins.
172 | zepto.init = function(selector, context) {
173 | var dom
174 | // If nothing given, return an empty Zepto collection
175 | if (!selector) return zepto.Z()
176 | // Optimize for string selectors
177 | else if (typeof selector == 'string') {
178 | selector = selector.trim()
179 | // If it's a html fragment, create nodes from it
180 | // Note: In both Chrome 21 and Firefox 15, DOM error 12
181 | // is thrown if the fragment doesn't begin with <
182 | if (selector[0] == '<' && fragmentRE.test(selector))
183 | dom = zepto.fragment(selector, RegExp.$1, context), selector = null
184 | // If there's a context, create a collection on that context first, and select
185 | // nodes from there
186 | else if (context !== undefined) return $(context).find(selector)
187 | // If it's a CSS selector, use it to select nodes.
188 | else dom = zepto.qsa(document, selector)
189 | }
190 | // If a function is given, call it when the DOM is ready
191 | else if (isFunction(selector)) return $(document).ready(selector)
192 | // If a Zepto collection is given, just return it
193 | else if (zepto.isZ(selector)) return selector
194 | else {
195 | // normalize array if an array of nodes is given
196 | if (isArray(selector)) dom = compact(selector)
197 | // Wrap DOM nodes.
198 | else if (isObject(selector))
199 | dom = [selector], selector = null
200 | // If it's a html fragment, create nodes from it
201 | else if (fragmentRE.test(selector))
202 | dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
203 | // If there's a context, create a collection on that context first, and select
204 | // nodes from there
205 | else if (context !== undefined) return $(context).find(selector)
206 | // And last but no least, if it's a CSS selector, use it to select nodes.
207 | else dom = zepto.qsa(document, selector)
208 | }
209 | // create a new Zepto collection from the nodes found
210 | return zepto.Z(dom, selector)
211 | }
212 |
213 | // `$` will be the base `Zepto` object. When calling this
214 | // function just call `$.zepto.init, which makes the implementation
215 | // details of selecting nodes and creating Zepto collections
216 | // patchable in plugins.
217 | $ = function(selector, context){
218 | return zepto.init(selector, context)
219 | }
220 |
221 | function extend(target, source, deep) {
222 | for (key in source)
223 | if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
224 | if (isPlainObject(source[key]) && !isPlainObject(target[key]))
225 | target[key] = {}
226 | if (isArray(source[key]) && !isArray(target[key]))
227 | target[key] = []
228 | extend(target[key], source[key], deep)
229 | }
230 | else if (source[key] !== undefined) target[key] = source[key]
231 | }
232 |
233 | // Copy all but undefined properties from one or more
234 | // objects to the `target` object.
235 | $.extend = function(target){
236 | var deep, args = slice.call(arguments, 1)
237 | if (typeof target == 'boolean') {
238 | deep = target
239 | target = args.shift()
240 | }
241 | args.forEach(function(arg){ extend(target, arg, deep) })
242 | return target
243 | }
244 |
245 | // `$.zepto.qsa` is Zepto's CSS selector implementation which
246 | // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.
247 | // This method can be overriden in plugins.
248 | zepto.qsa = function(element, selector){
249 | var found,
250 | maybeID = selector[0] == '#',
251 | maybeClass = !maybeID && selector[0] == '.',
252 | nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked
253 | isSimple = simpleSelectorRE.test(nameOnly)
254 | return (isDocument(element) && isSimple && maybeID) ?
255 | ( (found = element.getElementById(nameOnly)) ? [found] : [] ) :
256 | (element.nodeType !== 1 && element.nodeType !== 9) ? [] :
257 | slice.call(
258 | isSimple && !maybeID ?
259 | maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class
260 | element.getElementsByTagName(selector) : // Or a tag
261 | element.querySelectorAll(selector) // Or it's not simple, and we need to query all
262 | )
263 | }
264 |
265 | function filtered(nodes, selector) {
266 | return selector == null ? $(nodes) : $(nodes).filter(selector)
267 | }
268 |
269 | $.contains = document.documentElement.contains ?
270 | function(parent, node) {
271 | return parent !== node && parent.contains(node)
272 | } :
273 | function(parent, node) {
274 | while (node && (node = node.parentNode))
275 | if (node === parent) return true
276 | return false
277 | }
278 |
279 | function funcArg(context, arg, idx, payload) {
280 | return isFunction(arg) ? arg.call(context, idx, payload) : arg
281 | }
282 |
283 | function setAttribute(node, name, value) {
284 | value == null ? node.removeAttribute(name) : node.setAttribute(name, value)
285 | }
286 |
287 | // access className property while respecting SVGAnimatedString
288 | function className(node, value){
289 | var klass = node.className || '',
290 | svg = klass && klass.baseVal !== undefined
291 |
292 | if (value === undefined) return svg ? klass.baseVal : klass
293 | svg ? (klass.baseVal = value) : (node.className = value)
294 | }
295 |
296 | // "true" => true
297 | // "false" => false
298 | // "null" => null
299 | // "42" => 42
300 | // "42.5" => 42.5
301 | // "08" => "08"
302 | // JSON => parse if valid
303 | // String => self
304 | function deserializeValue(value) {
305 | try {
306 | return value ?
307 | value == "true" ||
308 | ( value == "false" ? false :
309 | value == "null" ? null :
310 | +value + "" == value ? +value :
311 | /^[\[\{]/.test(value) ? $.parseJSON(value) :
312 | value )
313 | : value
314 | } catch(e) {
315 | return value
316 | }
317 | }
318 |
319 | $.type = type
320 | $.isFunction = isFunction
321 | $.isWindow = isWindow
322 | $.isArray = isArray
323 | $.isPlainObject = isPlainObject
324 |
325 | $.isEmptyObject = function(obj) {
326 | var name
327 | for (name in obj) return false
328 | return true
329 | }
330 |
331 | $.inArray = function(elem, array, i){
332 | return emptyArray.indexOf.call(array, elem, i)
333 | }
334 |
335 | $.camelCase = camelize
336 | $.trim = function(str) {
337 | return str == null ? "" : String.prototype.trim.call(str)
338 | }
339 |
340 | // plugin compatibility
341 | $.uuid = 0
342 | $.support = { }
343 | $.expr = { }
344 |
345 | $.map = function(elements, callback){
346 | var value, values = [], i, key
347 | if (likeArray(elements))
348 | for (i = 0; i < elements.length; i++) {
349 | value = callback(elements[i], i)
350 | if (value != null) values.push(value)
351 | }
352 | else
353 | for (key in elements) {
354 | value = callback(elements[key], key)
355 | if (value != null) values.push(value)
356 | }
357 | return flatten(values)
358 | }
359 |
360 | $.each = function(elements, callback){
361 | var i, key
362 | if (likeArray(elements)) {
363 | for (i = 0; i < elements.length; i++)
364 | if (callback.call(elements[i], i, elements[i]) === false) return elements
365 | } else {
366 | for (key in elements)
367 | if (callback.call(elements[key], key, elements[key]) === false) return elements
368 | }
369 |
370 | return elements
371 | }
372 |
373 | $.grep = function(elements, callback){
374 | return filter.call(elements, callback)
375 | }
376 |
377 | if (window.JSON) $.parseJSON = JSON.parse
378 |
379 | // Populate the class2type map
380 | $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
381 | class2type[ "[object " + name + "]" ] = name.toLowerCase()
382 | })
383 |
384 | // Define methods that will be available on all
385 | // Zepto collections
386 | $.fn = {
387 | // Because a collection acts like an array
388 | // copy over these useful array functions.
389 | forEach: emptyArray.forEach,
390 | reduce: emptyArray.reduce,
391 | push: emptyArray.push,
392 | sort: emptyArray.sort,
393 | indexOf: emptyArray.indexOf,
394 | concat: emptyArray.concat,
395 |
396 | // `map` and `slice` in the jQuery API work differently
397 | // from their array counterparts
398 | map: function(fn){
399 | return $($.map(this, function(el, i){ return fn.call(el, i, el) }))
400 | },
401 | slice: function(){
402 | return $(slice.apply(this, arguments))
403 | },
404 |
405 | ready: function(callback){
406 | // need to check if document.body exists for IE as that browser reports
407 | // document ready when it hasn't yet created the body element
408 | if (readyRE.test(document.readyState) && document.body) callback($)
409 | else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)
410 | return this
411 | },
412 | get: function(idx){
413 | return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
414 | },
415 | toArray: function(){ return this.get() },
416 | size: function(){
417 | return this.length
418 | },
419 | remove: function(){
420 | return this.each(function(){
421 | if (this.parentNode != null)
422 | this.parentNode.removeChild(this)
423 | })
424 | },
425 | each: function(callback){
426 | emptyArray.every.call(this, function(el, idx){
427 | return callback.call(el, idx, el) !== false
428 | })
429 | return this
430 | },
431 | filter: function(selector){
432 | if (isFunction(selector)) return this.not(this.not(selector))
433 | return $(filter.call(this, function(element){
434 | return zepto.matches(element, selector)
435 | }))
436 | },
437 | add: function(selector,context){
438 | return $(uniq(this.concat($(selector,context))))
439 | },
440 | is: function(selector){
441 | return this.length > 0 && zepto.matches(this[0], selector)
442 | },
443 | not: function(selector){
444 | var nodes=[]
445 | if (isFunction(selector) && selector.call !== undefined)
446 | this.each(function(idx){
447 | if (!selector.call(this,idx)) nodes.push(this)
448 | })
449 | else {
450 | var excludes = typeof selector == 'string' ? this.filter(selector) :
451 | (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
452 | this.forEach(function(el){
453 | if (excludes.indexOf(el) < 0) nodes.push(el)
454 | })
455 | }
456 | return $(nodes)
457 | },
458 | has: function(selector){
459 | return this.filter(function(){
460 | return isObject(selector) ?
461 | $.contains(this, selector) :
462 | $(this).find(selector).size()
463 | })
464 | },
465 | eq: function(idx){
466 | return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)
467 | },
468 | first: function(){
469 | var el = this[0]
470 | return el && !isObject(el) ? el : $(el)
471 | },
472 | last: function(){
473 | var el = this[this.length - 1]
474 | return el && !isObject(el) ? el : $(el)
475 | },
476 | find: function(selector){
477 | var result, $this = this
478 | if (!selector) result = $()
479 | else if (typeof selector == 'object')
480 | result = $(selector).filter(function(){
481 | var node = this
482 | return emptyArray.some.call($this, function(parent){
483 | return $.contains(parent, node)
484 | })
485 | })
486 | else if (this.length == 1) result = $(zepto.qsa(this[0], selector))
487 | else result = this.map(function(){ return zepto.qsa(this, selector) })
488 | return result
489 | },
490 | closest: function(selector, context){
491 | var node = this[0], collection = false
492 | if (typeof selector == 'object') collection = $(selector)
493 | while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))
494 | node = node !== context && !isDocument(node) && node.parentNode
495 | return $(node)
496 | },
497 | parents: function(selector){
498 | var ancestors = [], nodes = this
499 | while (nodes.length > 0)
500 | nodes = $.map(nodes, function(node){
501 | if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {
502 | ancestors.push(node)
503 | return node
504 | }
505 | })
506 | return filtered(ancestors, selector)
507 | },
508 | parent: function(selector){
509 | return filtered(uniq(this.pluck('parentNode')), selector)
510 | },
511 | children: function(selector){
512 | return filtered(this.map(function(){ return children(this) }), selector)
513 | },
514 | contents: function() {
515 | return this.map(function() { return slice.call(this.childNodes) })
516 | },
517 | siblings: function(selector){
518 | return filtered(this.map(function(i, el){
519 | return filter.call(children(el.parentNode), function(child){ return child!==el })
520 | }), selector)
521 | },
522 | empty: function(){
523 | return this.each(function(){ this.innerHTML = '' })
524 | },
525 | // `pluck` is borrowed from Prototype.js
526 | pluck: function(property){
527 | return $.map(this, function(el){ return el[property] })
528 | },
529 | show: function(){
530 | return this.each(function(){
531 | this.style.display == "none" && (this.style.display = '')
532 | if (getComputedStyle(this, '').getPropertyValue("display") == "none")
533 | this.style.display = defaultDisplay(this.nodeName)
534 | })
535 | },
536 | replaceWith: function(newContent){
537 | return this.before(newContent).remove()
538 | },
539 | wrap: function(structure){
540 | var func = isFunction(structure)
541 | if (this[0] && !func)
542 | var dom = $(structure).get(0),
543 | clone = dom.parentNode || this.length > 1
544 |
545 | return this.each(function(index){
546 | $(this).wrapAll(
547 | func ? structure.call(this, index) :
548 | clone ? dom.cloneNode(true) : dom
549 | )
550 | })
551 | },
552 | wrapAll: function(structure){
553 | if (this[0]) {
554 | $(this[0]).before(structure = $(structure))
555 | var children
556 | // drill down to the inmost element
557 | while ((children = structure.children()).length) structure = children.first()
558 | $(structure).append(this)
559 | }
560 | return this
561 | },
562 | wrapInner: function(structure){
563 | var func = isFunction(structure)
564 | return this.each(function(index){
565 | var self = $(this), contents = self.contents(),
566 | dom = func ? structure.call(this, index) : structure
567 | contents.length ? contents.wrapAll(dom) : self.append(dom)
568 | })
569 | },
570 | unwrap: function(){
571 | this.parent().each(function(){
572 | $(this).replaceWith($(this).children())
573 | })
574 | return this
575 | },
576 | clone: function(){
577 | return this.map(function(){ return this.cloneNode(true) })
578 | },
579 | hide: function(){
580 | return this.css("display", "none")
581 | },
582 | toggle: function(setting){
583 | return this.each(function(){
584 | var el = $(this)
585 | ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide()
586 | })
587 | },
588 | prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') },
589 | next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') },
590 | html: function(html){
591 | return 0 in arguments ?
592 | this.each(function(idx){
593 | var originHtml = this.innerHTML
594 | $(this).empty().append( funcArg(this, html, idx, originHtml) )
595 | }) :
596 | (0 in this ? this[0].innerHTML : null)
597 | },
598 | text: function(text){
599 | return 0 in arguments ?
600 | this.each(function(idx){
601 | var newText = funcArg(this, text, idx, this.textContent)
602 | this.textContent = newText == null ? '' : ''+newText
603 | }) :
604 | (0 in this ? this[0].textContent : null)
605 | },
606 | attr: function(name, value){
607 | var result
608 | return (typeof name == 'string' && !(1 in arguments)) ?
609 | (!this.length || this[0].nodeType !== 1 ? undefined :
610 | (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result
611 | ) :
612 | this.each(function(idx){
613 | if (this.nodeType !== 1) return
614 | if (isObject(name)) for (key in name) setAttribute(this, key, name[key])
615 | else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))
616 | })
617 | },
618 | removeAttr: function(name){
619 | return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){
620 | setAttribute(this, attribute)
621 | }, this)})
622 | },
623 | prop: function(name, value){
624 | name = propMap[name] || name
625 | return (1 in arguments) ?
626 | this.each(function(idx){
627 | this[name] = funcArg(this, value, idx, this[name])
628 | }) :
629 | (this[0] && this[0][name])
630 | },
631 | data: function(name, value){
632 | var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase()
633 |
634 | var data = (1 in arguments) ?
635 | this.attr(attrName, value) :
636 | this.attr(attrName)
637 |
638 | return data !== null ? deserializeValue(data) : undefined
639 | },
640 | val: function(value){
641 | return 0 in arguments ?
642 | this.each(function(idx){
643 | this.value = funcArg(this, value, idx, this.value)
644 | }) :
645 | (this[0] && (this[0].multiple ?
646 | $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') :
647 | this[0].value)
648 | )
649 | },
650 | offset: function(coordinates){
651 | if (coordinates) return this.each(function(index){
652 | var $this = $(this),
653 | coords = funcArg(this, coordinates, index, $this.offset()),
654 | parentOffset = $this.offsetParent().offset(),
655 | props = {
656 | top: coords.top - parentOffset.top,
657 | left: coords.left - parentOffset.left
658 | }
659 |
660 | if ($this.css('position') == 'static') props['position'] = 'relative'
661 | $this.css(props)
662 | })
663 | if (!this.length) return null
664 | var obj = this[0].getBoundingClientRect()
665 | return {
666 | left: obj.left + window.pageXOffset,
667 | top: obj.top + window.pageYOffset,
668 | width: Math.round(obj.width),
669 | height: Math.round(obj.height)
670 | }
671 | },
672 | css: function(property, value){
673 | if (arguments.length < 2) {
674 | var computedStyle, element = this[0]
675 | if(!element) return
676 | computedStyle = getComputedStyle(element, '')
677 | if (typeof property == 'string')
678 | return element.style[camelize(property)] || computedStyle.getPropertyValue(property)
679 | else if (isArray(property)) {
680 | var props = {}
681 | $.each(property, function(_, prop){
682 | props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop))
683 | })
684 | return props
685 | }
686 | }
687 |
688 | var css = ''
689 | if (type(property) == 'string') {
690 | if (!value && value !== 0)
691 | this.each(function(){ this.style.removeProperty(dasherize(property)) })
692 | else
693 | css = dasherize(property) + ":" + maybeAddPx(property, value)
694 | } else {
695 | for (key in property)
696 | if (!property[key] && property[key] !== 0)
697 | this.each(function(){ this.style.removeProperty(dasherize(key)) })
698 | else
699 | css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'
700 | }
701 |
702 | return this.each(function(){ this.style.cssText += ';' + css })
703 | },
704 | index: function(element){
705 | return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])
706 | },
707 | hasClass: function(name){
708 | if (!name) return false
709 | return emptyArray.some.call(this, function(el){
710 | return this.test(className(el))
711 | }, classRE(name))
712 | },
713 | addClass: function(name){
714 | if (!name) return this
715 | return this.each(function(idx){
716 | if (!('className' in this)) return
717 | classList = []
718 | var cls = className(this), newName = funcArg(this, name, idx, cls)
719 | newName.split(/\s+/g).forEach(function(klass){
720 | if (!$(this).hasClass(klass)) classList.push(klass)
721 | }, this)
722 | classList.length && className(this, cls + (cls ? " " : "") + classList.join(" "))
723 | })
724 | },
725 | removeClass: function(name){
726 | return this.each(function(idx){
727 | if (!('className' in this)) return
728 | if (name === undefined) return className(this, '')
729 | classList = className(this)
730 | funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){
731 | classList = classList.replace(classRE(klass), " ")
732 | })
733 | className(this, classList.trim())
734 | })
735 | },
736 | toggleClass: function(name, when){
737 | if (!name) return this
738 | return this.each(function(idx){
739 | var $this = $(this), names = funcArg(this, name, idx, className(this))
740 | names.split(/\s+/g).forEach(function(klass){
741 | (when === undefined ? !$this.hasClass(klass) : when) ?
742 | $this.addClass(klass) : $this.removeClass(klass)
743 | })
744 | })
745 | },
746 | scrollTop: function(value){
747 | if (!this.length) return
748 | var hasScrollTop = 'scrollTop' in this[0]
749 | if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset
750 | return this.each(hasScrollTop ?
751 | function(){ this.scrollTop = value } :
752 | function(){ this.scrollTo(this.scrollX, value) })
753 | },
754 | scrollLeft: function(value){
755 | if (!this.length) return
756 | var hasScrollLeft = 'scrollLeft' in this[0]
757 | if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset
758 | return this.each(hasScrollLeft ?
759 | function(){ this.scrollLeft = value } :
760 | function(){ this.scrollTo(value, this.scrollY) })
761 | },
762 | position: function() {
763 | if (!this.length) return
764 |
765 | var elem = this[0],
766 | // Get *real* offsetParent
767 | offsetParent = this.offsetParent(),
768 | // Get correct offsets
769 | offset = this.offset(),
770 | parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset()
771 |
772 | // Subtract element margins
773 | // note: when an element has margin: auto the offsetLeft and marginLeft
774 | // are the same in Safari causing offset.left to incorrectly be 0
775 | offset.top -= parseFloat( $(elem).css('margin-top') ) || 0
776 | offset.left -= parseFloat( $(elem).css('margin-left') ) || 0
777 |
778 | // Add offsetParent borders
779 | parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0
780 | parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0
781 |
782 | // Subtract the two offsets
783 | return {
784 | top: offset.top - parentOffset.top,
785 | left: offset.left - parentOffset.left
786 | }
787 | },
788 | offsetParent: function() {
789 | return this.map(function(){
790 | var parent = this.offsetParent || document.body
791 | while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static")
792 | parent = parent.offsetParent
793 | return parent
794 | })
795 | }
796 | }
797 |
798 | // for now
799 | $.fn.detach = $.fn.remove
800 |
801 | // Generate the `width` and `height` functions
802 | ;['width', 'height'].forEach(function(dimension){
803 | var dimensionProperty =
804 | dimension.replace(/./, function(m){ return m[0].toUpperCase() })
805 |
806 | $.fn[dimension] = function(value){
807 | var offset, el = this[0]
808 | if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] :
809 | isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :
810 | (offset = this.offset()) && offset[dimension]
811 | else return this.each(function(idx){
812 | el = $(this)
813 | el.css(dimension, funcArg(this, value, idx, el[dimension]()))
814 | })
815 | }
816 | })
817 |
818 | function traverseNode(node, fun) {
819 | fun(node)
820 | for (var i = 0, len = node.childNodes.length; i < len; i++)
821 | traverseNode(node.childNodes[i], fun)
822 | }
823 |
824 | // Generate the `after`, `prepend`, `before`, `append`,
825 | // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.
826 | adjacencyOperators.forEach(function(operator, operatorIndex) {
827 | var inside = operatorIndex % 2 //=> prepend, append
828 |
829 | $.fn[operator] = function(){
830 | // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
831 | var argType, nodes = $.map(arguments, function(arg) {
832 | argType = type(arg)
833 | return argType == "object" || argType == "array" || arg == null ?
834 | arg : zepto.fragment(arg)
835 | }),
836 | parent, copyByClone = this.length > 1
837 | if (nodes.length < 1) return this
838 |
839 | return this.each(function(_, target){
840 | parent = inside ? target : target.parentNode
841 |
842 | // convert all methods to a "before" operation
843 | target = operatorIndex == 0 ? target.nextSibling :
844 | operatorIndex == 1 ? target.firstChild :
845 | operatorIndex == 2 ? target :
846 | null
847 |
848 | var parentInDocument = $.contains(document.documentElement, parent)
849 |
850 | nodes.forEach(function(node){
851 | if (copyByClone) node = node.cloneNode(true)
852 | else if (!parent) return $(node).remove()
853 |
854 | parent.insertBefore(node, target)
855 | if (parentInDocument) traverseNode(node, function(el){
856 | if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
857 | (!el.type || el.type === 'text/javascript') && !el.src)
858 | window['eval'].call(window, el.innerHTML)
859 | })
860 | })
861 | })
862 | }
863 |
864 | // after => insertAfter
865 | // prepend => prependTo
866 | // before => insertBefore
867 | // append => appendTo
868 | $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){
869 | $(html)[operator](this)
870 | return this
871 | }
872 | })
873 |
874 | zepto.Z.prototype = $.fn
875 |
876 | // Export internal API functions in the `$.zepto` namespace
877 | zepto.uniq = uniq
878 | zepto.deserializeValue = deserializeValue
879 | $.zepto = zepto
880 |
881 | return $
882 | })()
883 |
884 | window.Zepto = Zepto
885 | window.$ === undefined && (window.$ = Zepto)
886 |
887 | ;(function($){
888 | var _zid = 1, undefined,
889 | slice = Array.prototype.slice,
890 | isFunction = $.isFunction,
891 | isString = function(obj){ return typeof obj == 'string' },
892 | handlers = {},
893 | specialEvents={},
894 | focusinSupported = 'onfocusin' in window,
895 | focus = { focus: 'focusin', blur: 'focusout' },
896 | hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }
897 |
898 | specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
899 |
900 | function zid(element) {
901 | return element._zid || (element._zid = _zid++)
902 | }
903 | function findHandlers(element, event, fn, selector) {
904 | event = parse(event)
905 | if (event.ns) var matcher = matcherFor(event.ns)
906 | return (handlers[zid(element)] || []).filter(function(handler) {
907 | return handler
908 | && (!event.e || handler.e == event.e)
909 | && (!event.ns || matcher.test(handler.ns))
910 | && (!fn || zid(handler.fn) === zid(fn))
911 | && (!selector || handler.sel == selector)
912 | })
913 | }
914 | function parse(event) {
915 | var parts = ('' + event).split('.')
916 | return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
917 | }
918 | function matcherFor(ns) {
919 | return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')
920 | }
921 |
922 | function eventCapture(handler, captureSetting) {
923 | return handler.del &&
924 | (!focusinSupported && (handler.e in focus)) ||
925 | !!captureSetting
926 | }
927 |
928 | function realEvent(type) {
929 | return hover[type] || (focusinSupported && focus[type]) || type
930 | }
931 |
932 | function add(element, events, fn, data, selector, delegator, capture){
933 | var id = zid(element), set = (handlers[id] || (handlers[id] = []))
934 | events.split(/\s/).forEach(function(event){
935 | if (event == 'ready') return $(document).ready(fn)
936 | var handler = parse(event)
937 | handler.fn = fn
938 | handler.sel = selector
939 | // emulate mouseenter, mouseleave
940 | if (handler.e in hover) fn = function(e){
941 | var related = e.relatedTarget
942 | if (!related || (related !== this && !$.contains(this, related)))
943 | return handler.fn.apply(this, arguments)
944 | }
945 | handler.del = delegator
946 | var callback = delegator || fn
947 | handler.proxy = function(e){
948 | e = compatible(e)
949 | if (e.isImmediatePropagationStopped()) return
950 | e.data = data
951 | var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))
952 | if (result === false) e.preventDefault(), e.stopPropagation()
953 | return result
954 | }
955 | handler.i = set.length
956 | set.push(handler)
957 | if ('addEventListener' in element)
958 | element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
959 | })
960 | }
961 | function remove(element, events, fn, selector, capture){
962 | var id = zid(element)
963 | ;(events || '').split(/\s/).forEach(function(event){
964 | findHandlers(element, event, fn, selector).forEach(function(handler){
965 | delete handlers[id][handler.i]
966 | if ('removeEventListener' in element)
967 | element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
968 | })
969 | })
970 | }
971 |
972 | $.event = { add: add, remove: remove }
973 |
974 | $.proxy = function(fn, context) {
975 | var args = (2 in arguments) && slice.call(arguments, 2)
976 | if (isFunction(fn)) {
977 | var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) }
978 | proxyFn._zid = zid(fn)
979 | return proxyFn
980 | } else if (isString(context)) {
981 | if (args) {
982 | args.unshift(fn[context], fn)
983 | return $.proxy.apply(null, args)
984 | } else {
985 | return $.proxy(fn[context], fn)
986 | }
987 | } else {
988 | throw new TypeError("expected function")
989 | }
990 | }
991 |
992 | $.fn.bind = function(event, data, callback){
993 | return this.on(event, data, callback)
994 | }
995 | $.fn.unbind = function(event, callback){
996 | return this.off(event, callback)
997 | }
998 | $.fn.one = function(event, selector, data, callback){
999 | return this.on(event, selector, data, callback, 1)
1000 | }
1001 |
1002 | var returnTrue = function(){return true},
1003 | returnFalse = function(){return false},
1004 | ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$)/,
1005 | eventMethods = {
1006 | preventDefault: 'isDefaultPrevented',
1007 | stopImmediatePropagation: 'isImmediatePropagationStopped',
1008 | stopPropagation: 'isPropagationStopped'
1009 | }
1010 |
1011 | function compatible(event, source) {
1012 | if (source || !event.isDefaultPrevented) {
1013 | source || (source = event)
1014 |
1015 | $.each(eventMethods, function(name, predicate) {
1016 | var sourceMethod = source[name]
1017 | event[name] = function(){
1018 | this[predicate] = returnTrue
1019 | return sourceMethod && sourceMethod.apply(source, arguments)
1020 | }
1021 | event[predicate] = returnFalse
1022 | })
1023 |
1024 | if (source.defaultPrevented !== undefined ? source.defaultPrevented :
1025 | 'returnValue' in source ? source.returnValue === false :
1026 | source.getPreventDefault && source.getPreventDefault())
1027 | event.isDefaultPrevented = returnTrue
1028 | }
1029 | return event
1030 | }
1031 |
1032 | function createProxy(event) {
1033 | var key, proxy = { originalEvent: event }
1034 | for (key in event)
1035 | if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
1036 |
1037 | return compatible(proxy, event)
1038 | }
1039 |
1040 | $.fn.delegate = function(selector, event, callback){
1041 | return this.on(event, selector, callback)
1042 | }
1043 | $.fn.undelegate = function(selector, event, callback){
1044 | return this.off(event, selector, callback)
1045 | }
1046 |
1047 | $.fn.live = function(event, callback){
1048 | $(document.body).delegate(this.selector, event, callback)
1049 | return this
1050 | }
1051 | $.fn.die = function(event, callback){
1052 | $(document.body).undelegate(this.selector, event, callback)
1053 | return this
1054 | }
1055 |
1056 | $.fn.on = function(event, selector, data, callback, one){
1057 | var autoRemove, delegator, $this = this
1058 | if (event && !isString(event)) {
1059 | $.each(event, function(type, fn){
1060 | $this.on(type, selector, data, fn, one)
1061 | })
1062 | return $this
1063 | }
1064 |
1065 | if (!isString(selector) && !isFunction(callback) && callback !== false)
1066 | callback = data, data = selector, selector = undefined
1067 | if (isFunction(data) || data === false)
1068 | callback = data, data = undefined
1069 |
1070 | if (callback === false) callback = returnFalse
1071 |
1072 | return $this.each(function(_, element){
1073 | if (one) autoRemove = function(e){
1074 | remove(element, e.type, callback)
1075 | return callback.apply(this, arguments)
1076 | }
1077 |
1078 | if (selector) delegator = function(e){
1079 | var evt, match = $(e.target).closest(selector, element).get(0)
1080 | if (match && match !== element) {
1081 | evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
1082 | return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))
1083 | }
1084 | }
1085 |
1086 | add(element, event, callback, data, selector, delegator || autoRemove)
1087 | })
1088 | }
1089 | $.fn.off = function(event, selector, callback){
1090 | var $this = this
1091 | if (event && !isString(event)) {
1092 | $.each(event, function(type, fn){
1093 | $this.off(type, selector, fn)
1094 | })
1095 | return $this
1096 | }
1097 |
1098 | if (!isString(selector) && !isFunction(callback) && callback !== false)
1099 | callback = selector, selector = undefined
1100 |
1101 | if (callback === false) callback = returnFalse
1102 |
1103 | return $this.each(function(){
1104 | remove(this, event, callback, selector)
1105 | })
1106 | }
1107 |
1108 | $.fn.trigger = function(event, args){
1109 | event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event)
1110 | event._args = args
1111 | return this.each(function(){
1112 | // handle focus(), blur() by calling them directly
1113 | if (event.type in focus && typeof this[event.type] == "function") this[event.type]()
1114 | // items in the collection might not be DOM elements
1115 | else if ('dispatchEvent' in this) this.dispatchEvent(event)
1116 | else $(this).triggerHandler(event, args)
1117 | })
1118 | }
1119 |
1120 | // triggers event handlers on current element just as if an event occurred,
1121 | // doesn't trigger an actual event, doesn't bubble
1122 | $.fn.triggerHandler = function(event, args){
1123 | var e, result
1124 | this.each(function(i, element){
1125 | e = createProxy(isString(event) ? $.Event(event) : event)
1126 | e._args = args
1127 | e.target = element
1128 | $.each(findHandlers(element, event.type || event), function(i, handler){
1129 | result = handler.proxy(e)
1130 | if (e.isImmediatePropagationStopped()) return false
1131 | })
1132 | })
1133 | return result
1134 | }
1135 |
1136 | // shortcut methods for `.bind(event, fn)` for each event type
1137 | ;('focusin focusout focus blur load resize scroll unload click dblclick '+
1138 | 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+
1139 | 'change select keydown keypress keyup error').split(' ').forEach(function(event) {
1140 | $.fn[event] = function(callback) {
1141 | return (0 in arguments) ?
1142 | this.bind(event, callback) :
1143 | this.trigger(event)
1144 | }
1145 | })
1146 |
1147 | $.Event = function(type, props) {
1148 | if (!isString(type)) props = type, type = props.type
1149 | var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
1150 | if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
1151 | event.initEvent(type, bubbles, true)
1152 | return compatible(event)
1153 | }
1154 |
1155 | })(Zepto)
1156 |
1157 | ;(function($){
1158 | var jsonpID = 0,
1159 | document = window.document,
1160 | key,
1161 | name,
1162 | rscript = /
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |