· 8 years ago · Feb 27, 2018, 03:56 PM
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 typeof define === 'function' && define.amd ? define(factory) :
4 (global.getsy = factory());
5}(this, (function () { 'use strict';
6
7var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
8
9
10
11
12
13function createCommonjsModule(fn, module) {
14 return module = { exports: {} }, fn(module, module.exports), module.exports;
15}
16
17var jquery$1 = createCommonjsModule(function (module) {
18/*!
19 * jQuery JavaScript Library v3.2.1
20 * https://jquery.com/
21 *
22 * Includes Sizzle.js
23 * https://sizzlejs.com/
24 *
25 * Copyright JS Foundation and other contributors
26 * Released under the MIT license
27 * https://jquery.org/license
28 *
29 * Date: 2017-03-20T18:59Z
30 */
31( function( global, factory ) {
32
33 "use strict";
34
35 {
36
37 // For CommonJS and CommonJS-like environments where a proper `window`
38 // is present, execute the factory and get jQuery.
39 // For environments that do not have a `window` with a `document`
40 // (such as Node.js), expose a factory as module.exports.
41 // This accentuates the need for the creation of a real `window`.
42 // e.g. var jQuery = require("jquery")(window);
43 // See ticket #14549 for more info.
44 module.exports = global.document ?
45 factory( global, true ) :
46 function( w ) {
47 if ( !w.document ) {
48 throw new Error( "jQuery requires a window with a document" );
49 }
50 return factory( w );
51 };
52 }
53
54// Pass this if window is not defined yet
55} )( typeof window !== "undefined" ? window : commonjsGlobal, function( window, noGlobal ) {
56
57// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
58// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
59// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
60// enough that all such attempts are guarded in a try block.
61"use strict";
62
63var arr = [];
64
65var document = window.document;
66
67var getProto = Object.getPrototypeOf;
68
69var slice = arr.slice;
70
71var concat = arr.concat;
72
73var push = arr.push;
74
75var indexOf = arr.indexOf;
76
77var class2type = {};
78
79var toString = class2type.toString;
80
81var hasOwn = class2type.hasOwnProperty;
82
83var fnToString = hasOwn.toString;
84
85var ObjectFunctionString = fnToString.call( Object );
86
87var support = {};
88
89
90
91 function DOMEval( code, doc ) {
92 doc = doc || document;
93
94 var script = doc.createElement( "script" );
95
96 script.text = code;
97 doc.head.appendChild( script ).parentNode.removeChild( script );
98 }
99/* global Symbol */
100// Defining this global in .eslintrc.json would create a danger of using the global
101// unguarded in another place, it seems safer to define global only for this module
102
103
104
105var
106 version = "3.2.1",
107
108 // Define a local copy of jQuery
109 jQuery = function( selector, context ) {
110
111 // The jQuery object is actually just the init constructor 'enhanced'
112 // Need init if jQuery is called (just allow error to be thrown if not included)
113 return new jQuery.fn.init( selector, context );
114 },
115
116 // Support: Android <=4.0 only
117 // Make sure we trim BOM and NBSP
118 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
119
120 // Matches dashed string for camelizing
121 rmsPrefix = /^-ms-/,
122 rdashAlpha = /-([a-z])/g,
123
124 // Used by jQuery.camelCase as callback to replace()
125 fcamelCase = function( all, letter ) {
126 return letter.toUpperCase();
127 };
128
129jQuery.fn = jQuery.prototype = {
130
131 // The current version of jQuery being used
132 jquery: version,
133
134 constructor: jQuery,
135
136 // The default length of a jQuery object is 0
137 length: 0,
138
139 toArray: function() {
140 return slice.call( this );
141 },
142
143 // Get the Nth element in the matched element set OR
144 // Get the whole matched element set as a clean array
145 get: function( num ) {
146
147 // Return all the elements in a clean array
148 if ( num == null ) {
149 return slice.call( this );
150 }
151
152 // Return just the one element from the set
153 return num < 0 ? this[ num + this.length ] : this[ num ];
154 },
155
156 // Take an array of elements and push it onto the stack
157 // (returning the new matched element set)
158 pushStack: function( elems ) {
159
160 // Build a new jQuery matched element set
161 var ret = jQuery.merge( this.constructor(), elems );
162
163 // Add the old object onto the stack (as a reference)
164 ret.prevObject = this;
165
166 // Return the newly-formed element set
167 return ret;
168 },
169
170 // Execute a callback for every element in the matched set.
171 each: function( callback ) {
172 return jQuery.each( this, callback );
173 },
174
175 map: function( callback ) {
176 return this.pushStack( jQuery.map( this, function( elem, i ) {
177 return callback.call( elem, i, elem );
178 } ) );
179 },
180
181 slice: function() {
182 return this.pushStack( slice.apply( this, arguments ) );
183 },
184
185 first: function() {
186 return this.eq( 0 );
187 },
188
189 last: function() {
190 return this.eq( -1 );
191 },
192
193 eq: function( i ) {
194 var len = this.length,
195 j = +i + ( i < 0 ? len : 0 );
196 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
197 },
198
199 end: function() {
200 return this.prevObject || this.constructor();
201 },
202
203 // For internal use only.
204 // Behaves like an Array's method, not like a jQuery method.
205 push: push,
206 sort: arr.sort,
207 splice: arr.splice
208};
209
210jQuery.extend = jQuery.fn.extend = function() {
211 var options, name, src, copy, copyIsArray, clone,
212 target = arguments[ 0 ] || {},
213 i = 1,
214 length = arguments.length,
215 deep = false;
216
217 // Handle a deep copy situation
218 if ( typeof target === "boolean" ) {
219 deep = target;
220
221 // Skip the boolean and the target
222 target = arguments[ i ] || {};
223 i++;
224 }
225
226 // Handle case when target is a string or something (possible in deep copy)
227 if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
228 target = {};
229 }
230
231 // Extend jQuery itself if only one argument is passed
232 if ( i === length ) {
233 target = this;
234 i--;
235 }
236
237 for ( ; i < length; i++ ) {
238
239 // Only deal with non-null/undefined values
240 if ( ( options = arguments[ i ] ) != null ) {
241
242 // Extend the base object
243 for ( name in options ) {
244 src = target[ name ];
245 copy = options[ name ];
246
247 // Prevent never-ending loop
248 if ( target === copy ) {
249 continue;
250 }
251
252 // Recurse if we're merging plain objects or arrays
253 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
254 ( copyIsArray = Array.isArray( copy ) ) ) ) {
255
256 if ( copyIsArray ) {
257 copyIsArray = false;
258 clone = src && Array.isArray( src ) ? src : [];
259
260 } else {
261 clone = src && jQuery.isPlainObject( src ) ? src : {};
262 }
263
264 // Never move original objects, clone them
265 target[ name ] = jQuery.extend( deep, clone, copy );
266
267 // Don't bring in undefined values
268 } else if ( copy !== undefined ) {
269 target[ name ] = copy;
270 }
271 }
272 }
273 }
274
275 // Return the modified object
276 return target;
277};
278
279jQuery.extend( {
280
281 // Unique for each copy of jQuery on the page
282 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
283
284 // Assume jQuery is ready without the ready module
285 isReady: true,
286
287 error: function( msg ) {
288 throw new Error( msg );
289 },
290
291 noop: function() {},
292
293 isFunction: function( obj ) {
294 return jQuery.type( obj ) === "function";
295 },
296
297 isWindow: function( obj ) {
298 return obj != null && obj === obj.window;
299 },
300
301 isNumeric: function( obj ) {
302
303 // As of jQuery 3.0, isNumeric is limited to
304 // strings and numbers (primitives or objects)
305 // that can be coerced to finite numbers (gh-2662)
306 var type = jQuery.type( obj );
307 return ( type === "number" || type === "string" ) &&
308
309 // parseFloat NaNs numeric-cast false positives ("")
310 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
311 // subtraction forces infinities to NaN
312 !isNaN( obj - parseFloat( obj ) );
313 },
314
315 isPlainObject: function( obj ) {
316 var proto, Ctor;
317
318 // Detect obvious negatives
319 // Use toString instead of jQuery.type to catch host objects
320 if ( !obj || toString.call( obj ) !== "[object Object]" ) {
321 return false;
322 }
323
324 proto = getProto( obj );
325
326 // Objects with no prototype (e.g., `Object.create( null )`) are plain
327 if ( !proto ) {
328 return true;
329 }
330
331 // Objects with prototype are plain iff they were constructed by a global Object function
332 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
333 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
334 },
335
336 isEmptyObject: function( obj ) {
337
338 /* eslint-disable no-unused-vars */
339 // See https://github.com/eslint/eslint/issues/6125
340 var name;
341
342 for ( name in obj ) {
343 return false;
344 }
345 return true;
346 },
347
348 type: function( obj ) {
349 if ( obj == null ) {
350 return obj + "";
351 }
352
353 // Support: Android <=2.3 only (functionish RegExp)
354 return typeof obj === "object" || typeof obj === "function" ?
355 class2type[ toString.call( obj ) ] || "object" :
356 typeof obj;
357 },
358
359 // Evaluates a script in a global context
360 globalEval: function( code ) {
361 DOMEval( code );
362 },
363
364 // Convert dashed to camelCase; used by the css and data modules
365 // Support: IE <=9 - 11, Edge 12 - 13
366 // Microsoft forgot to hump their vendor prefix (#9572)
367 camelCase: function( string ) {
368 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
369 },
370
371 each: function( obj, callback ) {
372 var length, i = 0;
373
374 if ( isArrayLike( obj ) ) {
375 length = obj.length;
376 for ( ; i < length; i++ ) {
377 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
378 break;
379 }
380 }
381 } else {
382 for ( i in obj ) {
383 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
384 break;
385 }
386 }
387 }
388
389 return obj;
390 },
391
392 // Support: Android <=4.0 only
393 trim: function( text ) {
394 return text == null ?
395 "" :
396 ( text + "" ).replace( rtrim, "" );
397 },
398
399 // results is for internal usage only
400 makeArray: function( arr, results ) {
401 var ret = results || [];
402
403 if ( arr != null ) {
404 if ( isArrayLike( Object( arr ) ) ) {
405 jQuery.merge( ret,
406 typeof arr === "string" ?
407 [ arr ] : arr
408 );
409 } else {
410 push.call( ret, arr );
411 }
412 }
413
414 return ret;
415 },
416
417 inArray: function( elem, arr, i ) {
418 return arr == null ? -1 : indexOf.call( arr, elem, i );
419 },
420
421 // Support: Android <=4.0 only, PhantomJS 1 only
422 // push.apply(_, arraylike) throws on ancient WebKit
423 merge: function( first, second ) {
424 var len = +second.length,
425 j = 0,
426 i = first.length;
427
428 for ( ; j < len; j++ ) {
429 first[ i++ ] = second[ j ];
430 }
431
432 first.length = i;
433
434 return first;
435 },
436
437 grep: function( elems, callback, invert ) {
438 var callbackInverse,
439 matches = [],
440 i = 0,
441 length = elems.length,
442 callbackExpect = !invert;
443
444 // Go through the array, only saving the items
445 // that pass the validator function
446 for ( ; i < length; i++ ) {
447 callbackInverse = !callback( elems[ i ], i );
448 if ( callbackInverse !== callbackExpect ) {
449 matches.push( elems[ i ] );
450 }
451 }
452
453 return matches;
454 },
455
456 // arg is for internal usage only
457 map: function( elems, callback, arg ) {
458 var length, value,
459 i = 0,
460 ret = [];
461
462 // Go through the array, translating each of the items to their new values
463 if ( isArrayLike( elems ) ) {
464 length = elems.length;
465 for ( ; i < length; i++ ) {
466 value = callback( elems[ i ], i, arg );
467
468 if ( value != null ) {
469 ret.push( value );
470 }
471 }
472
473 // Go through every key on the object,
474 } else {
475 for ( i in elems ) {
476 value = callback( elems[ i ], i, arg );
477
478 if ( value != null ) {
479 ret.push( value );
480 }
481 }
482 }
483
484 // Flatten any nested arrays
485 return concat.apply( [], ret );
486 },
487
488 // A global GUID counter for objects
489 guid: 1,
490
491 // Bind a function to a context, optionally partially applying any
492 // arguments.
493 proxy: function( fn, context ) {
494 var tmp, args, proxy;
495
496 if ( typeof context === "string" ) {
497 tmp = fn[ context ];
498 context = fn;
499 fn = tmp;
500 }
501
502 // Quick check to determine if target is callable, in the spec
503 // this throws a TypeError, but we will just return undefined.
504 if ( !jQuery.isFunction( fn ) ) {
505 return undefined;
506 }
507
508 // Simulated bind
509 args = slice.call( arguments, 2 );
510 proxy = function() {
511 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
512 };
513
514 // Set the guid of unique handler to the same of original handler, so it can be removed
515 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
516
517 return proxy;
518 },
519
520 now: Date.now,
521
522 // jQuery.support is not used in Core but other projects attach their
523 // properties to it so it needs to exist.
524 support: support
525} );
526
527if ( typeof Symbol === "function" ) {
528 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
529}
530
531// Populate the class2type map
532jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
533function( i, name ) {
534 class2type[ "[object " + name + "]" ] = name.toLowerCase();
535} );
536
537function isArrayLike( obj ) {
538
539 // Support: real iOS 8.2 only (not reproducible in simulator)
540 // `in` check used to prevent JIT error (gh-2145)
541 // hasOwn isn't used here due to false negatives
542 // regarding Nodelist length in IE
543 var length = !!obj && "length" in obj && obj.length,
544 type = jQuery.type( obj );
545
546 if ( type === "function" || jQuery.isWindow( obj ) ) {
547 return false;
548 }
549
550 return type === "array" || length === 0 ||
551 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
552}
553var Sizzle =
554/*!
555 * Sizzle CSS Selector Engine v2.3.3
556 * https://sizzlejs.com/
557 *
558 * Copyright jQuery Foundation and other contributors
559 * Released under the MIT license
560 * http://jquery.org/license
561 *
562 * Date: 2016-08-08
563 */
564(function( window ) {
565
566var i,
567 support,
568 Expr,
569 getText,
570 isXML,
571 tokenize,
572 compile,
573 select,
574 outermostContext,
575 sortInput,
576 hasDuplicate,
577
578 // Local document vars
579 setDocument,
580 document,
581 docElem,
582 documentIsHTML,
583 rbuggyQSA,
584 rbuggyMatches,
585 matches,
586 contains,
587
588 // Instance-specific data
589 expando = "sizzle" + 1 * new Date(),
590 preferredDoc = window.document,
591 dirruns = 0,
592 done = 0,
593 classCache = createCache(),
594 tokenCache = createCache(),
595 compilerCache = createCache(),
596 sortOrder = function( a, b ) {
597 if ( a === b ) {
598 hasDuplicate = true;
599 }
600 return 0;
601 },
602
603 // Instance methods
604 hasOwn = ({}).hasOwnProperty,
605 arr = [],
606 pop = arr.pop,
607 push_native = arr.push,
608 push = arr.push,
609 slice = arr.slice,
610 // Use a stripped-down indexOf as it's faster than native
611 // https://jsperf.com/thor-indexof-vs-for/5
612 indexOf = function( list, elem ) {
613 var i = 0,
614 len = list.length;
615 for ( ; i < len; i++ ) {
616 if ( list[i] === elem ) {
617 return i;
618 }
619 }
620 return -1;
621 },
622
623 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
624
625 // Regular expressions
626
627 // http://www.w3.org/TR/css3-selectors/#whitespace
628 whitespace = "[\\x20\\t\\r\\n\\f]",
629
630 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
631 identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
632
633 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
634 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
635 // Operator (capture 2)
636 "*([*^$|!~]?=)" + whitespace +
637 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
638 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
639 "*\\]",
640
641 pseudos = ":(" + identifier + ")(?:\\((" +
642 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
643 // 1. quoted (capture 3; capture 4 or capture 5)
644 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
645 // 2. simple (capture 6)
646 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
647 // 3. anything else (capture 2)
648 ".*" +
649 ")\\)|)",
650
651 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
652 rwhitespace = new RegExp( whitespace + "+", "g" ),
653 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
654
655 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
656 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
657
658 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
659
660 rpseudo = new RegExp( pseudos ),
661 ridentifier = new RegExp( "^" + identifier + "$" ),
662
663 matchExpr = {
664 "ID": new RegExp( "^#(" + identifier + ")" ),
665 "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
666 "TAG": new RegExp( "^(" + identifier + "|[*])" ),
667 "ATTR": new RegExp( "^" + attributes ),
668 "PSEUDO": new RegExp( "^" + pseudos ),
669 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
670 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
671 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
672 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
673 // For use in libraries implementing .is()
674 // We use this for POS matching in `select`
675 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
676 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
677 },
678
679 rinputs = /^(?:input|select|textarea|button)$/i,
680 rheader = /^h\d$/i,
681
682 rnative = /^[^{]+\{\s*\[native \w/,
683
684 // Easily-parseable/retrievable ID or TAG or CLASS selectors
685 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
686
687 rsibling = /[+~]/,
688
689 // CSS escapes
690 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
691 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
692 funescape = function( _, escaped, escapedWhitespace ) {
693 var high = "0x" + escaped - 0x10000;
694 // NaN means non-codepoint
695 // Support: Firefox<24
696 // Workaround erroneous numeric interpretation of +"0x"
697 return high !== high || escapedWhitespace ?
698 escaped :
699 high < 0 ?
700 // BMP codepoint
701 String.fromCharCode( high + 0x10000 ) :
702 // Supplemental Plane codepoint (surrogate pair)
703 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
704 },
705
706 // CSS string/identifier serialization
707 // https://drafts.csswg.org/cssom/#common-serializing-idioms
708 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
709 fcssescape = function( ch, asCodePoint ) {
710 if ( asCodePoint ) {
711
712 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
713 if ( ch === "\0" ) {
714 return "\uFFFD";
715 }
716
717 // Control characters and (dependent upon position) numbers get escaped as code points
718 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
719 }
720
721 // Other potentially-special ASCII characters get backslash-escaped
722 return "\\" + ch;
723 },
724
725 // Used for iframes
726 // See setDocument()
727 // Removing the function wrapper causes a "Permission Denied"
728 // error in IE
729 unloadHandler = function() {
730 setDocument();
731 },
732
733 disabledAncestor = addCombinator(
734 function( elem ) {
735 return elem.disabled === true && ("form" in elem || "label" in elem);
736 },
737 { dir: "parentNode", next: "legend" }
738 );
739
740// Optimize for push.apply( _, NodeList )
741try {
742 push.apply(
743 (arr = slice.call( preferredDoc.childNodes )),
744 preferredDoc.childNodes
745 );
746 // Support: Android<4.0
747 // Detect silently failing push.apply
748 arr[ preferredDoc.childNodes.length ].nodeType;
749} catch ( e ) {
750 push = { apply: arr.length ?
751
752 // Leverage slice if possible
753 function( target, els ) {
754 push_native.apply( target, slice.call(els) );
755 } :
756
757 // Support: IE<9
758 // Otherwise append directly
759 function( target, els ) {
760 var j = target.length,
761 i = 0;
762 // Can't trust NodeList.length
763 while ( (target[j++] = els[i++]) ) {}
764 target.length = j - 1;
765 }
766 };
767}
768
769function Sizzle( selector, context, results, seed ) {
770 var m, i, elem, nid, match, groups, newSelector,
771 newContext = context && context.ownerDocument,
772
773 // nodeType defaults to 9, since context defaults to document
774 nodeType = context ? context.nodeType : 9;
775
776 results = results || [];
777
778 // Return early from calls with invalid selector or context
779 if ( typeof selector !== "string" || !selector ||
780 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
781
782 return results;
783 }
784
785 // Try to shortcut find operations (as opposed to filters) in HTML documents
786 if ( !seed ) {
787
788 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
789 setDocument( context );
790 }
791 context = context || document;
792
793 if ( documentIsHTML ) {
794
795 // If the selector is sufficiently simple, try using a "get*By*" DOM method
796 // (excepting DocumentFragment context, where the methods don't exist)
797 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
798
799 // ID selector
800 if ( (m = match[1]) ) {
801
802 // Document context
803 if ( nodeType === 9 ) {
804 if ( (elem = context.getElementById( m )) ) {
805
806 // Support: IE, Opera, Webkit
807 // TODO: identify versions
808 // getElementById can match elements by name instead of ID
809 if ( elem.id === m ) {
810 results.push( elem );
811 return results;
812 }
813 } else {
814 return results;
815 }
816
817 // Element context
818 } else {
819
820 // Support: IE, Opera, Webkit
821 // TODO: identify versions
822 // getElementById can match elements by name instead of ID
823 if ( newContext && (elem = newContext.getElementById( m )) &&
824 contains( context, elem ) &&
825 elem.id === m ) {
826
827 results.push( elem );
828 return results;
829 }
830 }
831
832 // Type selector
833 } else if ( match[2] ) {
834 push.apply( results, context.getElementsByTagName( selector ) );
835 return results;
836
837 // Class selector
838 } else if ( (m = match[3]) && support.getElementsByClassName &&
839 context.getElementsByClassName ) {
840
841 push.apply( results, context.getElementsByClassName( m ) );
842 return results;
843 }
844 }
845
846 // Take advantage of querySelectorAll
847 if ( support.qsa &&
848 !compilerCache[ selector + " " ] &&
849 (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
850
851 if ( nodeType !== 1 ) {
852 newContext = context;
853 newSelector = selector;
854
855 // qSA looks outside Element context, which is not what we want
856 // Thanks to Andrew Dupont for this workaround technique
857 // Support: IE <=8
858 // Exclude object elements
859 } else if ( context.nodeName.toLowerCase() !== "object" ) {
860
861 // Capture the context ID, setting it first if necessary
862 if ( (nid = context.getAttribute( "id" )) ) {
863 nid = nid.replace( rcssescape, fcssescape );
864 } else {
865 context.setAttribute( "id", (nid = expando) );
866 }
867
868 // Prefix every selector in the list
869 groups = tokenize( selector );
870 i = groups.length;
871 while ( i-- ) {
872 groups[i] = "#" + nid + " " + toSelector( groups[i] );
873 }
874 newSelector = groups.join( "," );
875
876 // Expand context for sibling selectors
877 newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
878 context;
879 }
880
881 if ( newSelector ) {
882 try {
883 push.apply( results,
884 newContext.querySelectorAll( newSelector )
885 );
886 return results;
887 } catch ( qsaError ) {
888 } finally {
889 if ( nid === expando ) {
890 context.removeAttribute( "id" );
891 }
892 }
893 }
894 }
895 }
896 }
897
898 // All others
899 return select( selector.replace( rtrim, "$1" ), context, results, seed );
900}
901
902/**
903 * Create key-value caches of limited size
904 * @returns {function(string, object)} Returns the Object data after storing it on itself with
905 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
906 * deleting the oldest entry
907 */
908function createCache() {
909 var keys = [];
910
911 function cache( key, value ) {
912 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
913 if ( keys.push( key + " " ) > Expr.cacheLength ) {
914 // Only keep the most recent entries
915 delete cache[ keys.shift() ];
916 }
917 return (cache[ key + " " ] = value);
918 }
919 return cache;
920}
921
922/**
923 * Mark a function for special use by Sizzle
924 * @param {Function} fn The function to mark
925 */
926function markFunction( fn ) {
927 fn[ expando ] = true;
928 return fn;
929}
930
931/**
932 * Support testing using an element
933 * @param {Function} fn Passed the created element and returns a boolean result
934 */
935function assert( fn ) {
936 var el = document.createElement("fieldset");
937
938 try {
939 return !!fn( el );
940 } catch (e) {
941 return false;
942 } finally {
943 // Remove from its parent by default
944 if ( el.parentNode ) {
945 el.parentNode.removeChild( el );
946 }
947 // release memory in IE
948 el = null;
949 }
950}
951
952/**
953 * Adds the same handler for all of the specified attrs
954 * @param {String} attrs Pipe-separated list of attributes
955 * @param {Function} handler The method that will be applied
956 */
957function addHandle( attrs, handler ) {
958 var arr = attrs.split("|"),
959 i = arr.length;
960
961 while ( i-- ) {
962 Expr.attrHandle[ arr[i] ] = handler;
963 }
964}
965
966/**
967 * Checks document order of two siblings
968 * @param {Element} a
969 * @param {Element} b
970 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
971 */
972function siblingCheck( a, b ) {
973 var cur = b && a,
974 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
975 a.sourceIndex - b.sourceIndex;
976
977 // Use IE sourceIndex if available on both nodes
978 if ( diff ) {
979 return diff;
980 }
981
982 // Check if b follows a
983 if ( cur ) {
984 while ( (cur = cur.nextSibling) ) {
985 if ( cur === b ) {
986 return -1;
987 }
988 }
989 }
990
991 return a ? 1 : -1;
992}
993
994/**
995 * Returns a function to use in pseudos for input types
996 * @param {String} type
997 */
998function createInputPseudo( type ) {
999 return function( elem ) {
1000 var name = elem.nodeName.toLowerCase();
1001 return name === "input" && elem.type === type;
1002 };
1003}
1004
1005/**
1006 * Returns a function to use in pseudos for buttons
1007 * @param {String} type
1008 */
1009function createButtonPseudo( type ) {
1010 return function( elem ) {
1011 var name = elem.nodeName.toLowerCase();
1012 return (name === "input" || name === "button") && elem.type === type;
1013 };
1014}
1015
1016/**
1017 * Returns a function to use in pseudos for :enabled/:disabled
1018 * @param {Boolean} disabled true for :disabled; false for :enabled
1019 */
1020function createDisabledPseudo( disabled ) {
1021
1022 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1023 return function( elem ) {
1024
1025 // Only certain elements can match :enabled or :disabled
1026 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1027 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1028 if ( "form" in elem ) {
1029
1030 // Check for inherited disabledness on relevant non-disabled elements:
1031 // * listed form-associated elements in a disabled fieldset
1032 // https://html.spec.whatwg.org/multipage/forms.html#category-listed
1033 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1034 // * option elements in a disabled optgroup
1035 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1036 // All such elements have a "form" property.
1037 if ( elem.parentNode && elem.disabled === false ) {
1038
1039 // Option elements defer to a parent optgroup if present
1040 if ( "label" in elem ) {
1041 if ( "label" in elem.parentNode ) {
1042 return elem.parentNode.disabled === disabled;
1043 } else {
1044 return elem.disabled === disabled;
1045 }
1046 }
1047
1048 // Support: IE 6 - 11
1049 // Use the isDisabled shortcut property to check for disabled fieldset ancestors
1050 return elem.isDisabled === disabled ||
1051
1052 // Where there is no isDisabled, check manually
1053 /* jshint -W018 */
1054 elem.isDisabled !== !disabled &&
1055 disabledAncestor( elem ) === disabled;
1056 }
1057
1058 return elem.disabled === disabled;
1059
1060 // Try to winnow out elements that can't be disabled before trusting the disabled property.
1061 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1062 // even exist on them, let alone have a boolean value.
1063 } else if ( "label" in elem ) {
1064 return elem.disabled === disabled;
1065 }
1066
1067 // Remaining elements are neither :enabled nor :disabled
1068 return false;
1069 };
1070}
1071
1072/**
1073 * Returns a function to use in pseudos for positionals
1074 * @param {Function} fn
1075 */
1076function createPositionalPseudo( fn ) {
1077 return markFunction(function( argument ) {
1078 argument = +argument;
1079 return markFunction(function( seed, matches ) {
1080 var j,
1081 matchIndexes = fn( [], seed.length, argument ),
1082 i = matchIndexes.length;
1083
1084 // Match elements found at the specified indexes
1085 while ( i-- ) {
1086 if ( seed[ (j = matchIndexes[i]) ] ) {
1087 seed[j] = !(matches[j] = seed[j]);
1088 }
1089 }
1090 });
1091 });
1092}
1093
1094/**
1095 * Checks a node for validity as a Sizzle context
1096 * @param {Element|Object=} context
1097 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1098 */
1099function testContext( context ) {
1100 return context && typeof context.getElementsByTagName !== "undefined" && context;
1101}
1102
1103// Expose support vars for convenience
1104support = Sizzle.support = {};
1105
1106/**
1107 * Detects XML nodes
1108 * @param {Element|Object} elem An element or a document
1109 * @returns {Boolean} True iff elem is a non-HTML XML node
1110 */
1111isXML = Sizzle.isXML = function( elem ) {
1112 // documentElement is verified for cases where it doesn't yet exist
1113 // (such as loading iframes in IE - #4833)
1114 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1115 return documentElement ? documentElement.nodeName !== "HTML" : false;
1116};
1117
1118/**
1119 * Sets document-related variables once based on the current document
1120 * @param {Element|Object} [doc] An element or document object to use to set the document
1121 * @returns {Object} Returns the current document
1122 */
1123setDocument = Sizzle.setDocument = function( node ) {
1124 var hasCompare, subWindow,
1125 doc = node ? node.ownerDocument || node : preferredDoc;
1126
1127 // Return early if doc is invalid or already selected
1128 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1129 return document;
1130 }
1131
1132 // Update global variables
1133 document = doc;
1134 docElem = document.documentElement;
1135 documentIsHTML = !isXML( document );
1136
1137 // Support: IE 9-11, Edge
1138 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1139 if ( preferredDoc !== document &&
1140 (subWindow = document.defaultView) && subWindow.top !== subWindow ) {
1141
1142 // Support: IE 11, Edge
1143 if ( subWindow.addEventListener ) {
1144 subWindow.addEventListener( "unload", unloadHandler, false );
1145
1146 // Support: IE 9 - 10 only
1147 } else if ( subWindow.attachEvent ) {
1148 subWindow.attachEvent( "onunload", unloadHandler );
1149 }
1150 }
1151
1152 /* Attributes
1153 ---------------------------------------------------------------------- */
1154
1155 // Support: IE<8
1156 // Verify that getAttribute really returns attributes and not properties
1157 // (excepting IE8 booleans)
1158 support.attributes = assert(function( el ) {
1159 el.className = "i";
1160 return !el.getAttribute("className");
1161 });
1162
1163 /* getElement(s)By*
1164 ---------------------------------------------------------------------- */
1165
1166 // Check if getElementsByTagName("*") returns only elements
1167 support.getElementsByTagName = assert(function( el ) {
1168 el.appendChild( document.createComment("") );
1169 return !el.getElementsByTagName("*").length;
1170 });
1171
1172 // Support: IE<9
1173 support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1174
1175 // Support: IE<10
1176 // Check if getElementById returns elements by name
1177 // The broken getElementById methods don't pick up programmatically-set names,
1178 // so use a roundabout getElementsByName test
1179 support.getById = assert(function( el ) {
1180 docElem.appendChild( el ).id = expando;
1181 return !document.getElementsByName || !document.getElementsByName( expando ).length;
1182 });
1183
1184 // ID filter and find
1185 if ( support.getById ) {
1186 Expr.filter["ID"] = function( id ) {
1187 var attrId = id.replace( runescape, funescape );
1188 return function( elem ) {
1189 return elem.getAttribute("id") === attrId;
1190 };
1191 };
1192 Expr.find["ID"] = function( id, context ) {
1193 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1194 var elem = context.getElementById( id );
1195 return elem ? [ elem ] : [];
1196 }
1197 };
1198 } else {
1199 Expr.filter["ID"] = function( id ) {
1200 var attrId = id.replace( runescape, funescape );
1201 return function( elem ) {
1202 var node = typeof elem.getAttributeNode !== "undefined" &&
1203 elem.getAttributeNode("id");
1204 return node && node.value === attrId;
1205 };
1206 };
1207
1208 // Support: IE 6 - 7 only
1209 // getElementById is not reliable as a find shortcut
1210 Expr.find["ID"] = function( id, context ) {
1211 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1212 var node, i, elems,
1213 elem = context.getElementById( id );
1214
1215 if ( elem ) {
1216
1217 // Verify the id attribute
1218 node = elem.getAttributeNode("id");
1219 if ( node && node.value === id ) {
1220 return [ elem ];
1221 }
1222
1223 // Fall back on getElementsByName
1224 elems = context.getElementsByName( id );
1225 i = 0;
1226 while ( (elem = elems[i++]) ) {
1227 node = elem.getAttributeNode("id");
1228 if ( node && node.value === id ) {
1229 return [ elem ];
1230 }
1231 }
1232 }
1233
1234 return [];
1235 }
1236 };
1237 }
1238
1239 // Tag
1240 Expr.find["TAG"] = support.getElementsByTagName ?
1241 function( tag, context ) {
1242 if ( typeof context.getElementsByTagName !== "undefined" ) {
1243 return context.getElementsByTagName( tag );
1244
1245 // DocumentFragment nodes don't have gEBTN
1246 } else if ( support.qsa ) {
1247 return context.querySelectorAll( tag );
1248 }
1249 } :
1250
1251 function( tag, context ) {
1252 var elem,
1253 tmp = [],
1254 i = 0,
1255 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1256 results = context.getElementsByTagName( tag );
1257
1258 // Filter out possible comments
1259 if ( tag === "*" ) {
1260 while ( (elem = results[i++]) ) {
1261 if ( elem.nodeType === 1 ) {
1262 tmp.push( elem );
1263 }
1264 }
1265
1266 return tmp;
1267 }
1268 return results;
1269 };
1270
1271 // Class
1272 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1273 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1274 return context.getElementsByClassName( className );
1275 }
1276 };
1277
1278 /* QSA/matchesSelector
1279 ---------------------------------------------------------------------- */
1280
1281 // QSA and matchesSelector support
1282
1283 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1284 rbuggyMatches = [];
1285
1286 // qSa(:focus) reports false when true (Chrome 21)
1287 // We allow this because of a bug in IE8/9 that throws an error
1288 // whenever `document.activeElement` is accessed on an iframe
1289 // So, we allow :focus to pass through QSA all the time to avoid the IE error
1290 // See https://bugs.jquery.com/ticket/13378
1291 rbuggyQSA = [];
1292
1293 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1294 // Build QSA regex
1295 // Regex strategy adopted from Diego Perini
1296 assert(function( el ) {
1297 // Select is set to empty string on purpose
1298 // This is to test IE's treatment of not explicitly
1299 // setting a boolean content attribute,
1300 // since its presence should be enough
1301 // https://bugs.jquery.com/ticket/12359
1302 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
1303 "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1304 "<option selected=''></option></select>";
1305
1306 // Support: IE8, Opera 11-12.16
1307 // Nothing should be selected when empty strings follow ^= or $= or *=
1308 // The test attribute must be unknown in Opera but "safe" for WinRT
1309 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1310 if ( el.querySelectorAll("[msallowcapture^='']").length ) {
1311 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1312 }
1313
1314 // Support: IE8
1315 // Boolean attributes and "value" are not treated correctly
1316 if ( !el.querySelectorAll("[selected]").length ) {
1317 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1318 }
1319
1320 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1321 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1322 rbuggyQSA.push("~=");
1323 }
1324
1325 // Webkit/Opera - :checked should return selected option elements
1326 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1327 // IE8 throws error here and will not see later tests
1328 if ( !el.querySelectorAll(":checked").length ) {
1329 rbuggyQSA.push(":checked");
1330 }
1331
1332 // Support: Safari 8+, iOS 8+
1333 // https://bugs.webkit.org/show_bug.cgi?id=136851
1334 // In-page `selector#id sibling-combinator selector` fails
1335 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
1336 rbuggyQSA.push(".#.+[+~]");
1337 }
1338 });
1339
1340 assert(function( el ) {
1341 el.innerHTML = "<a href='' disabled='disabled'></a>" +
1342 "<select disabled='disabled'><option/></select>";
1343
1344 // Support: Windows 8 Native Apps
1345 // The type and name attributes are restricted during .innerHTML assignment
1346 var input = document.createElement("input");
1347 input.setAttribute( "type", "hidden" );
1348 el.appendChild( input ).setAttribute( "name", "D" );
1349
1350 // Support: IE8
1351 // Enforce case-sensitivity of name attribute
1352 if ( el.querySelectorAll("[name=d]").length ) {
1353 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1354 }
1355
1356 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1357 // IE8 throws error here and will not see later tests
1358 if ( el.querySelectorAll(":enabled").length !== 2 ) {
1359 rbuggyQSA.push( ":enabled", ":disabled" );
1360 }
1361
1362 // Support: IE9-11+
1363 // IE's :disabled selector does not pick up the children of disabled fieldsets
1364 docElem.appendChild( el ).disabled = true;
1365 if ( el.querySelectorAll(":disabled").length !== 2 ) {
1366 rbuggyQSA.push( ":enabled", ":disabled" );
1367 }
1368
1369 // Opera 10-11 does not throw on post-comma invalid pseudos
1370 el.querySelectorAll("*,:x");
1371 rbuggyQSA.push(",.*:");
1372 });
1373 }
1374
1375 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1376 docElem.webkitMatchesSelector ||
1377 docElem.mozMatchesSelector ||
1378 docElem.oMatchesSelector ||
1379 docElem.msMatchesSelector) )) ) {
1380
1381 assert(function( el ) {
1382 // Check to see if it's possible to do matchesSelector
1383 // on a disconnected node (IE 9)
1384 support.disconnectedMatch = matches.call( el, "*" );
1385
1386 // This should fail with an exception
1387 // Gecko does not error, returns false instead
1388 matches.call( el, "[s!='']:x" );
1389 rbuggyMatches.push( "!=", pseudos );
1390 });
1391 }
1392
1393 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1394 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1395
1396 /* Contains
1397 ---------------------------------------------------------------------- */
1398 hasCompare = rnative.test( docElem.compareDocumentPosition );
1399
1400 // Element contains another
1401 // Purposefully self-exclusive
1402 // As in, an element does not contain itself
1403 contains = hasCompare || rnative.test( docElem.contains ) ?
1404 function( a, b ) {
1405 var adown = a.nodeType === 9 ? a.documentElement : a,
1406 bup = b && b.parentNode;
1407 return a === bup || !!( bup && bup.nodeType === 1 && (
1408 adown.contains ?
1409 adown.contains( bup ) :
1410 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1411 ));
1412 } :
1413 function( a, b ) {
1414 if ( b ) {
1415 while ( (b = b.parentNode) ) {
1416 if ( b === a ) {
1417 return true;
1418 }
1419 }
1420 }
1421 return false;
1422 };
1423
1424 /* Sorting
1425 ---------------------------------------------------------------------- */
1426
1427 // Document order sorting
1428 sortOrder = hasCompare ?
1429 function( a, b ) {
1430
1431 // Flag for duplicate removal
1432 if ( a === b ) {
1433 hasDuplicate = true;
1434 return 0;
1435 }
1436
1437 // Sort on method existence if only one input has compareDocumentPosition
1438 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1439 if ( compare ) {
1440 return compare;
1441 }
1442
1443 // Calculate position if both inputs belong to the same document
1444 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1445 a.compareDocumentPosition( b ) :
1446
1447 // Otherwise we know they are disconnected
1448 1;
1449
1450 // Disconnected nodes
1451 if ( compare & 1 ||
1452 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1453
1454 // Choose the first element that is related to our preferred document
1455 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1456 return -1;
1457 }
1458 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1459 return 1;
1460 }
1461
1462 // Maintain original order
1463 return sortInput ?
1464 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1465 0;
1466 }
1467
1468 return compare & 4 ? -1 : 1;
1469 } :
1470 function( a, b ) {
1471 // Exit early if the nodes are identical
1472 if ( a === b ) {
1473 hasDuplicate = true;
1474 return 0;
1475 }
1476
1477 var cur,
1478 i = 0,
1479 aup = a.parentNode,
1480 bup = b.parentNode,
1481 ap = [ a ],
1482 bp = [ b ];
1483
1484 // Parentless nodes are either documents or disconnected
1485 if ( !aup || !bup ) {
1486 return a === document ? -1 :
1487 b === document ? 1 :
1488 aup ? -1 :
1489 bup ? 1 :
1490 sortInput ?
1491 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1492 0;
1493
1494 // If the nodes are siblings, we can do a quick check
1495 } else if ( aup === bup ) {
1496 return siblingCheck( a, b );
1497 }
1498
1499 // Otherwise we need full lists of their ancestors for comparison
1500 cur = a;
1501 while ( (cur = cur.parentNode) ) {
1502 ap.unshift( cur );
1503 }
1504 cur = b;
1505 while ( (cur = cur.parentNode) ) {
1506 bp.unshift( cur );
1507 }
1508
1509 // Walk down the tree looking for a discrepancy
1510 while ( ap[i] === bp[i] ) {
1511 i++;
1512 }
1513
1514 return i ?
1515 // Do a sibling check if the nodes have a common ancestor
1516 siblingCheck( ap[i], bp[i] ) :
1517
1518 // Otherwise nodes in our document sort first
1519 ap[i] === preferredDoc ? -1 :
1520 bp[i] === preferredDoc ? 1 :
1521 0;
1522 };
1523
1524 return document;
1525};
1526
1527Sizzle.matches = function( expr, elements ) {
1528 return Sizzle( expr, null, null, elements );
1529};
1530
1531Sizzle.matchesSelector = function( elem, expr ) {
1532 // Set document vars if needed
1533 if ( ( elem.ownerDocument || elem ) !== document ) {
1534 setDocument( elem );
1535 }
1536
1537 // Make sure that attribute selectors are quoted
1538 expr = expr.replace( rattributeQuotes, "='$1']" );
1539
1540 if ( support.matchesSelector && documentIsHTML &&
1541 !compilerCache[ expr + " " ] &&
1542 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1543 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1544
1545 try {
1546 var ret = matches.call( elem, expr );
1547
1548 // IE 9's matchesSelector returns false on disconnected nodes
1549 if ( ret || support.disconnectedMatch ||
1550 // As well, disconnected nodes are said to be in a document
1551 // fragment in IE 9
1552 elem.document && elem.document.nodeType !== 11 ) {
1553 return ret;
1554 }
1555 } catch (e) {}
1556 }
1557
1558 return Sizzle( expr, document, null, [ elem ] ).length > 0;
1559};
1560
1561Sizzle.contains = function( context, elem ) {
1562 // Set document vars if needed
1563 if ( ( context.ownerDocument || context ) !== document ) {
1564 setDocument( context );
1565 }
1566 return contains( context, elem );
1567};
1568
1569Sizzle.attr = function( elem, name ) {
1570 // Set document vars if needed
1571 if ( ( elem.ownerDocument || elem ) !== document ) {
1572 setDocument( elem );
1573 }
1574
1575 var fn = Expr.attrHandle[ name.toLowerCase() ],
1576 // Don't get fooled by Object.prototype properties (jQuery #13807)
1577 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1578 fn( elem, name, !documentIsHTML ) :
1579 undefined;
1580
1581 return val !== undefined ?
1582 val :
1583 support.attributes || !documentIsHTML ?
1584 elem.getAttribute( name ) :
1585 (val = elem.getAttributeNode(name)) && val.specified ?
1586 val.value :
1587 null;
1588};
1589
1590Sizzle.escape = function( sel ) {
1591 return (sel + "").replace( rcssescape, fcssescape );
1592};
1593
1594Sizzle.error = function( msg ) {
1595 throw new Error( "Syntax error, unrecognized expression: " + msg );
1596};
1597
1598/**
1599 * Document sorting and removing duplicates
1600 * @param {ArrayLike} results
1601 */
1602Sizzle.uniqueSort = function( results ) {
1603 var elem,
1604 duplicates = [],
1605 j = 0,
1606 i = 0;
1607
1608 // Unless we *know* we can detect duplicates, assume their presence
1609 hasDuplicate = !support.detectDuplicates;
1610 sortInput = !support.sortStable && results.slice( 0 );
1611 results.sort( sortOrder );
1612
1613 if ( hasDuplicate ) {
1614 while ( (elem = results[i++]) ) {
1615 if ( elem === results[ i ] ) {
1616 j = duplicates.push( i );
1617 }
1618 }
1619 while ( j-- ) {
1620 results.splice( duplicates[ j ], 1 );
1621 }
1622 }
1623
1624 // Clear input after sorting to release objects
1625 // See https://github.com/jquery/sizzle/pull/225
1626 sortInput = null;
1627
1628 return results;
1629};
1630
1631/**
1632 * Utility function for retrieving the text value of an array of DOM nodes
1633 * @param {Array|Element} elem
1634 */
1635getText = Sizzle.getText = function( elem ) {
1636 var node,
1637 ret = "",
1638 i = 0,
1639 nodeType = elem.nodeType;
1640
1641 if ( !nodeType ) {
1642 // If no nodeType, this is expected to be an array
1643 while ( (node = elem[i++]) ) {
1644 // Do not traverse comment nodes
1645 ret += getText( node );
1646 }
1647 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1648 // Use textContent for elements
1649 // innerText usage removed for consistency of new lines (jQuery #11153)
1650 if ( typeof elem.textContent === "string" ) {
1651 return elem.textContent;
1652 } else {
1653 // Traverse its children
1654 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1655 ret += getText( elem );
1656 }
1657 }
1658 } else if ( nodeType === 3 || nodeType === 4 ) {
1659 return elem.nodeValue;
1660 }
1661 // Do not include comment or processing instruction nodes
1662
1663 return ret;
1664};
1665
1666Expr = Sizzle.selectors = {
1667
1668 // Can be adjusted by the user
1669 cacheLength: 50,
1670
1671 createPseudo: markFunction,
1672
1673 match: matchExpr,
1674
1675 attrHandle: {},
1676
1677 find: {},
1678
1679 relative: {
1680 ">": { dir: "parentNode", first: true },
1681 " ": { dir: "parentNode" },
1682 "+": { dir: "previousSibling", first: true },
1683 "~": { dir: "previousSibling" }
1684 },
1685
1686 preFilter: {
1687 "ATTR": function( match ) {
1688 match[1] = match[1].replace( runescape, funescape );
1689
1690 // Move the given value to match[3] whether quoted or unquoted
1691 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1692
1693 if ( match[2] === "~=" ) {
1694 match[3] = " " + match[3] + " ";
1695 }
1696
1697 return match.slice( 0, 4 );
1698 },
1699
1700 "CHILD": function( match ) {
1701 /* matches from matchExpr["CHILD"]
1702 1 type (only|nth|...)
1703 2 what (child|of-type)
1704 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1705 4 xn-component of xn+y argument ([+-]?\d*n|)
1706 5 sign of xn-component
1707 6 x of xn-component
1708 7 sign of y-component
1709 8 y of y-component
1710 */
1711 match[1] = match[1].toLowerCase();
1712
1713 if ( match[1].slice( 0, 3 ) === "nth" ) {
1714 // nth-* requires argument
1715 if ( !match[3] ) {
1716 Sizzle.error( match[0] );
1717 }
1718
1719 // numeric x and y parameters for Expr.filter.CHILD
1720 // remember that false/true cast respectively to 0/1
1721 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1722 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1723
1724 // other types prohibit arguments
1725 } else if ( match[3] ) {
1726 Sizzle.error( match[0] );
1727 }
1728
1729 return match;
1730 },
1731
1732 "PSEUDO": function( match ) {
1733 var excess,
1734 unquoted = !match[6] && match[2];
1735
1736 if ( matchExpr["CHILD"].test( match[0] ) ) {
1737 return null;
1738 }
1739
1740 // Accept quoted arguments as-is
1741 if ( match[3] ) {
1742 match[2] = match[4] || match[5] || "";
1743
1744 // Strip excess characters from unquoted arguments
1745 } else if ( unquoted && rpseudo.test( unquoted ) &&
1746 // Get excess from tokenize (recursively)
1747 (excess = tokenize( unquoted, true )) &&
1748 // advance to the next closing parenthesis
1749 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1750
1751 // excess is a negative index
1752 match[0] = match[0].slice( 0, excess );
1753 match[2] = unquoted.slice( 0, excess );
1754 }
1755
1756 // Return only captures needed by the pseudo filter method (type and argument)
1757 return match.slice( 0, 3 );
1758 }
1759 },
1760
1761 filter: {
1762
1763 "TAG": function( nodeNameSelector ) {
1764 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1765 return nodeNameSelector === "*" ?
1766 function() { return true; } :
1767 function( elem ) {
1768 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1769 };
1770 },
1771
1772 "CLASS": function( className ) {
1773 var pattern = classCache[ className + " " ];
1774
1775 return pattern ||
1776 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1777 classCache( className, function( elem ) {
1778 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1779 });
1780 },
1781
1782 "ATTR": function( name, operator, check ) {
1783 return function( elem ) {
1784 var result = Sizzle.attr( elem, name );
1785
1786 if ( result == null ) {
1787 return operator === "!=";
1788 }
1789 if ( !operator ) {
1790 return true;
1791 }
1792
1793 result += "";
1794
1795 return operator === "=" ? result === check :
1796 operator === "!=" ? result !== check :
1797 operator === "^=" ? check && result.indexOf( check ) === 0 :
1798 operator === "*=" ? check && result.indexOf( check ) > -1 :
1799 operator === "$=" ? check && result.slice( -check.length ) === check :
1800 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1801 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1802 false;
1803 };
1804 },
1805
1806 "CHILD": function( type, what, argument, first, last ) {
1807 var simple = type.slice( 0, 3 ) !== "nth",
1808 forward = type.slice( -4 ) !== "last",
1809 ofType = what === "of-type";
1810
1811 return first === 1 && last === 0 ?
1812
1813 // Shortcut for :nth-*(n)
1814 function( elem ) {
1815 return !!elem.parentNode;
1816 } :
1817
1818 function( elem, context, xml ) {
1819 var cache, uniqueCache, outerCache, node, nodeIndex, start,
1820 dir = simple !== forward ? "nextSibling" : "previousSibling",
1821 parent = elem.parentNode,
1822 name = ofType && elem.nodeName.toLowerCase(),
1823 useCache = !xml && !ofType,
1824 diff = false;
1825
1826 if ( parent ) {
1827
1828 // :(first|last|only)-(child|of-type)
1829 if ( simple ) {
1830 while ( dir ) {
1831 node = elem;
1832 while ( (node = node[ dir ]) ) {
1833 if ( ofType ?
1834 node.nodeName.toLowerCase() === name :
1835 node.nodeType === 1 ) {
1836
1837 return false;
1838 }
1839 }
1840 // Reverse direction for :only-* (if we haven't yet done so)
1841 start = dir = type === "only" && !start && "nextSibling";
1842 }
1843 return true;
1844 }
1845
1846 start = [ forward ? parent.firstChild : parent.lastChild ];
1847
1848 // non-xml :nth-child(...) stores cache data on `parent`
1849 if ( forward && useCache ) {
1850
1851 // Seek `elem` from a previously-cached index
1852
1853 // ...in a gzip-friendly way
1854 node = parent;
1855 outerCache = node[ expando ] || (node[ expando ] = {});
1856
1857 // Support: IE <9 only
1858 // Defend against cloned attroperties (jQuery gh-1709)
1859 uniqueCache = outerCache[ node.uniqueID ] ||
1860 (outerCache[ node.uniqueID ] = {});
1861
1862 cache = uniqueCache[ type ] || [];
1863 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1864 diff = nodeIndex && cache[ 2 ];
1865 node = nodeIndex && parent.childNodes[ nodeIndex ];
1866
1867 while ( (node = ++nodeIndex && node && node[ dir ] ||
1868
1869 // Fallback to seeking `elem` from the start
1870 (diff = nodeIndex = 0) || start.pop()) ) {
1871
1872 // When found, cache indexes on `parent` and break
1873 if ( node.nodeType === 1 && ++diff && node === elem ) {
1874 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1875 break;
1876 }
1877 }
1878
1879 } else {
1880 // Use previously-cached element index if available
1881 if ( useCache ) {
1882 // ...in a gzip-friendly way
1883 node = elem;
1884 outerCache = node[ expando ] || (node[ expando ] = {});
1885
1886 // Support: IE <9 only
1887 // Defend against cloned attroperties (jQuery gh-1709)
1888 uniqueCache = outerCache[ node.uniqueID ] ||
1889 (outerCache[ node.uniqueID ] = {});
1890
1891 cache = uniqueCache[ type ] || [];
1892 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1893 diff = nodeIndex;
1894 }
1895
1896 // xml :nth-child(...)
1897 // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1898 if ( diff === false ) {
1899 // Use the same loop as above to seek `elem` from the start
1900 while ( (node = ++nodeIndex && node && node[ dir ] ||
1901 (diff = nodeIndex = 0) || start.pop()) ) {
1902
1903 if ( ( ofType ?
1904 node.nodeName.toLowerCase() === name :
1905 node.nodeType === 1 ) &&
1906 ++diff ) {
1907
1908 // Cache the index of each encountered element
1909 if ( useCache ) {
1910 outerCache = node[ expando ] || (node[ expando ] = {});
1911
1912 // Support: IE <9 only
1913 // Defend against cloned attroperties (jQuery gh-1709)
1914 uniqueCache = outerCache[ node.uniqueID ] ||
1915 (outerCache[ node.uniqueID ] = {});
1916
1917 uniqueCache[ type ] = [ dirruns, diff ];
1918 }
1919
1920 if ( node === elem ) {
1921 break;
1922 }
1923 }
1924 }
1925 }
1926 }
1927
1928 // Incorporate the offset, then check against cycle size
1929 diff -= last;
1930 return diff === first || ( diff % first === 0 && diff / first >= 0 );
1931 }
1932 };
1933 },
1934
1935 "PSEUDO": function( pseudo, argument ) {
1936 // pseudo-class names are case-insensitive
1937 // http://www.w3.org/TR/selectors/#pseudo-classes
1938 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1939 // Remember that setFilters inherits from pseudos
1940 var args,
1941 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1942 Sizzle.error( "unsupported pseudo: " + pseudo );
1943
1944 // The user may use createPseudo to indicate that
1945 // arguments are needed to create the filter function
1946 // just as Sizzle does
1947 if ( fn[ expando ] ) {
1948 return fn( argument );
1949 }
1950
1951 // But maintain support for old signatures
1952 if ( fn.length > 1 ) {
1953 args = [ pseudo, pseudo, "", argument ];
1954 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1955 markFunction(function( seed, matches ) {
1956 var idx,
1957 matched = fn( seed, argument ),
1958 i = matched.length;
1959 while ( i-- ) {
1960 idx = indexOf( seed, matched[i] );
1961 seed[ idx ] = !( matches[ idx ] = matched[i] );
1962 }
1963 }) :
1964 function( elem ) {
1965 return fn( elem, 0, args );
1966 };
1967 }
1968
1969 return fn;
1970 }
1971 },
1972
1973 pseudos: {
1974 // Potentially complex pseudos
1975 "not": markFunction(function( selector ) {
1976 // Trim the selector passed to compile
1977 // to avoid treating leading and trailing
1978 // spaces as combinators
1979 var input = [],
1980 results = [],
1981 matcher = compile( selector.replace( rtrim, "$1" ) );
1982
1983 return matcher[ expando ] ?
1984 markFunction(function( seed, matches, context, xml ) {
1985 var elem,
1986 unmatched = matcher( seed, null, xml, [] ),
1987 i = seed.length;
1988
1989 // Match elements unmatched by `matcher`
1990 while ( i-- ) {
1991 if ( (elem = unmatched[i]) ) {
1992 seed[i] = !(matches[i] = elem);
1993 }
1994 }
1995 }) :
1996 function( elem, context, xml ) {
1997 input[0] = elem;
1998 matcher( input, null, xml, results );
1999 // Don't keep the element (issue #299)
2000 input[0] = null;
2001 return !results.pop();
2002 };
2003 }),
2004
2005 "has": markFunction(function( selector ) {
2006 return function( elem ) {
2007 return Sizzle( selector, elem ).length > 0;
2008 };
2009 }),
2010
2011 "contains": markFunction(function( text ) {
2012 text = text.replace( runescape, funescape );
2013 return function( elem ) {
2014 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
2015 };
2016 }),
2017
2018 // "Whether an element is represented by a :lang() selector
2019 // is based solely on the element's language value
2020 // being equal to the identifier C,
2021 // or beginning with the identifier C immediately followed by "-".
2022 // The matching of C against the element's language value is performed case-insensitively.
2023 // The identifier C does not have to be a valid language name."
2024 // http://www.w3.org/TR/selectors/#lang-pseudo
2025 "lang": markFunction( function( lang ) {
2026 // lang value must be a valid identifier
2027 if ( !ridentifier.test(lang || "") ) {
2028 Sizzle.error( "unsupported lang: " + lang );
2029 }
2030 lang = lang.replace( runescape, funescape ).toLowerCase();
2031 return function( elem ) {
2032 var elemLang;
2033 do {
2034 if ( (elemLang = documentIsHTML ?
2035 elem.lang :
2036 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
2037
2038 elemLang = elemLang.toLowerCase();
2039 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2040 }
2041 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
2042 return false;
2043 };
2044 }),
2045
2046 // Miscellaneous
2047 "target": function( elem ) {
2048 var hash = window.location && window.location.hash;
2049 return hash && hash.slice( 1 ) === elem.id;
2050 },
2051
2052 "root": function( elem ) {
2053 return elem === docElem;
2054 },
2055
2056 "focus": function( elem ) {
2057 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
2058 },
2059
2060 // Boolean properties
2061 "enabled": createDisabledPseudo( false ),
2062 "disabled": createDisabledPseudo( true ),
2063
2064 "checked": function( elem ) {
2065 // In CSS3, :checked should return both checked and selected elements
2066 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2067 var nodeName = elem.nodeName.toLowerCase();
2068 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
2069 },
2070
2071 "selected": function( elem ) {
2072 // Accessing this property makes selected-by-default
2073 // options in Safari work properly
2074 if ( elem.parentNode ) {
2075 elem.parentNode.selectedIndex;
2076 }
2077
2078 return elem.selected === true;
2079 },
2080
2081 // Contents
2082 "empty": function( elem ) {
2083 // http://www.w3.org/TR/selectors/#empty-pseudo
2084 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2085 // but not by others (comment: 8; processing instruction: 7; etc.)
2086 // nodeType < 6 works because attributes (2) do not appear as children
2087 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2088 if ( elem.nodeType < 6 ) {
2089 return false;
2090 }
2091 }
2092 return true;
2093 },
2094
2095 "parent": function( elem ) {
2096 return !Expr.pseudos["empty"]( elem );
2097 },
2098
2099 // Element/input types
2100 "header": function( elem ) {
2101 return rheader.test( elem.nodeName );
2102 },
2103
2104 "input": function( elem ) {
2105 return rinputs.test( elem.nodeName );
2106 },
2107
2108 "button": function( elem ) {
2109 var name = elem.nodeName.toLowerCase();
2110 return name === "input" && elem.type === "button" || name === "button";
2111 },
2112
2113 "text": function( elem ) {
2114 var attr;
2115 return elem.nodeName.toLowerCase() === "input" &&
2116 elem.type === "text" &&
2117
2118 // Support: IE<8
2119 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2120 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2121 },
2122
2123 // Position-in-collection
2124 "first": createPositionalPseudo(function() {
2125 return [ 0 ];
2126 }),
2127
2128 "last": createPositionalPseudo(function( matchIndexes, length ) {
2129 return [ length - 1 ];
2130 }),
2131
2132 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2133 return [ argument < 0 ? argument + length : argument ];
2134 }),
2135
2136 "even": createPositionalPseudo(function( matchIndexes, length ) {
2137 var i = 0;
2138 for ( ; i < length; i += 2 ) {
2139 matchIndexes.push( i );
2140 }
2141 return matchIndexes;
2142 }),
2143
2144 "odd": createPositionalPseudo(function( matchIndexes, length ) {
2145 var i = 1;
2146 for ( ; i < length; i += 2 ) {
2147 matchIndexes.push( i );
2148 }
2149 return matchIndexes;
2150 }),
2151
2152 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2153 var i = argument < 0 ? argument + length : argument;
2154 for ( ; --i >= 0; ) {
2155 matchIndexes.push( i );
2156 }
2157 return matchIndexes;
2158 }),
2159
2160 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2161 var i = argument < 0 ? argument + length : argument;
2162 for ( ; ++i < length; ) {
2163 matchIndexes.push( i );
2164 }
2165 return matchIndexes;
2166 })
2167 }
2168};
2169
2170Expr.pseudos["nth"] = Expr.pseudos["eq"];
2171
2172// Add button/input type pseudos
2173for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2174 Expr.pseudos[ i ] = createInputPseudo( i );
2175}
2176for ( i in { submit: true, reset: true } ) {
2177 Expr.pseudos[ i ] = createButtonPseudo( i );
2178}
2179
2180// Easy API for creating new setFilters
2181function setFilters() {}
2182setFilters.prototype = Expr.filters = Expr.pseudos;
2183Expr.setFilters = new setFilters();
2184
2185tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2186 var matched, match, tokens, type,
2187 soFar, groups, preFilters,
2188 cached = tokenCache[ selector + " " ];
2189
2190 if ( cached ) {
2191 return parseOnly ? 0 : cached.slice( 0 );
2192 }
2193
2194 soFar = selector;
2195 groups = [];
2196 preFilters = Expr.preFilter;
2197
2198 while ( soFar ) {
2199
2200 // Comma and first run
2201 if ( !matched || (match = rcomma.exec( soFar )) ) {
2202 if ( match ) {
2203 // Don't consume trailing commas as valid
2204 soFar = soFar.slice( match[0].length ) || soFar;
2205 }
2206 groups.push( (tokens = []) );
2207 }
2208
2209 matched = false;
2210
2211 // Combinators
2212 if ( (match = rcombinators.exec( soFar )) ) {
2213 matched = match.shift();
2214 tokens.push({
2215 value: matched,
2216 // Cast descendant combinators to space
2217 type: match[0].replace( rtrim, " " )
2218 });
2219 soFar = soFar.slice( matched.length );
2220 }
2221
2222 // Filters
2223 for ( type in Expr.filter ) {
2224 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2225 (match = preFilters[ type ]( match ))) ) {
2226 matched = match.shift();
2227 tokens.push({
2228 value: matched,
2229 type: type,
2230 matches: match
2231 });
2232 soFar = soFar.slice( matched.length );
2233 }
2234 }
2235
2236 if ( !matched ) {
2237 break;
2238 }
2239 }
2240
2241 // Return the length of the invalid excess
2242 // if we're just parsing
2243 // Otherwise, throw an error or return tokens
2244 return parseOnly ?
2245 soFar.length :
2246 soFar ?
2247 Sizzle.error( selector ) :
2248 // Cache the tokens
2249 tokenCache( selector, groups ).slice( 0 );
2250};
2251
2252function toSelector( tokens ) {
2253 var i = 0,
2254 len = tokens.length,
2255 selector = "";
2256 for ( ; i < len; i++ ) {
2257 selector += tokens[i].value;
2258 }
2259 return selector;
2260}
2261
2262function addCombinator( matcher, combinator, base ) {
2263 var dir = combinator.dir,
2264 skip = combinator.next,
2265 key = skip || dir,
2266 checkNonElements = base && key === "parentNode",
2267 doneName = done++;
2268
2269 return combinator.first ?
2270 // Check against closest ancestor/preceding element
2271 function( elem, context, xml ) {
2272 while ( (elem = elem[ dir ]) ) {
2273 if ( elem.nodeType === 1 || checkNonElements ) {
2274 return matcher( elem, context, xml );
2275 }
2276 }
2277 return false;
2278 } :
2279
2280 // Check against all ancestor/preceding elements
2281 function( elem, context, xml ) {
2282 var oldCache, uniqueCache, outerCache,
2283 newCache = [ dirruns, doneName ];
2284
2285 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2286 if ( xml ) {
2287 while ( (elem = elem[ dir ]) ) {
2288 if ( elem.nodeType === 1 || checkNonElements ) {
2289 if ( matcher( elem, context, xml ) ) {
2290 return true;
2291 }
2292 }
2293 }
2294 } else {
2295 while ( (elem = elem[ dir ]) ) {
2296 if ( elem.nodeType === 1 || checkNonElements ) {
2297 outerCache = elem[ expando ] || (elem[ expando ] = {});
2298
2299 // Support: IE <9 only
2300 // Defend against cloned attroperties (jQuery gh-1709)
2301 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2302
2303 if ( skip && skip === elem.nodeName.toLowerCase() ) {
2304 elem = elem[ dir ] || elem;
2305 } else if ( (oldCache = uniqueCache[ key ]) &&
2306 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2307
2308 // Assign to newCache so results back-propagate to previous elements
2309 return (newCache[ 2 ] = oldCache[ 2 ]);
2310 } else {
2311 // Reuse newcache so results back-propagate to previous elements
2312 uniqueCache[ key ] = newCache;
2313
2314 // A match means we're done; a fail means we have to keep checking
2315 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2316 return true;
2317 }
2318 }
2319 }
2320 }
2321 }
2322 return false;
2323 };
2324}
2325
2326function elementMatcher( matchers ) {
2327 return matchers.length > 1 ?
2328 function( elem, context, xml ) {
2329 var i = matchers.length;
2330 while ( i-- ) {
2331 if ( !matchers[i]( elem, context, xml ) ) {
2332 return false;
2333 }
2334 }
2335 return true;
2336 } :
2337 matchers[0];
2338}
2339
2340function multipleContexts( selector, contexts, results ) {
2341 var i = 0,
2342 len = contexts.length;
2343 for ( ; i < len; i++ ) {
2344 Sizzle( selector, contexts[i], results );
2345 }
2346 return results;
2347}
2348
2349function condense( unmatched, map, filter, context, xml ) {
2350 var elem,
2351 newUnmatched = [],
2352 i = 0,
2353 len = unmatched.length,
2354 mapped = map != null;
2355
2356 for ( ; i < len; i++ ) {
2357 if ( (elem = unmatched[i]) ) {
2358 if ( !filter || filter( elem, context, xml ) ) {
2359 newUnmatched.push( elem );
2360 if ( mapped ) {
2361 map.push( i );
2362 }
2363 }
2364 }
2365 }
2366
2367 return newUnmatched;
2368}
2369
2370function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2371 if ( postFilter && !postFilter[ expando ] ) {
2372 postFilter = setMatcher( postFilter );
2373 }
2374 if ( postFinder && !postFinder[ expando ] ) {
2375 postFinder = setMatcher( postFinder, postSelector );
2376 }
2377 return markFunction(function( seed, results, context, xml ) {
2378 var temp, i, elem,
2379 preMap = [],
2380 postMap = [],
2381 preexisting = results.length,
2382
2383 // Get initial elements from seed or context
2384 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2385
2386 // Prefilter to get matcher input, preserving a map for seed-results synchronization
2387 matcherIn = preFilter && ( seed || !selector ) ?
2388 condense( elems, preMap, preFilter, context, xml ) :
2389 elems,
2390
2391 matcherOut = matcher ?
2392 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2393 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2394
2395 // ...intermediate processing is necessary
2396 [] :
2397
2398 // ...otherwise use results directly
2399 results :
2400 matcherIn;
2401
2402 // Find primary matches
2403 if ( matcher ) {
2404 matcher( matcherIn, matcherOut, context, xml );
2405 }
2406
2407 // Apply postFilter
2408 if ( postFilter ) {
2409 temp = condense( matcherOut, postMap );
2410 postFilter( temp, [], context, xml );
2411
2412 // Un-match failing elements by moving them back to matcherIn
2413 i = temp.length;
2414 while ( i-- ) {
2415 if ( (elem = temp[i]) ) {
2416 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2417 }
2418 }
2419 }
2420
2421 if ( seed ) {
2422 if ( postFinder || preFilter ) {
2423 if ( postFinder ) {
2424 // Get the final matcherOut by condensing this intermediate into postFinder contexts
2425 temp = [];
2426 i = matcherOut.length;
2427 while ( i-- ) {
2428 if ( (elem = matcherOut[i]) ) {
2429 // Restore matcherIn since elem is not yet a final match
2430 temp.push( (matcherIn[i] = elem) );
2431 }
2432 }
2433 postFinder( null, (matcherOut = []), temp, xml );
2434 }
2435
2436 // Move matched elements from seed to results to keep them synchronized
2437 i = matcherOut.length;
2438 while ( i-- ) {
2439 if ( (elem = matcherOut[i]) &&
2440 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2441
2442 seed[temp] = !(results[temp] = elem);
2443 }
2444 }
2445 }
2446
2447 // Add elements to results, through postFinder if defined
2448 } else {
2449 matcherOut = condense(
2450 matcherOut === results ?
2451 matcherOut.splice( preexisting, matcherOut.length ) :
2452 matcherOut
2453 );
2454 if ( postFinder ) {
2455 postFinder( null, results, matcherOut, xml );
2456 } else {
2457 push.apply( results, matcherOut );
2458 }
2459 }
2460 });
2461}
2462
2463function matcherFromTokens( tokens ) {
2464 var checkContext, matcher, j,
2465 len = tokens.length,
2466 leadingRelative = Expr.relative[ tokens[0].type ],
2467 implicitRelative = leadingRelative || Expr.relative[" "],
2468 i = leadingRelative ? 1 : 0,
2469
2470 // The foundational matcher ensures that elements are reachable from top-level context(s)
2471 matchContext = addCombinator( function( elem ) {
2472 return elem === checkContext;
2473 }, implicitRelative, true ),
2474 matchAnyContext = addCombinator( function( elem ) {
2475 return indexOf( checkContext, elem ) > -1;
2476 }, implicitRelative, true ),
2477 matchers = [ function( elem, context, xml ) {
2478 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2479 (checkContext = context).nodeType ?
2480 matchContext( elem, context, xml ) :
2481 matchAnyContext( elem, context, xml ) );
2482 // Avoid hanging onto element (issue #299)
2483 checkContext = null;
2484 return ret;
2485 } ];
2486
2487 for ( ; i < len; i++ ) {
2488 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2489 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2490 } else {
2491 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2492
2493 // Return special upon seeing a positional matcher
2494 if ( matcher[ expando ] ) {
2495 // Find the next relative operator (if any) for proper handling
2496 j = ++i;
2497 for ( ; j < len; j++ ) {
2498 if ( Expr.relative[ tokens[j].type ] ) {
2499 break;
2500 }
2501 }
2502 return setMatcher(
2503 i > 1 && elementMatcher( matchers ),
2504 i > 1 && toSelector(
2505 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2506 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2507 ).replace( rtrim, "$1" ),
2508 matcher,
2509 i < j && matcherFromTokens( tokens.slice( i, j ) ),
2510 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2511 j < len && toSelector( tokens )
2512 );
2513 }
2514 matchers.push( matcher );
2515 }
2516 }
2517
2518 return elementMatcher( matchers );
2519}
2520
2521function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2522 var bySet = setMatchers.length > 0,
2523 byElement = elementMatchers.length > 0,
2524 superMatcher = function( seed, context, xml, results, outermost ) {
2525 var elem, j, matcher,
2526 matchedCount = 0,
2527 i = "0",
2528 unmatched = seed && [],
2529 setMatched = [],
2530 contextBackup = outermostContext,
2531 // We must always have either seed elements or outermost context
2532 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2533 // Use integer dirruns iff this is the outermost matcher
2534 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2535 len = elems.length;
2536
2537 if ( outermost ) {
2538 outermostContext = context === document || context || outermost;
2539 }
2540
2541 // Add elements passing elementMatchers directly to results
2542 // Support: IE<9, Safari
2543 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2544 for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2545 if ( byElement && elem ) {
2546 j = 0;
2547 if ( !context && elem.ownerDocument !== document ) {
2548 setDocument( elem );
2549 xml = !documentIsHTML;
2550 }
2551 while ( (matcher = elementMatchers[j++]) ) {
2552 if ( matcher( elem, context || document, xml) ) {
2553 results.push( elem );
2554 break;
2555 }
2556 }
2557 if ( outermost ) {
2558 dirruns = dirrunsUnique;
2559 }
2560 }
2561
2562 // Track unmatched elements for set filters
2563 if ( bySet ) {
2564 // They will have gone through all possible matchers
2565 if ( (elem = !matcher && elem) ) {
2566 matchedCount--;
2567 }
2568
2569 // Lengthen the array for every element, matched or not
2570 if ( seed ) {
2571 unmatched.push( elem );
2572 }
2573 }
2574 }
2575
2576 // `i` is now the count of elements visited above, and adding it to `matchedCount`
2577 // makes the latter nonnegative.
2578 matchedCount += i;
2579
2580 // Apply set filters to unmatched elements
2581 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2582 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2583 // no element matchers and no seed.
2584 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2585 // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2586 // numerically zero.
2587 if ( bySet && i !== matchedCount ) {
2588 j = 0;
2589 while ( (matcher = setMatchers[j++]) ) {
2590 matcher( unmatched, setMatched, context, xml );
2591 }
2592
2593 if ( seed ) {
2594 // Reintegrate element matches to eliminate the need for sorting
2595 if ( matchedCount > 0 ) {
2596 while ( i-- ) {
2597 if ( !(unmatched[i] || setMatched[i]) ) {
2598 setMatched[i] = pop.call( results );
2599 }
2600 }
2601 }
2602
2603 // Discard index placeholder values to get only actual matches
2604 setMatched = condense( setMatched );
2605 }
2606
2607 // Add matches to results
2608 push.apply( results, setMatched );
2609
2610 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2611 if ( outermost && !seed && setMatched.length > 0 &&
2612 ( matchedCount + setMatchers.length ) > 1 ) {
2613
2614 Sizzle.uniqueSort( results );
2615 }
2616 }
2617
2618 // Override manipulation of globals by nested matchers
2619 if ( outermost ) {
2620 dirruns = dirrunsUnique;
2621 outermostContext = contextBackup;
2622 }
2623
2624 return unmatched;
2625 };
2626
2627 return bySet ?
2628 markFunction( superMatcher ) :
2629 superMatcher;
2630}
2631
2632compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2633 var i,
2634 setMatchers = [],
2635 elementMatchers = [],
2636 cached = compilerCache[ selector + " " ];
2637
2638 if ( !cached ) {
2639 // Generate a function of recursive functions that can be used to check each element
2640 if ( !match ) {
2641 match = tokenize( selector );
2642 }
2643 i = match.length;
2644 while ( i-- ) {
2645 cached = matcherFromTokens( match[i] );
2646 if ( cached[ expando ] ) {
2647 setMatchers.push( cached );
2648 } else {
2649 elementMatchers.push( cached );
2650 }
2651 }
2652
2653 // Cache the compiled function
2654 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2655
2656 // Save selector and tokenization
2657 cached.selector = selector;
2658 }
2659 return cached;
2660};
2661
2662/**
2663 * A low-level selection function that works with Sizzle's compiled
2664 * selector functions
2665 * @param {String|Function} selector A selector or a pre-compiled
2666 * selector function built with Sizzle.compile
2667 * @param {Element} context
2668 * @param {Array} [results]
2669 * @param {Array} [seed] A set of elements to match against
2670 */
2671select = Sizzle.select = function( selector, context, results, seed ) {
2672 var i, tokens, token, type, find,
2673 compiled = typeof selector === "function" && selector,
2674 match = !seed && tokenize( (selector = compiled.selector || selector) );
2675
2676 results = results || [];
2677
2678 // Try to minimize operations if there is only one selector in the list and no seed
2679 // (the latter of which guarantees us context)
2680 if ( match.length === 1 ) {
2681
2682 // Reduce context if the leading compound selector is an ID
2683 tokens = match[0] = match[0].slice( 0 );
2684 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2685 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
2686
2687 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2688 if ( !context ) {
2689 return results;
2690
2691 // Precompiled matchers will still verify ancestry, so step up a level
2692 } else if ( compiled ) {
2693 context = context.parentNode;
2694 }
2695
2696 selector = selector.slice( tokens.shift().value.length );
2697 }
2698
2699 // Fetch a seed set for right-to-left matching
2700 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2701 while ( i-- ) {
2702 token = tokens[i];
2703
2704 // Abort if we hit a combinator
2705 if ( Expr.relative[ (type = token.type) ] ) {
2706 break;
2707 }
2708 if ( (find = Expr.find[ type ]) ) {
2709 // Search, expanding context for leading sibling combinators
2710 if ( (seed = find(
2711 token.matches[0].replace( runescape, funescape ),
2712 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2713 )) ) {
2714
2715 // If seed is empty or no tokens remain, we can return early
2716 tokens.splice( i, 1 );
2717 selector = seed.length && toSelector( tokens );
2718 if ( !selector ) {
2719 push.apply( results, seed );
2720 return results;
2721 }
2722
2723 break;
2724 }
2725 }
2726 }
2727 }
2728
2729 // Compile and execute a filtering function if one is not provided
2730 // Provide `match` to avoid retokenization if we modified the selector above
2731 ( compiled || compile( selector, match ) )(
2732 seed,
2733 context,
2734 !documentIsHTML,
2735 results,
2736 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2737 );
2738 return results;
2739};
2740
2741// One-time assignments
2742
2743// Sort stability
2744support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2745
2746// Support: Chrome 14-35+
2747// Always assume duplicates if they aren't passed to the comparison function
2748support.detectDuplicates = !!hasDuplicate;
2749
2750// Initialize against the default document
2751setDocument();
2752
2753// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2754// Detached nodes confoundingly follow *each other*
2755support.sortDetached = assert(function( el ) {
2756 // Should return 1, but returns 4 (following)
2757 return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
2758});
2759
2760// Support: IE<8
2761// Prevent attribute/property "interpolation"
2762// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2763if ( !assert(function( el ) {
2764 el.innerHTML = "<a href='#'></a>";
2765 return el.firstChild.getAttribute("href") === "#" ;
2766}) ) {
2767 addHandle( "type|href|height|width", function( elem, name, isXML ) {
2768 if ( !isXML ) {
2769 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2770 }
2771 });
2772}
2773
2774// Support: IE<9
2775// Use defaultValue in place of getAttribute("value")
2776if ( !support.attributes || !assert(function( el ) {
2777 el.innerHTML = "<input/>";
2778 el.firstChild.setAttribute( "value", "" );
2779 return el.firstChild.getAttribute( "value" ) === "";
2780}) ) {
2781 addHandle( "value", function( elem, name, isXML ) {
2782 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2783 return elem.defaultValue;
2784 }
2785 });
2786}
2787
2788// Support: IE<9
2789// Use getAttributeNode to fetch booleans when getAttribute lies
2790if ( !assert(function( el ) {
2791 return el.getAttribute("disabled") == null;
2792}) ) {
2793 addHandle( booleans, function( elem, name, isXML ) {
2794 var val;
2795 if ( !isXML ) {
2796 return elem[ name ] === true ? name.toLowerCase() :
2797 (val = elem.getAttributeNode( name )) && val.specified ?
2798 val.value :
2799 null;
2800 }
2801 });
2802}
2803
2804return Sizzle;
2805
2806})( window );
2807
2808
2809
2810jQuery.find = Sizzle;
2811jQuery.expr = Sizzle.selectors;
2812
2813// Deprecated
2814jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2815jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2816jQuery.text = Sizzle.getText;
2817jQuery.isXMLDoc = Sizzle.isXML;
2818jQuery.contains = Sizzle.contains;
2819jQuery.escapeSelector = Sizzle.escape;
2820
2821
2822
2823
2824var dir = function( elem, dir, until ) {
2825 var matched = [],
2826 truncate = until !== undefined;
2827
2828 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2829 if ( elem.nodeType === 1 ) {
2830 if ( truncate && jQuery( elem ).is( until ) ) {
2831 break;
2832 }
2833 matched.push( elem );
2834 }
2835 }
2836 return matched;
2837};
2838
2839
2840var siblings = function( n, elem ) {
2841 var matched = [];
2842
2843 for ( ; n; n = n.nextSibling ) {
2844 if ( n.nodeType === 1 && n !== elem ) {
2845 matched.push( n );
2846 }
2847 }
2848
2849 return matched;
2850};
2851
2852
2853var rneedsContext = jQuery.expr.match.needsContext;
2854
2855
2856
2857function nodeName( elem, name ) {
2858
2859 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
2860
2861}
2862var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
2863
2864
2865
2866var risSimple = /^.[^:#\[\.,]*$/;
2867
2868// Implement the identical functionality for filter and not
2869function winnow( elements, qualifier, not ) {
2870 if ( jQuery.isFunction( qualifier ) ) {
2871 return jQuery.grep( elements, function( elem, i ) {
2872 return !!qualifier.call( elem, i, elem ) !== not;
2873 } );
2874 }
2875
2876 // Single element
2877 if ( qualifier.nodeType ) {
2878 return jQuery.grep( elements, function( elem ) {
2879 return ( elem === qualifier ) !== not;
2880 } );
2881 }
2882
2883 // Arraylike of elements (jQuery, arguments, Array)
2884 if ( typeof qualifier !== "string" ) {
2885 return jQuery.grep( elements, function( elem ) {
2886 return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
2887 } );
2888 }
2889
2890 // Simple selector that can be filtered directly, removing non-Elements
2891 if ( risSimple.test( qualifier ) ) {
2892 return jQuery.filter( qualifier, elements, not );
2893 }
2894
2895 // Complex selector, compare the two sets, removing non-Elements
2896 qualifier = jQuery.filter( qualifier, elements );
2897 return jQuery.grep( elements, function( elem ) {
2898 return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
2899 } );
2900}
2901
2902jQuery.filter = function( expr, elems, not ) {
2903 var elem = elems[ 0 ];
2904
2905 if ( not ) {
2906 expr = ":not(" + expr + ")";
2907 }
2908
2909 if ( elems.length === 1 && elem.nodeType === 1 ) {
2910 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
2911 }
2912
2913 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2914 return elem.nodeType === 1;
2915 } ) );
2916};
2917
2918jQuery.fn.extend( {
2919 find: function( selector ) {
2920 var i, ret,
2921 len = this.length,
2922 self = this;
2923
2924 if ( typeof selector !== "string" ) {
2925 return this.pushStack( jQuery( selector ).filter( function() {
2926 for ( i = 0; i < len; i++ ) {
2927 if ( jQuery.contains( self[ i ], this ) ) {
2928 return true;
2929 }
2930 }
2931 } ) );
2932 }
2933
2934 ret = this.pushStack( [] );
2935
2936 for ( i = 0; i < len; i++ ) {
2937 jQuery.find( selector, self[ i ], ret );
2938 }
2939
2940 return len > 1 ? jQuery.uniqueSort( ret ) : ret;
2941 },
2942 filter: function( selector ) {
2943 return this.pushStack( winnow( this, selector || [], false ) );
2944 },
2945 not: function( selector ) {
2946 return this.pushStack( winnow( this, selector || [], true ) );
2947 },
2948 is: function( selector ) {
2949 return !!winnow(
2950 this,
2951
2952 // If this is a positional/relative selector, check membership in the returned set
2953 // so $("p:first").is("p:last") won't return true for a doc with two "p".
2954 typeof selector === "string" && rneedsContext.test( selector ) ?
2955 jQuery( selector ) :
2956 selector || [],
2957 false
2958 ).length;
2959 }
2960} );
2961
2962
2963// Initialize a jQuery object
2964
2965
2966// A central reference to the root jQuery(document)
2967var rootjQuery,
2968
2969 // A simple way to check for HTML strings
2970 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2971 // Strict HTML recognition (#11290: must start with <)
2972 // Shortcut simple #id case for speed
2973 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
2974
2975 init = jQuery.fn.init = function( selector, context, root ) {
2976 var match, elem;
2977
2978 // HANDLE: $(""), $(null), $(undefined), $(false)
2979 if ( !selector ) {
2980 return this;
2981 }
2982
2983 // Method init() accepts an alternate rootjQuery
2984 // so migrate can support jQuery.sub (gh-2101)
2985 root = root || rootjQuery;
2986
2987 // Handle HTML strings
2988 if ( typeof selector === "string" ) {
2989 if ( selector[ 0 ] === "<" &&
2990 selector[ selector.length - 1 ] === ">" &&
2991 selector.length >= 3 ) {
2992
2993 // Assume that strings that start and end with <> are HTML and skip the regex check
2994 match = [ null, selector, null ];
2995
2996 } else {
2997 match = rquickExpr.exec( selector );
2998 }
2999
3000 // Match html or make sure no context is specified for #id
3001 if ( match && ( match[ 1 ] || !context ) ) {
3002
3003 // HANDLE: $(html) -> $(array)
3004 if ( match[ 1 ] ) {
3005 context = context instanceof jQuery ? context[ 0 ] : context;
3006
3007 // Option to run scripts is true for back-compat
3008 // Intentionally let the error be thrown if parseHTML is not present
3009 jQuery.merge( this, jQuery.parseHTML(
3010 match[ 1 ],
3011 context && context.nodeType ? context.ownerDocument || context : document,
3012 true
3013 ) );
3014
3015 // HANDLE: $(html, props)
3016 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
3017 for ( match in context ) {
3018
3019 // Properties of context are called as methods if possible
3020 if ( jQuery.isFunction( this[ match ] ) ) {
3021 this[ match ]( context[ match ] );
3022
3023 // ...and otherwise set as attributes
3024 } else {
3025 this.attr( match, context[ match ] );
3026 }
3027 }
3028 }
3029
3030 return this;
3031
3032 // HANDLE: $(#id)
3033 } else {
3034 elem = document.getElementById( match[ 2 ] );
3035
3036 if ( elem ) {
3037
3038 // Inject the element directly into the jQuery object
3039 this[ 0 ] = elem;
3040 this.length = 1;
3041 }
3042 return this;
3043 }
3044
3045 // HANDLE: $(expr, $(...))
3046 } else if ( !context || context.jquery ) {
3047 return ( context || root ).find( selector );
3048
3049 // HANDLE: $(expr, context)
3050 // (which is just equivalent to: $(context).find(expr)
3051 } else {
3052 return this.constructor( context ).find( selector );
3053 }
3054
3055 // HANDLE: $(DOMElement)
3056 } else if ( selector.nodeType ) {
3057 this[ 0 ] = selector;
3058 this.length = 1;
3059 return this;
3060
3061 // HANDLE: $(function)
3062 // Shortcut for document ready
3063 } else if ( jQuery.isFunction( selector ) ) {
3064 return root.ready !== undefined ?
3065 root.ready( selector ) :
3066
3067 // Execute immediately if ready is not present
3068 selector( jQuery );
3069 }
3070
3071 return jQuery.makeArray( selector, this );
3072 };
3073
3074// Give the init function the jQuery prototype for later instantiation
3075init.prototype = jQuery.fn;
3076
3077// Initialize central reference
3078rootjQuery = jQuery( document );
3079
3080
3081var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3082
3083 // Methods guaranteed to produce a unique set when starting from a unique set
3084 guaranteedUnique = {
3085 children: true,
3086 contents: true,
3087 next: true,
3088 prev: true
3089 };
3090
3091jQuery.fn.extend( {
3092 has: function( target ) {
3093 var targets = jQuery( target, this ),
3094 l = targets.length;
3095
3096 return this.filter( function() {
3097 var i = 0;
3098 for ( ; i < l; i++ ) {
3099 if ( jQuery.contains( this, targets[ i ] ) ) {
3100 return true;
3101 }
3102 }
3103 } );
3104 },
3105
3106 closest: function( selectors, context ) {
3107 var cur,
3108 i = 0,
3109 l = this.length,
3110 matched = [],
3111 targets = typeof selectors !== "string" && jQuery( selectors );
3112
3113 // Positional selectors never match, since there's no _selection_ context
3114 if ( !rneedsContext.test( selectors ) ) {
3115 for ( ; i < l; i++ ) {
3116 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3117
3118 // Always skip document fragments
3119 if ( cur.nodeType < 11 && ( targets ?
3120 targets.index( cur ) > -1 :
3121
3122 // Don't pass non-elements to Sizzle
3123 cur.nodeType === 1 &&
3124 jQuery.find.matchesSelector( cur, selectors ) ) ) {
3125
3126 matched.push( cur );
3127 break;
3128 }
3129 }
3130 }
3131 }
3132
3133 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3134 },
3135
3136 // Determine the position of an element within the set
3137 index: function( elem ) {
3138
3139 // No argument, return index in parent
3140 if ( !elem ) {
3141 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3142 }
3143
3144 // Index in selector
3145 if ( typeof elem === "string" ) {
3146 return indexOf.call( jQuery( elem ), this[ 0 ] );
3147 }
3148
3149 // Locate the position of the desired element
3150 return indexOf.call( this,
3151
3152 // If it receives a jQuery object, the first element is used
3153 elem.jquery ? elem[ 0 ] : elem
3154 );
3155 },
3156
3157 add: function( selector, context ) {
3158 return this.pushStack(
3159 jQuery.uniqueSort(
3160 jQuery.merge( this.get(), jQuery( selector, context ) )
3161 )
3162 );
3163 },
3164
3165 addBack: function( selector ) {
3166 return this.add( selector == null ?
3167 this.prevObject : this.prevObject.filter( selector )
3168 );
3169 }
3170} );
3171
3172function sibling( cur, dir ) {
3173 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3174 return cur;
3175}
3176
3177jQuery.each( {
3178 parent: function( elem ) {
3179 var parent = elem.parentNode;
3180 return parent && parent.nodeType !== 11 ? parent : null;
3181 },
3182 parents: function( elem ) {
3183 return dir( elem, "parentNode" );
3184 },
3185 parentsUntil: function( elem, i, until ) {
3186 return dir( elem, "parentNode", until );
3187 },
3188 next: function( elem ) {
3189 return sibling( elem, "nextSibling" );
3190 },
3191 prev: function( elem ) {
3192 return sibling( elem, "previousSibling" );
3193 },
3194 nextAll: function( elem ) {
3195 return dir( elem, "nextSibling" );
3196 },
3197 prevAll: function( elem ) {
3198 return dir( elem, "previousSibling" );
3199 },
3200 nextUntil: function( elem, i, until ) {
3201 return dir( elem, "nextSibling", until );
3202 },
3203 prevUntil: function( elem, i, until ) {
3204 return dir( elem, "previousSibling", until );
3205 },
3206 siblings: function( elem ) {
3207 return siblings( ( elem.parentNode || {} ).firstChild, elem );
3208 },
3209 children: function( elem ) {
3210 return siblings( elem.firstChild );
3211 },
3212 contents: function( elem ) {
3213 if ( nodeName( elem, "iframe" ) ) {
3214 return elem.contentDocument;
3215 }
3216
3217 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3218 // Treat the template element as a regular one in browsers that
3219 // don't support it.
3220 if ( nodeName( elem, "template" ) ) {
3221 elem = elem.content || elem;
3222 }
3223
3224 return jQuery.merge( [], elem.childNodes );
3225 }
3226}, function( name, fn ) {
3227 jQuery.fn[ name ] = function( until, selector ) {
3228 var matched = jQuery.map( this, fn, until );
3229
3230 if ( name.slice( -5 ) !== "Until" ) {
3231 selector = until;
3232 }
3233
3234 if ( selector && typeof selector === "string" ) {
3235 matched = jQuery.filter( selector, matched );
3236 }
3237
3238 if ( this.length > 1 ) {
3239
3240 // Remove duplicates
3241 if ( !guaranteedUnique[ name ] ) {
3242 jQuery.uniqueSort( matched );
3243 }
3244
3245 // Reverse order for parents* and prev-derivatives
3246 if ( rparentsprev.test( name ) ) {
3247 matched.reverse();
3248 }
3249 }
3250
3251 return this.pushStack( matched );
3252 };
3253} );
3254var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
3255
3256
3257
3258// Convert String-formatted options into Object-formatted ones
3259function createOptions( options ) {
3260 var object = {};
3261 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
3262 object[ flag ] = true;
3263 } );
3264 return object;
3265}
3266
3267/*
3268 * Create a callback list using the following parameters:
3269 *
3270 * options: an optional list of space-separated options that will change how
3271 * the callback list behaves or a more traditional option object
3272 *
3273 * By default a callback list will act like an event callback list and can be
3274 * "fired" multiple times.
3275 *
3276 * Possible options:
3277 *
3278 * once: will ensure the callback list can only be fired once (like a Deferred)
3279 *
3280 * memory: will keep track of previous values and will call any callback added
3281 * after the list has been fired right away with the latest "memorized"
3282 * values (like a Deferred)
3283 *
3284 * unique: will ensure a callback can only be added once (no duplicate in the list)
3285 *
3286 * stopOnFalse: interrupt callings when a callback returns false
3287 *
3288 */
3289jQuery.Callbacks = function( options ) {
3290
3291 // Convert options from String-formatted to Object-formatted if needed
3292 // (we check in cache first)
3293 options = typeof options === "string" ?
3294 createOptions( options ) :
3295 jQuery.extend( {}, options );
3296
3297 var // Flag to know if list is currently firing
3298 firing,
3299
3300 // Last fire value for non-forgettable lists
3301 memory,
3302
3303 // Flag to know if list was already fired
3304 fired,
3305
3306 // Flag to prevent firing
3307 locked,
3308
3309 // Actual callback list
3310 list = [],
3311
3312 // Queue of execution data for repeatable lists
3313 queue = [],
3314
3315 // Index of currently firing callback (modified by add/remove as needed)
3316 firingIndex = -1,
3317
3318 // Fire callbacks
3319 fire = function() {
3320
3321 // Enforce single-firing
3322 locked = locked || options.once;
3323
3324 // Execute callbacks for all pending executions,
3325 // respecting firingIndex overrides and runtime changes
3326 fired = firing = true;
3327 for ( ; queue.length; firingIndex = -1 ) {
3328 memory = queue.shift();
3329 while ( ++firingIndex < list.length ) {
3330
3331 // Run callback and check for early termination
3332 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3333 options.stopOnFalse ) {
3334
3335 // Jump to end and forget the data so .add doesn't re-fire
3336 firingIndex = list.length;
3337 memory = false;
3338 }
3339 }
3340 }
3341
3342 // Forget the data if we're done with it
3343 if ( !options.memory ) {
3344 memory = false;
3345 }
3346
3347 firing = false;
3348
3349 // Clean up if we're done firing for good
3350 if ( locked ) {
3351
3352 // Keep an empty list if we have data for future add calls
3353 if ( memory ) {
3354 list = [];
3355
3356 // Otherwise, this object is spent
3357 } else {
3358 list = "";
3359 }
3360 }
3361 },
3362
3363 // Actual Callbacks object
3364 self = {
3365
3366 // Add a callback or a collection of callbacks to the list
3367 add: function() {
3368 if ( list ) {
3369
3370 // If we have memory from a past run, we should fire after adding
3371 if ( memory && !firing ) {
3372 firingIndex = list.length - 1;
3373 queue.push( memory );
3374 }
3375
3376 ( function add( args ) {
3377 jQuery.each( args, function( _, arg ) {
3378 if ( jQuery.isFunction( arg ) ) {
3379 if ( !options.unique || !self.has( arg ) ) {
3380 list.push( arg );
3381 }
3382 } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3383
3384 // Inspect recursively
3385 add( arg );
3386 }
3387 } );
3388 } )( arguments );
3389
3390 if ( memory && !firing ) {
3391 fire();
3392 }
3393 }
3394 return this;
3395 },
3396
3397 // Remove a callback from the list
3398 remove: function() {
3399 jQuery.each( arguments, function( _, arg ) {
3400 var index;
3401 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3402 list.splice( index, 1 );
3403
3404 // Handle firing indexes
3405 if ( index <= firingIndex ) {
3406 firingIndex--;
3407 }
3408 }
3409 } );
3410 return this;
3411 },
3412
3413 // Check if a given callback is in the list.
3414 // If no argument is given, return whether or not list has callbacks attached.
3415 has: function( fn ) {
3416 return fn ?
3417 jQuery.inArray( fn, list ) > -1 :
3418 list.length > 0;
3419 },
3420
3421 // Remove all callbacks from the list
3422 empty: function() {
3423 if ( list ) {
3424 list = [];
3425 }
3426 return this;
3427 },
3428
3429 // Disable .fire and .add
3430 // Abort any current/pending executions
3431 // Clear all callbacks and values
3432 disable: function() {
3433 locked = queue = [];
3434 list = memory = "";
3435 return this;
3436 },
3437 disabled: function() {
3438 return !list;
3439 },
3440
3441 // Disable .fire
3442 // Also disable .add unless we have memory (since it would have no effect)
3443 // Abort any pending executions
3444 lock: function() {
3445 locked = queue = [];
3446 if ( !memory && !firing ) {
3447 list = memory = "";
3448 }
3449 return this;
3450 },
3451 locked: function() {
3452 return !!locked;
3453 },
3454
3455 // Call all callbacks with the given context and arguments
3456 fireWith: function( context, args ) {
3457 if ( !locked ) {
3458 args = args || [];
3459 args = [ context, args.slice ? args.slice() : args ];
3460 queue.push( args );
3461 if ( !firing ) {
3462 fire();
3463 }
3464 }
3465 return this;
3466 },
3467
3468 // Call all the callbacks with the given arguments
3469 fire: function() {
3470 self.fireWith( this, arguments );
3471 return this;
3472 },
3473
3474 // To know if the callbacks have already been called at least once
3475 fired: function() {
3476 return !!fired;
3477 }
3478 };
3479
3480 return self;
3481};
3482
3483
3484function Identity( v ) {
3485 return v;
3486}
3487function Thrower( ex ) {
3488 throw ex;
3489}
3490
3491function adoptValue( value, resolve, reject, noValue ) {
3492 var method;
3493
3494 try {
3495
3496 // Check for promise aspect first to privilege synchronous behavior
3497 if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
3498 method.call( value ).done( resolve ).fail( reject );
3499
3500 // Other thenables
3501 } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
3502 method.call( value, resolve, reject );
3503
3504 // Other non-thenables
3505 } else {
3506
3507 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3508 // * false: [ value ].slice( 0 ) => resolve( value )
3509 // * true: [ value ].slice( 1 ) => resolve()
3510 resolve.apply( undefined, [ value ].slice( noValue ) );
3511 }
3512
3513 // For Promises/A+, convert exceptions into rejections
3514 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3515 // Deferred#then to conditionally suppress rejection.
3516 } catch ( value ) {
3517
3518 // Support: Android 4.0 only
3519 // Strict mode functions invoked without .call/.apply get global-object context
3520 reject.apply( undefined, [ value ] );
3521 }
3522}
3523
3524jQuery.extend( {
3525
3526 Deferred: function( func ) {
3527 var tuples = [
3528
3529 // action, add listener, callbacks,
3530 // ... .then handlers, argument index, [final state]
3531 [ "notify", "progress", jQuery.Callbacks( "memory" ),
3532 jQuery.Callbacks( "memory" ), 2 ],
3533 [ "resolve", "done", jQuery.Callbacks( "once memory" ),
3534 jQuery.Callbacks( "once memory" ), 0, "resolved" ],
3535 [ "reject", "fail", jQuery.Callbacks( "once memory" ),
3536 jQuery.Callbacks( "once memory" ), 1, "rejected" ]
3537 ],
3538 state = "pending",
3539 promise = {
3540 state: function() {
3541 return state;
3542 },
3543 always: function() {
3544 deferred.done( arguments ).fail( arguments );
3545 return this;
3546 },
3547 "catch": function( fn ) {
3548 return promise.then( null, fn );
3549 },
3550
3551 // Keep pipe for back-compat
3552 pipe: function( /* fnDone, fnFail, fnProgress */ ) {
3553 var fns = arguments;
3554
3555 return jQuery.Deferred( function( newDefer ) {
3556 jQuery.each( tuples, function( i, tuple ) {
3557
3558 // Map tuples (progress, done, fail) to arguments (done, fail, progress)
3559 var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
3560
3561 // deferred.progress(function() { bind to newDefer or newDefer.notify })
3562 // deferred.done(function() { bind to newDefer or newDefer.resolve })
3563 // deferred.fail(function() { bind to newDefer or newDefer.reject })
3564 deferred[ tuple[ 1 ] ]( function() {
3565 var returned = fn && fn.apply( this, arguments );
3566 if ( returned && jQuery.isFunction( returned.promise ) ) {
3567 returned.promise()
3568 .progress( newDefer.notify )
3569 .done( newDefer.resolve )
3570 .fail( newDefer.reject );
3571 } else {
3572 newDefer[ tuple[ 0 ] + "With" ](
3573 this,
3574 fn ? [ returned ] : arguments
3575 );
3576 }
3577 } );
3578 } );
3579 fns = null;
3580 } ).promise();
3581 },
3582 then: function( onFulfilled, onRejected, onProgress ) {
3583 var maxDepth = 0;
3584 function resolve( depth, deferred, handler, special ) {
3585 return function() {
3586 var that = this,
3587 args = arguments,
3588 mightThrow = function() {
3589 var returned, then;
3590
3591 // Support: Promises/A+ section 2.3.3.3.3
3592 // https://promisesaplus.com/#point-59
3593 // Ignore double-resolution attempts
3594 if ( depth < maxDepth ) {
3595 return;
3596 }
3597
3598 returned = handler.apply( that, args );
3599
3600 // Support: Promises/A+ section 2.3.1
3601 // https://promisesaplus.com/#point-48
3602 if ( returned === deferred.promise() ) {
3603 throw new TypeError( "Thenable self-resolution" );
3604 }
3605
3606 // Support: Promises/A+ sections 2.3.3.1, 3.5
3607 // https://promisesaplus.com/#point-54
3608 // https://promisesaplus.com/#point-75
3609 // Retrieve `then` only once
3610 then = returned &&
3611
3612 // Support: Promises/A+ section 2.3.4
3613 // https://promisesaplus.com/#point-64
3614 // Only check objects and functions for thenability
3615 ( typeof returned === "object" ||
3616 typeof returned === "function" ) &&
3617 returned.then;
3618
3619 // Handle a returned thenable
3620 if ( jQuery.isFunction( then ) ) {
3621
3622 // Special processors (notify) just wait for resolution
3623 if ( special ) {
3624 then.call(
3625 returned,
3626 resolve( maxDepth, deferred, Identity, special ),
3627 resolve( maxDepth, deferred, Thrower, special )
3628 );
3629
3630 // Normal processors (resolve) also hook into progress
3631 } else {
3632
3633 // ...and disregard older resolution values
3634 maxDepth++;
3635
3636 then.call(
3637 returned,
3638 resolve( maxDepth, deferred, Identity, special ),
3639 resolve( maxDepth, deferred, Thrower, special ),
3640 resolve( maxDepth, deferred, Identity,
3641 deferred.notifyWith )
3642 );
3643 }
3644
3645 // Handle all other returned values
3646 } else {
3647
3648 // Only substitute handlers pass on context
3649 // and multiple values (non-spec behavior)
3650 if ( handler !== Identity ) {
3651 that = undefined;
3652 args = [ returned ];
3653 }
3654
3655 // Process the value(s)
3656 // Default process is resolve
3657 ( special || deferred.resolveWith )( that, args );
3658 }
3659 },
3660
3661 // Only normal processors (resolve) catch and reject exceptions
3662 process = special ?
3663 mightThrow :
3664 function() {
3665 try {
3666 mightThrow();
3667 } catch ( e ) {
3668
3669 if ( jQuery.Deferred.exceptionHook ) {
3670 jQuery.Deferred.exceptionHook( e,
3671 process.stackTrace );
3672 }
3673
3674 // Support: Promises/A+ section 2.3.3.3.4.1
3675 // https://promisesaplus.com/#point-61
3676 // Ignore post-resolution exceptions
3677 if ( depth + 1 >= maxDepth ) {
3678
3679 // Only substitute handlers pass on context
3680 // and multiple values (non-spec behavior)
3681 if ( handler !== Thrower ) {
3682 that = undefined;
3683 args = [ e ];
3684 }
3685
3686 deferred.rejectWith( that, args );
3687 }
3688 }
3689 };
3690
3691 // Support: Promises/A+ section 2.3.3.3.1
3692 // https://promisesaplus.com/#point-57
3693 // Re-resolve promises immediately to dodge false rejection from
3694 // subsequent errors
3695 if ( depth ) {
3696 process();
3697 } else {
3698
3699 // Call an optional hook to record the stack, in case of exception
3700 // since it's otherwise lost when execution goes async
3701 if ( jQuery.Deferred.getStackHook ) {
3702 process.stackTrace = jQuery.Deferred.getStackHook();
3703 }
3704 window.setTimeout( process );
3705 }
3706 };
3707 }
3708
3709 return jQuery.Deferred( function( newDefer ) {
3710
3711 // progress_handlers.add( ... )
3712 tuples[ 0 ][ 3 ].add(
3713 resolve(
3714 0,
3715 newDefer,
3716 jQuery.isFunction( onProgress ) ?
3717 onProgress :
3718 Identity,
3719 newDefer.notifyWith
3720 )
3721 );
3722
3723 // fulfilled_handlers.add( ... )
3724 tuples[ 1 ][ 3 ].add(
3725 resolve(
3726 0,
3727 newDefer,
3728 jQuery.isFunction( onFulfilled ) ?
3729 onFulfilled :
3730 Identity
3731 )
3732 );
3733
3734 // rejected_handlers.add( ... )
3735 tuples[ 2 ][ 3 ].add(
3736 resolve(
3737 0,
3738 newDefer,
3739 jQuery.isFunction( onRejected ) ?
3740 onRejected :
3741 Thrower
3742 )
3743 );
3744 } ).promise();
3745 },
3746
3747 // Get a promise for this deferred
3748 // If obj is provided, the promise aspect is added to the object
3749 promise: function( obj ) {
3750 return obj != null ? jQuery.extend( obj, promise ) : promise;
3751 }
3752 },
3753 deferred = {};
3754
3755 // Add list-specific methods
3756 jQuery.each( tuples, function( i, tuple ) {
3757 var list = tuple[ 2 ],
3758 stateString = tuple[ 5 ];
3759
3760 // promise.progress = list.add
3761 // promise.done = list.add
3762 // promise.fail = list.add
3763 promise[ tuple[ 1 ] ] = list.add;
3764
3765 // Handle state
3766 if ( stateString ) {
3767 list.add(
3768 function() {
3769
3770 // state = "resolved" (i.e., fulfilled)
3771 // state = "rejected"
3772 state = stateString;
3773 },
3774
3775 // rejected_callbacks.disable
3776 // fulfilled_callbacks.disable
3777 tuples[ 3 - i ][ 2 ].disable,
3778
3779 // progress_callbacks.lock
3780 tuples[ 0 ][ 2 ].lock
3781 );
3782 }
3783
3784 // progress_handlers.fire
3785 // fulfilled_handlers.fire
3786 // rejected_handlers.fire
3787 list.add( tuple[ 3 ].fire );
3788
3789 // deferred.notify = function() { deferred.notifyWith(...) }
3790 // deferred.resolve = function() { deferred.resolveWith(...) }
3791 // deferred.reject = function() { deferred.rejectWith(...) }
3792 deferred[ tuple[ 0 ] ] = function() {
3793 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
3794 return this;
3795 };
3796
3797 // deferred.notifyWith = list.fireWith
3798 // deferred.resolveWith = list.fireWith
3799 // deferred.rejectWith = list.fireWith
3800 deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3801 } );
3802
3803 // Make the deferred a promise
3804 promise.promise( deferred );
3805
3806 // Call given func if any
3807 if ( func ) {
3808 func.call( deferred, deferred );
3809 }
3810
3811 // All done!
3812 return deferred;
3813 },
3814
3815 // Deferred helper
3816 when: function( singleValue ) {
3817 var
3818
3819 // count of uncompleted subordinates
3820 remaining = arguments.length,
3821
3822 // count of unprocessed arguments
3823 i = remaining,
3824
3825 // subordinate fulfillment data
3826 resolveContexts = Array( i ),
3827 resolveValues = slice.call( arguments ),
3828
3829 // the master Deferred
3830 master = jQuery.Deferred(),
3831
3832 // subordinate callback factory
3833 updateFunc = function( i ) {
3834 return function( value ) {
3835 resolveContexts[ i ] = this;
3836 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3837 if ( !( --remaining ) ) {
3838 master.resolveWith( resolveContexts, resolveValues );
3839 }
3840 };
3841 };
3842
3843 // Single- and empty arguments are adopted like Promise.resolve
3844 if ( remaining <= 1 ) {
3845 adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
3846 !remaining );
3847
3848 // Use .then() to unwrap secondary thenables (cf. gh-3000)
3849 if ( master.state() === "pending" ||
3850 jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
3851
3852 return master.then();
3853 }
3854 }
3855
3856 // Multiple arguments are aggregated like Promise.all array elements
3857 while ( i-- ) {
3858 adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
3859 }
3860
3861 return master.promise();
3862 }
3863} );
3864
3865
3866// These usually indicate a programmer mistake during development,
3867// warn about them ASAP rather than swallowing them by default.
3868var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
3869
3870jQuery.Deferred.exceptionHook = function( error, stack ) {
3871
3872 // Support: IE 8 - 9 only
3873 // Console exists when dev tools are open, which can happen at any time
3874 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
3875 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
3876 }
3877};
3878
3879
3880
3881
3882jQuery.readyException = function( error ) {
3883 window.setTimeout( function() {
3884 throw error;
3885 } );
3886};
3887
3888
3889
3890
3891// The deferred used on DOM ready
3892var readyList = jQuery.Deferred();
3893
3894jQuery.fn.ready = function( fn ) {
3895
3896 readyList
3897 .then( fn )
3898
3899 // Wrap jQuery.readyException in a function so that the lookup
3900 // happens at the time of error handling instead of callback
3901 // registration.
3902 .catch( function( error ) {
3903 jQuery.readyException( error );
3904 } );
3905
3906 return this;
3907};
3908
3909jQuery.extend( {
3910
3911 // Is the DOM ready to be used? Set to true once it occurs.
3912 isReady: false,
3913
3914 // A counter to track how many items to wait for before
3915 // the ready event fires. See #6781
3916 readyWait: 1,
3917
3918 // Handle when the DOM is ready
3919 ready: function( wait ) {
3920
3921 // Abort if there are pending holds or we're already ready
3922 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3923 return;
3924 }
3925
3926 // Remember that the DOM is ready
3927 jQuery.isReady = true;
3928
3929 // If a normal DOM Ready event fired, decrement, and wait if need be
3930 if ( wait !== true && --jQuery.readyWait > 0 ) {
3931 return;
3932 }
3933
3934 // If there are functions bound, to execute
3935 readyList.resolveWith( document, [ jQuery ] );
3936 }
3937} );
3938
3939jQuery.ready.then = readyList.then;
3940
3941// The ready event handler and self cleanup method
3942function completed() {
3943 document.removeEventListener( "DOMContentLoaded", completed );
3944 window.removeEventListener( "load", completed );
3945 jQuery.ready();
3946}
3947
3948// Catch cases where $(document).ready() is called
3949// after the browser event has already occurred.
3950// Support: IE <=9 - 10 only
3951// Older IE sometimes signals "interactive" too soon
3952if ( document.readyState === "complete" ||
3953 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3954
3955 // Handle it asynchronously to allow scripts the opportunity to delay ready
3956 window.setTimeout( jQuery.ready );
3957
3958} else {
3959
3960 // Use the handy event callback
3961 document.addEventListener( "DOMContentLoaded", completed );
3962
3963 // A fallback to window.onload, that will always work
3964 window.addEventListener( "load", completed );
3965}
3966
3967
3968
3969
3970// Multifunctional method to get and set values of a collection
3971// The value/s can optionally be executed if it's a function
3972var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3973 var i = 0,
3974 len = elems.length,
3975 bulk = key == null;
3976
3977 // Sets many values
3978 if ( jQuery.type( key ) === "object" ) {
3979 chainable = true;
3980 for ( i in key ) {
3981 access( elems, fn, i, key[ i ], true, emptyGet, raw );
3982 }
3983
3984 // Sets one value
3985 } else if ( value !== undefined ) {
3986 chainable = true;
3987
3988 if ( !jQuery.isFunction( value ) ) {
3989 raw = true;
3990 }
3991
3992 if ( bulk ) {
3993
3994 // Bulk operations run against the entire set
3995 if ( raw ) {
3996 fn.call( elems, value );
3997 fn = null;
3998
3999 // ...except when executing function values
4000 } else {
4001 bulk = fn;
4002 fn = function( elem, key, value ) {
4003 return bulk.call( jQuery( elem ), value );
4004 };
4005 }
4006 }
4007
4008 if ( fn ) {
4009 for ( ; i < len; i++ ) {
4010 fn(
4011 elems[ i ], key, raw ?
4012 value :
4013 value.call( elems[ i ], i, fn( elems[ i ], key ) )
4014 );
4015 }
4016 }
4017 }
4018
4019 if ( chainable ) {
4020 return elems;
4021 }
4022
4023 // Gets
4024 if ( bulk ) {
4025 return fn.call( elems );
4026 }
4027
4028 return len ? fn( elems[ 0 ], key ) : emptyGet;
4029};
4030var acceptData = function( owner ) {
4031
4032 // Accepts only:
4033 // - Node
4034 // - Node.ELEMENT_NODE
4035 // - Node.DOCUMENT_NODE
4036 // - Object
4037 // - Any
4038 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
4039};
4040
4041
4042
4043
4044function Data() {
4045 this.expando = jQuery.expando + Data.uid++;
4046}
4047
4048Data.uid = 1;
4049
4050Data.prototype = {
4051
4052 cache: function( owner ) {
4053
4054 // Check if the owner object already has a cache
4055 var value = owner[ this.expando ];
4056
4057 // If not, create one
4058 if ( !value ) {
4059 value = {};
4060
4061 // We can accept data for non-element nodes in modern browsers,
4062 // but we should not, see #8335.
4063 // Always return an empty object.
4064 if ( acceptData( owner ) ) {
4065
4066 // If it is a node unlikely to be stringify-ed or looped over
4067 // use plain assignment
4068 if ( owner.nodeType ) {
4069 owner[ this.expando ] = value;
4070
4071 // Otherwise secure it in a non-enumerable property
4072 // configurable must be true to allow the property to be
4073 // deleted when data is removed
4074 } else {
4075 Object.defineProperty( owner, this.expando, {
4076 value: value,
4077 configurable: true
4078 } );
4079 }
4080 }
4081 }
4082
4083 return value;
4084 },
4085 set: function( owner, data, value ) {
4086 var prop,
4087 cache = this.cache( owner );
4088
4089 // Handle: [ owner, key, value ] args
4090 // Always use camelCase key (gh-2257)
4091 if ( typeof data === "string" ) {
4092 cache[ jQuery.camelCase( data ) ] = value;
4093
4094 // Handle: [ owner, { properties } ] args
4095 } else {
4096
4097 // Copy the properties one-by-one to the cache object
4098 for ( prop in data ) {
4099 cache[ jQuery.camelCase( prop ) ] = data[ prop ];
4100 }
4101 }
4102 return cache;
4103 },
4104 get: function( owner, key ) {
4105 return key === undefined ?
4106 this.cache( owner ) :
4107
4108 // Always use camelCase key (gh-2257)
4109 owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
4110 },
4111 access: function( owner, key, value ) {
4112
4113 // In cases where either:
4114 //
4115 // 1. No key was specified
4116 // 2. A string key was specified, but no value provided
4117 //
4118 // Take the "read" path and allow the get method to determine
4119 // which value to return, respectively either:
4120 //
4121 // 1. The entire cache object
4122 // 2. The data stored at the key
4123 //
4124 if ( key === undefined ||
4125 ( ( key && typeof key === "string" ) && value === undefined ) ) {
4126
4127 return this.get( owner, key );
4128 }
4129
4130 // When the key is not a string, or both a key and value
4131 // are specified, set or extend (existing objects) with either:
4132 //
4133 // 1. An object of properties
4134 // 2. A key and value
4135 //
4136 this.set( owner, key, value );
4137
4138 // Since the "set" path can have two possible entry points
4139 // return the expected data based on which path was taken[*]
4140 return value !== undefined ? value : key;
4141 },
4142 remove: function( owner, key ) {
4143 var i,
4144 cache = owner[ this.expando ];
4145
4146 if ( cache === undefined ) {
4147 return;
4148 }
4149
4150 if ( key !== undefined ) {
4151
4152 // Support array or space separated string of keys
4153 if ( Array.isArray( key ) ) {
4154
4155 // If key is an array of keys...
4156 // We always set camelCase keys, so remove that.
4157 key = key.map( jQuery.camelCase );
4158 } else {
4159 key = jQuery.camelCase( key );
4160
4161 // If a key with the spaces exists, use it.
4162 // Otherwise, create an array by matching non-whitespace
4163 key = key in cache ?
4164 [ key ] :
4165 ( key.match( rnothtmlwhite ) || [] );
4166 }
4167
4168 i = key.length;
4169
4170 while ( i-- ) {
4171 delete cache[ key[ i ] ];
4172 }
4173 }
4174
4175 // Remove the expando if there's no more data
4176 if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4177
4178 // Support: Chrome <=35 - 45
4179 // Webkit & Blink performance suffers when deleting properties
4180 // from DOM nodes, so set to undefined instead
4181 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4182 if ( owner.nodeType ) {
4183 owner[ this.expando ] = undefined;
4184 } else {
4185 delete owner[ this.expando ];
4186 }
4187 }
4188 },
4189 hasData: function( owner ) {
4190 var cache = owner[ this.expando ];
4191 return cache !== undefined && !jQuery.isEmptyObject( cache );
4192 }
4193};
4194var dataPriv = new Data();
4195
4196var dataUser = new Data();
4197
4198
4199
4200// Implementation Summary
4201//
4202// 1. Enforce API surface and semantic compatibility with 1.9.x branch
4203// 2. Improve the module's maintainability by reducing the storage
4204// paths to a single mechanism.
4205// 3. Use the same single mechanism to support "private" and "user" data.
4206// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4207// 5. Avoid exposing implementation details on user objects (eg. expando properties)
4208// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
4209
4210var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4211 rmultiDash = /[A-Z]/g;
4212
4213function getData( data ) {
4214 if ( data === "true" ) {
4215 return true;
4216 }
4217
4218 if ( data === "false" ) {
4219 return false;
4220 }
4221
4222 if ( data === "null" ) {
4223 return null;
4224 }
4225
4226 // Only convert to a number if it doesn't change the string
4227 if ( data === +data + "" ) {
4228 return +data;
4229 }
4230
4231 if ( rbrace.test( data ) ) {
4232 return JSON.parse( data );
4233 }
4234
4235 return data;
4236}
4237
4238function dataAttr( elem, key, data ) {
4239 var name;
4240
4241 // If nothing was found internally, try to fetch any
4242 // data from the HTML5 data-* attribute
4243 if ( data === undefined && elem.nodeType === 1 ) {
4244 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
4245 data = elem.getAttribute( name );
4246
4247 if ( typeof data === "string" ) {
4248 try {
4249 data = getData( data );
4250 } catch ( e ) {}
4251
4252 // Make sure we set the data so it isn't changed later
4253 dataUser.set( elem, key, data );
4254 } else {
4255 data = undefined;
4256 }
4257 }
4258 return data;
4259}
4260
4261jQuery.extend( {
4262 hasData: function( elem ) {
4263 return dataUser.hasData( elem ) || dataPriv.hasData( elem );
4264 },
4265
4266 data: function( elem, name, data ) {
4267 return dataUser.access( elem, name, data );
4268 },
4269
4270 removeData: function( elem, name ) {
4271 dataUser.remove( elem, name );
4272 },
4273
4274 // TODO: Now that all calls to _data and _removeData have been replaced
4275 // with direct calls to dataPriv methods, these can be deprecated.
4276 _data: function( elem, name, data ) {
4277 return dataPriv.access( elem, name, data );
4278 },
4279
4280 _removeData: function( elem, name ) {
4281 dataPriv.remove( elem, name );
4282 }
4283} );
4284
4285jQuery.fn.extend( {
4286 data: function( key, value ) {
4287 var i, name, data,
4288 elem = this[ 0 ],
4289 attrs = elem && elem.attributes;
4290
4291 // Gets all values
4292 if ( key === undefined ) {
4293 if ( this.length ) {
4294 data = dataUser.get( elem );
4295
4296 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
4297 i = attrs.length;
4298 while ( i-- ) {
4299
4300 // Support: IE 11 only
4301 // The attrs elements can be null (#14894)
4302 if ( attrs[ i ] ) {
4303 name = attrs[ i ].name;
4304 if ( name.indexOf( "data-" ) === 0 ) {
4305 name = jQuery.camelCase( name.slice( 5 ) );
4306 dataAttr( elem, name, data[ name ] );
4307 }
4308 }
4309 }
4310 dataPriv.set( elem, "hasDataAttrs", true );
4311 }
4312 }
4313
4314 return data;
4315 }
4316
4317 // Sets multiple values
4318 if ( typeof key === "object" ) {
4319 return this.each( function() {
4320 dataUser.set( this, key );
4321 } );
4322 }
4323
4324 return access( this, function( value ) {
4325 var data;
4326
4327 // The calling jQuery object (element matches) is not empty
4328 // (and therefore has an element appears at this[ 0 ]) and the
4329 // `value` parameter was not undefined. An empty jQuery object
4330 // will result in `undefined` for elem = this[ 0 ] which will
4331 // throw an exception if an attempt to read a data cache is made.
4332 if ( elem && value === undefined ) {
4333
4334 // Attempt to get data from the cache
4335 // The key will always be camelCased in Data
4336 data = dataUser.get( elem, key );
4337 if ( data !== undefined ) {
4338 return data;
4339 }
4340
4341 // Attempt to "discover" the data in
4342 // HTML5 custom data-* attrs
4343 data = dataAttr( elem, key );
4344 if ( data !== undefined ) {
4345 return data;
4346 }
4347
4348 // We tried really hard, but the data doesn't exist.
4349 return;
4350 }
4351
4352 // Set the data...
4353 this.each( function() {
4354
4355 // We always store the camelCased key
4356 dataUser.set( this, key, value );
4357 } );
4358 }, null, value, arguments.length > 1, null, true );
4359 },
4360
4361 removeData: function( key ) {
4362 return this.each( function() {
4363 dataUser.remove( this, key );
4364 } );
4365 }
4366} );
4367
4368
4369jQuery.extend( {
4370 queue: function( elem, type, data ) {
4371 var queue;
4372
4373 if ( elem ) {
4374 type = ( type || "fx" ) + "queue";
4375 queue = dataPriv.get( elem, type );
4376
4377 // Speed up dequeue by getting out quickly if this is just a lookup
4378 if ( data ) {
4379 if ( !queue || Array.isArray( data ) ) {
4380 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4381 } else {
4382 queue.push( data );
4383 }
4384 }
4385 return queue || [];
4386 }
4387 },
4388
4389 dequeue: function( elem, type ) {
4390 type = type || "fx";
4391
4392 var queue = jQuery.queue( elem, type ),
4393 startLength = queue.length,
4394 fn = queue.shift(),
4395 hooks = jQuery._queueHooks( elem, type ),
4396 next = function() {
4397 jQuery.dequeue( elem, type );
4398 };
4399
4400 // If the fx queue is dequeued, always remove the progress sentinel
4401 if ( fn === "inprogress" ) {
4402 fn = queue.shift();
4403 startLength--;
4404 }
4405
4406 if ( fn ) {
4407
4408 // Add a progress sentinel to prevent the fx queue from being
4409 // automatically dequeued
4410 if ( type === "fx" ) {
4411 queue.unshift( "inprogress" );
4412 }
4413
4414 // Clear up the last queue stop function
4415 delete hooks.stop;
4416 fn.call( elem, next, hooks );
4417 }
4418
4419 if ( !startLength && hooks ) {
4420 hooks.empty.fire();
4421 }
4422 },
4423
4424 // Not public - generate a queueHooks object, or return the current one
4425 _queueHooks: function( elem, type ) {
4426 var key = type + "queueHooks";
4427 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4428 empty: jQuery.Callbacks( "once memory" ).add( function() {
4429 dataPriv.remove( elem, [ type + "queue", key ] );
4430 } )
4431 } );
4432 }
4433} );
4434
4435jQuery.fn.extend( {
4436 queue: function( type, data ) {
4437 var setter = 2;
4438
4439 if ( typeof type !== "string" ) {
4440 data = type;
4441 type = "fx";
4442 setter--;
4443 }
4444
4445 if ( arguments.length < setter ) {
4446 return jQuery.queue( this[ 0 ], type );
4447 }
4448
4449 return data === undefined ?
4450 this :
4451 this.each( function() {
4452 var queue = jQuery.queue( this, type, data );
4453
4454 // Ensure a hooks for this queue
4455 jQuery._queueHooks( this, type );
4456
4457 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4458 jQuery.dequeue( this, type );
4459 }
4460 } );
4461 },
4462 dequeue: function( type ) {
4463 return this.each( function() {
4464 jQuery.dequeue( this, type );
4465 } );
4466 },
4467 clearQueue: function( type ) {
4468 return this.queue( type || "fx", [] );
4469 },
4470
4471 // Get a promise resolved when queues of a certain type
4472 // are emptied (fx is the type by default)
4473 promise: function( type, obj ) {
4474 var tmp,
4475 count = 1,
4476 defer = jQuery.Deferred(),
4477 elements = this,
4478 i = this.length,
4479 resolve = function() {
4480 if ( !( --count ) ) {
4481 defer.resolveWith( elements, [ elements ] );
4482 }
4483 };
4484
4485 if ( typeof type !== "string" ) {
4486 obj = type;
4487 type = undefined;
4488 }
4489 type = type || "fx";
4490
4491 while ( i-- ) {
4492 tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4493 if ( tmp && tmp.empty ) {
4494 count++;
4495 tmp.empty.add( resolve );
4496 }
4497 }
4498 resolve();
4499 return defer.promise( obj );
4500 }
4501} );
4502var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4503
4504var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4505
4506
4507var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4508
4509var isHiddenWithinTree = function( elem, el ) {
4510
4511 // isHiddenWithinTree might be called from jQuery#filter function;
4512 // in that case, element will be second argument
4513 elem = el || elem;
4514
4515 // Inline style trumps all
4516 return elem.style.display === "none" ||
4517 elem.style.display === "" &&
4518
4519 // Otherwise, check computed style
4520 // Support: Firefox <=43 - 45
4521 // Disconnected elements can have computed display: none, so first confirm that elem is
4522 // in the document.
4523 jQuery.contains( elem.ownerDocument, elem ) &&
4524
4525 jQuery.css( elem, "display" ) === "none";
4526 };
4527
4528var swap = function( elem, options, callback, args ) {
4529 var ret, name,
4530 old = {};
4531
4532 // Remember the old values, and insert the new ones
4533 for ( name in options ) {
4534 old[ name ] = elem.style[ name ];
4535 elem.style[ name ] = options[ name ];
4536 }
4537
4538 ret = callback.apply( elem, args || [] );
4539
4540 // Revert the old values
4541 for ( name in options ) {
4542 elem.style[ name ] = old[ name ];
4543 }
4544
4545 return ret;
4546};
4547
4548
4549
4550
4551function adjustCSS( elem, prop, valueParts, tween ) {
4552 var adjusted,
4553 scale = 1,
4554 maxIterations = 20,
4555 currentValue = tween ?
4556 function() {
4557 return tween.cur();
4558 } :
4559 function() {
4560 return jQuery.css( elem, prop, "" );
4561 },
4562 initial = currentValue(),
4563 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4564
4565 // Starting value computation is required for potential unit mismatches
4566 initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4567 rcssNum.exec( jQuery.css( elem, prop ) );
4568
4569 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4570
4571 // Trust units reported by jQuery.css
4572 unit = unit || initialInUnit[ 3 ];
4573
4574 // Make sure we update the tween properties later on
4575 valueParts = valueParts || [];
4576
4577 // Iteratively approximate from a nonzero starting point
4578 initialInUnit = +initial || 1;
4579
4580 do {
4581
4582 // If previous iteration zeroed out, double until we get *something*.
4583 // Use string for doubling so we don't accidentally see scale as unchanged below
4584 scale = scale || ".5";
4585
4586 // Adjust and apply
4587 initialInUnit = initialInUnit / scale;
4588 jQuery.style( elem, prop, initialInUnit + unit );
4589
4590 // Update scale, tolerating zero or NaN from tween.cur()
4591 // Break the loop if scale is unchanged or perfect, or if we've just had enough.
4592 } while (
4593 scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4594 );
4595 }
4596
4597 if ( valueParts ) {
4598 initialInUnit = +initialInUnit || +initial || 0;
4599
4600 // Apply relative offset (+=/-=) if specified
4601 adjusted = valueParts[ 1 ] ?
4602 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4603 +valueParts[ 2 ];
4604 if ( tween ) {
4605 tween.unit = unit;
4606 tween.start = initialInUnit;
4607 tween.end = adjusted;
4608 }
4609 }
4610 return adjusted;
4611}
4612
4613
4614var defaultDisplayMap = {};
4615
4616function getDefaultDisplay( elem ) {
4617 var temp,
4618 doc = elem.ownerDocument,
4619 nodeName = elem.nodeName,
4620 display = defaultDisplayMap[ nodeName ];
4621
4622 if ( display ) {
4623 return display;
4624 }
4625
4626 temp = doc.body.appendChild( doc.createElement( nodeName ) );
4627 display = jQuery.css( temp, "display" );
4628
4629 temp.parentNode.removeChild( temp );
4630
4631 if ( display === "none" ) {
4632 display = "block";
4633 }
4634 defaultDisplayMap[ nodeName ] = display;
4635
4636 return display;
4637}
4638
4639function showHide( elements, show ) {
4640 var display, elem,
4641 values = [],
4642 index = 0,
4643 length = elements.length;
4644
4645 // Determine new display value for elements that need to change
4646 for ( ; index < length; index++ ) {
4647 elem = elements[ index ];
4648 if ( !elem.style ) {
4649 continue;
4650 }
4651
4652 display = elem.style.display;
4653 if ( show ) {
4654
4655 // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4656 // check is required in this first loop unless we have a nonempty display value (either
4657 // inline or about-to-be-restored)
4658 if ( display === "none" ) {
4659 values[ index ] = dataPriv.get( elem, "display" ) || null;
4660 if ( !values[ index ] ) {
4661 elem.style.display = "";
4662 }
4663 }
4664 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
4665 values[ index ] = getDefaultDisplay( elem );
4666 }
4667 } else {
4668 if ( display !== "none" ) {
4669 values[ index ] = "none";
4670
4671 // Remember what we're overwriting
4672 dataPriv.set( elem, "display", display );
4673 }
4674 }
4675 }
4676
4677 // Set the display of the elements in a second loop to avoid constant reflow
4678 for ( index = 0; index < length; index++ ) {
4679 if ( values[ index ] != null ) {
4680 elements[ index ].style.display = values[ index ];
4681 }
4682 }
4683
4684 return elements;
4685}
4686
4687jQuery.fn.extend( {
4688 show: function() {
4689 return showHide( this, true );
4690 },
4691 hide: function() {
4692 return showHide( this );
4693 },
4694 toggle: function( state ) {
4695 if ( typeof state === "boolean" ) {
4696 return state ? this.show() : this.hide();
4697 }
4698
4699 return this.each( function() {
4700 if ( isHiddenWithinTree( this ) ) {
4701 jQuery( this ).show();
4702 } else {
4703 jQuery( this ).hide();
4704 }
4705 } );
4706 }
4707} );
4708var rcheckableType = ( /^(?:checkbox|radio)$/i );
4709
4710var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
4711
4712var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4713
4714
4715
4716// We have to close these tags to support XHTML (#13200)
4717var wrapMap = {
4718
4719 // Support: IE <=9 only
4720 option: [ 1, "<select multiple='multiple'>", "</select>" ],
4721
4722 // XHTML parsers do not magically insert elements in the
4723 // same way that tag soup parsers do. So we cannot shorten
4724 // this by omitting <tbody> or other required elements.
4725 thead: [ 1, "<table>", "</table>" ],
4726 col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4727 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4728 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4729
4730 _default: [ 0, "", "" ]
4731};
4732
4733// Support: IE <=9 only
4734wrapMap.optgroup = wrapMap.option;
4735
4736wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4737wrapMap.th = wrapMap.td;
4738
4739
4740function getAll( context, tag ) {
4741
4742 // Support: IE <=9 - 11 only
4743 // Use typeof to avoid zero-argument method invocation on host objects (#15151)
4744 var ret;
4745
4746 if ( typeof context.getElementsByTagName !== "undefined" ) {
4747 ret = context.getElementsByTagName( tag || "*" );
4748
4749 } else if ( typeof context.querySelectorAll !== "undefined" ) {
4750 ret = context.querySelectorAll( tag || "*" );
4751
4752 } else {
4753 ret = [];
4754 }
4755
4756 if ( tag === undefined || tag && nodeName( context, tag ) ) {
4757 return jQuery.merge( [ context ], ret );
4758 }
4759
4760 return ret;
4761}
4762
4763
4764// Mark scripts as having already been evaluated
4765function setGlobalEval( elems, refElements ) {
4766 var i = 0,
4767 l = elems.length;
4768
4769 for ( ; i < l; i++ ) {
4770 dataPriv.set(
4771 elems[ i ],
4772 "globalEval",
4773 !refElements || dataPriv.get( refElements[ i ], "globalEval" )
4774 );
4775 }
4776}
4777
4778
4779var rhtml = /<|&#?\w+;/;
4780
4781function buildFragment( elems, context, scripts, selection, ignored ) {
4782 var elem, tmp, tag, wrap, contains, j,
4783 fragment = context.createDocumentFragment(),
4784 nodes = [],
4785 i = 0,
4786 l = elems.length;
4787
4788 for ( ; i < l; i++ ) {
4789 elem = elems[ i ];
4790
4791 if ( elem || elem === 0 ) {
4792
4793 // Add nodes directly
4794 if ( jQuery.type( elem ) === "object" ) {
4795
4796 // Support: Android <=4.0 only, PhantomJS 1 only
4797 // push.apply(_, arraylike) throws on ancient WebKit
4798 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4799
4800 // Convert non-html into a text node
4801 } else if ( !rhtml.test( elem ) ) {
4802 nodes.push( context.createTextNode( elem ) );
4803
4804 // Convert html into DOM nodes
4805 } else {
4806 tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
4807
4808 // Deserialize a standard representation
4809 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4810 wrap = wrapMap[ tag ] || wrapMap._default;
4811 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4812
4813 // Descend through wrappers to the right content
4814 j = wrap[ 0 ];
4815 while ( j-- ) {
4816 tmp = tmp.lastChild;
4817 }
4818
4819 // Support: Android <=4.0 only, PhantomJS 1 only
4820 // push.apply(_, arraylike) throws on ancient WebKit
4821 jQuery.merge( nodes, tmp.childNodes );
4822
4823 // Remember the top-level container
4824 tmp = fragment.firstChild;
4825
4826 // Ensure the created nodes are orphaned (#12392)
4827 tmp.textContent = "";
4828 }
4829 }
4830 }
4831
4832 // Remove wrapper from fragment
4833 fragment.textContent = "";
4834
4835 i = 0;
4836 while ( ( elem = nodes[ i++ ] ) ) {
4837
4838 // Skip elements already in the context collection (trac-4087)
4839 if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4840 if ( ignored ) {
4841 ignored.push( elem );
4842 }
4843 continue;
4844 }
4845
4846 contains = jQuery.contains( elem.ownerDocument, elem );
4847
4848 // Append to fragment
4849 tmp = getAll( fragment.appendChild( elem ), "script" );
4850
4851 // Preserve script evaluation history
4852 if ( contains ) {
4853 setGlobalEval( tmp );
4854 }
4855
4856 // Capture executables
4857 if ( scripts ) {
4858 j = 0;
4859 while ( ( elem = tmp[ j++ ] ) ) {
4860 if ( rscriptType.test( elem.type || "" ) ) {
4861 scripts.push( elem );
4862 }
4863 }
4864 }
4865 }
4866
4867 return fragment;
4868}
4869
4870
4871( function() {
4872 var fragment = document.createDocumentFragment(),
4873 div = fragment.appendChild( document.createElement( "div" ) ),
4874 input = document.createElement( "input" );
4875
4876 // Support: Android 4.0 - 4.3 only
4877 // Check state lost if the name is set (#11217)
4878 // Support: Windows Web Apps (WWA)
4879 // `name` and `type` must use .setAttribute for WWA (#14901)
4880 input.setAttribute( "type", "radio" );
4881 input.setAttribute( "checked", "checked" );
4882 input.setAttribute( "name", "t" );
4883
4884 div.appendChild( input );
4885
4886 // Support: Android <=4.1 only
4887 // Older WebKit doesn't clone checked state correctly in fragments
4888 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4889
4890 // Support: IE <=11 only
4891 // Make sure textarea (and checkbox) defaultValue is properly cloned
4892 div.innerHTML = "<textarea>x</textarea>";
4893 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4894} )();
4895var documentElement = document.documentElement;
4896
4897
4898
4899var
4900 rkeyEvent = /^key/,
4901 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4902 rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4903
4904function returnTrue() {
4905 return true;
4906}
4907
4908function returnFalse() {
4909 return false;
4910}
4911
4912// Support: IE <=9 only
4913// See #13393 for more info
4914function safeActiveElement() {
4915 try {
4916 return document.activeElement;
4917 } catch ( err ) { }
4918}
4919
4920function on( elem, types, selector, data, fn, one ) {
4921 var origFn, type;
4922
4923 // Types can be a map of types/handlers
4924 if ( typeof types === "object" ) {
4925
4926 // ( types-Object, selector, data )
4927 if ( typeof selector !== "string" ) {
4928
4929 // ( types-Object, data )
4930 data = data || selector;
4931 selector = undefined;
4932 }
4933 for ( type in types ) {
4934 on( elem, type, selector, data, types[ type ], one );
4935 }
4936 return elem;
4937 }
4938
4939 if ( data == null && fn == null ) {
4940
4941 // ( types, fn )
4942 fn = selector;
4943 data = selector = undefined;
4944 } else if ( fn == null ) {
4945 if ( typeof selector === "string" ) {
4946
4947 // ( types, selector, fn )
4948 fn = data;
4949 data = undefined;
4950 } else {
4951
4952 // ( types, data, fn )
4953 fn = data;
4954 data = selector;
4955 selector = undefined;
4956 }
4957 }
4958 if ( fn === false ) {
4959 fn = returnFalse;
4960 } else if ( !fn ) {
4961 return elem;
4962 }
4963
4964 if ( one === 1 ) {
4965 origFn = fn;
4966 fn = function( event ) {
4967
4968 // Can use an empty set, since event contains the info
4969 jQuery().off( event );
4970 return origFn.apply( this, arguments );
4971 };
4972
4973 // Use same guid so caller can remove using origFn
4974 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4975 }
4976 return elem.each( function() {
4977 jQuery.event.add( this, types, fn, data, selector );
4978 } );
4979}
4980
4981/*
4982 * Helper functions for managing events -- not part of the public interface.
4983 * Props to Dean Edwards' addEvent library for many of the ideas.
4984 */
4985jQuery.event = {
4986
4987 global: {},
4988
4989 add: function( elem, types, handler, data, selector ) {
4990
4991 var handleObjIn, eventHandle, tmp,
4992 events, t, handleObj,
4993 special, handlers, type, namespaces, origType,
4994 elemData = dataPriv.get( elem );
4995
4996 // Don't attach events to noData or text/comment nodes (but allow plain objects)
4997 if ( !elemData ) {
4998 return;
4999 }
5000
5001 // Caller can pass in an object of custom data in lieu of the handler
5002 if ( handler.handler ) {
5003 handleObjIn = handler;
5004 handler = handleObjIn.handler;
5005 selector = handleObjIn.selector;
5006 }
5007
5008 // Ensure that invalid selectors throw exceptions at attach time
5009 // Evaluate against documentElement in case elem is a non-element node (e.g., document)
5010 if ( selector ) {
5011 jQuery.find.matchesSelector( documentElement, selector );
5012 }
5013
5014 // Make sure that the handler has a unique ID, used to find/remove it later
5015 if ( !handler.guid ) {
5016 handler.guid = jQuery.guid++;
5017 }
5018
5019 // Init the element's event structure and main handler, if this is the first
5020 if ( !( events = elemData.events ) ) {
5021 events = elemData.events = {};
5022 }
5023 if ( !( eventHandle = elemData.handle ) ) {
5024 eventHandle = elemData.handle = function( e ) {
5025
5026 // Discard the second event of a jQuery.event.trigger() and
5027 // when an event is called after a page has unloaded
5028 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
5029 jQuery.event.dispatch.apply( elem, arguments ) : undefined;
5030 };
5031 }
5032
5033 // Handle multiple events separated by a space
5034 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5035 t = types.length;
5036 while ( t-- ) {
5037 tmp = rtypenamespace.exec( types[ t ] ) || [];
5038 type = origType = tmp[ 1 ];
5039 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5040
5041 // There *must* be a type, no attaching namespace-only handlers
5042 if ( !type ) {
5043 continue;
5044 }
5045
5046 // If event changes its type, use the special event handlers for the changed type
5047 special = jQuery.event.special[ type ] || {};
5048
5049 // If selector defined, determine special event api type, otherwise given type
5050 type = ( selector ? special.delegateType : special.bindType ) || type;
5051
5052 // Update special based on newly reset type
5053 special = jQuery.event.special[ type ] || {};
5054
5055 // handleObj is passed to all event handlers
5056 handleObj = jQuery.extend( {
5057 type: type,
5058 origType: origType,
5059 data: data,
5060 handler: handler,
5061 guid: handler.guid,
5062 selector: selector,
5063 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
5064 namespace: namespaces.join( "." )
5065 }, handleObjIn );
5066
5067 // Init the event handler queue if we're the first
5068 if ( !( handlers = events[ type ] ) ) {
5069 handlers = events[ type ] = [];
5070 handlers.delegateCount = 0;
5071
5072 // Only use addEventListener if the special events handler returns false
5073 if ( !special.setup ||
5074 special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
5075
5076 if ( elem.addEventListener ) {
5077 elem.addEventListener( type, eventHandle );
5078 }
5079 }
5080 }
5081
5082 if ( special.add ) {
5083 special.add.call( elem, handleObj );
5084
5085 if ( !handleObj.handler.guid ) {
5086 handleObj.handler.guid = handler.guid;
5087 }
5088 }
5089
5090 // Add to the element's handler list, delegates in front
5091 if ( selector ) {
5092 handlers.splice( handlers.delegateCount++, 0, handleObj );
5093 } else {
5094 handlers.push( handleObj );
5095 }
5096
5097 // Keep track of which events have ever been used, for event optimization
5098 jQuery.event.global[ type ] = true;
5099 }
5100
5101 },
5102
5103 // Detach an event or set of events from an element
5104 remove: function( elem, types, handler, selector, mappedTypes ) {
5105
5106 var j, origCount, tmp,
5107 events, t, handleObj,
5108 special, handlers, type, namespaces, origType,
5109 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
5110
5111 if ( !elemData || !( events = elemData.events ) ) {
5112 return;
5113 }
5114
5115 // Once for each type.namespace in types; type may be omitted
5116 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5117 t = types.length;
5118 while ( t-- ) {
5119 tmp = rtypenamespace.exec( types[ t ] ) || [];
5120 type = origType = tmp[ 1 ];
5121 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5122
5123 // Unbind all events (on this namespace, if provided) for the element
5124 if ( !type ) {
5125 for ( type in events ) {
5126 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
5127 }
5128 continue;
5129 }
5130
5131 special = jQuery.event.special[ type ] || {};
5132 type = ( selector ? special.delegateType : special.bindType ) || type;
5133 handlers = events[ type ] || [];
5134 tmp = tmp[ 2 ] &&
5135 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
5136
5137 // Remove matching events
5138 origCount = j = handlers.length;
5139 while ( j-- ) {
5140 handleObj = handlers[ j ];
5141
5142 if ( ( mappedTypes || origType === handleObj.origType ) &&
5143 ( !handler || handler.guid === handleObj.guid ) &&
5144 ( !tmp || tmp.test( handleObj.namespace ) ) &&
5145 ( !selector || selector === handleObj.selector ||
5146 selector === "**" && handleObj.selector ) ) {
5147 handlers.splice( j, 1 );
5148
5149 if ( handleObj.selector ) {
5150 handlers.delegateCount--;
5151 }
5152 if ( special.remove ) {
5153 special.remove.call( elem, handleObj );
5154 }
5155 }
5156 }
5157
5158 // Remove generic event handler if we removed something and no more handlers exist
5159 // (avoids potential for endless recursion during removal of special event handlers)
5160 if ( origCount && !handlers.length ) {
5161 if ( !special.teardown ||
5162 special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5163
5164 jQuery.removeEvent( elem, type, elemData.handle );
5165 }
5166
5167 delete events[ type ];
5168 }
5169 }
5170
5171 // Remove data and the expando if it's no longer used
5172 if ( jQuery.isEmptyObject( events ) ) {
5173 dataPriv.remove( elem, "handle events" );
5174 }
5175 },
5176
5177 dispatch: function( nativeEvent ) {
5178
5179 // Make a writable jQuery.Event from the native event object
5180 var event = jQuery.event.fix( nativeEvent );
5181
5182 var i, j, ret, matched, handleObj, handlerQueue,
5183 args = new Array( arguments.length ),
5184 handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
5185 special = jQuery.event.special[ event.type ] || {};
5186
5187 // Use the fix-ed jQuery.Event rather than the (read-only) native event
5188 args[ 0 ] = event;
5189
5190 for ( i = 1; i < arguments.length; i++ ) {
5191 args[ i ] = arguments[ i ];
5192 }
5193
5194 event.delegateTarget = this;
5195
5196 // Call the preDispatch hook for the mapped type, and let it bail if desired
5197 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5198 return;
5199 }
5200
5201 // Determine handlers
5202 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5203
5204 // Run delegates first; they may want to stop propagation beneath us
5205 i = 0;
5206 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5207 event.currentTarget = matched.elem;
5208
5209 j = 0;
5210 while ( ( handleObj = matched.handlers[ j++ ] ) &&
5211 !event.isImmediatePropagationStopped() ) {
5212
5213 // Triggered event must either 1) have no namespace, or 2) have namespace(s)
5214 // a subset or equal to those in the bound event (both can have no namespace).
5215 if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
5216
5217 event.handleObj = handleObj;
5218 event.data = handleObj.data;
5219
5220 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5221 handleObj.handler ).apply( matched.elem, args );
5222
5223 if ( ret !== undefined ) {
5224 if ( ( event.result = ret ) === false ) {
5225 event.preventDefault();
5226 event.stopPropagation();
5227 }
5228 }
5229 }
5230 }
5231 }
5232
5233 // Call the postDispatch hook for the mapped type
5234 if ( special.postDispatch ) {
5235 special.postDispatch.call( this, event );
5236 }
5237
5238 return event.result;
5239 },
5240
5241 handlers: function( event, handlers ) {
5242 var i, handleObj, sel, matchedHandlers, matchedSelectors,
5243 handlerQueue = [],
5244 delegateCount = handlers.delegateCount,
5245 cur = event.target;
5246
5247 // Find delegate handlers
5248 if ( delegateCount &&
5249
5250 // Support: IE <=9
5251 // Black-hole SVG <use> instance trees (trac-13180)
5252 cur.nodeType &&
5253
5254 // Support: Firefox <=42
5255 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5256 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5257 // Support: IE 11 only
5258 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5259 !( event.type === "click" && event.button >= 1 ) ) {
5260
5261 for ( ; cur !== this; cur = cur.parentNode || this ) {
5262
5263 // Don't check non-elements (#13208)
5264 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5265 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
5266 matchedHandlers = [];
5267 matchedSelectors = {};
5268 for ( i = 0; i < delegateCount; i++ ) {
5269 handleObj = handlers[ i ];
5270
5271 // Don't conflict with Object.prototype properties (#13203)
5272 sel = handleObj.selector + " ";
5273
5274 if ( matchedSelectors[ sel ] === undefined ) {
5275 matchedSelectors[ sel ] = handleObj.needsContext ?
5276 jQuery( sel, this ).index( cur ) > -1 :
5277 jQuery.find( sel, this, null, [ cur ] ).length;
5278 }
5279 if ( matchedSelectors[ sel ] ) {
5280 matchedHandlers.push( handleObj );
5281 }
5282 }
5283 if ( matchedHandlers.length ) {
5284 handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
5285 }
5286 }
5287 }
5288 }
5289
5290 // Add the remaining (directly-bound) handlers
5291 cur = this;
5292 if ( delegateCount < handlers.length ) {
5293 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
5294 }
5295
5296 return handlerQueue;
5297 },
5298
5299 addProp: function( name, hook ) {
5300 Object.defineProperty( jQuery.Event.prototype, name, {
5301 enumerable: true,
5302 configurable: true,
5303
5304 get: jQuery.isFunction( hook ) ?
5305 function() {
5306 if ( this.originalEvent ) {
5307 return hook( this.originalEvent );
5308 }
5309 } :
5310 function() {
5311 if ( this.originalEvent ) {
5312 return this.originalEvent[ name ];
5313 }
5314 },
5315
5316 set: function( value ) {
5317 Object.defineProperty( this, name, {
5318 enumerable: true,
5319 configurable: true,
5320 writable: true,
5321 value: value
5322 } );
5323 }
5324 } );
5325 },
5326
5327 fix: function( originalEvent ) {
5328 return originalEvent[ jQuery.expando ] ?
5329 originalEvent :
5330 new jQuery.Event( originalEvent );
5331 },
5332
5333 special: {
5334 load: {
5335
5336 // Prevent triggered image.load events from bubbling to window.load
5337 noBubble: true
5338 },
5339 focus: {
5340
5341 // Fire native event if possible so blur/focus sequence is correct
5342 trigger: function() {
5343 if ( this !== safeActiveElement() && this.focus ) {
5344 this.focus();
5345 return false;
5346 }
5347 },
5348 delegateType: "focusin"
5349 },
5350 blur: {
5351 trigger: function() {
5352 if ( this === safeActiveElement() && this.blur ) {
5353 this.blur();
5354 return false;
5355 }
5356 },
5357 delegateType: "focusout"
5358 },
5359 click: {
5360
5361 // For checkbox, fire native event so checked state will be right
5362 trigger: function() {
5363 if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
5364 this.click();
5365 return false;
5366 }
5367 },
5368
5369 // For cross-browser consistency, don't fire native .click() on links
5370 _default: function( event ) {
5371 return nodeName( event.target, "a" );
5372 }
5373 },
5374
5375 beforeunload: {
5376 postDispatch: function( event ) {
5377
5378 // Support: Firefox 20+
5379 // Firefox doesn't alert if the returnValue field is not set.
5380 if ( event.result !== undefined && event.originalEvent ) {
5381 event.originalEvent.returnValue = event.result;
5382 }
5383 }
5384 }
5385 }
5386};
5387
5388jQuery.removeEvent = function( elem, type, handle ) {
5389
5390 // This "if" is needed for plain objects
5391 if ( elem.removeEventListener ) {
5392 elem.removeEventListener( type, handle );
5393 }
5394};
5395
5396jQuery.Event = function( src, props ) {
5397
5398 // Allow instantiation without the 'new' keyword
5399 if ( !( this instanceof jQuery.Event ) ) {
5400 return new jQuery.Event( src, props );
5401 }
5402
5403 // Event object
5404 if ( src && src.type ) {
5405 this.originalEvent = src;
5406 this.type = src.type;
5407
5408 // Events bubbling up the document may have been marked as prevented
5409 // by a handler lower down the tree; reflect the correct value.
5410 this.isDefaultPrevented = src.defaultPrevented ||
5411 src.defaultPrevented === undefined &&
5412
5413 // Support: Android <=2.3 only
5414 src.returnValue === false ?
5415 returnTrue :
5416 returnFalse;
5417
5418 // Create target properties
5419 // Support: Safari <=6 - 7 only
5420 // Target should not be a text node (#504, #13143)
5421 this.target = ( src.target && src.target.nodeType === 3 ) ?
5422 src.target.parentNode :
5423 src.target;
5424
5425 this.currentTarget = src.currentTarget;
5426 this.relatedTarget = src.relatedTarget;
5427
5428 // Event type
5429 } else {
5430 this.type = src;
5431 }
5432
5433 // Put explicitly provided properties onto the event object
5434 if ( props ) {
5435 jQuery.extend( this, props );
5436 }
5437
5438 // Create a timestamp if incoming event doesn't have one
5439 this.timeStamp = src && src.timeStamp || jQuery.now();
5440
5441 // Mark it as fixed
5442 this[ jQuery.expando ] = true;
5443};
5444
5445// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5446// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5447jQuery.Event.prototype = {
5448 constructor: jQuery.Event,
5449 isDefaultPrevented: returnFalse,
5450 isPropagationStopped: returnFalse,
5451 isImmediatePropagationStopped: returnFalse,
5452 isSimulated: false,
5453
5454 preventDefault: function() {
5455 var e = this.originalEvent;
5456
5457 this.isDefaultPrevented = returnTrue;
5458
5459 if ( e && !this.isSimulated ) {
5460 e.preventDefault();
5461 }
5462 },
5463 stopPropagation: function() {
5464 var e = this.originalEvent;
5465
5466 this.isPropagationStopped = returnTrue;
5467
5468 if ( e && !this.isSimulated ) {
5469 e.stopPropagation();
5470 }
5471 },
5472 stopImmediatePropagation: function() {
5473 var e = this.originalEvent;
5474
5475 this.isImmediatePropagationStopped = returnTrue;
5476
5477 if ( e && !this.isSimulated ) {
5478 e.stopImmediatePropagation();
5479 }
5480
5481 this.stopPropagation();
5482 }
5483};
5484
5485// Includes all common event props including KeyEvent and MouseEvent specific props
5486jQuery.each( {
5487 altKey: true,
5488 bubbles: true,
5489 cancelable: true,
5490 changedTouches: true,
5491 ctrlKey: true,
5492 detail: true,
5493 eventPhase: true,
5494 metaKey: true,
5495 pageX: true,
5496 pageY: true,
5497 shiftKey: true,
5498 view: true,
5499 "char": true,
5500 charCode: true,
5501 key: true,
5502 keyCode: true,
5503 button: true,
5504 buttons: true,
5505 clientX: true,
5506 clientY: true,
5507 offsetX: true,
5508 offsetY: true,
5509 pointerId: true,
5510 pointerType: true,
5511 screenX: true,
5512 screenY: true,
5513 targetTouches: true,
5514 toElement: true,
5515 touches: true,
5516
5517 which: function( event ) {
5518 var button = event.button;
5519
5520 // Add which for key events
5521 if ( event.which == null && rkeyEvent.test( event.type ) ) {
5522 return event.charCode != null ? event.charCode : event.keyCode;
5523 }
5524
5525 // Add which for click: 1 === left; 2 === middle; 3 === right
5526 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
5527 if ( button & 1 ) {
5528 return 1;
5529 }
5530
5531 if ( button & 2 ) {
5532 return 3;
5533 }
5534
5535 if ( button & 4 ) {
5536 return 2;
5537 }
5538
5539 return 0;
5540 }
5541
5542 return event.which;
5543 }
5544}, jQuery.event.addProp );
5545
5546// Create mouseenter/leave events using mouseover/out and event-time checks
5547// so that event delegation works in jQuery.
5548// Do the same for pointerenter/pointerleave and pointerover/pointerout
5549//
5550// Support: Safari 7 only
5551// Safari sends mouseenter too often; see:
5552// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5553// for the description of the bug (it existed in older Chrome versions as well).
5554jQuery.each( {
5555 mouseenter: "mouseover",
5556 mouseleave: "mouseout",
5557 pointerenter: "pointerover",
5558 pointerleave: "pointerout"
5559}, function( orig, fix ) {
5560 jQuery.event.special[ orig ] = {
5561 delegateType: fix,
5562 bindType: fix,
5563
5564 handle: function( event ) {
5565 var ret,
5566 target = this,
5567 related = event.relatedTarget,
5568 handleObj = event.handleObj;
5569
5570 // For mouseenter/leave call the handler if related is outside the target.
5571 // NB: No relatedTarget if the mouse left/entered the browser window
5572 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5573 event.type = handleObj.origType;
5574 ret = handleObj.handler.apply( this, arguments );
5575 event.type = fix;
5576 }
5577 return ret;
5578 }
5579 };
5580} );
5581
5582jQuery.fn.extend( {
5583
5584 on: function( types, selector, data, fn ) {
5585 return on( this, types, selector, data, fn );
5586 },
5587 one: function( types, selector, data, fn ) {
5588 return on( this, types, selector, data, fn, 1 );
5589 },
5590 off: function( types, selector, fn ) {
5591 var handleObj, type;
5592 if ( types && types.preventDefault && types.handleObj ) {
5593
5594 // ( event ) dispatched jQuery.Event
5595 handleObj = types.handleObj;
5596 jQuery( types.delegateTarget ).off(
5597 handleObj.namespace ?
5598 handleObj.origType + "." + handleObj.namespace :
5599 handleObj.origType,
5600 handleObj.selector,
5601 handleObj.handler
5602 );
5603 return this;
5604 }
5605 if ( typeof types === "object" ) {
5606
5607 // ( types-object [, selector] )
5608 for ( type in types ) {
5609 this.off( type, selector, types[ type ] );
5610 }
5611 return this;
5612 }
5613 if ( selector === false || typeof selector === "function" ) {
5614
5615 // ( types [, fn] )
5616 fn = selector;
5617 selector = undefined;
5618 }
5619 if ( fn === false ) {
5620 fn = returnFalse;
5621 }
5622 return this.each( function() {
5623 jQuery.event.remove( this, types, fn, selector );
5624 } );
5625 }
5626} );
5627
5628
5629var
5630
5631 /* eslint-disable max-len */
5632
5633 // See https://github.com/eslint/eslint/issues/3229
5634 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
5635
5636 /* eslint-enable */
5637
5638 // Support: IE <=10 - 11, Edge 12 - 13
5639 // In IE/Edge using regex groups here causes severe slowdowns.
5640 // See https://connect.microsoft.com/IE/feedback/details/1736512/
5641 rnoInnerhtml = /<script|<style|<link/i,
5642
5643 // checked="checked" or checked
5644 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5645 rscriptTypeMasked = /^true\/(.*)/,
5646 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5647
5648// Prefer a tbody over its parent table for containing new rows
5649function manipulationTarget( elem, content ) {
5650 if ( nodeName( elem, "table" ) &&
5651 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
5652
5653 return jQuery( ">tbody", elem )[ 0 ] || elem;
5654 }
5655
5656 return elem;
5657}
5658
5659// Replace/restore the type attribute of script elements for safe DOM manipulation
5660function disableScript( elem ) {
5661 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5662 return elem;
5663}
5664function restoreScript( elem ) {
5665 var match = rscriptTypeMasked.exec( elem.type );
5666
5667 if ( match ) {
5668 elem.type = match[ 1 ];
5669 } else {
5670 elem.removeAttribute( "type" );
5671 }
5672
5673 return elem;
5674}
5675
5676function cloneCopyEvent( src, dest ) {
5677 var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
5678
5679 if ( dest.nodeType !== 1 ) {
5680 return;
5681 }
5682
5683 // 1. Copy private data: events, handlers, etc.
5684 if ( dataPriv.hasData( src ) ) {
5685 pdataOld = dataPriv.access( src );
5686 pdataCur = dataPriv.set( dest, pdataOld );
5687 events = pdataOld.events;
5688
5689 if ( events ) {
5690 delete pdataCur.handle;
5691 pdataCur.events = {};
5692
5693 for ( type in events ) {
5694 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5695 jQuery.event.add( dest, type, events[ type ][ i ] );
5696 }
5697 }
5698 }
5699 }
5700
5701 // 2. Copy user data
5702 if ( dataUser.hasData( src ) ) {
5703 udataOld = dataUser.access( src );
5704 udataCur = jQuery.extend( {}, udataOld );
5705
5706 dataUser.set( dest, udataCur );
5707 }
5708}
5709
5710// Fix IE bugs, see support tests
5711function fixInput( src, dest ) {
5712 var nodeName = dest.nodeName.toLowerCase();
5713
5714 // Fails to persist the checked state of a cloned checkbox or radio button.
5715 if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5716 dest.checked = src.checked;
5717
5718 // Fails to return the selected option to the default selected state when cloning options
5719 } else if ( nodeName === "input" || nodeName === "textarea" ) {
5720 dest.defaultValue = src.defaultValue;
5721 }
5722}
5723
5724function domManip( collection, args, callback, ignored ) {
5725
5726 // Flatten any nested arrays
5727 args = concat.apply( [], args );
5728
5729 var fragment, first, scripts, hasScripts, node, doc,
5730 i = 0,
5731 l = collection.length,
5732 iNoClone = l - 1,
5733 value = args[ 0 ],
5734 isFunction = jQuery.isFunction( value );
5735
5736 // We can't cloneNode fragments that contain checked, in WebKit
5737 if ( isFunction ||
5738 ( l > 1 && typeof value === "string" &&
5739 !support.checkClone && rchecked.test( value ) ) ) {
5740 return collection.each( function( index ) {
5741 var self = collection.eq( index );
5742 if ( isFunction ) {
5743 args[ 0 ] = value.call( this, index, self.html() );
5744 }
5745 domManip( self, args, callback, ignored );
5746 } );
5747 }
5748
5749 if ( l ) {
5750 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
5751 first = fragment.firstChild;
5752
5753 if ( fragment.childNodes.length === 1 ) {
5754 fragment = first;
5755 }
5756
5757 // Require either new content or an interest in ignored elements to invoke the callback
5758 if ( first || ignored ) {
5759 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5760 hasScripts = scripts.length;
5761
5762 // Use the original fragment for the last item
5763 // instead of the first because it can end up
5764 // being emptied incorrectly in certain situations (#8070).
5765 for ( ; i < l; i++ ) {
5766 node = fragment;
5767
5768 if ( i !== iNoClone ) {
5769 node = jQuery.clone( node, true, true );
5770
5771 // Keep references to cloned scripts for later restoration
5772 if ( hasScripts ) {
5773
5774 // Support: Android <=4.0 only, PhantomJS 1 only
5775 // push.apply(_, arraylike) throws on ancient WebKit
5776 jQuery.merge( scripts, getAll( node, "script" ) );
5777 }
5778 }
5779
5780 callback.call( collection[ i ], node, i );
5781 }
5782
5783 if ( hasScripts ) {
5784 doc = scripts[ scripts.length - 1 ].ownerDocument;
5785
5786 // Reenable scripts
5787 jQuery.map( scripts, restoreScript );
5788
5789 // Evaluate executable scripts on first document insertion
5790 for ( i = 0; i < hasScripts; i++ ) {
5791 node = scripts[ i ];
5792 if ( rscriptType.test( node.type || "" ) &&
5793 !dataPriv.access( node, "globalEval" ) &&
5794 jQuery.contains( doc, node ) ) {
5795
5796 if ( node.src ) {
5797
5798 // Optional AJAX dependency, but won't run scripts if not present
5799 if ( jQuery._evalUrl ) {
5800 jQuery._evalUrl( node.src );
5801 }
5802 } else {
5803 DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
5804 }
5805 }
5806 }
5807 }
5808 }
5809 }
5810
5811 return collection;
5812}
5813
5814function remove( elem, selector, keepData ) {
5815 var node,
5816 nodes = selector ? jQuery.filter( selector, elem ) : elem,
5817 i = 0;
5818
5819 for ( ; ( node = nodes[ i ] ) != null; i++ ) {
5820 if ( !keepData && node.nodeType === 1 ) {
5821 jQuery.cleanData( getAll( node ) );
5822 }
5823
5824 if ( node.parentNode ) {
5825 if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
5826 setGlobalEval( getAll( node, "script" ) );
5827 }
5828 node.parentNode.removeChild( node );
5829 }
5830 }
5831
5832 return elem;
5833}
5834
5835jQuery.extend( {
5836 htmlPrefilter: function( html ) {
5837 return html.replace( rxhtmlTag, "<$1></$2>" );
5838 },
5839
5840 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5841 var i, l, srcElements, destElements,
5842 clone = elem.cloneNode( true ),
5843 inPage = jQuery.contains( elem.ownerDocument, elem );
5844
5845 // Fix IE cloning issues
5846 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5847 !jQuery.isXMLDoc( elem ) ) {
5848
5849 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
5850 destElements = getAll( clone );
5851 srcElements = getAll( elem );
5852
5853 for ( i = 0, l = srcElements.length; i < l; i++ ) {
5854 fixInput( srcElements[ i ], destElements[ i ] );
5855 }
5856 }
5857
5858 // Copy the events from the original to the clone
5859 if ( dataAndEvents ) {
5860 if ( deepDataAndEvents ) {
5861 srcElements = srcElements || getAll( elem );
5862 destElements = destElements || getAll( clone );
5863
5864 for ( i = 0, l = srcElements.length; i < l; i++ ) {
5865 cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5866 }
5867 } else {
5868 cloneCopyEvent( elem, clone );
5869 }
5870 }
5871
5872 // Preserve script evaluation history
5873 destElements = getAll( clone, "script" );
5874 if ( destElements.length > 0 ) {
5875 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5876 }
5877
5878 // Return the cloned set
5879 return clone;
5880 },
5881
5882 cleanData: function( elems ) {
5883 var data, elem, type,
5884 special = jQuery.event.special,
5885 i = 0;
5886
5887 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
5888 if ( acceptData( elem ) ) {
5889 if ( ( data = elem[ dataPriv.expando ] ) ) {
5890 if ( data.events ) {
5891 for ( type in data.events ) {
5892 if ( special[ type ] ) {
5893 jQuery.event.remove( elem, type );
5894
5895 // This is a shortcut to avoid jQuery.event.remove's overhead
5896 } else {
5897 jQuery.removeEvent( elem, type, data.handle );
5898 }
5899 }
5900 }
5901
5902 // Support: Chrome <=35 - 45+
5903 // Assign undefined instead of using delete, see Data#remove
5904 elem[ dataPriv.expando ] = undefined;
5905 }
5906 if ( elem[ dataUser.expando ] ) {
5907
5908 // Support: Chrome <=35 - 45+
5909 // Assign undefined instead of using delete, see Data#remove
5910 elem[ dataUser.expando ] = undefined;
5911 }
5912 }
5913 }
5914 }
5915} );
5916
5917jQuery.fn.extend( {
5918 detach: function( selector ) {
5919 return remove( this, selector, true );
5920 },
5921
5922 remove: function( selector ) {
5923 return remove( this, selector );
5924 },
5925
5926 text: function( value ) {
5927 return access( this, function( value ) {
5928 return value === undefined ?
5929 jQuery.text( this ) :
5930 this.empty().each( function() {
5931 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5932 this.textContent = value;
5933 }
5934 } );
5935 }, null, value, arguments.length );
5936 },
5937
5938 append: function() {
5939 return domManip( this, arguments, function( elem ) {
5940 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5941 var target = manipulationTarget( this, elem );
5942 target.appendChild( elem );
5943 }
5944 } );
5945 },
5946
5947 prepend: function() {
5948 return domManip( this, arguments, function( elem ) {
5949 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5950 var target = manipulationTarget( this, elem );
5951 target.insertBefore( elem, target.firstChild );
5952 }
5953 } );
5954 },
5955
5956 before: function() {
5957 return domManip( this, arguments, function( elem ) {
5958 if ( this.parentNode ) {
5959 this.parentNode.insertBefore( elem, this );
5960 }
5961 } );
5962 },
5963
5964 after: function() {
5965 return domManip( this, arguments, function( elem ) {
5966 if ( this.parentNode ) {
5967 this.parentNode.insertBefore( elem, this.nextSibling );
5968 }
5969 } );
5970 },
5971
5972 empty: function() {
5973 var elem,
5974 i = 0;
5975
5976 for ( ; ( elem = this[ i ] ) != null; i++ ) {
5977 if ( elem.nodeType === 1 ) {
5978
5979 // Prevent memory leaks
5980 jQuery.cleanData( getAll( elem, false ) );
5981
5982 // Remove any remaining nodes
5983 elem.textContent = "";
5984 }
5985 }
5986
5987 return this;
5988 },
5989
5990 clone: function( dataAndEvents, deepDataAndEvents ) {
5991 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5992 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5993
5994 return this.map( function() {
5995 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5996 } );
5997 },
5998
5999 html: function( value ) {
6000 return access( this, function( value ) {
6001 var elem = this[ 0 ] || {},
6002 i = 0,
6003 l = this.length;
6004
6005 if ( value === undefined && elem.nodeType === 1 ) {
6006 return elem.innerHTML;
6007 }
6008
6009 // See if we can take a shortcut and just use innerHTML
6010 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6011 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6012
6013 value = jQuery.htmlPrefilter( value );
6014
6015 try {
6016 for ( ; i < l; i++ ) {
6017 elem = this[ i ] || {};
6018
6019 // Remove element nodes and prevent memory leaks
6020 if ( elem.nodeType === 1 ) {
6021 jQuery.cleanData( getAll( elem, false ) );
6022 elem.innerHTML = value;
6023 }
6024 }
6025
6026 elem = 0;
6027
6028 // If using innerHTML throws an exception, use the fallback method
6029 } catch ( e ) {}
6030 }
6031
6032 if ( elem ) {
6033 this.empty().append( value );
6034 }
6035 }, null, value, arguments.length );
6036 },
6037
6038 replaceWith: function() {
6039 var ignored = [];
6040
6041 // Make the changes, replacing each non-ignored context element with the new content
6042 return domManip( this, arguments, function( elem ) {
6043 var parent = this.parentNode;
6044
6045 if ( jQuery.inArray( this, ignored ) < 0 ) {
6046 jQuery.cleanData( getAll( this ) );
6047 if ( parent ) {
6048 parent.replaceChild( elem, this );
6049 }
6050 }
6051
6052 // Force callback invocation
6053 }, ignored );
6054 }
6055} );
6056
6057jQuery.each( {
6058 appendTo: "append",
6059 prependTo: "prepend",
6060 insertBefore: "before",
6061 insertAfter: "after",
6062 replaceAll: "replaceWith"
6063}, function( name, original ) {
6064 jQuery.fn[ name ] = function( selector ) {
6065 var elems,
6066 ret = [],
6067 insert = jQuery( selector ),
6068 last = insert.length - 1,
6069 i = 0;
6070
6071 for ( ; i <= last; i++ ) {
6072 elems = i === last ? this : this.clone( true );
6073 jQuery( insert[ i ] )[ original ]( elems );
6074
6075 // Support: Android <=4.0 only, PhantomJS 1 only
6076 // .get() because push.apply(_, arraylike) throws on ancient WebKit
6077 push.apply( ret, elems.get() );
6078 }
6079
6080 return this.pushStack( ret );
6081 };
6082} );
6083var rmargin = ( /^margin/ );
6084
6085var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6086
6087var getStyles = function( elem ) {
6088
6089 // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
6090 // IE throws on elements created in popups
6091 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6092 var view = elem.ownerDocument.defaultView;
6093
6094 if ( !view || !view.opener ) {
6095 view = window;
6096 }
6097
6098 return view.getComputedStyle( elem );
6099 };
6100
6101
6102
6103( function() {
6104
6105 // Executing both pixelPosition & boxSizingReliable tests require only one layout
6106 // so they're executed at the same time to save the second computation.
6107 function computeStyleTests() {
6108
6109 // This is a singleton, we need to execute it only once
6110 if ( !div ) {
6111 return;
6112 }
6113
6114 div.style.cssText =
6115 "box-sizing:border-box;" +
6116 "position:relative;display:block;" +
6117 "margin:auto;border:1px;padding:1px;" +
6118 "top:1%;width:50%";
6119 div.innerHTML = "";
6120 documentElement.appendChild( container );
6121
6122 var divStyle = window.getComputedStyle( div );
6123 pixelPositionVal = divStyle.top !== "1%";
6124
6125 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6126 reliableMarginLeftVal = divStyle.marginLeft === "2px";
6127 boxSizingReliableVal = divStyle.width === "4px";
6128
6129 // Support: Android 4.0 - 4.3 only
6130 // Some styles come back with percentage values, even though they shouldn't
6131 div.style.marginRight = "50%";
6132 pixelMarginRightVal = divStyle.marginRight === "4px";
6133
6134 documentElement.removeChild( container );
6135
6136 // Nullify the div so it wouldn't be stored in the memory and
6137 // it will also be a sign that checks already performed
6138 div = null;
6139 }
6140
6141 var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
6142 container = document.createElement( "div" ),
6143 div = document.createElement( "div" );
6144
6145 // Finish early in limited (non-browser) environments
6146 if ( !div.style ) {
6147 return;
6148 }
6149
6150 // Support: IE <=9 - 11 only
6151 // Style of cloned element affects source element cloned (#8908)
6152 div.style.backgroundClip = "content-box";
6153 div.cloneNode( true ).style.backgroundClip = "";
6154 support.clearCloneStyle = div.style.backgroundClip === "content-box";
6155
6156 container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
6157 "padding:0;margin-top:1px;position:absolute";
6158 container.appendChild( div );
6159
6160 jQuery.extend( support, {
6161 pixelPosition: function() {
6162 computeStyleTests();
6163 return pixelPositionVal;
6164 },
6165 boxSizingReliable: function() {
6166 computeStyleTests();
6167 return boxSizingReliableVal;
6168 },
6169 pixelMarginRight: function() {
6170 computeStyleTests();
6171 return pixelMarginRightVal;
6172 },
6173 reliableMarginLeft: function() {
6174 computeStyleTests();
6175 return reliableMarginLeftVal;
6176 }
6177 } );
6178} )();
6179
6180
6181function curCSS( elem, name, computed ) {
6182 var width, minWidth, maxWidth, ret,
6183
6184 // Support: Firefox 51+
6185 // Retrieving style before computed somehow
6186 // fixes an issue with getting wrong values
6187 // on detached elements
6188 style = elem.style;
6189
6190 computed = computed || getStyles( elem );
6191
6192 // getPropertyValue is needed for:
6193 // .css('filter') (IE 9 only, #12537)
6194 // .css('--customProperty) (#3144)
6195 if ( computed ) {
6196 ret = computed.getPropertyValue( name ) || computed[ name ];
6197
6198 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6199 ret = jQuery.style( elem, name );
6200 }
6201
6202 // A tribute to the "awesome hack by Dean Edwards"
6203 // Android Browser returns percentage for some values,
6204 // but width seems to be reliably pixels.
6205 // This is against the CSSOM draft spec:
6206 // https://drafts.csswg.org/cssom/#resolved-values
6207 if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6208
6209 // Remember the original values
6210 width = style.width;
6211 minWidth = style.minWidth;
6212 maxWidth = style.maxWidth;
6213
6214 // Put in the new values to get a computed value out
6215 style.minWidth = style.maxWidth = style.width = ret;
6216 ret = computed.width;
6217
6218 // Revert the changed values
6219 style.width = width;
6220 style.minWidth = minWidth;
6221 style.maxWidth = maxWidth;
6222 }
6223 }
6224
6225 return ret !== undefined ?
6226
6227 // Support: IE <=9 - 11 only
6228 // IE returns zIndex value as an integer.
6229 ret + "" :
6230 ret;
6231}
6232
6233
6234function addGetHookIf( conditionFn, hookFn ) {
6235
6236 // Define the hook, we'll check on the first run if it's really needed.
6237 return {
6238 get: function() {
6239 if ( conditionFn() ) {
6240
6241 // Hook not needed (or it's not possible to use it due
6242 // to missing dependency), remove it.
6243 delete this.get;
6244 return;
6245 }
6246
6247 // Hook needed; redefine it so that the support test is not executed again.
6248 return ( this.get = hookFn ).apply( this, arguments );
6249 }
6250 };
6251}
6252
6253
6254var
6255
6256 // Swappable if display is none or starts with table
6257 // except "table", "table-cell", or "table-caption"
6258 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6259 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6260 rcustomProp = /^--/,
6261 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6262 cssNormalTransform = {
6263 letterSpacing: "0",
6264 fontWeight: "400"
6265 },
6266
6267 cssPrefixes = [ "Webkit", "Moz", "ms" ],
6268 emptyStyle = document.createElement( "div" ).style;
6269
6270// Return a css property mapped to a potentially vendor prefixed property
6271function vendorPropName( name ) {
6272
6273 // Shortcut for names that are not vendor prefixed
6274 if ( name in emptyStyle ) {
6275 return name;
6276 }
6277
6278 // Check for vendor prefixed names
6279 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
6280 i = cssPrefixes.length;
6281
6282 while ( i-- ) {
6283 name = cssPrefixes[ i ] + capName;
6284 if ( name in emptyStyle ) {
6285 return name;
6286 }
6287 }
6288}
6289
6290// Return a property mapped along what jQuery.cssProps suggests or to
6291// a vendor prefixed property.
6292function finalPropName( name ) {
6293 var ret = jQuery.cssProps[ name ];
6294 if ( !ret ) {
6295 ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
6296 }
6297 return ret;
6298}
6299
6300function setPositiveNumber( elem, value, subtract ) {
6301
6302 // Any relative (+/-) values have already been
6303 // normalized at this point
6304 var matches = rcssNum.exec( value );
6305 return matches ?
6306
6307 // Guard against undefined "subtract", e.g., when used as in cssHooks
6308 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
6309 value;
6310}
6311
6312function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6313 var i,
6314 val = 0;
6315
6316 // If we already have the right measurement, avoid augmentation
6317 if ( extra === ( isBorderBox ? "border" : "content" ) ) {
6318 i = 4;
6319
6320 // Otherwise initialize for horizontal or vertical properties
6321 } else {
6322 i = name === "width" ? 1 : 0;
6323 }
6324
6325 for ( ; i < 4; i += 2 ) {
6326
6327 // Both box models exclude margin, so add it if we want it
6328 if ( extra === "margin" ) {
6329 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6330 }
6331
6332 if ( isBorderBox ) {
6333
6334 // border-box includes padding, so remove it if we want content
6335 if ( extra === "content" ) {
6336 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6337 }
6338
6339 // At this point, extra isn't border nor margin, so remove border
6340 if ( extra !== "margin" ) {
6341 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6342 }
6343 } else {
6344
6345 // At this point, extra isn't content, so add padding
6346 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6347
6348 // At this point, extra isn't content nor padding, so add border
6349 if ( extra !== "padding" ) {
6350 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6351 }
6352 }
6353 }
6354
6355 return val;
6356}
6357
6358function getWidthOrHeight( elem, name, extra ) {
6359
6360 // Start with computed style
6361 var valueIsBorderBox,
6362 styles = getStyles( elem ),
6363 val = curCSS( elem, name, styles ),
6364 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6365
6366 // Computed unit is not pixels. Stop here and return.
6367 if ( rnumnonpx.test( val ) ) {
6368 return val;
6369 }
6370
6371 // Check for style in case a browser which returns unreliable values
6372 // for getComputedStyle silently falls back to the reliable elem.style
6373 valueIsBorderBox = isBorderBox &&
6374 ( support.boxSizingReliable() || val === elem.style[ name ] );
6375
6376 // Fall back to offsetWidth/Height when value is "auto"
6377 // This happens for inline elements with no explicit setting (gh-3571)
6378 if ( val === "auto" ) {
6379 val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
6380 }
6381
6382 // Normalize "", auto, and prepare for extra
6383 val = parseFloat( val ) || 0;
6384
6385 // Use the active box-sizing model to add/subtract irrelevant styles
6386 return ( val +
6387 augmentWidthOrHeight(
6388 elem,
6389 name,
6390 extra || ( isBorderBox ? "border" : "content" ),
6391 valueIsBorderBox,
6392 styles
6393 )
6394 ) + "px";
6395}
6396
6397jQuery.extend( {
6398
6399 // Add in style property hooks for overriding the default
6400 // behavior of getting and setting a style property
6401 cssHooks: {
6402 opacity: {
6403 get: function( elem, computed ) {
6404 if ( computed ) {
6405
6406 // We should always get a number back from opacity
6407 var ret = curCSS( elem, "opacity" );
6408 return ret === "" ? "1" : ret;
6409 }
6410 }
6411 }
6412 },
6413
6414 // Don't automatically add "px" to these possibly-unitless properties
6415 cssNumber: {
6416 "animationIterationCount": true,
6417 "columnCount": true,
6418 "fillOpacity": true,
6419 "flexGrow": true,
6420 "flexShrink": true,
6421 "fontWeight": true,
6422 "lineHeight": true,
6423 "opacity": true,
6424 "order": true,
6425 "orphans": true,
6426 "widows": true,
6427 "zIndex": true,
6428 "zoom": true
6429 },
6430
6431 // Add in properties whose names you wish to fix before
6432 // setting or getting the value
6433 cssProps: {
6434 "float": "cssFloat"
6435 },
6436
6437 // Get and set the style property on a DOM Node
6438 style: function( elem, name, value, extra ) {
6439
6440 // Don't set styles on text and comment nodes
6441 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6442 return;
6443 }
6444
6445 // Make sure that we're working with the right name
6446 var ret, type, hooks,
6447 origName = jQuery.camelCase( name ),
6448 isCustomProp = rcustomProp.test( name ),
6449 style = elem.style;
6450
6451 // Make sure that we're working with the right name. We don't
6452 // want to query the value if it is a CSS custom property
6453 // since they are user-defined.
6454 if ( !isCustomProp ) {
6455 name = finalPropName( origName );
6456 }
6457
6458 // Gets hook for the prefixed version, then unprefixed version
6459 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6460
6461 // Check if we're setting a value
6462 if ( value !== undefined ) {
6463 type = typeof value;
6464
6465 // Convert "+=" or "-=" to relative numbers (#7345)
6466 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6467 value = adjustCSS( elem, name, ret );
6468
6469 // Fixes bug #9237
6470 type = "number";
6471 }
6472
6473 // Make sure that null and NaN values aren't set (#7116)
6474 if ( value == null || value !== value ) {
6475 return;
6476 }
6477
6478 // If a number was passed in, add the unit (except for certain CSS properties)
6479 if ( type === "number" ) {
6480 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6481 }
6482
6483 // background-* props affect original clone's values
6484 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6485 style[ name ] = "inherit";
6486 }
6487
6488 // If a hook was provided, use that value, otherwise just set the specified value
6489 if ( !hooks || !( "set" in hooks ) ||
6490 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6491
6492 if ( isCustomProp ) {
6493 style.setProperty( name, value );
6494 } else {
6495 style[ name ] = value;
6496 }
6497 }
6498
6499 } else {
6500
6501 // If a hook was provided get the non-computed value from there
6502 if ( hooks && "get" in hooks &&
6503 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6504
6505 return ret;
6506 }
6507
6508 // Otherwise just get the value from the style object
6509 return style[ name ];
6510 }
6511 },
6512
6513 css: function( elem, name, extra, styles ) {
6514 var val, num, hooks,
6515 origName = jQuery.camelCase( name ),
6516 isCustomProp = rcustomProp.test( name );
6517
6518 // Make sure that we're working with the right name. We don't
6519 // want to modify the value if it is a CSS custom property
6520 // since they are user-defined.
6521 if ( !isCustomProp ) {
6522 name = finalPropName( origName );
6523 }
6524
6525 // Try prefixed name followed by the unprefixed name
6526 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6527
6528 // If a hook was provided get the computed value from there
6529 if ( hooks && "get" in hooks ) {
6530 val = hooks.get( elem, true, extra );
6531 }
6532
6533 // Otherwise, if a way to get the computed value exists, use that
6534 if ( val === undefined ) {
6535 val = curCSS( elem, name, styles );
6536 }
6537
6538 // Convert "normal" to computed value
6539 if ( val === "normal" && name in cssNormalTransform ) {
6540 val = cssNormalTransform[ name ];
6541 }
6542
6543 // Make numeric if forced or a qualifier was provided and val looks numeric
6544 if ( extra === "" || extra ) {
6545 num = parseFloat( val );
6546 return extra === true || isFinite( num ) ? num || 0 : val;
6547 }
6548
6549 return val;
6550 }
6551} );
6552
6553jQuery.each( [ "height", "width" ], function( i, name ) {
6554 jQuery.cssHooks[ name ] = {
6555 get: function( elem, computed, extra ) {
6556 if ( computed ) {
6557
6558 // Certain elements can have dimension info if we invisibly show them
6559 // but it must have a current display style that would benefit
6560 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
6561
6562 // Support: Safari 8+
6563 // Table columns in Safari have non-zero offsetWidth & zero
6564 // getBoundingClientRect().width unless display is changed.
6565 // Support: IE <=11 only
6566 // Running getBoundingClientRect on a disconnected node
6567 // in IE throws an error.
6568 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
6569 swap( elem, cssShow, function() {
6570 return getWidthOrHeight( elem, name, extra );
6571 } ) :
6572 getWidthOrHeight( elem, name, extra );
6573 }
6574 },
6575
6576 set: function( elem, value, extra ) {
6577 var matches,
6578 styles = extra && getStyles( elem ),
6579 subtract = extra && augmentWidthOrHeight(
6580 elem,
6581 name,
6582 extra,
6583 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6584 styles
6585 );
6586
6587 // Convert to pixels if value adjustment is needed
6588 if ( subtract && ( matches = rcssNum.exec( value ) ) &&
6589 ( matches[ 3 ] || "px" ) !== "px" ) {
6590
6591 elem.style[ name ] = value;
6592 value = jQuery.css( elem, name );
6593 }
6594
6595 return setPositiveNumber( elem, value, subtract );
6596 }
6597 };
6598} );
6599
6600jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
6601 function( elem, computed ) {
6602 if ( computed ) {
6603 return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
6604 elem.getBoundingClientRect().left -
6605 swap( elem, { marginLeft: 0 }, function() {
6606 return elem.getBoundingClientRect().left;
6607 } )
6608 ) + "px";
6609 }
6610 }
6611);
6612
6613// These hooks are used by animate to expand properties
6614jQuery.each( {
6615 margin: "",
6616 padding: "",
6617 border: "Width"
6618}, function( prefix, suffix ) {
6619 jQuery.cssHooks[ prefix + suffix ] = {
6620 expand: function( value ) {
6621 var i = 0,
6622 expanded = {},
6623
6624 // Assumes a single number if not a string
6625 parts = typeof value === "string" ? value.split( " " ) : [ value ];
6626
6627 for ( ; i < 4; i++ ) {
6628 expanded[ prefix + cssExpand[ i ] + suffix ] =
6629 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6630 }
6631
6632 return expanded;
6633 }
6634 };
6635
6636 if ( !rmargin.test( prefix ) ) {
6637 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6638 }
6639} );
6640
6641jQuery.fn.extend( {
6642 css: function( name, value ) {
6643 return access( this, function( elem, name, value ) {
6644 var styles, len,
6645 map = {},
6646 i = 0;
6647
6648 if ( Array.isArray( name ) ) {
6649 styles = getStyles( elem );
6650 len = name.length;
6651
6652 for ( ; i < len; i++ ) {
6653 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6654 }
6655
6656 return map;
6657 }
6658
6659 return value !== undefined ?
6660 jQuery.style( elem, name, value ) :
6661 jQuery.css( elem, name );
6662 }, name, value, arguments.length > 1 );
6663 }
6664} );
6665
6666
6667function Tween( elem, options, prop, end, easing ) {
6668 return new Tween.prototype.init( elem, options, prop, end, easing );
6669}
6670jQuery.Tween = Tween;
6671
6672Tween.prototype = {
6673 constructor: Tween,
6674 init: function( elem, options, prop, end, easing, unit ) {
6675 this.elem = elem;
6676 this.prop = prop;
6677 this.easing = easing || jQuery.easing._default;
6678 this.options = options;
6679 this.start = this.now = this.cur();
6680 this.end = end;
6681 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6682 },
6683 cur: function() {
6684 var hooks = Tween.propHooks[ this.prop ];
6685
6686 return hooks && hooks.get ?
6687 hooks.get( this ) :
6688 Tween.propHooks._default.get( this );
6689 },
6690 run: function( percent ) {
6691 var eased,
6692 hooks = Tween.propHooks[ this.prop ];
6693
6694 if ( this.options.duration ) {
6695 this.pos = eased = jQuery.easing[ this.easing ](
6696 percent, this.options.duration * percent, 0, 1, this.options.duration
6697 );
6698 } else {
6699 this.pos = eased = percent;
6700 }
6701 this.now = ( this.end - this.start ) * eased + this.start;
6702
6703 if ( this.options.step ) {
6704 this.options.step.call( this.elem, this.now, this );
6705 }
6706
6707 if ( hooks && hooks.set ) {
6708 hooks.set( this );
6709 } else {
6710 Tween.propHooks._default.set( this );
6711 }
6712 return this;
6713 }
6714};
6715
6716Tween.prototype.init.prototype = Tween.prototype;
6717
6718Tween.propHooks = {
6719 _default: {
6720 get: function( tween ) {
6721 var result;
6722
6723 // Use a property on the element directly when it is not a DOM element,
6724 // or when there is no matching style property that exists.
6725 if ( tween.elem.nodeType !== 1 ||
6726 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
6727 return tween.elem[ tween.prop ];
6728 }
6729
6730 // Passing an empty string as a 3rd parameter to .css will automatically
6731 // attempt a parseFloat and fallback to a string if the parse fails.
6732 // Simple values such as "10px" are parsed to Float;
6733 // complex values such as "rotate(1rad)" are returned as-is.
6734 result = jQuery.css( tween.elem, tween.prop, "" );
6735
6736 // Empty strings, null, undefined and "auto" are converted to 0.
6737 return !result || result === "auto" ? 0 : result;
6738 },
6739 set: function( tween ) {
6740
6741 // Use step hook for back compat.
6742 // Use cssHook if its there.
6743 // Use .style if available and use plain properties where available.
6744 if ( jQuery.fx.step[ tween.prop ] ) {
6745 jQuery.fx.step[ tween.prop ]( tween );
6746 } else if ( tween.elem.nodeType === 1 &&
6747 ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
6748 jQuery.cssHooks[ tween.prop ] ) ) {
6749 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6750 } else {
6751 tween.elem[ tween.prop ] = tween.now;
6752 }
6753 }
6754 }
6755};
6756
6757// Support: IE <=9 only
6758// Panic based approach to setting things on disconnected nodes
6759Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6760 set: function( tween ) {
6761 if ( tween.elem.nodeType && tween.elem.parentNode ) {
6762 tween.elem[ tween.prop ] = tween.now;
6763 }
6764 }
6765};
6766
6767jQuery.easing = {
6768 linear: function( p ) {
6769 return p;
6770 },
6771 swing: function( p ) {
6772 return 0.5 - Math.cos( p * Math.PI ) / 2;
6773 },
6774 _default: "swing"
6775};
6776
6777jQuery.fx = Tween.prototype.init;
6778
6779// Back compat <1.8 extension point
6780jQuery.fx.step = {};
6781
6782
6783
6784
6785var
6786 fxNow, inProgress,
6787 rfxtypes = /^(?:toggle|show|hide)$/,
6788 rrun = /queueHooks$/;
6789
6790function schedule() {
6791 if ( inProgress ) {
6792 if ( document.hidden === false && window.requestAnimationFrame ) {
6793 window.requestAnimationFrame( schedule );
6794 } else {
6795 window.setTimeout( schedule, jQuery.fx.interval );
6796 }
6797
6798 jQuery.fx.tick();
6799 }
6800}
6801
6802// Animations created synchronously will run synchronously
6803function createFxNow() {
6804 window.setTimeout( function() {
6805 fxNow = undefined;
6806 } );
6807 return ( fxNow = jQuery.now() );
6808}
6809
6810// Generate parameters to create a standard animation
6811function genFx( type, includeWidth ) {
6812 var which,
6813 i = 0,
6814 attrs = { height: type };
6815
6816 // If we include width, step value is 1 to do all cssExpand values,
6817 // otherwise step value is 2 to skip over Left and Right
6818 includeWidth = includeWidth ? 1 : 0;
6819 for ( ; i < 4; i += 2 - includeWidth ) {
6820 which = cssExpand[ i ];
6821 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6822 }
6823
6824 if ( includeWidth ) {
6825 attrs.opacity = attrs.width = type;
6826 }
6827
6828 return attrs;
6829}
6830
6831function createTween( value, prop, animation ) {
6832 var tween,
6833 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
6834 index = 0,
6835 length = collection.length;
6836 for ( ; index < length; index++ ) {
6837 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
6838
6839 // We're done with this property
6840 return tween;
6841 }
6842 }
6843}
6844
6845function defaultPrefilter( elem, props, opts ) {
6846 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
6847 isBox = "width" in props || "height" in props,
6848 anim = this,
6849 orig = {},
6850 style = elem.style,
6851 hidden = elem.nodeType && isHiddenWithinTree( elem ),
6852 dataShow = dataPriv.get( elem, "fxshow" );
6853
6854 // Queue-skipping animations hijack the fx hooks
6855 if ( !opts.queue ) {
6856 hooks = jQuery._queueHooks( elem, "fx" );
6857 if ( hooks.unqueued == null ) {
6858 hooks.unqueued = 0;
6859 oldfire = hooks.empty.fire;
6860 hooks.empty.fire = function() {
6861 if ( !hooks.unqueued ) {
6862 oldfire();
6863 }
6864 };
6865 }
6866 hooks.unqueued++;
6867
6868 anim.always( function() {
6869
6870 // Ensure the complete handler is called before this completes
6871 anim.always( function() {
6872 hooks.unqueued--;
6873 if ( !jQuery.queue( elem, "fx" ).length ) {
6874 hooks.empty.fire();
6875 }
6876 } );
6877 } );
6878 }
6879
6880 // Detect show/hide animations
6881 for ( prop in props ) {
6882 value = props[ prop ];
6883 if ( rfxtypes.test( value ) ) {
6884 delete props[ prop ];
6885 toggle = toggle || value === "toggle";
6886 if ( value === ( hidden ? "hide" : "show" ) ) {
6887
6888 // Pretend to be hidden if this is a "show" and
6889 // there is still data from a stopped show/hide
6890 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6891 hidden = true;
6892
6893 // Ignore all other no-op show/hide data
6894 } else {
6895 continue;
6896 }
6897 }
6898 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6899 }
6900 }
6901
6902 // Bail out if this is a no-op like .hide().hide()
6903 propTween = !jQuery.isEmptyObject( props );
6904 if ( !propTween && jQuery.isEmptyObject( orig ) ) {
6905 return;
6906 }
6907
6908 // Restrict "overflow" and "display" styles during box animations
6909 if ( isBox && elem.nodeType === 1 ) {
6910
6911 // Support: IE <=9 - 11, Edge 12 - 13
6912 // Record all 3 overflow attributes because IE does not infer the shorthand
6913 // from identically-valued overflowX and overflowY
6914 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6915
6916 // Identify a display type, preferring old show/hide data over the CSS cascade
6917 restoreDisplay = dataShow && dataShow.display;
6918 if ( restoreDisplay == null ) {
6919 restoreDisplay = dataPriv.get( elem, "display" );
6920 }
6921 display = jQuery.css( elem, "display" );
6922 if ( display === "none" ) {
6923 if ( restoreDisplay ) {
6924 display = restoreDisplay;
6925 } else {
6926
6927 // Get nonempty value(s) by temporarily forcing visibility
6928 showHide( [ elem ], true );
6929 restoreDisplay = elem.style.display || restoreDisplay;
6930 display = jQuery.css( elem, "display" );
6931 showHide( [ elem ] );
6932 }
6933 }
6934
6935 // Animate inline elements as inline-block
6936 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
6937 if ( jQuery.css( elem, "float" ) === "none" ) {
6938
6939 // Restore the original display value at the end of pure show/hide animations
6940 if ( !propTween ) {
6941 anim.done( function() {
6942 style.display = restoreDisplay;
6943 } );
6944 if ( restoreDisplay == null ) {
6945 display = style.display;
6946 restoreDisplay = display === "none" ? "" : display;
6947 }
6948 }
6949 style.display = "inline-block";
6950 }
6951 }
6952 }
6953
6954 if ( opts.overflow ) {
6955 style.overflow = "hidden";
6956 anim.always( function() {
6957 style.overflow = opts.overflow[ 0 ];
6958 style.overflowX = opts.overflow[ 1 ];
6959 style.overflowY = opts.overflow[ 2 ];
6960 } );
6961 }
6962
6963 // Implement show/hide animations
6964 propTween = false;
6965 for ( prop in orig ) {
6966
6967 // General show/hide setup for this element animation
6968 if ( !propTween ) {
6969 if ( dataShow ) {
6970 if ( "hidden" in dataShow ) {
6971 hidden = dataShow.hidden;
6972 }
6973 } else {
6974 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
6975 }
6976
6977 // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
6978 if ( toggle ) {
6979 dataShow.hidden = !hidden;
6980 }
6981
6982 // Show elements before animating them
6983 if ( hidden ) {
6984 showHide( [ elem ], true );
6985 }
6986
6987 /* eslint-disable no-loop-func */
6988
6989 anim.done( function() {
6990
6991 /* eslint-enable no-loop-func */
6992
6993 // The final step of a "hide" animation is actually hiding the element
6994 if ( !hidden ) {
6995 showHide( [ elem ] );
6996 }
6997 dataPriv.remove( elem, "fxshow" );
6998 for ( prop in orig ) {
6999 jQuery.style( elem, prop, orig[ prop ] );
7000 }
7001 } );
7002 }
7003
7004 // Per-property setup
7005 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7006 if ( !( prop in dataShow ) ) {
7007 dataShow[ prop ] = propTween.start;
7008 if ( hidden ) {
7009 propTween.end = propTween.start;
7010 propTween.start = 0;
7011 }
7012 }
7013 }
7014}
7015
7016function propFilter( props, specialEasing ) {
7017 var index, name, easing, value, hooks;
7018
7019 // camelCase, specialEasing and expand cssHook pass
7020 for ( index in props ) {
7021 name = jQuery.camelCase( index );
7022 easing = specialEasing[ name ];
7023 value = props[ index ];
7024 if ( Array.isArray( value ) ) {
7025 easing = value[ 1 ];
7026 value = props[ index ] = value[ 0 ];
7027 }
7028
7029 if ( index !== name ) {
7030 props[ name ] = value;
7031 delete props[ index ];
7032 }
7033
7034 hooks = jQuery.cssHooks[ name ];
7035 if ( hooks && "expand" in hooks ) {
7036 value = hooks.expand( value );
7037 delete props[ name ];
7038
7039 // Not quite $.extend, this won't overwrite existing keys.
7040 // Reusing 'index' because we have the correct "name"
7041 for ( index in value ) {
7042 if ( !( index in props ) ) {
7043 props[ index ] = value[ index ];
7044 specialEasing[ index ] = easing;
7045 }
7046 }
7047 } else {
7048 specialEasing[ name ] = easing;
7049 }
7050 }
7051}
7052
7053function Animation( elem, properties, options ) {
7054 var result,
7055 stopped,
7056 index = 0,
7057 length = Animation.prefilters.length,
7058 deferred = jQuery.Deferred().always( function() {
7059
7060 // Don't match elem in the :animated selector
7061 delete tick.elem;
7062 } ),
7063 tick = function() {
7064 if ( stopped ) {
7065 return false;
7066 }
7067 var currentTime = fxNow || createFxNow(),
7068 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7069
7070 // Support: Android 2.3 only
7071 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7072 temp = remaining / animation.duration || 0,
7073 percent = 1 - temp,
7074 index = 0,
7075 length = animation.tweens.length;
7076
7077 for ( ; index < length; index++ ) {
7078 animation.tweens[ index ].run( percent );
7079 }
7080
7081 deferred.notifyWith( elem, [ animation, percent, remaining ] );
7082
7083 // If there's more to do, yield
7084 if ( percent < 1 && length ) {
7085 return remaining;
7086 }
7087
7088 // If this was an empty animation, synthesize a final progress notification
7089 if ( !length ) {
7090 deferred.notifyWith( elem, [ animation, 1, 0 ] );
7091 }
7092
7093 // Resolve the animation and report its conclusion
7094 deferred.resolveWith( elem, [ animation ] );
7095 return false;
7096 },
7097 animation = deferred.promise( {
7098 elem: elem,
7099 props: jQuery.extend( {}, properties ),
7100 opts: jQuery.extend( true, {
7101 specialEasing: {},
7102 easing: jQuery.easing._default
7103 }, options ),
7104 originalProperties: properties,
7105 originalOptions: options,
7106 startTime: fxNow || createFxNow(),
7107 duration: options.duration,
7108 tweens: [],
7109 createTween: function( prop, end ) {
7110 var tween = jQuery.Tween( elem, animation.opts, prop, end,
7111 animation.opts.specialEasing[ prop ] || animation.opts.easing );
7112 animation.tweens.push( tween );
7113 return tween;
7114 },
7115 stop: function( gotoEnd ) {
7116 var index = 0,
7117
7118 // If we are going to the end, we want to run all the tweens
7119 // otherwise we skip this part
7120 length = gotoEnd ? animation.tweens.length : 0;
7121 if ( stopped ) {
7122 return this;
7123 }
7124 stopped = true;
7125 for ( ; index < length; index++ ) {
7126 animation.tweens[ index ].run( 1 );
7127 }
7128
7129 // Resolve when we played the last frame; otherwise, reject
7130 if ( gotoEnd ) {
7131 deferred.notifyWith( elem, [ animation, 1, 0 ] );
7132 deferred.resolveWith( elem, [ animation, gotoEnd ] );
7133 } else {
7134 deferred.rejectWith( elem, [ animation, gotoEnd ] );
7135 }
7136 return this;
7137 }
7138 } ),
7139 props = animation.props;
7140
7141 propFilter( props, animation.opts.specialEasing );
7142
7143 for ( ; index < length; index++ ) {
7144 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7145 if ( result ) {
7146 if ( jQuery.isFunction( result.stop ) ) {
7147 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7148 jQuery.proxy( result.stop, result );
7149 }
7150 return result;
7151 }
7152 }
7153
7154 jQuery.map( props, createTween, animation );
7155
7156 if ( jQuery.isFunction( animation.opts.start ) ) {
7157 animation.opts.start.call( elem, animation );
7158 }
7159
7160 // Attach callbacks from options
7161 animation
7162 .progress( animation.opts.progress )
7163 .done( animation.opts.done, animation.opts.complete )
7164 .fail( animation.opts.fail )
7165 .always( animation.opts.always );
7166
7167 jQuery.fx.timer(
7168 jQuery.extend( tick, {
7169 elem: elem,
7170 anim: animation,
7171 queue: animation.opts.queue
7172 } )
7173 );
7174
7175 return animation;
7176}
7177
7178jQuery.Animation = jQuery.extend( Animation, {
7179
7180 tweeners: {
7181 "*": [ function( prop, value ) {
7182 var tween = this.createTween( prop, value );
7183 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7184 return tween;
7185 } ]
7186 },
7187
7188 tweener: function( props, callback ) {
7189 if ( jQuery.isFunction( props ) ) {
7190 callback = props;
7191 props = [ "*" ];
7192 } else {
7193 props = props.match( rnothtmlwhite );
7194 }
7195
7196 var prop,
7197 index = 0,
7198 length = props.length;
7199
7200 for ( ; index < length; index++ ) {
7201 prop = props[ index ];
7202 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7203 Animation.tweeners[ prop ].unshift( callback );
7204 }
7205 },
7206
7207 prefilters: [ defaultPrefilter ],
7208
7209 prefilter: function( callback, prepend ) {
7210 if ( prepend ) {
7211 Animation.prefilters.unshift( callback );
7212 } else {
7213 Animation.prefilters.push( callback );
7214 }
7215 }
7216} );
7217
7218jQuery.speed = function( speed, easing, fn ) {
7219 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7220 complete: fn || !fn && easing ||
7221 jQuery.isFunction( speed ) && speed,
7222 duration: speed,
7223 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7224 };
7225
7226 // Go to the end state if fx are off
7227 if ( jQuery.fx.off ) {
7228 opt.duration = 0;
7229
7230 } else {
7231 if ( typeof opt.duration !== "number" ) {
7232 if ( opt.duration in jQuery.fx.speeds ) {
7233 opt.duration = jQuery.fx.speeds[ opt.duration ];
7234
7235 } else {
7236 opt.duration = jQuery.fx.speeds._default;
7237 }
7238 }
7239 }
7240
7241 // Normalize opt.queue - true/undefined/null -> "fx"
7242 if ( opt.queue == null || opt.queue === true ) {
7243 opt.queue = "fx";
7244 }
7245
7246 // Queueing
7247 opt.old = opt.complete;
7248
7249 opt.complete = function() {
7250 if ( jQuery.isFunction( opt.old ) ) {
7251 opt.old.call( this );
7252 }
7253
7254 if ( opt.queue ) {
7255 jQuery.dequeue( this, opt.queue );
7256 }
7257 };
7258
7259 return opt;
7260};
7261
7262jQuery.fn.extend( {
7263 fadeTo: function( speed, to, easing, callback ) {
7264
7265 // Show any hidden elements after setting opacity to 0
7266 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
7267
7268 // Animate to the value specified
7269 .end().animate( { opacity: to }, speed, easing, callback );
7270 },
7271 animate: function( prop, speed, easing, callback ) {
7272 var empty = jQuery.isEmptyObject( prop ),
7273 optall = jQuery.speed( speed, easing, callback ),
7274 doAnimation = function() {
7275
7276 // Operate on a copy of prop so per-property easing won't be lost
7277 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7278
7279 // Empty animations, or finishing resolves immediately
7280 if ( empty || dataPriv.get( this, "finish" ) ) {
7281 anim.stop( true );
7282 }
7283 };
7284 doAnimation.finish = doAnimation;
7285
7286 return empty || optall.queue === false ?
7287 this.each( doAnimation ) :
7288 this.queue( optall.queue, doAnimation );
7289 },
7290 stop: function( type, clearQueue, gotoEnd ) {
7291 var stopQueue = function( hooks ) {
7292 var stop = hooks.stop;
7293 delete hooks.stop;
7294 stop( gotoEnd );
7295 };
7296
7297 if ( typeof type !== "string" ) {
7298 gotoEnd = clearQueue;
7299 clearQueue = type;
7300 type = undefined;
7301 }
7302 if ( clearQueue && type !== false ) {
7303 this.queue( type || "fx", [] );
7304 }
7305
7306 return this.each( function() {
7307 var dequeue = true,
7308 index = type != null && type + "queueHooks",
7309 timers = jQuery.timers,
7310 data = dataPriv.get( this );
7311
7312 if ( index ) {
7313 if ( data[ index ] && data[ index ].stop ) {
7314 stopQueue( data[ index ] );
7315 }
7316 } else {
7317 for ( index in data ) {
7318 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7319 stopQueue( data[ index ] );
7320 }
7321 }
7322 }
7323
7324 for ( index = timers.length; index--; ) {
7325 if ( timers[ index ].elem === this &&
7326 ( type == null || timers[ index ].queue === type ) ) {
7327
7328 timers[ index ].anim.stop( gotoEnd );
7329 dequeue = false;
7330 timers.splice( index, 1 );
7331 }
7332 }
7333
7334 // Start the next in the queue if the last step wasn't forced.
7335 // Timers currently will call their complete callbacks, which
7336 // will dequeue but only if they were gotoEnd.
7337 if ( dequeue || !gotoEnd ) {
7338 jQuery.dequeue( this, type );
7339 }
7340 } );
7341 },
7342 finish: function( type ) {
7343 if ( type !== false ) {
7344 type = type || "fx";
7345 }
7346 return this.each( function() {
7347 var index,
7348 data = dataPriv.get( this ),
7349 queue = data[ type + "queue" ],
7350 hooks = data[ type + "queueHooks" ],
7351 timers = jQuery.timers,
7352 length = queue ? queue.length : 0;
7353
7354 // Enable finishing flag on private data
7355 data.finish = true;
7356
7357 // Empty the queue first
7358 jQuery.queue( this, type, [] );
7359
7360 if ( hooks && hooks.stop ) {
7361 hooks.stop.call( this, true );
7362 }
7363
7364 // Look for any active animations, and finish them
7365 for ( index = timers.length; index--; ) {
7366 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7367 timers[ index ].anim.stop( true );
7368 timers.splice( index, 1 );
7369 }
7370 }
7371
7372 // Look for any animations in the old queue and finish them
7373 for ( index = 0; index < length; index++ ) {
7374 if ( queue[ index ] && queue[ index ].finish ) {
7375 queue[ index ].finish.call( this );
7376 }
7377 }
7378
7379 // Turn off finishing flag
7380 delete data.finish;
7381 } );
7382 }
7383} );
7384
7385jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
7386 var cssFn = jQuery.fn[ name ];
7387 jQuery.fn[ name ] = function( speed, easing, callback ) {
7388 return speed == null || typeof speed === "boolean" ?
7389 cssFn.apply( this, arguments ) :
7390 this.animate( genFx( name, true ), speed, easing, callback );
7391 };
7392} );
7393
7394// Generate shortcuts for custom animations
7395jQuery.each( {
7396 slideDown: genFx( "show" ),
7397 slideUp: genFx( "hide" ),
7398 slideToggle: genFx( "toggle" ),
7399 fadeIn: { opacity: "show" },
7400 fadeOut: { opacity: "hide" },
7401 fadeToggle: { opacity: "toggle" }
7402}, function( name, props ) {
7403 jQuery.fn[ name ] = function( speed, easing, callback ) {
7404 return this.animate( props, speed, easing, callback );
7405 };
7406} );
7407
7408jQuery.timers = [];
7409jQuery.fx.tick = function() {
7410 var timer,
7411 i = 0,
7412 timers = jQuery.timers;
7413
7414 fxNow = jQuery.now();
7415
7416 for ( ; i < timers.length; i++ ) {
7417 timer = timers[ i ];
7418
7419 // Run the timer and safely remove it when done (allowing for external removal)
7420 if ( !timer() && timers[ i ] === timer ) {
7421 timers.splice( i--, 1 );
7422 }
7423 }
7424
7425 if ( !timers.length ) {
7426 jQuery.fx.stop();
7427 }
7428 fxNow = undefined;
7429};
7430
7431jQuery.fx.timer = function( timer ) {
7432 jQuery.timers.push( timer );
7433 jQuery.fx.start();
7434};
7435
7436jQuery.fx.interval = 13;
7437jQuery.fx.start = function() {
7438 if ( inProgress ) {
7439 return;
7440 }
7441
7442 inProgress = true;
7443 schedule();
7444};
7445
7446jQuery.fx.stop = function() {
7447 inProgress = null;
7448};
7449
7450jQuery.fx.speeds = {
7451 slow: 600,
7452 fast: 200,
7453
7454 // Default speed
7455 _default: 400
7456};
7457
7458
7459// Based off of the plugin by Clint Helfers, with permission.
7460// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7461jQuery.fn.delay = function( time, type ) {
7462 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7463 type = type || "fx";
7464
7465 return this.queue( type, function( next, hooks ) {
7466 var timeout = window.setTimeout( next, time );
7467 hooks.stop = function() {
7468 window.clearTimeout( timeout );
7469 };
7470 } );
7471};
7472
7473
7474( function() {
7475 var input = document.createElement( "input" ),
7476 select = document.createElement( "select" ),
7477 opt = select.appendChild( document.createElement( "option" ) );
7478
7479 input.type = "checkbox";
7480
7481 // Support: Android <=4.3 only
7482 // Default value for a checkbox should be "on"
7483 support.checkOn = input.value !== "";
7484
7485 // Support: IE <=11 only
7486 // Must access selectedIndex to make default options select
7487 support.optSelected = opt.selected;
7488
7489 // Support: IE <=11 only
7490 // An input loses its value after becoming a radio
7491 input = document.createElement( "input" );
7492 input.value = "t";
7493 input.type = "radio";
7494 support.radioValue = input.value === "t";
7495} )();
7496
7497
7498var boolHook,
7499 attrHandle = jQuery.expr.attrHandle;
7500
7501jQuery.fn.extend( {
7502 attr: function( name, value ) {
7503 return access( this, jQuery.attr, name, value, arguments.length > 1 );
7504 },
7505
7506 removeAttr: function( name ) {
7507 return this.each( function() {
7508 jQuery.removeAttr( this, name );
7509 } );
7510 }
7511} );
7512
7513jQuery.extend( {
7514 attr: function( elem, name, value ) {
7515 var ret, hooks,
7516 nType = elem.nodeType;
7517
7518 // Don't get/set attributes on text, comment and attribute nodes
7519 if ( nType === 3 || nType === 8 || nType === 2 ) {
7520 return;
7521 }
7522
7523 // Fallback to prop when attributes are not supported
7524 if ( typeof elem.getAttribute === "undefined" ) {
7525 return jQuery.prop( elem, name, value );
7526 }
7527
7528 // Attribute hooks are determined by the lowercase version
7529 // Grab necessary hook if one is defined
7530 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7531 hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
7532 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
7533 }
7534
7535 if ( value !== undefined ) {
7536 if ( value === null ) {
7537 jQuery.removeAttr( elem, name );
7538 return;
7539 }
7540
7541 if ( hooks && "set" in hooks &&
7542 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7543 return ret;
7544 }
7545
7546 elem.setAttribute( name, value + "" );
7547 return value;
7548 }
7549
7550 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7551 return ret;
7552 }
7553
7554 ret = jQuery.find.attr( elem, name );
7555
7556 // Non-existent attributes return null, we normalize to undefined
7557 return ret == null ? undefined : ret;
7558 },
7559
7560 attrHooks: {
7561 type: {
7562 set: function( elem, value ) {
7563 if ( !support.radioValue && value === "radio" &&
7564 nodeName( elem, "input" ) ) {
7565 var val = elem.value;
7566 elem.setAttribute( "type", value );
7567 if ( val ) {
7568 elem.value = val;
7569 }
7570 return value;
7571 }
7572 }
7573 }
7574 },
7575
7576 removeAttr: function( elem, value ) {
7577 var name,
7578 i = 0,
7579
7580 // Attribute names can contain non-HTML whitespace characters
7581 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
7582 attrNames = value && value.match( rnothtmlwhite );
7583
7584 if ( attrNames && elem.nodeType === 1 ) {
7585 while ( ( name = attrNames[ i++ ] ) ) {
7586 elem.removeAttribute( name );
7587 }
7588 }
7589 }
7590} );
7591
7592// Hooks for boolean attributes
7593boolHook = {
7594 set: function( elem, value, name ) {
7595 if ( value === false ) {
7596
7597 // Remove boolean attributes when set to false
7598 jQuery.removeAttr( elem, name );
7599 } else {
7600 elem.setAttribute( name, name );
7601 }
7602 return name;
7603 }
7604};
7605
7606jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7607 var getter = attrHandle[ name ] || jQuery.find.attr;
7608
7609 attrHandle[ name ] = function( elem, name, isXML ) {
7610 var ret, handle,
7611 lowercaseName = name.toLowerCase();
7612
7613 if ( !isXML ) {
7614
7615 // Avoid an infinite loop by temporarily removing this function from the getter
7616 handle = attrHandle[ lowercaseName ];
7617 attrHandle[ lowercaseName ] = ret;
7618 ret = getter( elem, name, isXML ) != null ?
7619 lowercaseName :
7620 null;
7621 attrHandle[ lowercaseName ] = handle;
7622 }
7623 return ret;
7624 };
7625} );
7626
7627
7628
7629
7630var rfocusable = /^(?:input|select|textarea|button)$/i,
7631 rclickable = /^(?:a|area)$/i;
7632
7633jQuery.fn.extend( {
7634 prop: function( name, value ) {
7635 return access( this, jQuery.prop, name, value, arguments.length > 1 );
7636 },
7637
7638 removeProp: function( name ) {
7639 return this.each( function() {
7640 delete this[ jQuery.propFix[ name ] || name ];
7641 } );
7642 }
7643} );
7644
7645jQuery.extend( {
7646 prop: function( elem, name, value ) {
7647 var ret, hooks,
7648 nType = elem.nodeType;
7649
7650 // Don't get/set properties on text, comment and attribute nodes
7651 if ( nType === 3 || nType === 8 || nType === 2 ) {
7652 return;
7653 }
7654
7655 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7656
7657 // Fix name and attach hooks
7658 name = jQuery.propFix[ name ] || name;
7659 hooks = jQuery.propHooks[ name ];
7660 }
7661
7662 if ( value !== undefined ) {
7663 if ( hooks && "set" in hooks &&
7664 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7665 return ret;
7666 }
7667
7668 return ( elem[ name ] = value );
7669 }
7670
7671 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7672 return ret;
7673 }
7674
7675 return elem[ name ];
7676 },
7677
7678 propHooks: {
7679 tabIndex: {
7680 get: function( elem ) {
7681
7682 // Support: IE <=9 - 11 only
7683 // elem.tabIndex doesn't always return the
7684 // correct value when it hasn't been explicitly set
7685 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
7686 // Use proper attribute retrieval(#12072)
7687 var tabindex = jQuery.find.attr( elem, "tabindex" );
7688
7689 if ( tabindex ) {
7690 return parseInt( tabindex, 10 );
7691 }
7692
7693 if (
7694 rfocusable.test( elem.nodeName ) ||
7695 rclickable.test( elem.nodeName ) &&
7696 elem.href
7697 ) {
7698 return 0;
7699 }
7700
7701 return -1;
7702 }
7703 }
7704 },
7705
7706 propFix: {
7707 "for": "htmlFor",
7708 "class": "className"
7709 }
7710} );
7711
7712// Support: IE <=11 only
7713// Accessing the selectedIndex property
7714// forces the browser to respect setting selected
7715// on the option
7716// The getter ensures a default option is selected
7717// when in an optgroup
7718// eslint rule "no-unused-expressions" is disabled for this code
7719// since it considers such accessions noop
7720if ( !support.optSelected ) {
7721 jQuery.propHooks.selected = {
7722 get: function( elem ) {
7723
7724 /* eslint no-unused-expressions: "off" */
7725
7726 var parent = elem.parentNode;
7727 if ( parent && parent.parentNode ) {
7728 parent.parentNode.selectedIndex;
7729 }
7730 return null;
7731 },
7732 set: function( elem ) {
7733
7734 /* eslint no-unused-expressions: "off" */
7735
7736 var parent = elem.parentNode;
7737 if ( parent ) {
7738 parent.selectedIndex;
7739
7740 if ( parent.parentNode ) {
7741 parent.parentNode.selectedIndex;
7742 }
7743 }
7744 }
7745 };
7746}
7747
7748jQuery.each( [
7749 "tabIndex",
7750 "readOnly",
7751 "maxLength",
7752 "cellSpacing",
7753 "cellPadding",
7754 "rowSpan",
7755 "colSpan",
7756 "useMap",
7757 "frameBorder",
7758 "contentEditable"
7759], function() {
7760 jQuery.propFix[ this.toLowerCase() ] = this;
7761} );
7762
7763
7764
7765
7766 // Strip and collapse whitespace according to HTML spec
7767 // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
7768 function stripAndCollapse( value ) {
7769 var tokens = value.match( rnothtmlwhite ) || [];
7770 return tokens.join( " " );
7771 }
7772
7773
7774function getClass( elem ) {
7775 return elem.getAttribute && elem.getAttribute( "class" ) || "";
7776}
7777
7778jQuery.fn.extend( {
7779 addClass: function( value ) {
7780 var classes, elem, cur, curValue, clazz, j, finalValue,
7781 i = 0;
7782
7783 if ( jQuery.isFunction( value ) ) {
7784 return this.each( function( j ) {
7785 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
7786 } );
7787 }
7788
7789 if ( typeof value === "string" && value ) {
7790 classes = value.match( rnothtmlwhite ) || [];
7791
7792 while ( ( elem = this[ i++ ] ) ) {
7793 curValue = getClass( elem );
7794 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
7795
7796 if ( cur ) {
7797 j = 0;
7798 while ( ( clazz = classes[ j++ ] ) ) {
7799 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7800 cur += clazz + " ";
7801 }
7802 }
7803
7804 // Only assign if different to avoid unneeded rendering.
7805 finalValue = stripAndCollapse( cur );
7806 if ( curValue !== finalValue ) {
7807 elem.setAttribute( "class", finalValue );
7808 }
7809 }
7810 }
7811 }
7812
7813 return this;
7814 },
7815
7816 removeClass: function( value ) {
7817 var classes, elem, cur, curValue, clazz, j, finalValue,
7818 i = 0;
7819
7820 if ( jQuery.isFunction( value ) ) {
7821 return this.each( function( j ) {
7822 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
7823 } );
7824 }
7825
7826 if ( !arguments.length ) {
7827 return this.attr( "class", "" );
7828 }
7829
7830 if ( typeof value === "string" && value ) {
7831 classes = value.match( rnothtmlwhite ) || [];
7832
7833 while ( ( elem = this[ i++ ] ) ) {
7834 curValue = getClass( elem );
7835
7836 // This expression is here for better compressibility (see addClass)
7837 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
7838
7839 if ( cur ) {
7840 j = 0;
7841 while ( ( clazz = classes[ j++ ] ) ) {
7842
7843 // Remove *all* instances
7844 while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
7845 cur = cur.replace( " " + clazz + " ", " " );
7846 }
7847 }
7848
7849 // Only assign if different to avoid unneeded rendering.
7850 finalValue = stripAndCollapse( cur );
7851 if ( curValue !== finalValue ) {
7852 elem.setAttribute( "class", finalValue );
7853 }
7854 }
7855 }
7856 }
7857
7858 return this;
7859 },
7860
7861 toggleClass: function( value, stateVal ) {
7862 var type = typeof value;
7863
7864 if ( typeof stateVal === "boolean" && type === "string" ) {
7865 return stateVal ? this.addClass( value ) : this.removeClass( value );
7866 }
7867
7868 if ( jQuery.isFunction( value ) ) {
7869 return this.each( function( i ) {
7870 jQuery( this ).toggleClass(
7871 value.call( this, i, getClass( this ), stateVal ),
7872 stateVal
7873 );
7874 } );
7875 }
7876
7877 return this.each( function() {
7878 var className, i, self, classNames;
7879
7880 if ( type === "string" ) {
7881
7882 // Toggle individual class names
7883 i = 0;
7884 self = jQuery( this );
7885 classNames = value.match( rnothtmlwhite ) || [];
7886
7887 while ( ( className = classNames[ i++ ] ) ) {
7888
7889 // Check each className given, space separated list
7890 if ( self.hasClass( className ) ) {
7891 self.removeClass( className );
7892 } else {
7893 self.addClass( className );
7894 }
7895 }
7896
7897 // Toggle whole class name
7898 } else if ( value === undefined || type === "boolean" ) {
7899 className = getClass( this );
7900 if ( className ) {
7901
7902 // Store className if set
7903 dataPriv.set( this, "__className__", className );
7904 }
7905
7906 // If the element has a class name or if we're passed `false`,
7907 // then remove the whole classname (if there was one, the above saved it).
7908 // Otherwise bring back whatever was previously saved (if anything),
7909 // falling back to the empty string if nothing was stored.
7910 if ( this.setAttribute ) {
7911 this.setAttribute( "class",
7912 className || value === false ?
7913 "" :
7914 dataPriv.get( this, "__className__" ) || ""
7915 );
7916 }
7917 }
7918 } );
7919 },
7920
7921 hasClass: function( selector ) {
7922 var className, elem,
7923 i = 0;
7924
7925 className = " " + selector + " ";
7926 while ( ( elem = this[ i++ ] ) ) {
7927 if ( elem.nodeType === 1 &&
7928 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
7929 return true;
7930 }
7931 }
7932
7933 return false;
7934 }
7935} );
7936
7937
7938
7939
7940var rreturn = /\r/g;
7941
7942jQuery.fn.extend( {
7943 val: function( value ) {
7944 var hooks, ret, isFunction,
7945 elem = this[ 0 ];
7946
7947 if ( !arguments.length ) {
7948 if ( elem ) {
7949 hooks = jQuery.valHooks[ elem.type ] ||
7950 jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7951
7952 if ( hooks &&
7953 "get" in hooks &&
7954 ( ret = hooks.get( elem, "value" ) ) !== undefined
7955 ) {
7956 return ret;
7957 }
7958
7959 ret = elem.value;
7960
7961 // Handle most common string cases
7962 if ( typeof ret === "string" ) {
7963 return ret.replace( rreturn, "" );
7964 }
7965
7966 // Handle cases where value is null/undef or number
7967 return ret == null ? "" : ret;
7968 }
7969
7970 return;
7971 }
7972
7973 isFunction = jQuery.isFunction( value );
7974
7975 return this.each( function( i ) {
7976 var val;
7977
7978 if ( this.nodeType !== 1 ) {
7979 return;
7980 }
7981
7982 if ( isFunction ) {
7983 val = value.call( this, i, jQuery( this ).val() );
7984 } else {
7985 val = value;
7986 }
7987
7988 // Treat null/undefined as ""; convert numbers to string
7989 if ( val == null ) {
7990 val = "";
7991
7992 } else if ( typeof val === "number" ) {
7993 val += "";
7994
7995 } else if ( Array.isArray( val ) ) {
7996 val = jQuery.map( val, function( value ) {
7997 return value == null ? "" : value + "";
7998 } );
7999 }
8000
8001 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8002
8003 // If set returns undefined, fall back to normal setting
8004 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8005 this.value = val;
8006 }
8007 } );
8008 }
8009} );
8010
8011jQuery.extend( {
8012 valHooks: {
8013 option: {
8014 get: function( elem ) {
8015
8016 var val = jQuery.find.attr( elem, "value" );
8017 return val != null ?
8018 val :
8019
8020 // Support: IE <=10 - 11 only
8021 // option.text throws exceptions (#14686, #14858)
8022 // Strip and collapse whitespace
8023 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8024 stripAndCollapse( jQuery.text( elem ) );
8025 }
8026 },
8027 select: {
8028 get: function( elem ) {
8029 var value, option, i,
8030 options = elem.options,
8031 index = elem.selectedIndex,
8032 one = elem.type === "select-one",
8033 values = one ? null : [],
8034 max = one ? index + 1 : options.length;
8035
8036 if ( index < 0 ) {
8037 i = max;
8038
8039 } else {
8040 i = one ? index : 0;
8041 }
8042
8043 // Loop through all the selected options
8044 for ( ; i < max; i++ ) {
8045 option = options[ i ];
8046
8047 // Support: IE <=9 only
8048 // IE8-9 doesn't update selected after form reset (#2551)
8049 if ( ( option.selected || i === index ) &&
8050
8051 // Don't return options that are disabled or in a disabled optgroup
8052 !option.disabled &&
8053 ( !option.parentNode.disabled ||
8054 !nodeName( option.parentNode, "optgroup" ) ) ) {
8055
8056 // Get the specific value for the option
8057 value = jQuery( option ).val();
8058
8059 // We don't need an array for one selects
8060 if ( one ) {
8061 return value;
8062 }
8063
8064 // Multi-Selects return an array
8065 values.push( value );
8066 }
8067 }
8068
8069 return values;
8070 },
8071
8072 set: function( elem, value ) {
8073 var optionSet, option,
8074 options = elem.options,
8075 values = jQuery.makeArray( value ),
8076 i = options.length;
8077
8078 while ( i-- ) {
8079 option = options[ i ];
8080
8081 /* eslint-disable no-cond-assign */
8082
8083 if ( option.selected =
8084 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
8085 ) {
8086 optionSet = true;
8087 }
8088
8089 /* eslint-enable no-cond-assign */
8090 }
8091
8092 // Force browsers to behave consistently when non-matching value is set
8093 if ( !optionSet ) {
8094 elem.selectedIndex = -1;
8095 }
8096 return values;
8097 }
8098 }
8099 }
8100} );
8101
8102// Radios and checkboxes getter/setter
8103jQuery.each( [ "radio", "checkbox" ], function() {
8104 jQuery.valHooks[ this ] = {
8105 set: function( elem, value ) {
8106 if ( Array.isArray( value ) ) {
8107 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8108 }
8109 }
8110 };
8111 if ( !support.checkOn ) {
8112 jQuery.valHooks[ this ].get = function( elem ) {
8113 return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8114 };
8115 }
8116} );
8117
8118
8119
8120
8121// Return jQuery for attributes-only inclusion
8122
8123
8124var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
8125
8126jQuery.extend( jQuery.event, {
8127
8128 trigger: function( event, data, elem, onlyHandlers ) {
8129
8130 var i, cur, tmp, bubbleType, ontype, handle, special,
8131 eventPath = [ elem || document ],
8132 type = hasOwn.call( event, "type" ) ? event.type : event,
8133 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
8134
8135 cur = tmp = elem = elem || document;
8136
8137 // Don't do events on text and comment nodes
8138 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
8139 return;
8140 }
8141
8142 // focus/blur morphs to focusin/out; ensure we're not firing them right now
8143 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
8144 return;
8145 }
8146
8147 if ( type.indexOf( "." ) > -1 ) {
8148
8149 // Namespaced trigger; create a regexp to match event type in handle()
8150 namespaces = type.split( "." );
8151 type = namespaces.shift();
8152 namespaces.sort();
8153 }
8154 ontype = type.indexOf( ":" ) < 0 && "on" + type;
8155
8156 // Caller can pass in a jQuery.Event object, Object, or just an event type string
8157 event = event[ jQuery.expando ] ?
8158 event :
8159 new jQuery.Event( type, typeof event === "object" && event );
8160
8161 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8162 event.isTrigger = onlyHandlers ? 2 : 3;
8163 event.namespace = namespaces.join( "." );
8164 event.rnamespace = event.namespace ?
8165 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
8166 null;
8167
8168 // Clean up the event in case it is being reused
8169 event.result = undefined;
8170 if ( !event.target ) {
8171 event.target = elem;
8172 }
8173
8174 // Clone any incoming data and prepend the event, creating the handler arg list
8175 data = data == null ?
8176 [ event ] :
8177 jQuery.makeArray( data, [ event ] );
8178
8179 // Allow special events to draw outside the lines
8180 special = jQuery.event.special[ type ] || {};
8181 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
8182 return;
8183 }
8184
8185 // Determine event propagation path in advance, per W3C events spec (#9951)
8186 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
8187 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
8188
8189 bubbleType = special.delegateType || type;
8190 if ( !rfocusMorph.test( bubbleType + type ) ) {
8191 cur = cur.parentNode;
8192 }
8193 for ( ; cur; cur = cur.parentNode ) {
8194 eventPath.push( cur );
8195 tmp = cur;
8196 }
8197
8198 // Only add window if we got to document (e.g., not plain obj or detached DOM)
8199 if ( tmp === ( elem.ownerDocument || document ) ) {
8200 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
8201 }
8202 }
8203
8204 // Fire handlers on the event path
8205 i = 0;
8206 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
8207
8208 event.type = i > 1 ?
8209 bubbleType :
8210 special.bindType || type;
8211
8212 // jQuery handler
8213 handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
8214 dataPriv.get( cur, "handle" );
8215 if ( handle ) {
8216 handle.apply( cur, data );
8217 }
8218
8219 // Native handler
8220 handle = ontype && cur[ ontype ];
8221 if ( handle && handle.apply && acceptData( cur ) ) {
8222 event.result = handle.apply( cur, data );
8223 if ( event.result === false ) {
8224 event.preventDefault();
8225 }
8226 }
8227 }
8228 event.type = type;
8229
8230 // If nobody prevented the default action, do it now
8231 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
8232
8233 if ( ( !special._default ||
8234 special._default.apply( eventPath.pop(), data ) === false ) &&
8235 acceptData( elem ) ) {
8236
8237 // Call a native DOM method on the target with the same name as the event.
8238 // Don't do default actions on window, that's where global variables be (#6170)
8239 if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
8240
8241 // Don't re-trigger an onFOO event when we call its FOO() method
8242 tmp = elem[ ontype ];
8243
8244 if ( tmp ) {
8245 elem[ ontype ] = null;
8246 }
8247
8248 // Prevent re-triggering of the same event, since we already bubbled it above
8249 jQuery.event.triggered = type;
8250 elem[ type ]();
8251 jQuery.event.triggered = undefined;
8252
8253 if ( tmp ) {
8254 elem[ ontype ] = tmp;
8255 }
8256 }
8257 }
8258 }
8259
8260 return event.result;
8261 },
8262
8263 // Piggyback on a donor event to simulate a different one
8264 // Used only for `focus(in | out)` events
8265 simulate: function( type, elem, event ) {
8266 var e = jQuery.extend(
8267 new jQuery.Event(),
8268 event,
8269 {
8270 type: type,
8271 isSimulated: true
8272 }
8273 );
8274
8275 jQuery.event.trigger( e, null, elem );
8276 }
8277
8278} );
8279
8280jQuery.fn.extend( {
8281
8282 trigger: function( type, data ) {
8283 return this.each( function() {
8284 jQuery.event.trigger( type, data, this );
8285 } );
8286 },
8287 triggerHandler: function( type, data ) {
8288 var elem = this[ 0 ];
8289 if ( elem ) {
8290 return jQuery.event.trigger( type, data, elem, true );
8291 }
8292 }
8293} );
8294
8295
8296jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
8297 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8298 "change select submit keydown keypress keyup contextmenu" ).split( " " ),
8299 function( i, name ) {
8300
8301 // Handle event binding
8302 jQuery.fn[ name ] = function( data, fn ) {
8303 return arguments.length > 0 ?
8304 this.on( name, null, data, fn ) :
8305 this.trigger( name );
8306 };
8307} );
8308
8309jQuery.fn.extend( {
8310 hover: function( fnOver, fnOut ) {
8311 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8312 }
8313} );
8314
8315
8316
8317
8318support.focusin = "onfocusin" in window;
8319
8320
8321// Support: Firefox <=44
8322// Firefox doesn't have focus(in | out) events
8323// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
8324//
8325// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
8326// focus(in | out) events fire after focus & blur events,
8327// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
8328// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
8329if ( !support.focusin ) {
8330 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
8331
8332 // Attach a single capturing handler on the document while someone wants focusin/focusout
8333 var handler = function( event ) {
8334 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
8335 };
8336
8337 jQuery.event.special[ fix ] = {
8338 setup: function() {
8339 var doc = this.ownerDocument || this,
8340 attaches = dataPriv.access( doc, fix );
8341
8342 if ( !attaches ) {
8343 doc.addEventListener( orig, handler, true );
8344 }
8345 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
8346 },
8347 teardown: function() {
8348 var doc = this.ownerDocument || this,
8349 attaches = dataPriv.access( doc, fix ) - 1;
8350
8351 if ( !attaches ) {
8352 doc.removeEventListener( orig, handler, true );
8353 dataPriv.remove( doc, fix );
8354
8355 } else {
8356 dataPriv.access( doc, fix, attaches );
8357 }
8358 }
8359 };
8360 } );
8361}
8362var location = window.location;
8363
8364var nonce = jQuery.now();
8365
8366var rquery = ( /\?/ );
8367
8368
8369
8370// Cross-browser xml parsing
8371jQuery.parseXML = function( data ) {
8372 var xml;
8373 if ( !data || typeof data !== "string" ) {
8374 return null;
8375 }
8376
8377 // Support: IE 9 - 11 only
8378 // IE throws on parseFromString with invalid input.
8379 try {
8380 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
8381 } catch ( e ) {
8382 xml = undefined;
8383 }
8384
8385 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
8386 jQuery.error( "Invalid XML: " + data );
8387 }
8388 return xml;
8389};
8390
8391
8392var
8393 rbracket = /\[\]$/,
8394 rCRLF = /\r?\n/g,
8395 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8396 rsubmittable = /^(?:input|select|textarea|keygen)/i;
8397
8398function buildParams( prefix, obj, traditional, add ) {
8399 var name;
8400
8401 if ( Array.isArray( obj ) ) {
8402
8403 // Serialize array item.
8404 jQuery.each( obj, function( i, v ) {
8405 if ( traditional || rbracket.test( prefix ) ) {
8406
8407 // Treat each array item as a scalar.
8408 add( prefix, v );
8409
8410 } else {
8411
8412 // Item is non-scalar (array or object), encode its numeric index.
8413 buildParams(
8414 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8415 v,
8416 traditional,
8417 add
8418 );
8419 }
8420 } );
8421
8422 } else if ( !traditional && jQuery.type( obj ) === "object" ) {
8423
8424 // Serialize object item.
8425 for ( name in obj ) {
8426 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8427 }
8428
8429 } else {
8430
8431 // Serialize scalar item.
8432 add( prefix, obj );
8433 }
8434}
8435
8436// Serialize an array of form elements or a set of
8437// key/values into a query string
8438jQuery.param = function( a, traditional ) {
8439 var prefix,
8440 s = [],
8441 add = function( key, valueOrFunction ) {
8442
8443 // If value is a function, invoke it and use its return value
8444 var value = jQuery.isFunction( valueOrFunction ) ?
8445 valueOrFunction() :
8446 valueOrFunction;
8447
8448 s[ s.length ] = encodeURIComponent( key ) + "=" +
8449 encodeURIComponent( value == null ? "" : value );
8450 };
8451
8452 // If an array was passed in, assume that it is an array of form elements.
8453 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8454
8455 // Serialize the form elements
8456 jQuery.each( a, function() {
8457 add( this.name, this.value );
8458 } );
8459
8460 } else {
8461
8462 // If traditional, encode the "old" way (the way 1.3.2 or older
8463 // did it), otherwise encode params recursively.
8464 for ( prefix in a ) {
8465 buildParams( prefix, a[ prefix ], traditional, add );
8466 }
8467 }
8468
8469 // Return the resulting serialization
8470 return s.join( "&" );
8471};
8472
8473jQuery.fn.extend( {
8474 serialize: function() {
8475 return jQuery.param( this.serializeArray() );
8476 },
8477 serializeArray: function() {
8478 return this.map( function() {
8479
8480 // Can add propHook for "elements" to filter or add form elements
8481 var elements = jQuery.prop( this, "elements" );
8482 return elements ? jQuery.makeArray( elements ) : this;
8483 } )
8484 .filter( function() {
8485 var type = this.type;
8486
8487 // Use .is( ":disabled" ) so that fieldset[disabled] works
8488 return this.name && !jQuery( this ).is( ":disabled" ) &&
8489 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
8490 ( this.checked || !rcheckableType.test( type ) );
8491 } )
8492 .map( function( i, elem ) {
8493 var val = jQuery( this ).val();
8494
8495 if ( val == null ) {
8496 return null;
8497 }
8498
8499 if ( Array.isArray( val ) ) {
8500 return jQuery.map( val, function( val ) {
8501 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8502 } );
8503 }
8504
8505 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8506 } ).get();
8507 }
8508} );
8509
8510
8511var
8512 r20 = /%20/g,
8513 rhash = /#.*$/,
8514 rantiCache = /([?&])_=[^&]*/,
8515 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
8516
8517 // #7653, #8125, #8152: local protocol detection
8518 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8519 rnoContent = /^(?:GET|HEAD)$/,
8520 rprotocol = /^\/\//,
8521
8522 /* Prefilters
8523 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8524 * 2) These are called:
8525 * - BEFORE asking for a transport
8526 * - AFTER param serialization (s.data is a string if s.processData is true)
8527 * 3) key is the dataType
8528 * 4) the catchall symbol "*" can be used
8529 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8530 */
8531 prefilters = {},
8532
8533 /* Transports bindings
8534 * 1) key is the dataType
8535 * 2) the catchall symbol "*" can be used
8536 * 3) selection will start with transport dataType and THEN go to "*" if needed
8537 */
8538 transports = {},
8539
8540 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8541 allTypes = "*/".concat( "*" ),
8542
8543 // Anchor tag for parsing the document origin
8544 originAnchor = document.createElement( "a" );
8545 originAnchor.href = location.href;
8546
8547// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8548function addToPrefiltersOrTransports( structure ) {
8549
8550 // dataTypeExpression is optional and defaults to "*"
8551 return function( dataTypeExpression, func ) {
8552
8553 if ( typeof dataTypeExpression !== "string" ) {
8554 func = dataTypeExpression;
8555 dataTypeExpression = "*";
8556 }
8557
8558 var dataType,
8559 i = 0,
8560 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
8561
8562 if ( jQuery.isFunction( func ) ) {
8563
8564 // For each dataType in the dataTypeExpression
8565 while ( ( dataType = dataTypes[ i++ ] ) ) {
8566
8567 // Prepend if requested
8568 if ( dataType[ 0 ] === "+" ) {
8569 dataType = dataType.slice( 1 ) || "*";
8570 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
8571
8572 // Otherwise append
8573 } else {
8574 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
8575 }
8576 }
8577 }
8578 };
8579}
8580
8581// Base inspection function for prefilters and transports
8582function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8583
8584 var inspected = {},
8585 seekingTransport = ( structure === transports );
8586
8587 function inspect( dataType ) {
8588 var selected;
8589 inspected[ dataType ] = true;
8590 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8591 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8592 if ( typeof dataTypeOrTransport === "string" &&
8593 !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8594
8595 options.dataTypes.unshift( dataTypeOrTransport );
8596 inspect( dataTypeOrTransport );
8597 return false;
8598 } else if ( seekingTransport ) {
8599 return !( selected = dataTypeOrTransport );
8600 }
8601 } );
8602 return selected;
8603 }
8604
8605 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8606}
8607
8608// A special extend for ajax options
8609// that takes "flat" options (not to be deep extended)
8610// Fixes #9887
8611function ajaxExtend( target, src ) {
8612 var key, deep,
8613 flatOptions = jQuery.ajaxSettings.flatOptions || {};
8614
8615 for ( key in src ) {
8616 if ( src[ key ] !== undefined ) {
8617 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
8618 }
8619 }
8620 if ( deep ) {
8621 jQuery.extend( true, target, deep );
8622 }
8623
8624 return target;
8625}
8626
8627/* Handles responses to an ajax request:
8628 * - finds the right dataType (mediates between content-type and expected dataType)
8629 * - returns the corresponding response
8630 */
8631function ajaxHandleResponses( s, jqXHR, responses ) {
8632
8633 var ct, type, finalDataType, firstDataType,
8634 contents = s.contents,
8635 dataTypes = s.dataTypes;
8636
8637 // Remove auto dataType and get content-type in the process
8638 while ( dataTypes[ 0 ] === "*" ) {
8639 dataTypes.shift();
8640 if ( ct === undefined ) {
8641 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
8642 }
8643 }
8644
8645 // Check if we're dealing with a known content-type
8646 if ( ct ) {
8647 for ( type in contents ) {
8648 if ( contents[ type ] && contents[ type ].test( ct ) ) {
8649 dataTypes.unshift( type );
8650 break;
8651 }
8652 }
8653 }
8654
8655 // Check to see if we have a response for the expected dataType
8656 if ( dataTypes[ 0 ] in responses ) {
8657 finalDataType = dataTypes[ 0 ];
8658 } else {
8659
8660 // Try convertible dataTypes
8661 for ( type in responses ) {
8662 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
8663 finalDataType = type;
8664 break;
8665 }
8666 if ( !firstDataType ) {
8667 firstDataType = type;
8668 }
8669 }
8670
8671 // Or just use first one
8672 finalDataType = finalDataType || firstDataType;
8673 }
8674
8675 // If we found a dataType
8676 // We add the dataType to the list if needed
8677 // and return the corresponding response
8678 if ( finalDataType ) {
8679 if ( finalDataType !== dataTypes[ 0 ] ) {
8680 dataTypes.unshift( finalDataType );
8681 }
8682 return responses[ finalDataType ];
8683 }
8684}
8685
8686/* Chain conversions given the request and the original response
8687 * Also sets the responseXXX fields on the jqXHR instance
8688 */
8689function ajaxConvert( s, response, jqXHR, isSuccess ) {
8690 var conv2, current, conv, tmp, prev,
8691 converters = {},
8692
8693 // Work with a copy of dataTypes in case we need to modify it for conversion
8694 dataTypes = s.dataTypes.slice();
8695
8696 // Create converters map with lowercased keys
8697 if ( dataTypes[ 1 ] ) {
8698 for ( conv in s.converters ) {
8699 converters[ conv.toLowerCase() ] = s.converters[ conv ];
8700 }
8701 }
8702
8703 current = dataTypes.shift();
8704
8705 // Convert to each sequential dataType
8706 while ( current ) {
8707
8708 if ( s.responseFields[ current ] ) {
8709 jqXHR[ s.responseFields[ current ] ] = response;
8710 }
8711
8712 // Apply the dataFilter if provided
8713 if ( !prev && isSuccess && s.dataFilter ) {
8714 response = s.dataFilter( response, s.dataType );
8715 }
8716
8717 prev = current;
8718 current = dataTypes.shift();
8719
8720 if ( current ) {
8721
8722 // There's only work to do if current dataType is non-auto
8723 if ( current === "*" ) {
8724
8725 current = prev;
8726
8727 // Convert response if prev dataType is non-auto and differs from current
8728 } else if ( prev !== "*" && prev !== current ) {
8729
8730 // Seek a direct converter
8731 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8732
8733 // If none found, seek a pair
8734 if ( !conv ) {
8735 for ( conv2 in converters ) {
8736
8737 // If conv2 outputs current
8738 tmp = conv2.split( " " );
8739 if ( tmp[ 1 ] === current ) {
8740
8741 // If prev can be converted to accepted input
8742 conv = converters[ prev + " " + tmp[ 0 ] ] ||
8743 converters[ "* " + tmp[ 0 ] ];
8744 if ( conv ) {
8745
8746 // Condense equivalence converters
8747 if ( conv === true ) {
8748 conv = converters[ conv2 ];
8749
8750 // Otherwise, insert the intermediate dataType
8751 } else if ( converters[ conv2 ] !== true ) {
8752 current = tmp[ 0 ];
8753 dataTypes.unshift( tmp[ 1 ] );
8754 }
8755 break;
8756 }
8757 }
8758 }
8759 }
8760
8761 // Apply converter (if not an equivalence)
8762 if ( conv !== true ) {
8763
8764 // Unless errors are allowed to bubble, catch and return them
8765 if ( conv && s.throws ) {
8766 response = conv( response );
8767 } else {
8768 try {
8769 response = conv( response );
8770 } catch ( e ) {
8771 return {
8772 state: "parsererror",
8773 error: conv ? e : "No conversion from " + prev + " to " + current
8774 };
8775 }
8776 }
8777 }
8778 }
8779 }
8780 }
8781
8782 return { state: "success", data: response };
8783}
8784
8785jQuery.extend( {
8786
8787 // Counter for holding the number of active queries
8788 active: 0,
8789
8790 // Last-Modified header cache for next request
8791 lastModified: {},
8792 etag: {},
8793
8794 ajaxSettings: {
8795 url: location.href,
8796 type: "GET",
8797 isLocal: rlocalProtocol.test( location.protocol ),
8798 global: true,
8799 processData: true,
8800 async: true,
8801 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8802
8803 /*
8804 timeout: 0,
8805 data: null,
8806 dataType: null,
8807 username: null,
8808 password: null,
8809 cache: null,
8810 throws: false,
8811 traditional: false,
8812 headers: {},
8813 */
8814
8815 accepts: {
8816 "*": allTypes,
8817 text: "text/plain",
8818 html: "text/html",
8819 xml: "application/xml, text/xml",
8820 json: "application/json, text/javascript"
8821 },
8822
8823 contents: {
8824 xml: /\bxml\b/,
8825 html: /\bhtml/,
8826 json: /\bjson\b/
8827 },
8828
8829 responseFields: {
8830 xml: "responseXML",
8831 text: "responseText",
8832 json: "responseJSON"
8833 },
8834
8835 // Data converters
8836 // Keys separate source (or catchall "*") and destination types with a single space
8837 converters: {
8838
8839 // Convert anything to text
8840 "* text": String,
8841
8842 // Text to html (true = no transformation)
8843 "text html": true,
8844
8845 // Evaluate text as a json expression
8846 "text json": JSON.parse,
8847
8848 // Parse text as xml
8849 "text xml": jQuery.parseXML
8850 },
8851
8852 // For options that shouldn't be deep extended:
8853 // you can add your own custom options here if
8854 // and when you create one that shouldn't be
8855 // deep extended (see ajaxExtend)
8856 flatOptions: {
8857 url: true,
8858 context: true
8859 }
8860 },
8861
8862 // Creates a full fledged settings object into target
8863 // with both ajaxSettings and settings fields.
8864 // If target is omitted, writes into ajaxSettings.
8865 ajaxSetup: function( target, settings ) {
8866 return settings ?
8867
8868 // Building a settings object
8869 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8870
8871 // Extending ajaxSettings
8872 ajaxExtend( jQuery.ajaxSettings, target );
8873 },
8874
8875 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8876 ajaxTransport: addToPrefiltersOrTransports( transports ),
8877
8878 // Main method
8879 ajax: function( url, options ) {
8880
8881 // If url is an object, simulate pre-1.5 signature
8882 if ( typeof url === "object" ) {
8883 options = url;
8884 url = undefined;
8885 }
8886
8887 // Force options to be an object
8888 options = options || {};
8889
8890 var transport,
8891
8892 // URL without anti-cache param
8893 cacheURL,
8894
8895 // Response headers
8896 responseHeadersString,
8897 responseHeaders,
8898
8899 // timeout handle
8900 timeoutTimer,
8901
8902 // Url cleanup var
8903 urlAnchor,
8904
8905 // Request state (becomes false upon send and true upon completion)
8906 completed,
8907
8908 // To know if global events are to be dispatched
8909 fireGlobals,
8910
8911 // Loop variable
8912 i,
8913
8914 // uncached part of the url
8915 uncached,
8916
8917 // Create the final options object
8918 s = jQuery.ajaxSetup( {}, options ),
8919
8920 // Callbacks context
8921 callbackContext = s.context || s,
8922
8923 // Context for global events is callbackContext if it is a DOM node or jQuery collection
8924 globalEventContext = s.context &&
8925 ( callbackContext.nodeType || callbackContext.jquery ) ?
8926 jQuery( callbackContext ) :
8927 jQuery.event,
8928
8929 // Deferreds
8930 deferred = jQuery.Deferred(),
8931 completeDeferred = jQuery.Callbacks( "once memory" ),
8932
8933 // Status-dependent callbacks
8934 statusCode = s.statusCode || {},
8935
8936 // Headers (they are sent all at once)
8937 requestHeaders = {},
8938 requestHeadersNames = {},
8939
8940 // Default abort message
8941 strAbort = "canceled",
8942
8943 // Fake xhr
8944 jqXHR = {
8945 readyState: 0,
8946
8947 // Builds headers hashtable if needed
8948 getResponseHeader: function( key ) {
8949 var match;
8950 if ( completed ) {
8951 if ( !responseHeaders ) {
8952 responseHeaders = {};
8953 while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
8954 responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
8955 }
8956 }
8957 match = responseHeaders[ key.toLowerCase() ];
8958 }
8959 return match == null ? null : match;
8960 },
8961
8962 // Raw string
8963 getAllResponseHeaders: function() {
8964 return completed ? responseHeadersString : null;
8965 },
8966
8967 // Caches the header
8968 setRequestHeader: function( name, value ) {
8969 if ( completed == null ) {
8970 name = requestHeadersNames[ name.toLowerCase() ] =
8971 requestHeadersNames[ name.toLowerCase() ] || name;
8972 requestHeaders[ name ] = value;
8973 }
8974 return this;
8975 },
8976
8977 // Overrides response content-type header
8978 overrideMimeType: function( type ) {
8979 if ( completed == null ) {
8980 s.mimeType = type;
8981 }
8982 return this;
8983 },
8984
8985 // Status-dependent callbacks
8986 statusCode: function( map ) {
8987 var code;
8988 if ( map ) {
8989 if ( completed ) {
8990
8991 // Execute the appropriate callbacks
8992 jqXHR.always( map[ jqXHR.status ] );
8993 } else {
8994
8995 // Lazy-add the new callbacks in a way that preserves old ones
8996 for ( code in map ) {
8997 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8998 }
8999 }
9000 }
9001 return this;
9002 },
9003
9004 // Cancel the request
9005 abort: function( statusText ) {
9006 var finalText = statusText || strAbort;
9007 if ( transport ) {
9008 transport.abort( finalText );
9009 }
9010 done( 0, finalText );
9011 return this;
9012 }
9013 };
9014
9015 // Attach deferreds
9016 deferred.promise( jqXHR );
9017
9018 // Add protocol if not provided (prefilters might expect it)
9019 // Handle falsy url in the settings object (#10093: consistency with old signature)
9020 // We also use the url parameter if available
9021 s.url = ( ( url || s.url || location.href ) + "" )
9022 .replace( rprotocol, location.protocol + "//" );
9023
9024 // Alias method option to type as per ticket #12004
9025 s.type = options.method || options.type || s.method || s.type;
9026
9027 // Extract dataTypes list
9028 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
9029
9030 // A cross-domain request is in order when the origin doesn't match the current origin.
9031 if ( s.crossDomain == null ) {
9032 urlAnchor = document.createElement( "a" );
9033
9034 // Support: IE <=8 - 11, Edge 12 - 13
9035 // IE throws exception on accessing the href property if url is malformed,
9036 // e.g. http://example.com:80x/
9037 try {
9038 urlAnchor.href = s.url;
9039
9040 // Support: IE <=8 - 11 only
9041 // Anchor's host property isn't correctly set when s.url is relative
9042 urlAnchor.href = urlAnchor.href;
9043 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9044 urlAnchor.protocol + "//" + urlAnchor.host;
9045 } catch ( e ) {
9046
9047 // If there is an error parsing the URL, assume it is crossDomain,
9048 // it can be rejected by the transport if it is invalid
9049 s.crossDomain = true;
9050 }
9051 }
9052
9053 // Convert data if not already a string
9054 if ( s.data && s.processData && typeof s.data !== "string" ) {
9055 s.data = jQuery.param( s.data, s.traditional );
9056 }
9057
9058 // Apply prefilters
9059 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9060
9061 // If request was aborted inside a prefilter, stop there
9062 if ( completed ) {
9063 return jqXHR;
9064 }
9065
9066 // We can fire global events as of now if asked to
9067 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9068 fireGlobals = jQuery.event && s.global;
9069
9070 // Watch for a new set of requests
9071 if ( fireGlobals && jQuery.active++ === 0 ) {
9072 jQuery.event.trigger( "ajaxStart" );
9073 }
9074
9075 // Uppercase the type
9076 s.type = s.type.toUpperCase();
9077
9078 // Determine if request has content
9079 s.hasContent = !rnoContent.test( s.type );
9080
9081 // Save the URL in case we're toying with the If-Modified-Since
9082 // and/or If-None-Match header later on
9083 // Remove hash to simplify url manipulation
9084 cacheURL = s.url.replace( rhash, "" );
9085
9086 // More options handling for requests with no content
9087 if ( !s.hasContent ) {
9088
9089 // Remember the hash so we can put it back
9090 uncached = s.url.slice( cacheURL.length );
9091
9092 // If data is available, append data to url
9093 if ( s.data ) {
9094 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
9095
9096 // #9682: remove data so that it's not used in an eventual retry
9097 delete s.data;
9098 }
9099
9100 // Add or update anti-cache param if needed
9101 if ( s.cache === false ) {
9102 cacheURL = cacheURL.replace( rantiCache, "$1" );
9103 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
9104 }
9105
9106 // Put hash and anti-cache on the URL that will be requested (gh-1732)
9107 s.url = cacheURL + uncached;
9108
9109 // Change '%20' to '+' if this is encoded form body content (gh-2658)
9110 } else if ( s.data && s.processData &&
9111 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
9112 s.data = s.data.replace( r20, "+" );
9113 }
9114
9115 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9116 if ( s.ifModified ) {
9117 if ( jQuery.lastModified[ cacheURL ] ) {
9118 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9119 }
9120 if ( jQuery.etag[ cacheURL ] ) {
9121 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9122 }
9123 }
9124
9125 // Set the correct header, if data is being sent
9126 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9127 jqXHR.setRequestHeader( "Content-Type", s.contentType );
9128 }
9129
9130 // Set the Accepts header for the server, depending on the dataType
9131 jqXHR.setRequestHeader(
9132 "Accept",
9133 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9134 s.accepts[ s.dataTypes[ 0 ] ] +
9135 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9136 s.accepts[ "*" ]
9137 );
9138
9139 // Check for headers option
9140 for ( i in s.headers ) {
9141 jqXHR.setRequestHeader( i, s.headers[ i ] );
9142 }
9143
9144 // Allow custom headers/mimetypes and early abort
9145 if ( s.beforeSend &&
9146 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
9147
9148 // Abort if not done already and return
9149 return jqXHR.abort();
9150 }
9151
9152 // Aborting is no longer a cancellation
9153 strAbort = "abort";
9154
9155 // Install callbacks on deferreds
9156 completeDeferred.add( s.complete );
9157 jqXHR.done( s.success );
9158 jqXHR.fail( s.error );
9159
9160 // Get transport
9161 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9162
9163 // If no transport, we auto-abort
9164 if ( !transport ) {
9165 done( -1, "No Transport" );
9166 } else {
9167 jqXHR.readyState = 1;
9168
9169 // Send global event
9170 if ( fireGlobals ) {
9171 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9172 }
9173
9174 // If request was aborted inside ajaxSend, stop there
9175 if ( completed ) {
9176 return jqXHR;
9177 }
9178
9179 // Timeout
9180 if ( s.async && s.timeout > 0 ) {
9181 timeoutTimer = window.setTimeout( function() {
9182 jqXHR.abort( "timeout" );
9183 }, s.timeout );
9184 }
9185
9186 try {
9187 completed = false;
9188 transport.send( requestHeaders, done );
9189 } catch ( e ) {
9190
9191 // Rethrow post-completion exceptions
9192 if ( completed ) {
9193 throw e;
9194 }
9195
9196 // Propagate others as results
9197 done( -1, e );
9198 }
9199 }
9200
9201 // Callback for when everything is done
9202 function done( status, nativeStatusText, responses, headers ) {
9203 var isSuccess, success, error, response, modified,
9204 statusText = nativeStatusText;
9205
9206 // Ignore repeat invocations
9207 if ( completed ) {
9208 return;
9209 }
9210
9211 completed = true;
9212
9213 // Clear timeout if it exists
9214 if ( timeoutTimer ) {
9215 window.clearTimeout( timeoutTimer );
9216 }
9217
9218 // Dereference transport for early garbage collection
9219 // (no matter how long the jqXHR object will be used)
9220 transport = undefined;
9221
9222 // Cache response headers
9223 responseHeadersString = headers || "";
9224
9225 // Set readyState
9226 jqXHR.readyState = status > 0 ? 4 : 0;
9227
9228 // Determine if successful
9229 isSuccess = status >= 200 && status < 300 || status === 304;
9230
9231 // Get response data
9232 if ( responses ) {
9233 response = ajaxHandleResponses( s, jqXHR, responses );
9234 }
9235
9236 // Convert no matter what (that way responseXXX fields are always set)
9237 response = ajaxConvert( s, response, jqXHR, isSuccess );
9238
9239 // If successful, handle type chaining
9240 if ( isSuccess ) {
9241
9242 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9243 if ( s.ifModified ) {
9244 modified = jqXHR.getResponseHeader( "Last-Modified" );
9245 if ( modified ) {
9246 jQuery.lastModified[ cacheURL ] = modified;
9247 }
9248 modified = jqXHR.getResponseHeader( "etag" );
9249 if ( modified ) {
9250 jQuery.etag[ cacheURL ] = modified;
9251 }
9252 }
9253
9254 // if no content
9255 if ( status === 204 || s.type === "HEAD" ) {
9256 statusText = "nocontent";
9257
9258 // if not modified
9259 } else if ( status === 304 ) {
9260 statusText = "notmodified";
9261
9262 // If we have data, let's convert it
9263 } else {
9264 statusText = response.state;
9265 success = response.data;
9266 error = response.error;
9267 isSuccess = !error;
9268 }
9269 } else {
9270
9271 // Extract error from statusText and normalize for non-aborts
9272 error = statusText;
9273 if ( status || !statusText ) {
9274 statusText = "error";
9275 if ( status < 0 ) {
9276 status = 0;
9277 }
9278 }
9279 }
9280
9281 // Set data for the fake xhr object
9282 jqXHR.status = status;
9283 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9284
9285 // Success/Error
9286 if ( isSuccess ) {
9287 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9288 } else {
9289 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9290 }
9291
9292 // Status-dependent callbacks
9293 jqXHR.statusCode( statusCode );
9294 statusCode = undefined;
9295
9296 if ( fireGlobals ) {
9297 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9298 [ jqXHR, s, isSuccess ? success : error ] );
9299 }
9300
9301 // Complete
9302 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9303
9304 if ( fireGlobals ) {
9305 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9306
9307 // Handle the global AJAX counter
9308 if ( !( --jQuery.active ) ) {
9309 jQuery.event.trigger( "ajaxStop" );
9310 }
9311 }
9312 }
9313
9314 return jqXHR;
9315 },
9316
9317 getJSON: function( url, data, callback ) {
9318 return jQuery.get( url, data, callback, "json" );
9319 },
9320
9321 getScript: function( url, callback ) {
9322 return jQuery.get( url, undefined, callback, "script" );
9323 }
9324} );
9325
9326jQuery.each( [ "get", "post" ], function( i, method ) {
9327 jQuery[ method ] = function( url, data, callback, type ) {
9328
9329 // Shift arguments if data argument was omitted
9330 if ( jQuery.isFunction( data ) ) {
9331 type = type || callback;
9332 callback = data;
9333 data = undefined;
9334 }
9335
9336 // The url can be an options object (which then must have .url)
9337 return jQuery.ajax( jQuery.extend( {
9338 url: url,
9339 type: method,
9340 dataType: type,
9341 data: data,
9342 success: callback
9343 }, jQuery.isPlainObject( url ) && url ) );
9344 };
9345} );
9346
9347
9348jQuery._evalUrl = function( url ) {
9349 return jQuery.ajax( {
9350 url: url,
9351
9352 // Make this explicit, since user can override this through ajaxSetup (#11264)
9353 type: "GET",
9354 dataType: "script",
9355 cache: true,
9356 async: false,
9357 global: false,
9358 "throws": true
9359 } );
9360};
9361
9362
9363jQuery.fn.extend( {
9364 wrapAll: function( html ) {
9365 var wrap;
9366
9367 if ( this[ 0 ] ) {
9368 if ( jQuery.isFunction( html ) ) {
9369 html = html.call( this[ 0 ] );
9370 }
9371
9372 // The elements to wrap the target around
9373 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9374
9375 if ( this[ 0 ].parentNode ) {
9376 wrap.insertBefore( this[ 0 ] );
9377 }
9378
9379 wrap.map( function() {
9380 var elem = this;
9381
9382 while ( elem.firstElementChild ) {
9383 elem = elem.firstElementChild;
9384 }
9385
9386 return elem;
9387 } ).append( this );
9388 }
9389
9390 return this;
9391 },
9392
9393 wrapInner: function( html ) {
9394 if ( jQuery.isFunction( html ) ) {
9395 return this.each( function( i ) {
9396 jQuery( this ).wrapInner( html.call( this, i ) );
9397 } );
9398 }
9399
9400 return this.each( function() {
9401 var self = jQuery( this ),
9402 contents = self.contents();
9403
9404 if ( contents.length ) {
9405 contents.wrapAll( html );
9406
9407 } else {
9408 self.append( html );
9409 }
9410 } );
9411 },
9412
9413 wrap: function( html ) {
9414 var isFunction = jQuery.isFunction( html );
9415
9416 return this.each( function( i ) {
9417 jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
9418 } );
9419 },
9420
9421 unwrap: function( selector ) {
9422 this.parent( selector ).not( "body" ).each( function() {
9423 jQuery( this ).replaceWith( this.childNodes );
9424 } );
9425 return this;
9426 }
9427} );
9428
9429
9430jQuery.expr.pseudos.hidden = function( elem ) {
9431 return !jQuery.expr.pseudos.visible( elem );
9432};
9433jQuery.expr.pseudos.visible = function( elem ) {
9434 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
9435};
9436
9437
9438
9439
9440jQuery.ajaxSettings.xhr = function() {
9441 try {
9442 return new window.XMLHttpRequest();
9443 } catch ( e ) {}
9444};
9445
9446var xhrSuccessStatus = {
9447
9448 // File protocol always yields status code 0, assume 200
9449 0: 200,
9450
9451 // Support: IE <=9 only
9452 // #1450: sometimes IE returns 1223 when it should be 204
9453 1223: 204
9454 },
9455 xhrSupported = jQuery.ajaxSettings.xhr();
9456
9457support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9458support.ajax = xhrSupported = !!xhrSupported;
9459
9460jQuery.ajaxTransport( function( options ) {
9461 var callback, errorCallback;
9462
9463 // Cross domain only allowed if supported through XMLHttpRequest
9464 if ( support.cors || xhrSupported && !options.crossDomain ) {
9465 return {
9466 send: function( headers, complete ) {
9467 var i,
9468 xhr = options.xhr();
9469
9470 xhr.open(
9471 options.type,
9472 options.url,
9473 options.async,
9474 options.username,
9475 options.password
9476 );
9477
9478 // Apply custom fields if provided
9479 if ( options.xhrFields ) {
9480 for ( i in options.xhrFields ) {
9481 xhr[ i ] = options.xhrFields[ i ];
9482 }
9483 }
9484
9485 // Override mime type if needed
9486 if ( options.mimeType && xhr.overrideMimeType ) {
9487 xhr.overrideMimeType( options.mimeType );
9488 }
9489
9490 // X-Requested-With header
9491 // For cross-domain requests, seeing as conditions for a preflight are
9492 // akin to a jigsaw puzzle, we simply never set it to be sure.
9493 // (it can always be set on a per-request basis or even using ajaxSetup)
9494 // For same-domain requests, won't change header if already provided.
9495 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
9496 headers[ "X-Requested-With" ] = "XMLHttpRequest";
9497 }
9498
9499 // Set headers
9500 for ( i in headers ) {
9501 xhr.setRequestHeader( i, headers[ i ] );
9502 }
9503
9504 // Callback
9505 callback = function( type ) {
9506 return function() {
9507 if ( callback ) {
9508 callback = errorCallback = xhr.onload =
9509 xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
9510
9511 if ( type === "abort" ) {
9512 xhr.abort();
9513 } else if ( type === "error" ) {
9514
9515 // Support: IE <=9 only
9516 // On a manual native abort, IE9 throws
9517 // errors on any property access that is not readyState
9518 if ( typeof xhr.status !== "number" ) {
9519 complete( 0, "error" );
9520 } else {
9521 complete(
9522
9523 // File: protocol always yields status 0; see #8605, #14207
9524 xhr.status,
9525 xhr.statusText
9526 );
9527 }
9528 } else {
9529 complete(
9530 xhrSuccessStatus[ xhr.status ] || xhr.status,
9531 xhr.statusText,
9532
9533 // Support: IE <=9 only
9534 // IE9 has no XHR2 but throws on binary (trac-11426)
9535 // For XHR2 non-text, let the caller handle it (gh-2498)
9536 ( xhr.responseType || "text" ) !== "text" ||
9537 typeof xhr.responseText !== "string" ?
9538 { binary: xhr.response } :
9539 { text: xhr.responseText },
9540 xhr.getAllResponseHeaders()
9541 );
9542 }
9543 }
9544 };
9545 };
9546
9547 // Listen to events
9548 xhr.onload = callback();
9549 errorCallback = xhr.onerror = callback( "error" );
9550
9551 // Support: IE 9 only
9552 // Use onreadystatechange to replace onabort
9553 // to handle uncaught aborts
9554 if ( xhr.onabort !== undefined ) {
9555 xhr.onabort = errorCallback;
9556 } else {
9557 xhr.onreadystatechange = function() {
9558
9559 // Check readyState before timeout as it changes
9560 if ( xhr.readyState === 4 ) {
9561
9562 // Allow onerror to be called first,
9563 // but that will not handle a native abort
9564 // Also, save errorCallback to a variable
9565 // as xhr.onerror cannot be accessed
9566 window.setTimeout( function() {
9567 if ( callback ) {
9568 errorCallback();
9569 }
9570 } );
9571 }
9572 };
9573 }
9574
9575 // Create the abort callback
9576 callback = callback( "abort" );
9577
9578 try {
9579
9580 // Do send the request (this may raise an exception)
9581 xhr.send( options.hasContent && options.data || null );
9582 } catch ( e ) {
9583
9584 // #14683: Only rethrow if this hasn't been notified as an error yet
9585 if ( callback ) {
9586 throw e;
9587 }
9588 }
9589 },
9590
9591 abort: function() {
9592 if ( callback ) {
9593 callback();
9594 }
9595 }
9596 };
9597 }
9598} );
9599
9600
9601
9602
9603// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
9604jQuery.ajaxPrefilter( function( s ) {
9605 if ( s.crossDomain ) {
9606 s.contents.script = false;
9607 }
9608} );
9609
9610// Install script dataType
9611jQuery.ajaxSetup( {
9612 accepts: {
9613 script: "text/javascript, application/javascript, " +
9614 "application/ecmascript, application/x-ecmascript"
9615 },
9616 contents: {
9617 script: /\b(?:java|ecma)script\b/
9618 },
9619 converters: {
9620 "text script": function( text ) {
9621 jQuery.globalEval( text );
9622 return text;
9623 }
9624 }
9625} );
9626
9627// Handle cache's special case and crossDomain
9628jQuery.ajaxPrefilter( "script", function( s ) {
9629 if ( s.cache === undefined ) {
9630 s.cache = false;
9631 }
9632 if ( s.crossDomain ) {
9633 s.type = "GET";
9634 }
9635} );
9636
9637// Bind script tag hack transport
9638jQuery.ajaxTransport( "script", function( s ) {
9639
9640 // This transport only deals with cross domain requests
9641 if ( s.crossDomain ) {
9642 var script, callback;
9643 return {
9644 send: function( _, complete ) {
9645 script = jQuery( "<script>" ).prop( {
9646 charset: s.scriptCharset,
9647 src: s.url
9648 } ).on(
9649 "load error",
9650 callback = function( evt ) {
9651 script.remove();
9652 callback = null;
9653 if ( evt ) {
9654 complete( evt.type === "error" ? 404 : 200, evt.type );
9655 }
9656 }
9657 );
9658
9659 // Use native DOM manipulation to avoid our domManip AJAX trickery
9660 document.head.appendChild( script[ 0 ] );
9661 },
9662 abort: function() {
9663 if ( callback ) {
9664 callback();
9665 }
9666 }
9667 };
9668 }
9669} );
9670
9671
9672
9673
9674var oldCallbacks = [],
9675 rjsonp = /(=)\?(?=&|$)|\?\?/;
9676
9677// Default jsonp settings
9678jQuery.ajaxSetup( {
9679 jsonp: "callback",
9680 jsonpCallback: function() {
9681 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9682 this[ callback ] = true;
9683 return callback;
9684 }
9685} );
9686
9687// Detect, normalize options and install callbacks for jsonp requests
9688jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9689
9690 var callbackName, overwritten, responseContainer,
9691 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9692 "url" :
9693 typeof s.data === "string" &&
9694 ( s.contentType || "" )
9695 .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
9696 rjsonp.test( s.data ) && "data"
9697 );
9698
9699 // Handle iff the expected data type is "jsonp" or we have a parameter to set
9700 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9701
9702 // Get callback name, remembering preexisting value associated with it
9703 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9704 s.jsonpCallback() :
9705 s.jsonpCallback;
9706
9707 // Insert callback into url or form data
9708 if ( jsonProp ) {
9709 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9710 } else if ( s.jsonp !== false ) {
9711 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9712 }
9713
9714 // Use data converter to retrieve json after script execution
9715 s.converters[ "script json" ] = function() {
9716 if ( !responseContainer ) {
9717 jQuery.error( callbackName + " was not called" );
9718 }
9719 return responseContainer[ 0 ];
9720 };
9721
9722 // Force json dataType
9723 s.dataTypes[ 0 ] = "json";
9724
9725 // Install callback
9726 overwritten = window[ callbackName ];
9727 window[ callbackName ] = function() {
9728 responseContainer = arguments;
9729 };
9730
9731 // Clean-up function (fires after converters)
9732 jqXHR.always( function() {
9733
9734 // If previous value didn't exist - remove it
9735 if ( overwritten === undefined ) {
9736 jQuery( window ).removeProp( callbackName );
9737
9738 // Otherwise restore preexisting value
9739 } else {
9740 window[ callbackName ] = overwritten;
9741 }
9742
9743 // Save back as free
9744 if ( s[ callbackName ] ) {
9745
9746 // Make sure that re-using the options doesn't screw things around
9747 s.jsonpCallback = originalSettings.jsonpCallback;
9748
9749 // Save the callback name for future use
9750 oldCallbacks.push( callbackName );
9751 }
9752
9753 // Call if it was a function and we have a response
9754 if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9755 overwritten( responseContainer[ 0 ] );
9756 }
9757
9758 responseContainer = overwritten = undefined;
9759 } );
9760
9761 // Delegate to script
9762 return "script";
9763 }
9764} );
9765
9766
9767
9768
9769// Support: Safari 8 only
9770// In Safari 8 documents created via document.implementation.createHTMLDocument
9771// collapse sibling forms: the second one becomes a child of the first one.
9772// Because of that, this security measure has to be disabled in Safari 8.
9773// https://bugs.webkit.org/show_bug.cgi?id=137337
9774support.createHTMLDocument = ( function() {
9775 var body = document.implementation.createHTMLDocument( "" ).body;
9776 body.innerHTML = "<form></form><form></form>";
9777 return body.childNodes.length === 2;
9778} )();
9779
9780
9781// Argument "data" should be string of html
9782// context (optional): If specified, the fragment will be created in this context,
9783// defaults to document
9784// keepScripts (optional): If true, will include scripts passed in the html string
9785jQuery.parseHTML = function( data, context, keepScripts ) {
9786 if ( typeof data !== "string" ) {
9787 return [];
9788 }
9789 if ( typeof context === "boolean" ) {
9790 keepScripts = context;
9791 context = false;
9792 }
9793
9794 var base, parsed, scripts;
9795
9796 if ( !context ) {
9797
9798 // Stop scripts or inline event handlers from being executed immediately
9799 // by using document.implementation
9800 if ( support.createHTMLDocument ) {
9801 context = document.implementation.createHTMLDocument( "" );
9802
9803 // Set the base href for the created document
9804 // so any parsed elements with URLs
9805 // are based on the document's URL (gh-2965)
9806 base = context.createElement( "base" );
9807 base.href = document.location.href;
9808 context.head.appendChild( base );
9809 } else {
9810 context = document;
9811 }
9812 }
9813
9814 parsed = rsingleTag.exec( data );
9815 scripts = !keepScripts && [];
9816
9817 // Single tag
9818 if ( parsed ) {
9819 return [ context.createElement( parsed[ 1 ] ) ];
9820 }
9821
9822 parsed = buildFragment( [ data ], context, scripts );
9823
9824 if ( scripts && scripts.length ) {
9825 jQuery( scripts ).remove();
9826 }
9827
9828 return jQuery.merge( [], parsed.childNodes );
9829};
9830
9831
9832/**
9833 * Load a url into a page
9834 */
9835jQuery.fn.load = function( url, params, callback ) {
9836 var selector, type, response,
9837 self = this,
9838 off = url.indexOf( " " );
9839
9840 if ( off > -1 ) {
9841 selector = stripAndCollapse( url.slice( off ) );
9842 url = url.slice( 0, off );
9843 }
9844
9845 // If it's a function
9846 if ( jQuery.isFunction( params ) ) {
9847
9848 // We assume that it's the callback
9849 callback = params;
9850 params = undefined;
9851
9852 // Otherwise, build a param string
9853 } else if ( params && typeof params === "object" ) {
9854 type = "POST";
9855 }
9856
9857 // If we have elements to modify, make the request
9858 if ( self.length > 0 ) {
9859 jQuery.ajax( {
9860 url: url,
9861
9862 // If "type" variable is undefined, then "GET" method will be used.
9863 // Make value of this field explicit since
9864 // user can override it through ajaxSetup method
9865 type: type || "GET",
9866 dataType: "html",
9867 data: params
9868 } ).done( function( responseText ) {
9869
9870 // Save response for use in complete callback
9871 response = arguments;
9872
9873 self.html( selector ?
9874
9875 // If a selector was specified, locate the right elements in a dummy div
9876 // Exclude scripts to avoid IE 'Permission Denied' errors
9877 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
9878
9879 // Otherwise use the full result
9880 responseText );
9881
9882 // If the request succeeds, this function gets "data", "status", "jqXHR"
9883 // but they are ignored because response was set above.
9884 // If it fails, this function gets "jqXHR", "status", "error"
9885 } ).always( callback && function( jqXHR, status ) {
9886 self.each( function() {
9887 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
9888 } );
9889 } );
9890 }
9891
9892 return this;
9893};
9894
9895
9896
9897
9898// Attach a bunch of functions for handling common AJAX events
9899jQuery.each( [
9900 "ajaxStart",
9901 "ajaxStop",
9902 "ajaxComplete",
9903 "ajaxError",
9904 "ajaxSuccess",
9905 "ajaxSend"
9906], function( i, type ) {
9907 jQuery.fn[ type ] = function( fn ) {
9908 return this.on( type, fn );
9909 };
9910} );
9911
9912
9913
9914
9915jQuery.expr.pseudos.animated = function( elem ) {
9916 return jQuery.grep( jQuery.timers, function( fn ) {
9917 return elem === fn.elem;
9918 } ).length;
9919};
9920
9921
9922
9923
9924jQuery.offset = {
9925 setOffset: function( elem, options, i ) {
9926 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
9927 position = jQuery.css( elem, "position" ),
9928 curElem = jQuery( elem ),
9929 props = {};
9930
9931 // Set position first, in-case top/left are set even on static elem
9932 if ( position === "static" ) {
9933 elem.style.position = "relative";
9934 }
9935
9936 curOffset = curElem.offset();
9937 curCSSTop = jQuery.css( elem, "top" );
9938 curCSSLeft = jQuery.css( elem, "left" );
9939 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
9940 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
9941
9942 // Need to be able to calculate position if either
9943 // top or left is auto and position is either absolute or fixed
9944 if ( calculatePosition ) {
9945 curPosition = curElem.position();
9946 curTop = curPosition.top;
9947 curLeft = curPosition.left;
9948
9949 } else {
9950 curTop = parseFloat( curCSSTop ) || 0;
9951 curLeft = parseFloat( curCSSLeft ) || 0;
9952 }
9953
9954 if ( jQuery.isFunction( options ) ) {
9955
9956 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
9957 options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
9958 }
9959
9960 if ( options.top != null ) {
9961 props.top = ( options.top - curOffset.top ) + curTop;
9962 }
9963 if ( options.left != null ) {
9964 props.left = ( options.left - curOffset.left ) + curLeft;
9965 }
9966
9967 if ( "using" in options ) {
9968 options.using.call( elem, props );
9969
9970 } else {
9971 curElem.css( props );
9972 }
9973 }
9974};
9975
9976jQuery.fn.extend( {
9977 offset: function( options ) {
9978
9979 // Preserve chaining for setter
9980 if ( arguments.length ) {
9981 return options === undefined ?
9982 this :
9983 this.each( function( i ) {
9984 jQuery.offset.setOffset( this, options, i );
9985 } );
9986 }
9987
9988 var doc, docElem, rect, win,
9989 elem = this[ 0 ];
9990
9991 if ( !elem ) {
9992 return;
9993 }
9994
9995 // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
9996 // Support: IE <=11 only
9997 // Running getBoundingClientRect on a
9998 // disconnected node in IE throws an error
9999 if ( !elem.getClientRects().length ) {
10000 return { top: 0, left: 0 };
10001 }
10002
10003 rect = elem.getBoundingClientRect();
10004
10005 doc = elem.ownerDocument;
10006 docElem = doc.documentElement;
10007 win = doc.defaultView;
10008
10009 return {
10010 top: rect.top + win.pageYOffset - docElem.clientTop,
10011 left: rect.left + win.pageXOffset - docElem.clientLeft
10012 };
10013 },
10014
10015 position: function() {
10016 if ( !this[ 0 ] ) {
10017 return;
10018 }
10019
10020 var offsetParent, offset,
10021 elem = this[ 0 ],
10022 parentOffset = { top: 0, left: 0 };
10023
10024 // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
10025 // because it is its only offset parent
10026 if ( jQuery.css( elem, "position" ) === "fixed" ) {
10027
10028 // Assume getBoundingClientRect is there when computed position is fixed
10029 offset = elem.getBoundingClientRect();
10030
10031 } else {
10032
10033 // Get *real* offsetParent
10034 offsetParent = this.offsetParent();
10035
10036 // Get correct offsets
10037 offset = this.offset();
10038 if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
10039 parentOffset = offsetParent.offset();
10040 }
10041
10042 // Add offsetParent borders
10043 parentOffset = {
10044 top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
10045 left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
10046 };
10047 }
10048
10049 // Subtract parent offsets and element margins
10050 return {
10051 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10052 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10053 };
10054 },
10055
10056 // This method will return documentElement in the following cases:
10057 // 1) For the element inside the iframe without offsetParent, this method will return
10058 // documentElement of the parent window
10059 // 2) For the hidden or detached element
10060 // 3) For body or html element, i.e. in case of the html node - it will return itself
10061 //
10062 // but those exceptions were never presented as a real life use-cases
10063 // and might be considered as more preferable results.
10064 //
10065 // This logic, however, is not guaranteed and can change at any point in the future
10066 offsetParent: function() {
10067 return this.map( function() {
10068 var offsetParent = this.offsetParent;
10069
10070 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
10071 offsetParent = offsetParent.offsetParent;
10072 }
10073
10074 return offsetParent || documentElement;
10075 } );
10076 }
10077} );
10078
10079// Create scrollLeft and scrollTop methods
10080jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10081 var top = "pageYOffset" === prop;
10082
10083 jQuery.fn[ method ] = function( val ) {
10084 return access( this, function( elem, method, val ) {
10085
10086 // Coalesce documents and windows
10087 var win;
10088 if ( jQuery.isWindow( elem ) ) {
10089 win = elem;
10090 } else if ( elem.nodeType === 9 ) {
10091 win = elem.defaultView;
10092 }
10093
10094 if ( val === undefined ) {
10095 return win ? win[ prop ] : elem[ method ];
10096 }
10097
10098 if ( win ) {
10099 win.scrollTo(
10100 !top ? val : win.pageXOffset,
10101 top ? val : win.pageYOffset
10102 );
10103
10104 } else {
10105 elem[ method ] = val;
10106 }
10107 }, method, val, arguments.length );
10108 };
10109} );
10110
10111// Support: Safari <=7 - 9.1, Chrome <=37 - 49
10112// Add the top/left cssHooks using jQuery.fn.position
10113// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10114// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10115// getComputedStyle returns percent when specified for top/left/bottom/right;
10116// rather than make the css module depend on the offset module, just check for it here
10117jQuery.each( [ "top", "left" ], function( i, prop ) {
10118 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10119 function( elem, computed ) {
10120 if ( computed ) {
10121 computed = curCSS( elem, prop );
10122
10123 // If curCSS returns percentage, fallback to offset
10124 return rnumnonpx.test( computed ) ?
10125 jQuery( elem ).position()[ prop ] + "px" :
10126 computed;
10127 }
10128 }
10129 );
10130} );
10131
10132
10133// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10134jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10135 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10136 function( defaultExtra, funcName ) {
10137
10138 // Margin is only for outerHeight, outerWidth
10139 jQuery.fn[ funcName ] = function( margin, value ) {
10140 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10141 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10142
10143 return access( this, function( elem, type, value ) {
10144 var doc;
10145
10146 if ( jQuery.isWindow( elem ) ) {
10147
10148 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10149 return funcName.indexOf( "outer" ) === 0 ?
10150 elem[ "inner" + name ] :
10151 elem.document.documentElement[ "client" + name ];
10152 }
10153
10154 // Get document width or height
10155 if ( elem.nodeType === 9 ) {
10156 doc = elem.documentElement;
10157
10158 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10159 // whichever is greatest
10160 return Math.max(
10161 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10162 elem.body[ "offset" + name ], doc[ "offset" + name ],
10163 doc[ "client" + name ]
10164 );
10165 }
10166
10167 return value === undefined ?
10168
10169 // Get width or height on the element, requesting but not forcing parseFloat
10170 jQuery.css( elem, type, extra ) :
10171
10172 // Set width or height on the element
10173 jQuery.style( elem, type, value, extra );
10174 }, type, chainable ? margin : undefined, chainable );
10175 };
10176 } );
10177} );
10178
10179
10180jQuery.fn.extend( {
10181
10182 bind: function( types, data, fn ) {
10183 return this.on( types, null, data, fn );
10184 },
10185 unbind: function( types, fn ) {
10186 return this.off( types, null, fn );
10187 },
10188
10189 delegate: function( selector, types, data, fn ) {
10190 return this.on( types, selector, data, fn );
10191 },
10192 undelegate: function( selector, types, fn ) {
10193
10194 // ( namespace ) or ( selector, types [, fn] )
10195 return arguments.length === 1 ?
10196 this.off( selector, "**" ) :
10197 this.off( types, selector || "**", fn );
10198 }
10199} );
10200
10201jQuery.holdReady = function( hold ) {
10202 if ( hold ) {
10203 jQuery.readyWait++;
10204 } else {
10205 jQuery.ready( true );
10206 }
10207};
10208jQuery.isArray = Array.isArray;
10209jQuery.parseJSON = JSON.parse;
10210jQuery.nodeName = nodeName;
10211
10212
10213
10214
10215// Register as a named AMD module, since jQuery can be concatenated with other
10216// files that may use define, but not via a proper concatenation script that
10217// understands anonymous AMD modules. A named AMD is safest and most robust
10218// way to register. Lowercase jquery is used because AMD module names are
10219// derived from file names, and jQuery is normally delivered in a lowercase
10220// file name. Do this after creating the global so that if an AMD module wants
10221// to call noConflict to hide this version of jQuery, it will work.
10222
10223// Note that for maximum portability, libraries that are not jQuery should
10224// declare themselves as anonymous modules, and avoid setting a global if an
10225// AMD loader is present. jQuery is a special case. For more information, see
10226// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10227
10228if ( typeof undefined === "function" && undefined.amd ) {
10229 undefined( "jquery", [], function() {
10230 return jQuery;
10231 } );
10232}
10233
10234
10235
10236
10237var
10238
10239 // Map over jQuery in case of overwrite
10240 _jQuery = window.jQuery,
10241
10242 // Map over the $ in case of overwrite
10243 _$ = window.$;
10244
10245jQuery.noConflict = function( deep ) {
10246 if ( window.$ === jQuery ) {
10247 window.$ = _$;
10248 }
10249
10250 if ( deep && window.jQuery === jQuery ) {
10251 window.jQuery = _jQuery;
10252 }
10253
10254 return jQuery;
10255};
10256
10257// Expose jQuery and $ identifiers, even in AMD
10258// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10259// and CommonJS for browser emulators (#13566)
10260if ( !noGlobal ) {
10261 window.jQuery = window.$ = jQuery;
10262}
10263
10264
10265
10266
10267return jQuery;
10268} );
10269});
10270
10271
10272
10273var jqueryProxy = Object.freeze({
10274 default: jquery$1,
10275 __moduleExports: jquery$1
10276});
10277
10278// Copyright Joyent, Inc. and other Node contributors.
10279//
10280// Permission is hereby granted, free of charge, to any person obtaining a
10281// copy of this software and associated documentation files (the
10282// "Software"), to deal in the Software without restriction, including
10283// without limitation the rights to use, copy, modify, merge, publish,
10284// distribute, sublicense, and/or sell copies of the Software, and to permit
10285// persons to whom the Software is furnished to do so, subject to the
10286// following conditions:
10287//
10288// The above copyright notice and this permission notice shall be included
10289// in all copies or substantial portions of the Software.
10290//
10291// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10292// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10293// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
10294// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
10295// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
10296// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
10297// USE OR OTHER DEALINGS IN THE SOFTWARE.
10298
10299// resolves . and .. elements in a path array with directory names there
10300// must be no slashes, empty elements, or device names (c:\) in the array
10301// (so also no leading and trailing slashes - it does not distinguish
10302// relative and absolute paths)
10303function normalizeArray(parts, allowAboveRoot) {
10304 // if the path tries to go above the root, `up` ends up > 0
10305 var up = 0;
10306 for (var i = parts.length - 1; i >= 0; i--) {
10307 var last = parts[i];
10308 if (last === '.') {
10309 parts.splice(i, 1);
10310 } else if (last === '..') {
10311 parts.splice(i, 1);
10312 up++;
10313 } else if (up) {
10314 parts.splice(i, 1);
10315 up--;
10316 }
10317 }
10318
10319 // if the path is allowed to go above the root, restore leading ..s
10320 if (allowAboveRoot) {
10321 for (; up--; up) {
10322 parts.unshift('..');
10323 }
10324 }
10325
10326 return parts;
10327}
10328
10329// path.resolve([from ...], to)
10330// posix version
10331
10332
10333// path.normalize(path)
10334// posix version
10335function normalize(path) {
10336 var isPathAbsolute = isAbsolute(path),
10337 trailingSlash = substr(path, -1) === '/';
10338
10339 // Normalize the path
10340 path = normalizeArray(filter(path.split('/'), function(p) {
10341 return !!p;
10342 }), !isPathAbsolute).join('/');
10343
10344 if (!path && !isPathAbsolute) {
10345 path = '.';
10346 }
10347 if (path && trailingSlash) {
10348 path += '/';
10349 }
10350
10351 return (isPathAbsolute ? '/' : '') + path;
10352}
10353
10354// posix version
10355function isAbsolute(path) {
10356 return path.charAt(0) === '/';
10357}
10358
10359// posix version
10360function join() {
10361 var paths = Array.prototype.slice.call(arguments, 0);
10362 return normalize(filter(paths, function(p, index) {
10363 if (typeof p !== 'string') {
10364 throw new TypeError('Arguments to path.join must be strings');
10365 }
10366 return p;
10367 }).join('/'));
10368}
10369
10370
10371// path.relative(from, to)
10372// posix version
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384function filter (xs, f) {
10385 if (xs.filter) return xs.filter(f);
10386 var res = [];
10387 for (var i = 0; i < xs.length; i++) {
10388 if (f(xs[i], i, xs)) res.push(xs[i]);
10389 }
10390 return res;
10391}
10392
10393// String.prototype.substr - negative index don't work in IE8
10394var substr = 'ab'.substr(-1) === 'b' ?
10395 function (str, start, len) { return str.substr(start, len) } :
10396 function (str, start, len) {
10397 if (start < 0) start = str.length + start;
10398 return str.substr(start, len);
10399 };
10400
10401/**
10402 * Utility functions.
10403 */
10404function addTrailingSlash(str) {
10405 return str && str[str.length - 1] !== '/' ? str + '/' : str;
10406}
10407var urlsRE = /(src|href|srcset)=("|')(?!http)(\/{0,2})((?:(?!\2).)*)\2/g;
10408var trailExtRE = /(?!.+\/).+\.html$/;
10409var joinFixRE = /^(https?:)\//;
10410var joinFixRP = '$1//';
10411function resolveRelativeURLs(html, url) {
10412 var protocol = url.slice(0, 5) === 'https' ? 'https://' : 'http://';
10413 var base = addTrailingSlash(url.replace(trailExtRE, ''));
10414 return html.replace(urlsRE, function (m, attr, quot, leadSlashes, href) {
10415 return attr + '=' + quot + (leadSlashes === '//' ? (protocol + href) : join(base, href).replace(joinFixRE, joinFixRP)) + quot;
10416 });
10417}
10418
10419/**
10420 * @export
10421 * @class Getsy
10422 */
10423var jquery = jquery$1 || jqueryProxy;
10424var defaults = {
10425 corsProxy: 'https://crossorigin.me/',
10426 resolveURLs: true,
10427 iframe: false,
10428};
10429var Getsy = (function () {
10430 function Getsy(url, onLoad, _a) {
10431 var _b = _a === void 0 ? defaults : _a, _c = _b.corsProxy, corsProxy = _c === void 0 ? defaults.corsProxy : _c, _d = _b.resolveURLs, resolveURLs = _d === void 0 ? defaults.resolveURLs : _d, _e = _b.iframe, iframe = _e === void 0 ? defaults.iframe : _e;
10432 var _this = this;
10433 this.url = url;
10434 this.corsProxy = corsProxy;
10435 jquery.get(addTrailingSlash(corsProxy) + url, 'html').done(function (data) {
10436 _this.content = resolveURLs ? resolveRelativeURLs(data, url) : data;
10437 if (iframe) {
10438 var _a = iframe, _b = _a.width, width = _b === void 0 ? '100%' : _b, _c = _a.height, height = _c === void 0 ? '100%' : _c;
10439 // Make iframe script:
10440 var iframeScript = document.createElement('script');
10441 iframeScript.textContent = 'document.open();document.write(' + JSON.stringify(_this.content) + ');document.close()';
10442 // Make and append iframe element:
10443 var iframeEl = document.createElement('iframe');
10444 iframeEl.className = 'getsy-frame';
10445 iframeEl.style.width = width;
10446 iframeEl.style.height = height;
10447 iframeEl.style.position = 'fixed';
10448 iframeEl.style.opacity = '0';
10449 iframeEl.style.zIndex = '-1000';
10450 iframeEl.style.pointerEvents = 'none';
10451 document.body.appendChild(iframeEl);
10452 // Append iframe script to iframe element:
10453 var iframeDoc = iframeEl.contentDocument || iframeEl.contentWindow.document;
10454 iframeDoc.body.appendChild(iframeScript);
10455 // Save a reference to the iframe and doc.
10456 _this.iframe = iframeEl;
10457 _this.iframeDoc = iframeDoc;
10458 return iframeEl.contentWindow.onload = function () { return onLoad(null, _this); };
10459 }
10460 return onLoad(null, _this);
10461 }).fail(function () { return onLoad(Error('Failed to load site.')); });
10462 }
10463 Getsy.prototype.getMe = function (sel) {
10464 return jquery(sel, this.iframeDoc || this.content);
10465 };
10466 Getsy.prototype.scroll = function (numberOfTimes, element, interval, retries) {
10467 var _this = this;
10468 if (element === void 0) { element = this.getMe('body')[0]; }
10469 if (interval === void 0) { interval = 2000; }
10470 if (retries === void 0) { retries = 5; }
10471 return new Promise(function (resolve, reject) {
10472 if (!_this.iframe)
10473 return reject(Error('Scroll can only be used in iframe mode.'));
10474 if (numberOfTimes < 1)
10475 return reject(Error('Number of times is less than 1.'));
10476 var times = numberOfTimes; // Keep track of times.
10477 var totalRetries = 0; // Keep track of how many retries per time.
10478 var initialHeight = element.scrollHeight; // Save initialHeight for resolve message.
10479 var lastHeight = initialHeight; // Keep track of last height.
10480 var tries = 0; // Keep track of retries.
10481 element.scrollTop = initialHeight; // Scroll down.
10482 setTimeout(function infiniteScroll() {
10483 if (lastHeight < element.scrollHeight) {
10484 lastHeight = element.scrollHeight;
10485 element.scrollTop = lastHeight;
10486 totalRetries += tries;
10487 times -= 1;
10488 if (times <= 0)
10489 return resolve({ succesfulTimes: numberOfTimes - times, totalRetries: totalRetries });
10490 tries = 0;
10491 return setTimeout(infiniteScroll, interval); // Get more content.
10492 }
10493 // No new content yet:
10494 element.scrollTop = element.scrollHeight; // Try scrolling again.
10495 tries += 1;
10496 if (tries >= retries)
10497 return resolve({ succesfulTimes: numberOfTimes - times, totalRetries: totalRetries });
10498 setTimeout(infiniteScroll, interval); // Retry
10499 }, interval);
10500 });
10501 };
10502 Getsy.prototype.hideFrame = function () {
10503 if (!this.iframe)
10504 throw Error('No iframe to hide.');
10505 this.iframe.style.opacity = '0';
10506 this.iframe.style.zIndex = '-1000';
10507 this.iframe.style.pointerEvents = 'none';
10508 };
10509 Getsy.prototype.showFrame = function () {
10510 if (!this.iframe)
10511 throw Error('No iframe to show.');
10512 this.iframe.style.opacity = '1';
10513 this.iframe.style.zIndex = '1000';
10514 this.iframe.style.pointerEvents = 'auto';
10515 };
10516 return Getsy;
10517}());
10518function getsy$1(url, options) {
10519 return new Promise(function (resolve, reject) {
10520 new Getsy(url, function (err, obj) {
10521 if (err)
10522 reject(err);
10523 resolve(obj);
10524 }, options);
10525 });
10526}
10527
10528/**
10529 * Entry point.
10530 */
10531
10532return getsy$1;
10533
10534})));