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

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

  ViewVC Help
Powered by ViewVC 1.1.20