/[projects]/misc/horsensspejder-web/jquery/jquery-ui-1.10.3/tests/jquery-1.8.3.js
ViewVC logotype

Annotation of /misc/horsensspejder-web/jquery/jquery-ui-1.10.3/tests/jquery-1.8.3.js

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20