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