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