]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blob - underlays/jquery/ikiwiki/jquery.js
3.20161229.1~bpo8+1
[git.ikiwiki.info.git] / underlays / jquery / ikiwiki / jquery.js
1 /*!
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 ) {
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() {
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         },
30         // Map over jQuery in case of overwrite
31         _jQuery = window.jQuery,
33         // Map over the $ in case of overwrite
34         _$ = window.$,
36         // A central reference to the root jQuery(document)
37         rootjQuery,
39         // A simple way to check for HTML strings or ID strings
40         // (both of which we optimize for)
41         quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
43         // Check if a string has a non-whitespace character in it
44         rnotwhite = /\S/,
46         // Used for trimming whitespace
47         trimLeft = /^\s+/,
48         trimRight = /\s+$/,
50         // Check for digits
51         rdigit = /\d/,
53         // Match a standalone tag
54         rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
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,
62         // Useragent RegExp
63         rwebkit = /(webkit)[ \/]([\w.]+)/,
64         ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
65         rmsie = /(msie) ([\w.]+)/,
66         rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
68         // Matches dashed string for camelizing
69         rdashAlpha = /-([a-z])/ig,
71         // Used by jQuery.camelCase as callback to replace()
72         fcamelCase = function( all, letter ) {
73                 return letter.toUpperCase();
74         },
76         // Keep a UserAgent string for use with jQuery.browser
77         userAgent = navigator.userAgent,
79         // For matching the engine and version of the browser
80         browserMatch,
82         // The deferred used on DOM ready
83         readyList,
85         // The ready event handler
86         DOMContentLoaded,
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,
96         // [[Class]] -> type pairs
97         class2type = {};
99 jQuery.fn = jQuery.prototype = {
100         constructor: jQuery,
101         init: function( selector, context, rootjQuery ) {
102                 var match, elem, ret, doc;
104                 // Handle $(""), $(null), or $(undefined)
105                 if ( !selector ) {
106                         return this;
107                 }
109                 // Handle $(DOMElement)
110                 if ( selector.nodeType ) {
111                         this.context = this[0] = selector;
112                         this.length = 1;
113                         return this;
114                 }
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                 }
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 ];
132                         } else {
133                                 match = quickExpr.exec( selector );
134                         }
136                         // Verify a match, and that no context was specified for #id
137                         if ( match && (match[1] || !context) ) {
139                                 // HANDLE: $(html) -> $(array)
140                                 if ( match[1] ) {
141                                         context = context instanceof jQuery ? context[0] : context;
142                                         doc = (context ? context.ownerDocument || context : document);
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 );
148                                         if ( ret ) {
149                                                 if ( jQuery.isPlainObject( context ) ) {
150                                                         selector = [ document.createElement( ret[1] ) ];
151                                                         jQuery.fn.attr.call( selector, context, true );
153                                                 } else {
154                                                         selector = [ doc.createElement( ret[1] ) ];
155                                                 }
157                                         } else {
158                                                 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
159                                                 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
160                                         }
162                                         return jQuery.merge( this, selector );
164                                 // HANDLE: $("#id")
165                                 } else {
166                                         elem = document.getElementById( match[2] );
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                                                 }
177                                                 // Otherwise, we inject the element directly into the jQuery object
178                                                 this.length = 1;
179                                                 this[0] = elem;
180                                         }
182                                         this.context = document;
183                                         this.selector = selector;
184                                         return this;
185                                 }
187                         // HANDLE: $(expr, $(...))
188                         } else if ( !context || context.jquery ) {
189                                 return (context || rootjQuery).find( selector );
191                         // HANDLE: $(expr, context)
192                         // (which is just equivalent to: $(context).find(expr)
193                         } else {
194                                 return this.constructor( context ).find( selector );
195                         }
197                 // HANDLE: $(function)
198                 // Shortcut for document ready
199                 } else if ( jQuery.isFunction( selector ) ) {
200                         return rootjQuery.ready( selector );
201                 }
203                 if (selector.selector !== undefined) {
204                         this.selector = selector.selector;
205                         this.context = selector.context;
206                 }
208                 return jQuery.makeArray( selector, this );
209         },
211         // Start with an empty selector
212         selector: "",
214         // The current version of jQuery being used
215         jquery: "1.6.2",
217         // The default length of a jQuery object is 0
218         length: 0,
220         // The number of elements contained in the matched element set
221         size: function() {
222                 return this.length;
223         },
225         toArray: function() {
226                 return slice.call( this, 0 );
227         },
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 ?
234                         // Return a 'clean' array
235                         this.toArray() :
237                         // Return just the object
238                         ( num < 0 ? this[ this.length + num ] : this[ num ] );
239         },
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();
247                 if ( jQuery.isArray( elems ) ) {
248                         push.apply( ret, elems );
250                 } else {
251                         jQuery.merge( ret, elems );
252                 }
254                 // Add the old object onto the stack (as a reference)
255                 ret.prevObject = this;
257                 ret.context = this.context;
259                 if ( name === "find" ) {
260                         ret.selector = this.selector + (this.selector ? " " : "") + selector;
261                 } else if ( name ) {
262                         ret.selector = this.selector + "." + name + "(" + selector + ")";
263                 }
265                 // Return the newly-formed element set
266                 return ret;
267         },
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         },
276         ready: function( fn ) {
277                 // Attach the listeners
278                 jQuery.bindReady();
280                 // Add the callback
281                 readyList.done( fn );
283                 return this;
284         },
286         eq: function( i ) {
287                 return i === -1 ?
288                         this.slice( i ) :
289                         this.slice( i, +i + 1 );
290         },
292         first: function() {
293                 return this.eq( 0 );
294         },
296         last: function() {
297                 return this.eq( -1 );
298         },
300         slice: function() {
301                 return this.pushStack( slice.apply( this, arguments ),
302                         "slice", slice.call(arguments).join(",") );
303         },
305         map: function( callback ) {
306                 return this.pushStack( jQuery.map(this, function( elem, i ) {
307                         return callback.call( elem, i, elem );
308                 }));
309         },
311         end: function() {
312                 return this.prevObject || this.constructor(null);
313         },
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 };
322 // Give the init function the jQuery prototype for later instantiation
323 jQuery.fn.init.prototype = jQuery.fn;
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;
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         }
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         }
345         // extend jQuery itself if only one argument is passed
346         if ( length === i ) {
347                 target = this;
348                 --i;
349         }
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 ];
359                                 // Prevent never-ending loop
360                                 if ( target === copy ) {
361                                         continue;
362                                 }
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 : [];
370                                         } else {
371                                                 clone = src && jQuery.isPlainObject(src) ? src : {};
372                                         }
374                                         // Never move original objects, clone them
375                                         target[ name ] = jQuery.extend( deep, clone, copy );
377                                 // Don't bring in undefined values
378                                 } else if ( copy !== undefined ) {
379                                         target[ name ] = copy;
380                                 }
381                         }
382                 }
383         }
385         // Return the modified object
386         return target;
387 };
389 jQuery.extend({
390         noConflict: function( deep ) {
391                 if ( window.$ === jQuery ) {
392                         window.$ = _$;
393                 }
395                 if ( deep && window.jQuery === jQuery ) {
396                         window.jQuery = _jQuery;
397                 }
399                 return jQuery;
400         },
402         // Is the DOM ready to be used? Set to true once it occurs.
403         isReady: false,
405         // A counter to track how many items to wait for before
406         // the ready event fires. See #6781
407         readyWait: 1,
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         },
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                         }
427                         // Remember that the DOM is ready
428                         jQuery.isReady = true;
430                         // If a normal DOM Ready event fired, decrement, and wait if need be
431                         if ( wait !== true && --jQuery.readyWait > 0 ) {
432                                 return;
433                         }
435                         // If there are functions bound, to execute
436                         readyList.resolveWith( document, [ jQuery ] );
438                         // Trigger any bound ready events
439                         if ( jQuery.fn.trigger ) {
440                                 jQuery( document ).trigger( "ready" ).unbind( "ready" );
441                         }
442                 }
443         },
445         bindReady: function() {
446                 if ( readyList ) {
447                         return;
448                 }
450                 readyList = jQuery._Deferred();
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                 }
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 );
464                         // A fallback to window.onload, that will always work
465                         window.addEventListener( "load", jQuery.ready, false );
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 );
473                         // A fallback to window.onload, that will always work
474                         window.attachEvent( "onload", jQuery.ready );
476                         // If IE and not a frame
477                         // continually check to see if the document is ready
478                         var toplevel = false;
480                         try {
481                                 toplevel = window.frameElement == null;
482                         } catch(e) {}
484                         if ( document.documentElement.doScroll && toplevel ) {
485                                 doScrollCheck();
486                         }
487                 }
488         },
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         },
497         isArray: Array.isArray || function( obj ) {
498                 return jQuery.type(obj) === "array";
499         },
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         },
506         isNaN: function( obj ) {
507                 return obj == null || !rdigit.test( obj ) || isNaN( obj );
508         },
510         type: function( obj ) {
511                 return obj == null ?
512                         String( obj ) :
513                         class2type[ toString.call(obj) ] || "object";
514         },
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                 }
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                 }
531                 // Own properties are enumerated firstly, so to speed up,
532                 // if last one is own, then all properties are own.
534                 var key;
535                 for ( key in obj ) {}
537                 return key === undefined || hasOwn.call( obj, key );
538         },
540         isEmptyObject: function( obj ) {
541                 for ( var name in obj ) {
542                         return false;
543                 }
544                 return true;
545         },
547         error: function( msg ) {
548                 throw msg;
549         },
551         parseJSON: function( data ) {
552                 if ( typeof data !== "string" || !data ) {
553                         return null;
554                 }
556                 // Make sure leading/trailing whitespace is removed (IE can't handle it)
557                 data = jQuery.trim( data );
559                 // Attempt to parse using the native JSON parser first
560                 if ( window.JSON && window.JSON.parse ) {
561                         return window.JSON.parse( data );
562                 }
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, "")) ) {
570                         return (new Function( "return " + data ))();
572                 }
573                 jQuery.error( "Invalid JSON: " + data );
574         },
576         // Cross-browser xml parsing
577         // (xml & tmp used internally)
578         parseXML: function( data , xml , tmp ) {
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                 }
589                 tmp = xml.documentElement;
591                 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
592                         jQuery.error( "Invalid XML: " + data );
593                 }
595                 return xml;
596         },
598         noop: function() {},
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         },
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         },
620         nodeName: function( elem, name ) {
621                 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
622         },
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 );
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                         }
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                 }
662                 return object;
663         },
665         // Use native String.trim function wherever possible
666         trim: trim ?
667                 function( text ) {
668                         return text == null ?
669                                 "" :
670                                 trim.call( text );
671                 } :
673                 // Otherwise use our own trimming functionality
674                 function( text ) {
675                         return text == null ?
676                                 "" :
677                                 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
678                 },
680         // results is for internal usage only
681         makeArray: function( array, results ) {
682                 var ret = results || [];
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 );
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                 }
698                 return ret;
699         },
701         inArray: function( elem, array ) {
703                 if ( indexOf ) {
704                         return indexOf.call( array, elem );
705                 }
707                 for ( var i = 0, length = array.length; i < length; i++ ) {
708                         if ( array[ i ] === elem ) {
709                                 return i;
710                         }
711                 }
713                 return -1;
714         },
716         merge: function( first, second ) {
717                 var i = first.length,
718                         j = 0;
720                 if ( typeof second.length === "number" ) {
721                         for ( var l = second.length; j < l; j++ ) {
722                                 first[ i++ ] = second[ j ];
723                         }
725                 } else {
726                         while ( second[j] !== undefined ) {
727                                 first[ i++ ] = second[ j++ ];
728                         }
729                 }
731                 first.length = i;
733                 return first;
734         },
736         grep: function( elems, callback, inv ) {
737                 var ret = [], retVal;
738                 inv = !!inv;
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                 }
749                 return ret;
750         },
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 ) ) ;
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 );
765                                 if ( value != null ) {
766                                         ret[ ret.length ] = value;
767                                 }
768                         }
770                 // Go through every key on the object,
771                 } else {
772                         for ( key in elems ) {
773                                 value = callback( elems[ key ], key, arg );
775                                 if ( value != null ) {
776                                         ret[ ret.length ] = value;
777                                 }
778                         }
779                 }
781                 // Flatten any nested arrays
782                 return ret.concat.apply( [], ret );
783         },
785         // A global GUID counter for objects
786         guid: 1,
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                 }
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                 }
803                 // Simulated bind
804                 var args = slice.call( arguments, 2 ),
805                         proxy = function() {
806                                 return fn.apply( context, args.concat( slice.call( arguments ) ) );
807                         };
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++;
812                 return proxy;
813         },
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;
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                 }
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);
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                         }
837                         return elems;
838                 }
840                 // Getting an attribute
841                 return length ? fn( elems[0], key ) : undefined;
842         },
844         now: function() {
845                 return (new Date()).getTime();
846         },
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();
853                 var match = rwebkit.exec( ua ) ||
854                         ropera.exec( ua ) ||
855                         rmsie.exec( ua ) ||
856                         ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
857                         [];
859                 return { browser: match[1] || "", version: match[2] || "0" };
860         },
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                         }
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         },
883         browser: {}
884 });
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 });
891 browserMatch = jQuery.uaMatch( userAgent );
892 if ( browserMatch.browser ) {
893         jQuery.browser[ browserMatch.browser ] = true;
894         jQuery.browser.version = browserMatch.version;
897 // Deprecated, use jQuery.browser.webkit instead
898 if ( jQuery.browser.webkit ) {
899         jQuery.browser.safari = true;
902 // IE doesn't match non-breaking spaces with \s
903 if ( rnotwhite.test( "\xA0" ) ) {
904         trimLeft = /^[\s\xA0]+/;
905         trimRight = /[\s\xA0]+$/;
908 // All jQuery objects should point back to these
909 rootjQuery = jQuery(document);
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         };
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         };
928 // The DOM ready check for Internet Explorer
929 function doScrollCheck() {
930         if ( jQuery.isReady ) {
931                 return;
932         }
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         }
943         // and execute any waiting functions
944         jQuery.ready();
947 return jQuery;
949 })();
952 var // Promise methods
953         promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
954         // Static reference to slice
955         sliceDeferred = [].slice;
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  = {
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                                 },
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                                 },
1019                                 // resolve with this as context and given arguments
1020                                 resolve: function() {
1021                                         deferred.resolveWith( this, arguments );
1022                                         return this;
1023                                 },
1025                                 // Has this deferred been resolved?
1026                                 isResolved: function() {
1027                                         return !!( firing || fired );
1028                                 },
1030                                 // Cancel
1031                                 cancel: function() {
1032                                         cancelled = 1;
1033                                         callbacks = [];
1034                                         return this;
1035                                 }
1036                         };
1038                 return deferred;
1039         },
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         },
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 });
1150 jQuery.support = (function() {
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;
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'/>";
1176         all = div.getElementsByTagName( "*" );
1177         a = div.getElementsByTagName( "a" )[ 0 ];
1179         // Can't get basic test support
1180         if ( !all || !all.length || !a ) {
1181                 return {};
1182         }
1184         // First batch of supports tests
1185         select = document.createElement( "select" );
1186         opt = select.appendChild( document.createElement("option") );
1187         input = div.getElementsByTagName( "input" )[ 0 ];
1189         support = {
1190                 // IE strips leading whitespace when .innerHTML is used
1191                 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1193                 // Make sure that tbody elements aren't automatically inserted
1194                 // IE will insert them into empty tables
1195                 tbody: !div.getElementsByTagName( "tbody" ).length,
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,
1201                 // Get the style information from getAttribute
1202                 // (IE uses .cssText instead)
1203                 style: /top/.test( a.getAttribute("style") ),
1205                 // Make sure that URLs aren't manipulated
1206                 // (IE normalizes it by default)
1207                 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
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 ),
1214                 // Verify style float existence
1215                 // (IE uses styleFloat instead of cssFloat)
1216                 cssFloat: !!a.style.cssFloat,
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" ),
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,
1227                 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1228                 getSetAttribute: div.className !== "t",
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         };
1241         // Make sure checked status is properly cloned
1242         input.checked = true;
1243         support.noCloneChecked = input.cloneNode( true ).checked;
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;
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         }
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         }
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";
1274         input.setAttribute("checked", "checked");
1275         div.appendChild( input );
1276         fragment = document.createDocumentFragment();
1277         fragment.appendChild( div.firstChild );
1279         // WebKit doesn't clone checked state correctly in fragments
1280         support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1282         div.innerHTML = "";
1284         // Figure out if the W3C box model works as expected
1285         div.style.width = div.style.paddingLeft = "1px";
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 );
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;
1316         support.boxModel = div.offsetWidth === 2;
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 );
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         }
1334         div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1335         tds = div.getElementsByTagName( "td" );
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 );
1346         tds[ 0 ].style.display = "";
1347         tds[ 1 ].style.display = "none";
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 = "";
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         }
1368         // Remove the body element we added
1369         testElement.innerHTML = "";
1370         testElementParent.removeChild( testElement );
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         }
1394         // Null connected elements to avoid leaks in IE
1395         testElement = fragment = select = opt = body = marginDiv = div = input = null;
1397         return support;
1398 })();
1400 // Keep track of boxModel
1401 jQuery.boxModel = jQuery.support.boxModel;
1406 var rbrace = /^(?:\{.*\}|\[.*\])$/,
1407         rmultiDash = /([a-z])([A-Z])/g;
1409 jQuery.extend({
1410         cache: {},
1412         // Please use with caution
1413         uuid: 0,
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, "" ),
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         },
1428         hasData: function( elem ) {
1429                 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1431                 return !!elem && !isEmptyDataObject( elem );
1432         },
1434         data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1435                 if ( !jQuery.acceptData( elem ) ) {
1436                         return;
1437                 }
1439                 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
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,
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,
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;
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                 }
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                 }
1469                 if ( !cache[ id ] ) {
1470                         cache[ id ] = {};
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                 }
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                 }
1490                 thisCache = cache[ id ];
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                         }
1500                         thisCache = thisCache[ internalKey ];
1501                 }
1503                 if ( data !== undefined ) {
1504                         thisCache[ jQuery.camelCase( name ) ] = data;
1505                 }
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                 }
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         },
1520         removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1521                 if ( !jQuery.acceptData( elem ) ) {
1522                         return;
1523                 }
1525                 var internalKey = jQuery.expando, isNode = elem.nodeType,
1527                         // See jQuery.data for more information
1528                         cache = isNode ? jQuery.cache : elem,
1530                         // See jQuery.data for more information
1531                         id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
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                 }
1539                 if ( name ) {
1540                         var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1542                         if ( thisCache ) {
1543                                 delete thisCache[ name ];
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                 }
1553                 // See jQuery.data for more information
1554                 if ( pvt ) {
1555                         delete cache[ id ][ internalKey ];
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                 }
1564                 var internalCache = cache[ id ][ internalKey ];
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                 }
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                         }
1587                         cache[ id ][ internalKey ] = internalCache;
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         },
1605         // For internal use only.
1606         _data: function( elem, name, data ) {
1607                 return jQuery.data( elem, name, data, true );
1608         },
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() ];
1615                         if ( match ) {
1616                                 return !(match === true || elem.getAttribute("classid") !== match);
1617                         }
1618                 }
1620                 return true;
1621         }
1622 });
1624 jQuery.fn.extend({
1625         data: function( key, value ) {
1626                 var data = null;
1628                 if ( typeof key === "undefined" ) {
1629                         if ( this.length ) {
1630                                 data = jQuery.data( this[0] );
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;
1637                                                 if ( name.indexOf( "data-" ) === 0 ) {
1638                                                         name = jQuery.camelCase( name.substring(5) );
1640                                                         dataAttr( this[0], name, data[ name ] );
1641                                                 }
1642                                         }
1643                                 }
1644                         }
1646                         return data;
1648                 } else if ( typeof key === "object" ) {
1649                         return this.each(function() {
1650                                 jQuery.data( this, key );
1651                         });
1652                 }
1654                 var parts = key.split(".");
1655                 parts[1] = parts[1] ? "." + parts[1] : "";
1657                 if ( value === undefined ) {
1658                         data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
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                         }
1666                         return data === undefined && parts[1] ?
1667                                 this.data( parts[0] ) :
1668                                 data;
1670                 } else {
1671                         return this.each(function() {
1672                                 var $this = jQuery( this ),
1673                                         args = [ parts[0], value ];
1675                                 $this.triggerHandler( "setData" + parts[1] + "!", args );
1676                                 jQuery.data( this, key, value );
1677                                 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1678                         });
1679                 }
1680         },
1682         removeData: function( key ) {
1683                 return this.each(function() {
1684                         jQuery.removeData( this, key );
1685                 });
1686         }
1687 });
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();
1695                 data = elem.getAttribute( name );
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 ) {}
1707                         // Make sure we set the data so it isn't changed later
1708                         jQuery.data( elem, key, data );
1710                 } else {
1711                         data = undefined;
1712                 }
1713         }
1715         return data;
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         }
1728         return true;
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         }
1754 jQuery.extend({
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         },
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         },
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         },
1798         dequeue: function( elem, type ) {
1799                 type = type || "fx";
1801                 var queue = jQuery.queue( elem, type ),
1802                         fn = queue.shift(),
1803                         defer;
1805                 // If the fx queue is dequeued, always remove the progress sentinel
1806                 if ( fn === "inprogress" ) {
1807                         fn = queue.shift();
1808                 }
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                         }
1817                         fn.call(elem, function() {
1818                                 jQuery.dequeue(elem, type);
1819                         });
1820                 }
1822                 if ( !queue.length ) {
1823                         jQuery.removeData( elem, type + "queue", true );
1824                         handleQueueMarkDefer( elem, type, "queue" );
1825                 }
1826         }
1827 });
1829 jQuery.fn.extend({
1830         queue: function( type, data ) {
1831                 if ( typeof type !== "string" ) {
1832                         data = type;
1833                         type = "fx";
1834                 }
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 );
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";
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 });
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;
1916 jQuery.fn.extend({
1917         attr: function( name, value ) {
1918                 return jQuery.access( this, name, value, true, jQuery.attr );
1919         },
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         },
1942         addClass: function( value ) {
1943                 var classNames, i, l, elem,
1944                         setClass, c, cl;
1946                 if ( jQuery.isFunction( value ) ) {
1947                         return this.each(function( j ) {
1948                                 jQuery( this ).addClass( value.call(this, j, this.className) );
1949                         });
1950                 }
1952                 if ( value && typeof value === "string" ) {
1953                         classNames = value.split( rspace );
1955                         for ( i = 0, l = this.length; i < l; i++ ) {
1956                                 elem = this[ i ];
1958                                 if ( elem.nodeType === 1 ) {
1959                                         if ( !elem.className && classNames.length === 1 ) {
1960                                                 elem.className = value;
1962                                         } else {
1963                                                 setClass = " " + elem.className + " ";
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                 }
1976                 return this;
1977         },
1979         removeClass: function( value ) {
1980                 var classNames, i, l, elem, className, c, cl;
1982                 if ( jQuery.isFunction( value ) ) {
1983                         return this.each(function( j ) {
1984                                 jQuery( this ).removeClass( value.call(this, j, this.className) );
1985                         });
1986                 }
1988                 if ( (value && typeof value === "string") || value === undefined ) {
1989                         classNames = (value || "").split( rspace );
1991                         for ( i = 0, l = this.length; i < l; i++ ) {
1992                                 elem = this[ i ];
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 );
2002                                         } else {
2003                                                 elem.className = "";
2004                                         }
2005                                 }
2006                         }
2007                 }
2009                 return this;
2010         },
2012         toggleClass: function( value, stateVal ) {
2013                 var type = typeof value,
2014                         isBool = typeof stateVal === "boolean";
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                 }
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 );
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                                 }
2037                         } else if ( type === "undefined" || type === "boolean" ) {
2038                                 if ( this.className ) {
2039                                         // store className if set
2040                                         jQuery._data( this, "__className__", this.className );
2041                                 }
2043                                 // toggle whole className
2044                                 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2045                         }
2046                 });
2047         },
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                 }
2057                 return false;
2058         },
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 ];
2068                                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2069                                         return ret;
2070                                 }
2072                                 ret = elem.value;
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                         }
2081                         return undefined;
2082                 }
2084                 var isFunction = jQuery.isFunction( value );
2086                 return this.each(function( i ) {
2087                         var self = jQuery(this), val;
2089                         if ( this.nodeType !== 1 ) {
2090                                 return;
2091                         }
2093                         if ( isFunction ) {
2094                                 val = value.call( this, i, self.val() );
2095                         } else {
2096                                 val = value;
2097                         }
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                         }
2110                         hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
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 });
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";
2138                                 // Nothing was selected
2139                                 if ( index < 0 ) {
2140                                         return null;
2141                                 }
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 ];
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" )) ) {
2151                                                 // Get the specific value for the option
2152                                                 value = jQuery( option ).val();
2154                                                 // We don't need an array for one selects
2155                                                 if ( one ) {
2156                                                         return value;
2157                                                 }
2159                                                 // Multi-Selects return an array
2160                                                 values.push( value );
2161                                         }
2162                                 }
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                                 }
2169                                 return values;
2170                         },
2172                         set: function( elem, value ) {
2173                                 var values = jQuery.makeArray( value );
2175                                 jQuery(elem).find("option").each(function() {
2176                                         this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2177                                 });
2179                                 if ( !values.length ) {
2180                                         elem.selectedIndex = -1;
2181                                 }
2182                                 return values;
2183                         }
2184                 }
2185         },
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                 }
2211                 if ( pass && name in jQuery.attrFn ) {
2212                         return jQuery( elem )[ name ]( value );
2213                 }
2215                 // Fallback to prop when attributes are not supported
2216                 if ( !("getAttribute" in elem) ) {
2217                         return jQuery.prop( elem, name, value );
2218                 }
2220                 var ret, hooks,
2221                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2223                 // Normalize the name if needed
2224                 if ( notxml ) {
2225                         name = jQuery.attrFix[ name ] || name;
2227                         hooks = jQuery.attrHooks[ name ];
2229                         if ( !hooks ) {
2230                                 // Use boolHook for boolean attributes
2231                                 if ( rboolean.test( name ) ) {
2233                                         hooks = boolHook;
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 )) ) {
2239                                         hooks = formHook;
2240                                 }
2241                         }
2242                 }
2244                 if ( value !== undefined ) {
2246                         if ( value === null ) {
2247                                 jQuery.removeAttr( elem, name );
2248                                 return undefined;
2250                         } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2251                                 return ret;
2253                         } else {
2254                                 elem.setAttribute( name, "" + value );
2255                                 return value;
2256                         }
2258                 } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2259                         return ret;
2261                 } else {
2263                         ret = elem.getAttribute( name );
2265                         // Non-existent attributes return null, we normalize to undefined
2266                         return ret === null ?
2267                                 undefined :
2268                                 ret;
2269                 }
2270         },
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                         }
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         },
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");
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         },
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;
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                 }
2368                 var ret, hooks,
2369                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2371                 if ( notxml ) {
2372                         // Fix name and attach hooks
2373                         name = jQuery.propFix[ name ] || name;
2374                         hooks = jQuery.propHooks[ name ];
2375                 }
2377                 if ( value !== undefined ) {
2378                         if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2379                                 return ret;
2381                         } else {
2382                                 return (elem[ name ] = value);
2383                         }
2385                 } else {
2386                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2387                                 return ret;
2389                         } else {
2390                                 return elem[ name ];
2391                         }
2392                 }
2393         },
2394         
2395         propHooks: {}
2396 });
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                         }
2420                         elem.setAttribute( name, name.toLowerCase() );
2421                 }
2422                 return name;
2423         }
2424 };
2426 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2427 if ( !jQuery.support.getSetAttribute ) {
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         };
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         });
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         });
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         };
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;
2500                         if ( parent ) {
2501                                 parent.selectedIndex;
2503                                 // Make sure that it also works with optgroups, see #5701
2504                                 if ( parent.parentNode ) {
2505                                         parent.parentNode.selectedIndex;
2506                                 }
2507                         }
2508                 }
2509         });
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         });
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 });
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         };
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 = {
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                 }
2559                 if ( handler === false ) {
2560                         handler = returnFalse;
2561                 } else if ( !handler ) {
2562                         // Fixes bug #7229. Fix recommended by jdalton
2563                         return;
2564                 }
2566                 var handleObjIn, handleObj;
2568                 if ( handler.handler ) {
2569                         handleObjIn = handler;
2570                         handler = handleObjIn.handler;
2571                 }
2573                 // Make sure that the function being executed has a unique ID
2574                 if ( !handler.guid ) {
2575                         handler.guid = jQuery.guid++;
2576                 }
2578                 // Init the element's event structure
2579                 var elemData = jQuery._data( elem );
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                 }
2587                 var events = elemData.events,
2588                         eventHandle = elemData.handle;
2590                 if ( !events ) {
2591                         elemData.events = events = {};
2592                 }
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                 }
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;
2608                 // Handle multiple events separated by a space
2609                 // jQuery(...).bind("mouseover mouseout", fn);
2610                 types = types.split(" ");
2612                 var type, i = 0, namespaces;
2614                 while ( (type = types[ i++ ]) ) {
2615                         handleObj = handleObjIn ?
2616                                 jQuery.extend({}, handleObjIn) :
2617                                 { handler: handler, data: data };
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(".");
2625                         } else {
2626                                 namespaces = [];
2627                                 handleObj.namespace = "";
2628                         }
2630                         handleObj.type = type;
2631                         if ( !handleObj.guid ) {
2632                                 handleObj.guid = handler.guid;
2633                         }
2635                         // Get the current list of functions bound to this event
2636                         var handlers = events[ type ],
2637                                 special = jQuery.event.special[ type ] || {};
2639                         // Init the event handler queue
2640                         if ( !handlers ) {
2641                                 handlers = events[ type ] = [];
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 );
2651                                         } else if ( elem.attachEvent ) {
2652                                                 elem.attachEvent( "on" + type, eventHandle );
2653                                         }
2654                                 }
2655                         }
2657                         if ( special.add ) {
2658                                 special.add.call( elem, handleObj );
2660                                 if ( !handleObj.handler.guid ) {
2661                                         handleObj.handler.guid = handler.guid;
2662                                 }
2663                         }
2665                         // Add the function to the element's handler list
2666                         handlers.push( handleObj );
2668                         // Keep track of which events have been used, for event optimization
2669                         jQuery.event.global[ type ] = true;
2670                 }
2672                 // Nullify elem to prevent memory leaks in IE
2673                 elem = null;
2674         },
2676         global: {},
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                 }
2685                 if ( handler === false ) {
2686                         handler = returnFalse;
2687                 }
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;
2693                 if ( !elemData || !events ) {
2694                         return;
2695                 }
2697                 // types is actually an event object here
2698                 if ( types && types.type ) {
2699                         handler = types.handler;
2700                         types = types.type;
2701                 }
2703                 // Unbind all events for the element
2704                 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2705                         types = types || "";
2707                         for ( type in events ) {
2708                                 jQuery.event.remove( elem, type + types );
2709                         }
2711                         return;
2712                 }
2714                 // Handle multiple events separated by a space
2715                 // jQuery(...).unbind("mouseover mouseout", fn);
2716                 types = types.split(" ");
2718                 while ( (type = types[ i++ ]) ) {
2719                         origType = type;
2720                         handleObj = null;
2721                         all = type.indexOf(".") < 0;
2722                         namespaces = [];
2724                         if ( !all ) {
2725                                 // Namespaced event handlers
2726                                 namespaces = type.split(".");
2727                                 type = namespaces.shift();
2729                                 namespace = new RegExp("(^|\\.)" +
2730                                         jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2731                         }
2733                         eventType = events[ type ];
2735                         if ( !eventType ) {
2736                                 continue;
2737                         }
2739                         if ( !handler ) {
2740                                 for ( j = 0; j < eventType.length; j++ ) {
2741                                         handleObj = eventType[ j ];
2743                                         if ( all || namespace.test( handleObj.namespace ) ) {
2744                                                 jQuery.event.remove( elem, origType, handleObj.handler, j );
2745                                                 eventType.splice( j--, 1 );
2746                                         }
2747                                 }
2749                                 continue;
2750                         }
2752                         special = jQuery.event.special[ type ] || {};
2754                         for ( j = pos || 0; j < eventType.length; j++ ) {
2755                                 handleObj = eventType[ j ];
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                                                 }
2764                                                 if ( special.remove ) {
2765                                                         special.remove.call( elem, handleObj );
2766                                                 }
2767                                         }
2769                                         if ( pos != null ) {
2770                                                 break;
2771                                         }
2772                                 }
2773                         }
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                                 }
2781                                 ret = null;
2782                                 delete events[ type ];
2783                         }
2784                 }
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                         }
2793                         delete elemData.events;
2794                         delete elemData.handle;
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         },
2810         trigger: function( event, data, elem, onlyHandlers ) {
2811                 // Event object or event type
2812                 var type = event.type || event,
2813                         namespaces = [],
2814                         exclusive;
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                 }
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                 }
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                 }
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 );
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                 }
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                 }
2870                 // Don't do events on text and comment nodes
2871                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2872                         return;
2873                 }
2875                 // Clean up the event in case it is being reused
2876                 event.result = undefined;
2877                 event.target = elem;
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 );
2883                 var cur = elem,
2884                         // IE doesn't like method names with a colon (#3533, #8272)
2885                         ontype = type.indexOf(":") < 0 ? "on" + type : "";
2887                 // Fire event on the current element, then bubble up the DOM tree
2888                 do {
2889                         var handle = jQuery._data( cur, "handle" );
2891                         event.currentTarget = cur;
2892                         if ( handle ) {
2893                                 handle.apply( cur, data );
2894                         }
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                         }
2902                         // Bubble up to document, then to window
2903                         cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2904                 } while ( cur && !event.isPropagationStopped() );
2906                 // If nobody prevented the default action, do it now
2907                 if ( !event.isDefaultPrevented() ) {
2908                         var old,
2909                                 special = jQuery.event.special[ type ] || {};
2911                         if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2912                                 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
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 ];
2922                                                 if ( old ) {
2923                                                         elem[ ontype ] = null;
2924                                                 }
2926                                                 jQuery.event.triggered = type;
2927                                                 elem[ type ]();
2928                                         }
2929                                 } catch ( ieError ) {}
2931                                 if ( old ) {
2932                                         elem[ ontype ] = old;
2933                                 }
2935                                 jQuery.event.triggered = undefined;
2936                         }
2937                 }
2938                 
2939                 return event.result;
2940         },
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 );
2949                 // Use the fix-ed Event rather than the (read-only) native event
2950                 args[0] = event;
2951                 event.currentTarget = this;
2953                 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2954                         var handleObj = handlers[ j ];
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;
2965                                 var ret = handleObj.handler.apply( this, args );
2967                                 if ( ret !== undefined ) {
2968                                         event.result = ret;
2969                                         if ( ret === false ) {
2970                                                 event.preventDefault();
2971                                                 event.stopPropagation();
2972                                         }
2973                                 }
2975                                 if ( event.isImmediatePropagationStopped() ) {
2976                                         break;
2977                                 }
2978                         }
2979                 }
2980                 return event.result;
2981         },
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(" "),
2985         fix: function( event ) {
2986                 if ( event[ jQuery.expando ] ) {
2987                         return event;
2988                 }
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 );
2995                 for ( var i = this.props.length, prop; i; ) {
2996                         prop = this.props[ --i ];
2997                         event[ prop ] = originalEvent[ prop ];
2998                 }
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                 }
3006                 // check if target is a textnode (safari)
3007                 if ( event.target.nodeType === 3 ) {
3008                         event.target = event.target.parentNode;
3009                 }
3011                 // Add relatedTarget, if necessary
3012                 if ( !event.relatedTarget && event.fromElement ) {
3013                         event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
3014                 }
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;
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                 }
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                 }
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                 }
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                 }
3042                 return event;
3043         },
3045         // Deprecated, use jQuery.guid instead
3046         guid: 1E8,
3048         // Deprecated, use jQuery.proxy instead
3049         proxy: jQuery.proxy,
3051         special: {
3052                 ready: {
3053                         // Make sure the ready event is setup
3054                         setup: jQuery.bindReady,
3055                         teardown: jQuery.noop
3056                 },
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                         },
3065                         remove: function( handleObj ) {
3066                                 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3067                         }
3068                 },
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                         },
3078                         teardown: function( namespaces, eventHandle ) {
3079                                 if ( this.onbeforeunload === eventHandle ) {
3080                                         this.onbeforeunload = null;
3081                                 }
3082                         }
3083                 }
3084         }
3085 };
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         };
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         }
3105         // Event object
3106         if ( src && src.type ) {
3107                 this.originalEvent = src;
3108                 this.type = src.type;
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;
3115         // Event type
3116         } else {
3117                 this.type = src;
3118         }
3120         // Put explicitly provided properties onto the event object
3121         if ( props ) {
3122                 jQuery.extend( this, props );
3123         }
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();
3129         // Mark it as fixed
3130         this[ jQuery.expando ] = true;
3131 };
3133 function returnFalse() {
3134         return false;
3136 function returnTrue() {
3137         return true;
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;
3146                 var e = this.originalEvent;
3147                 if ( !e ) {
3148                         return;
3149                 }
3151                 // if preventDefault exists run it on the original event
3152                 if ( e.preventDefault ) {
3153                         e.preventDefault();
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;
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 };
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 ) {
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;
3192         event.type = event.data;
3194         if ( related !== this ) {
3196                 if ( related ) {
3197                         inside = jQuery.contains( this, related );
3198                 }
3200                 if ( !inside ) {
3202                         jQuery.event.handle.apply( this, arguments );
3204                         event.type = eventType;
3205                 }
3206         }
3207 },
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 };
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 });
3231 // submit delegation
3232 if ( !jQuery.support.submitBubbles ) {
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;
3241                                         if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3242                                                 trigger( "submit", this, arguments );
3243                                         }
3244                                 });
3246                                 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3247                                         var elem = e.target,
3248                                                 type = elem.type;
3250                                         if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3251                                                 trigger( "submit", this, arguments );
3252                                         }
3253                                 });
3255                         } else {
3256                                 return false;
3257                         }
3258                 },
3260                 teardown: function( namespaces ) {
3261                         jQuery.event.remove( this, ".specialSubmit" );
3262                 }
3263         };
3267 // change delegation, happens here so we have bind.
3268 if ( !jQuery.support.changeBubbles ) {
3270         var changeFilters,
3272         getVal = function( elem ) {
3273                 var type = elem.type, val = elem.value;
3275                 if ( type === "radio" || type === "checkbox" ) {
3276                         val = elem.checked;
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                                 "";
3285                 } else if ( jQuery.nodeName( elem, "select" ) ) {
3286                         val = elem.selectedIndex;
3287                 }
3289                 return val;
3290         },
3292         testChange = function testChange( e ) {
3293                 var elem = e.target, data, val;
3295                 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3296                         return;
3297                 }
3299                 data = jQuery._data( elem, "_change_data" );
3300                 val = getVal(elem);
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                 }
3307                 if ( data === undefined || val === data ) {
3308                         return;
3309                 }
3311                 if ( data != null || val ) {
3312                         e.type = "change";
3313                         e.liveFired = undefined;
3314                         jQuery.event.trigger( e, arguments[1], elem );
3315                 }
3316         };
3318         jQuery.event.special.change = {
3319                 filters: {
3320                         focusout: testChange,
3322                         beforedeactivate: testChange,
3324                         click: function( e ) {
3325                                 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3327                                 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3328                                         testChange.call( this, e );
3329                                 }
3330                         },
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 : "";
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                         },
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                 },
3353                 setup: function( data, namespaces ) {
3354                         if ( this.type === "file" ) {
3355                                 return false;
3356                         }
3358                         for ( var type in changeFilters ) {
3359                                 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3360                         }
3362                         return rformElems.test( this.nodeName );
3363                 },
3365                 teardown: function( namespaces ) {
3366                         jQuery.event.remove( this, ".specialChange" );
3368                         return rformElems.test( this.nodeName );
3369                 }
3370         };
3372         changeFilters = jQuery.event.special.change.filters;
3374         // Handle when the input is .focus()'d
3375         changeFilters.focus = changeFilters.beforeactivate;
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         }
3393 // Create "bubbling" focus and blur events
3394 if ( !jQuery.support.focusinBubbles ) {
3395         jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3397                 // Attach a single capturing handler while someone wants focusin/focusout
3398                 var attaches = 0;
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                 };
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         });
3427 jQuery.each(["bind", "one"], function( i, name ) {
3428         jQuery.fn[ name ] = function( type, data, fn ) {
3429                 var handler;
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                 }
3439                 if ( arguments.length === 2 || data === false ) {
3440                         fn = data;
3441                         data = undefined;
3442                 }
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                 }
3454                 if ( type === "unload" && name !== "one" ) {
3455                         this.one( type, data, fn );
3457                 } else {
3458                         for ( var i = 0, l = this.length; i < l; i++ ) {
3459                                 jQuery.event.add( this[i], type, handler, data );
3460                         }
3461                 }
3463                 return this;
3464         };
3465 });
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                         }
3475                 } else {
3476                         for ( var i = 0, l = this.length; i < l; i++ ) {
3477                                 jQuery.event.remove( this[i], type, fn );
3478                         }
3479                 }
3481                 return this;
3482         },
3484         delegate: function( selector, types, data, fn ) {
3485                 return this.live( types, data, fn, selector );
3486         },
3488         undelegate: function( selector, types, fn ) {
3489                 if ( arguments.length === 0 ) {
3490                         return this.unbind( "live" );
3492                 } else {
3493                         return this.die( types, null, fn, selector );
3494                 }
3495         },
3497         trigger: function( type, data ) {
3498                 return this.each(function() {
3499                         jQuery.event.trigger( type, data, this );
3500                 });
3501         },
3503         triggerHandler: function( type, data ) {
3504                 if ( this[0] ) {
3505                         return jQuery.event.trigger( type, data, this[0], true );
3506                 }
3507         },
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 );
3519                                 // Make sure that clicks stop
3520                                 event.preventDefault();
3522                                 // and execute the function
3523                                 return args[ lastToggle ].apply( this, arguments ) || false;
3524                         };
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                 }
3532                 return this.click( toggler );
3533         },
3535         hover: function( fnOver, fnOut ) {
3536                 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3537         }
3538 });
3540 var liveMap = {
3541         focus: "focusin",
3542         blur: "focusout",
3543         mouseenter: "mouseover",
3544         mouseleave: "mouseout"
3545 };
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 );
3553                 if ( typeof types === "object" && !types.preventDefault ) {
3554                         for ( var key in types ) {
3555                                 context[ name ]( key, data, types[key], selector );
3556                         }
3558                         return this;
3559                 }
3561                 if ( name === "die" && !types &&
3562                                         origSelector && origSelector.charAt(0) === "." ) {
3564                         context.unbind( origSelector );
3566                         return this;
3567                 }
3569                 if ( data === false || jQuery.isFunction( data ) ) {
3570                         fn = data || returnFalse;
3571                         data = undefined;
3572                 }
3574                 types = (types || "").split(" ");
3576                 while ( (type = types[ i++ ]) != null ) {
3577                         match = rnamespaces.exec( type );
3578                         namespaces = "";
3580                         if ( match )  {
3581                                 namespaces = match[0];
3582                                 type = type.replace( rnamespaces, "" );
3583                         }
3585                         if ( type === "hover" ) {
3586                                 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3587                                 continue;
3588                         }
3590                         preType = type;
3592                         if ( liveMap[ type ] ) {
3593                                 types.push( liveMap[ type ] + namespaces );
3594                                 type = type + namespaces;
3596                         } else {
3597                                 type = (liveMap[ type ] || type) + namespaces;
3598                         }
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                                 }
3607                         } else {
3608                                 // unbind live handler
3609                                 context.unbind( "live." + liveConvert( type, selector ), fn );
3610                         }
3611                 }
3613                 return this;
3614         };
3615 });
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" );
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         }
3628         if ( event.namespace ) {
3629                 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3630         }
3632         event.liveFired = this;
3634         var live = events.live.slice(0);
3636         for ( j = 0; j < live.length; j++ ) {
3637                 handleObj = live[j];
3639                 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3640                         selectors.push( handleObj.selector );
3642                 } else {
3643                         live.splice( j--, 1 );
3644                 }
3645         }
3647         match = jQuery( event.target ).closest( selectors, event.currentTarget );
3649         for ( i = 0, l = match.length; i < l; i++ ) {
3650                 close = match[i];
3652                 for ( j = 0; j < live.length; j++ ) {
3653                         handleObj = live[j];
3655                         if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3656                                 elem = close.elem;
3657                                 related = null;
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];
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                                 }
3670                                 if ( !related || related !== elem ) {
3671                                         elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3672                                 }
3673                         }
3674                 }
3675         }
3677         for ( i = 0, l = elems.length; i < l; i++ ) {
3678                 match = elems[i];
3680                 if ( maxLevel && match.level > maxLevel ) {
3681                         break;
3682                 }
3684                 event.currentTarget = match.elem;
3685                 event.data = match.handleObj.data;
3686                 event.handleObj = match.handleObj;
3688                 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3690                 if ( ret === false || event.isPropagationStopped() ) {
3691                         maxLevel = match.level;
3693                         if ( ret === false ) {
3694                                 stop = false;
3695                         }
3696                         if ( event.isImmediatePropagationStopped() ) {
3697                                 break;
3698                         }
3699                 }
3700         }
3702         return stop;
3705 function liveConvert( type, selector ) {
3706         return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
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 ) {
3713         // Handle event binding
3714         jQuery.fn[ name ] = function( data, fn ) {
3715                 if ( fn == null ) {
3716                         fn = data;
3717                         data = null;
3718                 }
3720                 return arguments.length > 0 ?
3721                         this.bind( name, data, fn ) :
3722                         this.trigger( name );
3723         };
3725         if ( jQuery.attrFn ) {
3726                 jQuery.attrFn[ name ] = true;
3727         }
3728 });
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(){
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/;
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 });
3757 var Sizzle = function( selector, context, results, seed ) {
3758         results = results || [];
3759         context = context || document;
3761         var origContext = context;
3763         if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3764                 return [];
3765         }
3766         
3767         if ( !selector || typeof selector !== "string" ) {
3768                 return results;
3769         }
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 );
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 );
3794         if ( parts.length > 1 && origPOS.exec( selector ) ) {
3796                 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3797                         set = posProcess( parts[0] + parts[1], context );
3799                 } else {
3800                         set = Expr.relative[ parts[0] ] ?
3801                                 [ context ] :
3802                                 Sizzle( parts.shift(), context );
3804                         while ( parts.length ) {
3805                                 selector = parts.shift();
3807                                 if ( Expr.relative[ selector ] ) {
3808                                         selector += parts.shift();
3809                                 }
3810                                 
3811                                 set = posProcess( selector, set );
3812                         }
3813                 }
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]) ) {
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                 }
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 );
3832                         set = ret.expr ?
3833                                 Sizzle.filter( ret.expr, ret.set ) :
3834                                 ret.set;
3836                         if ( parts.length > 0 ) {
3837                                 checkSet = makeArray( set );
3839                         } else {
3840                                 prune = false;
3841                         }
3843                         while ( parts.length ) {
3844                                 cur = parts.pop();
3845                                 pop = cur;
3847                                 if ( !Expr.relative[ cur ] ) {
3848                                         cur = "";
3849                                 } else {
3850                                         pop = parts.pop();
3851                                 }
3853                                 if ( pop == null ) {
3854                                         pop = context;
3855                                 }
3857                                 Expr.relative[ cur ]( checkSet, pop, contextXML );
3858                         }
3860                 } else {
3861                         checkSet = parts = [];
3862                 }
3863         }
3865         if ( !checkSet ) {
3866                 checkSet = set;
3867         }
3869         if ( !checkSet ) {
3870                 Sizzle.error( cur || selector );
3871         }
3873         if ( toString.call(checkSet) === "[object Array]" ) {
3874                 if ( !prune ) {
3875                         results.push.apply( results, checkSet );
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                         }
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                 }
3892         } else {
3893                 makeArray( checkSet, results );
3894         }
3896         if ( extra ) {
3897                 Sizzle( extra, origContext, results, seed );
3898                 Sizzle.uniqueSort( results );
3899         }
3901         return results;
3902 };
3904 Sizzle.uniqueSort = function( results ) {
3905         if ( sortOrder ) {
3906                 hasDuplicate = baseHasDuplicate;
3907                 results.sort( sortOrder );
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         }
3918         return results;
3919 };
3921 Sizzle.matches = function( expr, set ) {
3922         return Sizzle( expr, null, null, set );
3923 };
3925 Sizzle.matchesSelector = function( node, expr ) {
3926         return Sizzle( expr, null, null, [node] ).length > 0;
3927 };
3929 Sizzle.find = function( expr, context, isXML ) {
3930         var set;
3932         if ( !expr ) {
3933                 return [];
3934         }
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 );
3944                         if ( left.substr( left.length - 1 ) !== "\\" ) {
3945                                 match[1] = (match[1] || "").replace( rBackslash, "" );
3946                                 set = Expr.find[ type ]( match, context, isXML );
3948                                 if ( set != null ) {
3949                                         expr = expr.replace( Expr.match[ type ], "" );
3950                                         break;
3951                                 }
3952                         }
3953                 }
3954         }
3956         if ( !set ) {
3957                 set = typeof context.getElementsByTagName !== "undefined" ?
3958                         context.getElementsByTagName( "*" ) :
3959                         [];
3960         }
3962         return { set: set, expr: expr };
3963 };
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] );
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];
3979                                 anyFound = false;
3981                                 match.splice(1,1);
3983                                 if ( left.substr( left.length - 1 ) === "\\" ) {
3984                                         continue;
3985                                 }
3987                                 if ( curLoop === result ) {
3988                                         result = [];
3989                                 }
3991                                 if ( Expr.preFilter[ type ] ) {
3992                                         match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3994                                         if ( !match ) {
3995                                                 anyFound = found = true;
3997                                         } else if ( match === true ) {
3998                                                 continue;
3999                                         }
4000                                 }
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;
4008                                                         if ( inplace && found != null ) {
4009                                                                 if ( pass ) {
4010                                                                         anyFound = true;
4012                                                                 } else {
4013                                                                         curLoop[i] = false;
4014                                                                 }
4016                                                         } else if ( pass ) {
4017                                                                 result.push( item );
4018                                                                 anyFound = true;
4019                                                         }
4020                                                 }
4021                                         }
4022                                 }
4024                                 if ( found !== undefined ) {
4025                                         if ( !inplace ) {
4026                                                 curLoop = result;
4027                                         }
4029                                         expr = expr.replace( Expr.match[ type ], "" );
4031                                         if ( !anyFound ) {
4032                                                 return [];
4033                                         }
4035                                         break;
4036                                 }
4037                         }
4038                 }
4040                 // Improper expression
4041                 if ( expr === old ) {
4042                         if ( anyFound == null ) {
4043                                 Sizzle.error( expr );
4045                         } else {
4046                                 break;
4047                         }
4048                 }
4050                 old = expr;
4051         }
4053         return curLoop;
4054 };
4056 Sizzle.error = function( msg ) {
4057         throw "Syntax error, unrecognized expression: " + msg;
4058 };
4060 var Expr = Sizzle.selectors = {
4061         order: [ "ID", "NAME", "TAG" ],
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         },
4074         leftMatch: {},
4076         attrMap: {
4077                 "class": "className",
4078                 "for": "htmlFor"
4079         },
4081         attrHandle: {
4082                 href: function( elem ) {
4083                         return elem.getAttribute( "href" );
4084                 },
4085                 type: function( elem ) {
4086                         return elem.getAttribute( "type" );
4087                 }
4088         },
4090         relative: {
4091                 "+": function(checkSet, part){
4092                         var isPartStr = typeof part === "string",
4093                                 isTag = isPartStr && !rNonWord.test( part ),
4094                                 isPartStrNotTag = isPartStr && !isTag;
4096                         if ( isTag ) {
4097                                 part = part.toLowerCase();
4098                         }
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 ) {}
4104                                         checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4105                                                 elem || false :
4106                                                 elem === part;
4107                                 }
4108                         }
4110                         if ( isPartStrNotTag ) {
4111                                 Sizzle.filter( part, checkSet, true );
4112                         }
4113                 },
4115                 ">": function( checkSet, part ) {
4116                         var elem,
4117                                 isPartStr = typeof part === "string",
4118                                 i = 0,
4119                                 l = checkSet.length;
4121                         if ( isPartStr && !rNonWord.test( part ) ) {
4122                                 part = part.toLowerCase();
4124                                 for ( ; i < l; i++ ) {
4125                                         elem = checkSet[i];
4127                                         if ( elem ) {
4128                                                 var parent = elem.parentNode;
4129                                                 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4130                                         }
4131                                 }
4133                         } else {
4134                                 for ( ; i < l; i++ ) {
4135                                         elem = checkSet[i];
4137                                         if ( elem ) {
4138                                                 checkSet[i] = isPartStr ?
4139                                                         elem.parentNode :
4140                                                         elem.parentNode === part;
4141                                         }
4142                                 }
4144                                 if ( isPartStr ) {
4145                                         Sizzle.filter( part, checkSet, true );
4146                                 }
4147                         }
4148                 },
4150                 "": function(checkSet, part, isXML){
4151                         var nodeCheck,
4152                                 doneName = done++,
4153                                 checkFn = dirCheck;
4155                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4156                                 part = part.toLowerCase();
4157                                 nodeCheck = part;
4158                                 checkFn = dirNodeCheck;
4159                         }
4161                         checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4162                 },
4164                 "~": function( checkSet, part, isXML ) {
4165                         var nodeCheck,
4166                                 doneName = done++,
4167                                 checkFn = dirCheck;
4169                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4170                                 part = part.toLowerCase();
4171                                 nodeCheck = part;
4172                                 checkFn = dirNodeCheck;
4173                         }
4175                         checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4176                 }
4177         },
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                 },
4189                 NAME: function( match, context ) {
4190                         if ( typeof context.getElementsByName !== "undefined" ) {
4191                                 var ret = [],
4192                                         results = context.getElementsByName( match[1] );
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                                 }
4200                                 return ret.length === 0 ? null : ret;
4201                         }
4202                 },
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, "" ) + " ";
4214                         if ( isXML ) {
4215                                 return match;
4216                         }
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                                                 }
4225                                         } else if ( inplace ) {
4226                                                 curLoop[i] = false;
4227                                         }
4228                                 }
4229                         }
4231                         return false;
4232                 },
4234                 ID: function( match ) {
4235                         return match[1].replace( rBackslash, "" );
4236                 },
4238                 TAG: function( match, curLoop ) {
4239                         return match[1].replace( rBackslash, "" ).toLowerCase();
4240                 },
4242                 CHILD: function( match ) {
4243                         if ( match[1] === "nth" ) {
4244                                 if ( !match[2] ) {
4245                                         Sizzle.error( match[0] );
4246                                 }
4248                                 match[2] = match[2].replace(/^\+|\s*/g, '');
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]);
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                         }
4263                         // TODO: Move to normal caching system
4264                         match[0] = done++;
4266                         return match;
4267                 },
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                         }
4276                         // Handle if an un-quoted value was used
4277                         match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4279                         if ( match[2] === "~=" ) {
4280                                 match[4] = " " + match[4] + " ";
4281                         }
4283                         return match;
4284                 },
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);
4292                                 } else {
4293                                         var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4295                                         if ( !inplace ) {
4296                                                 result.push.apply( result, ret );
4297                                         }
4299                                         return false;
4300                                 }
4302                         } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4303                                 return true;
4304                         }
4305                         
4306                         return match;
4307                 },
4309                 POS: function( match ) {
4310                         match.unshift( true );
4312                         return match;
4313                 }
4314         },
4315         
4316         filters: {
4317                 enabled: function( elem ) {
4318                         return elem.disabled === false && elem.type !== "hidden";
4319                 },
4321                 disabled: function( elem ) {
4322                         return elem.disabled === true;
4323                 },
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                 },
4339                 parent: function( elem ) {
4340                         return !!elem.firstChild;
4341                 },
4343                 empty: function( elem ) {
4344                         return !elem.firstChild;
4345                 },
4347                 has: function( elem, i, match ) {
4348                         return !!Sizzle( match[3], elem ).length;
4349                 },
4351                 header: function( elem ) {
4352                         return (/h\d/i).test( elem.nodeName );
4353                 },
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                 },
4362                 radio: function( elem ) {
4363                         return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4364                 },
4366                 checkbox: function( elem ) {
4367                         return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4368                 },
4370                 file: function( elem ) {
4371                         return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4372                 },
4374                 password: function( elem ) {
4375                         return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4376                 },
4378                 submit: function( elem ) {
4379                         var name = elem.nodeName.toLowerCase();
4380                         return (name === "input" || name === "button") && "submit" === elem.type;
4381                 },
4383                 image: function( elem ) {
4384                         return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4385                 },
4387                 reset: function( elem ) {
4388                         var name = elem.nodeName.toLowerCase();
4389                         return (name === "input" || name === "button") && "reset" === elem.type;
4390                 },
4392                 button: function( elem ) {
4393                         var name = elem.nodeName.toLowerCase();
4394                         return name === "input" && "button" === elem.type || name === "button";
4395                 },
4397                 input: function( elem ) {
4398                         return (/input|select|textarea|button/i).test( elem.nodeName );
4399                 },
4401                 focus: function( elem ) {
4402                         return elem === elem.ownerDocument.activeElement;
4403                 }
4404         },
4405         setFilters: {
4406                 first: function( elem, i ) {
4407                         return i === 0;
4408                 },
4410                 last: function( elem, i, match, array ) {
4411                         return i === array.length - 1;
4412                 },
4414                 even: function( elem, i ) {
4415                         return i % 2 === 0;
4416                 },
4418                 odd: function( elem, i ) {
4419                         return i % 2 === 1;
4420                 },
4422                 lt: function( elem, i, match ) {
4423                         return i < match[3] - 0;
4424                 },
4426                 gt: function( elem, i, match ) {
4427                         return i > match[3] - 0;
4428                 },
4430                 nth: function( elem, i, match ) {
4431                         return match[3] - 0 === i;
4432                 },
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 ];
4443                         if ( filter ) {
4444                                 return filter( elem, i, match, array );
4446                         } else if ( name === "contains" ) {
4447                                 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4449                         } else if ( name === "not" ) {
4450                                 var not = match[3];
4452                                 for ( var j = 0, l = not.length; j < l; j++ ) {
4453                                         if ( not[j] === elem ) {
4454                                                 return false;
4455                                         }
4456                                 }
4458                                 return true;
4460                         } else {
4461                                 Sizzle.error( name );
4462                         }
4463                 },
4465                 CHILD: function( elem, match ) {
4466                         var type = match[1],
4467                                 node = elem;
4469                         switch ( type ) {
4470                                 case "only":
4471                                 case "first":
4472                                         while ( (node = node.previousSibling) )  {
4473                                                 if ( node.nodeType === 1 ) { 
4474                                                         return false; 
4475                                                 }
4476                                         }
4478                                         if ( type === "first" ) { 
4479                                                 return true; 
4480                                         }
4482                                         node = elem;
4484                                 case "last":
4485                                         while ( (node = node.nextSibling) )      {
4486                                                 if ( node.nodeType === 1 ) { 
4487                                                         return false; 
4488                                                 }
4489                                         }
4491                                         return true;
4493                                 case "nth":
4494                                         var first = match[2],
4495                                                 last = match[3];
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                                                 } 
4513                                                 parent.sizcache = doneName;
4514                                         }
4515                                         
4516                                         var diff = elem.nodeIndex - last;
4518                                         if ( first === 0 ) {
4519                                                 return diff === 0;
4521                                         } else {
4522                                                 return ( diff % first === 0 && diff / first >= 0 );
4523                                         }
4524                         }
4525                 },
4527                 ID: function( elem, match ) {
4528                         return elem.nodeType === 1 && elem.getAttribute("id") === match;
4529                 },
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                 },
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];
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                 },
4572                 POS: function( elem, match, i, array ) {
4573                         var name = match[2],
4574                                 filter = Expr.setFilters[ name ];
4576                         if ( filter ) {
4577                                 return filter( elem, i, match, array );
4578                         }
4579                 }
4580         }
4581 };
4583 var origPOS = Expr.match.POS,
4584         fescape = function(all, num){
4585                 return "\\" + (num - 0 + 1);
4586         };
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) );
4593 var makeArray = function( array, results ) {
4594         array = Array.prototype.slice.call( array, 0 );
4596         if ( results ) {
4597                 results.push.apply( results, array );
4598                 return results;
4599         }
4600         
4601         return array;
4602 };
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;
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 || [];
4617                 if ( toString.call(array) === "[object Array]" ) {
4618                         Array.prototype.push.apply( ret, array );
4620                 } else {
4621                         if ( typeof array.length === "number" ) {
4622                                 for ( var l = array.length; i < l; i++ ) {
4623                                         ret.push( array[i] );
4624                                 }
4626                         } else {
4627                                 for ( ; array[i]; i++ ) {
4628                                         ret.push( array[i] );
4629                                 }
4630                         }
4631                 }
4633                 return ret;
4634         };
4637 var sortOrder, siblingCheck;
4639 if ( document.documentElement.compareDocumentPosition ) {
4640         sortOrder = function( a, b ) {
4641                 if ( a === b ) {
4642                         hasDuplicate = true;
4643                         return 0;
4644                 }
4646                 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4647                         return a.compareDocumentPosition ? -1 : 1;
4648                 }
4650                 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4651         };
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;
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                 }
4665                 var al, bl,
4666                         ap = [],
4667                         bp = [],
4668                         aup = a.parentNode,
4669                         bup = b.parentNode,
4670                         cur = aup;
4672                 // If the nodes are siblings (or identical) we can do a quick check
4673                 if ( aup === bup ) {
4674                         return siblingCheck( a, b );
4676                 // If no parents were found then the nodes are disconnected
4677                 } else if ( !aup ) {
4678                         return -1;
4680                 } else if ( !bup ) {
4681                         return 1;
4682                 }
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                 }
4691                 cur = bup;
4693                 while ( cur ) {
4694                         bp.unshift( cur );
4695                         cur = cur.parentNode;
4696                 }
4698                 al = ap.length;
4699                 bl = bp.length;
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                 }
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         };
4714         siblingCheck = function( a, b, ret ) {
4715                 if ( a === b ) {
4716                         return ret;
4717                 }
4719                 var cur = a.nextSibling;
4721                 while ( cur ) {
4722                         if ( cur === b ) {
4723                                 return -1;
4724                         }
4726                         cur = cur.nextSibling;
4727                 }
4729                 return 1;
4730         };
4733 // Utility function for retreiving the text value of an array of DOM nodes
4734 Sizzle.getText = function( elems ) {
4735         var ret = "", elem;
4737         for ( var i = 0; elems[i]; i++ ) {
4738                 elem = elems[i];
4740                 // Get the text from text nodes and CDATA nodes
4741                 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4742                         ret += elem.nodeValue;
4744                 // Traverse everything else, except comment nodes
4745                 } else if ( elem.nodeType !== 8 ) {
4746                         ret += Sizzle.getText( elem.childNodes );
4747                 }
4748         }
4750         return ret;
4751 };
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;
4761         form.innerHTML = "<a name='" + id + "'/>";
4763         // Inject it into the root element, check its status, and remove it quickly
4764         root.insertBefore( form, root.firstChild );
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]);
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                 };
4781                 Expr.filter.ID = function( elem, match ) {
4782                         var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4784                         return elem.nodeType === 1 && node && node.nodeValue === match;
4785                 };
4786         }
4788         root.removeChild( form );
4790         // release memory in IE
4791         root = form = null;
4792 })();
4794 (function(){
4795         // Check to see if the browser returns only elements
4796         // when doing getElementsByTagName("*")
4798         // Create a fake element
4799         var div = document.createElement("div");
4800         div.appendChild( document.createComment("") );
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] );
4807                         // Filter out possible comments
4808                         if ( match[1] === "*" ) {
4809                                 var tmp = [];
4811                                 for ( var i = 0; results[i]; i++ ) {
4812                                         if ( results[i].nodeType === 1 ) {
4813                                                 tmp.push( results[i] );
4814                                         }
4815                                 }
4817                                 results = tmp;
4818                         }
4820                         return results;
4821                 };
4822         }
4824         // Check to see if an attribute returns normalized href attributes
4825         div.innerHTML = "<a href='#'></a>";
4827         if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4828                         div.firstChild.getAttribute("href") !== "#" ) {
4830                 Expr.attrHandle.href = function( elem ) {
4831                         return elem.getAttribute( "href", 2 );
4832                 };
4833         }
4835         // release memory in IE
4836         div = null;
4837 })();
4839 if ( document.querySelectorAll ) {
4840         (function(){
4841                 var oldSizzle = Sizzle,
4842                         div = document.createElement("div"),
4843                         id = "__sizzle__";
4845                 div.innerHTML = "<p class='TEST'></p>";
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;
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] );
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) {}
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 );
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                                         }
4921                                         try {
4922                                                 if ( !relativeHierarchySelector || hasParent ) {
4923                                                         return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4924                                                 }
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                 };
4938                 for ( var prop in oldSizzle ) {
4939                         Sizzle[ prop ] = oldSizzle[ prop ];
4940                 }
4942                 // release memory in IE
4943                 div = null;
4944         })();
4947 (function(){
4948         var html = document.documentElement,
4949                 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
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;
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                 }
4966                 Sizzle.matchesSelector = function( node, expr ) {
4967                         // Make sure that attribute selectors are quoted
4968                         expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4970                         if ( !Sizzle.isXML( node ) ) {
4971                                 try { 
4972                                         if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4973                                                 var ret = matches.call( node, expr );
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                         }
4986                         return Sizzle(expr, null, null, [node]).length > 0;
4987                 };
4988         }
4989 })();
4991 (function(){
4992         var div = document.createElement("div");
4994         div.innerHTML = "<div class='test e'></div><div class='test'></div>";
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         }
5002         // Safari caches class attributes, doesn't catch changes (in 3.2)
5003         div.lastChild.className = "e";
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         };
5016         // release memory in IE
5017         div = null;
5018 })();
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];
5024                 if ( elem ) {
5025                         var match = false;
5027                         elem = elem[dir];
5029                         while ( elem ) {
5030                                 if ( elem.sizcache === doneName ) {
5031                                         match = checkSet[elem.sizset];
5032                                         break;
5033                                 }
5035                                 if ( elem.nodeType === 1 && !isXML ){
5036                                         elem.sizcache = doneName;
5037                                         elem.sizset = i;
5038                                 }
5040                                 if ( elem.nodeName.toLowerCase() === cur ) {
5041                                         match = elem;
5042                                         break;
5043                                 }
5045                                 elem = elem[dir];
5046                         }
5048                         checkSet[i] = match;
5049                 }
5050         }
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];
5057                 if ( elem ) {
5058                         var match = false;
5059                         
5060                         elem = elem[dir];
5062                         while ( elem ) {
5063                                 if ( elem.sizcache === doneName ) {
5064                                         match = checkSet[elem.sizset];
5065                                         break;
5066                                 }
5068                                 if ( elem.nodeType === 1 ) {
5069                                         if ( !isXML ) {
5070                                                 elem.sizcache = doneName;
5071                                                 elem.sizset = i;
5072                                         }
5074                                         if ( typeof cur !== "string" ) {
5075                                                 if ( elem === cur ) {
5076                                                         match = true;
5077                                                         break;
5078                                                 }
5080                                         } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5081                                                 match = elem;
5082                                                 break;
5083                                         }
5084                                 }
5086                                 elem = elem[dir];
5087                         }
5089                         checkSet[i] = match;
5090                 }
5091         }
5094 if ( document.documentElement.contains ) {
5095         Sizzle.contains = function( a, b ) {
5096                 return a !== b && (a.contains ? a.contains(b) : true);
5097         };
5099 } else if ( document.documentElement.compareDocumentPosition ) {
5100         Sizzle.contains = function( a, b ) {
5101                 return !!(a.compareDocumentPosition(b) & 16);
5102         };
5104 } else {
5105         Sizzle.contains = function() {
5106                 return false;
5107         };
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;
5115         return documentElement ? documentElement.nodeName !== "HTML" : false;
5116 };
5118 var posProcess = function( selector, context ) {
5119         var match,
5120                 tmpSet = [],
5121                 later = "",
5122                 root = context.nodeType ? [context] : context;
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         }
5131         selector = Expr.relative[selector] ? selector + "*" : selector;
5133         for ( var i = 0, l = root.length; i < l; i++ ) {
5134                 Sizzle( selector, root[i], tmpSet );
5135         }
5137         return Sizzle.filter( later, tmpSet );
5138 };
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;
5150 })();
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         };
5168 jQuery.fn.extend({
5169         find: function( selector ) {
5170                 var self = this,
5171                         i, l;
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                 }
5183                 var ret = this.pushStack( "", "find", selector ),
5184                         length, n, r;
5186                 for ( i = 0, l = this.length; i < l; i++ ) {
5187                         length = ret.length;
5188                         jQuery.find( selector, this[i], ret );
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                 }
5203                 return ret;
5204         },
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         },
5217         not: function( selector ) {
5218                 return this.pushStack( winnow(this, selector, false), "not", selector);
5219         },
5221         filter: function( selector ) {
5222                 return this.pushStack( winnow(this, selector, true), "filter", selector );
5223         },
5225         is: function( selector ) {
5226                 return !!selector && ( typeof selector === "string" ?
5227                         jQuery.filter( selector, this ).length > 0 :
5228                         this.filter( selector ).length > 0 );
5229         },
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;
5240                         if ( cur && selectors.length ) {
5241                                 for ( i = 0, l = selectors.length; i < l; i++ ) {
5242                                         selector = selectors[i];
5244                                         if ( !matches[ selector ] ) {
5245                                                 matches[ selector ] = POS.test( selector ) ?
5246                                                         jQuery( selector, context || this.context ) :
5247                                                         selector;
5248                                         }
5249                                 }
5251                                 while ( cur && cur.ownerDocument && cur !== context ) {
5252                                         for ( selector in matches ) {
5253                                                 match = matches[ selector ];
5255                                                 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5256                                                         ret.push({ selector: selector, elem: cur, level: level });
5257                                                 }
5258                                         }
5260                                         cur = cur.parentNode;
5261                                         level++;
5262                                 }
5263                         }
5265                         return ret;
5266                 }
5268                 // String
5269                 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5270                                 jQuery( selectors, context || this.context ) :
5271                                 0;
5273                 for ( i = 0, l = this.length; i < l; i++ ) {
5274                         cur = this[i];
5276                         while ( cur ) {
5277                                 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5278                                         ret.push( cur );
5279                                         break;
5281                                 } else {
5282                                         cur = cur.parentNode;
5283                                         if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5284                                                 break;
5285                                         }
5286                                 }
5287                         }
5288                 }
5290                 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5292                 return this.pushStack( ret, "closest", selectors );
5293         },
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         },
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 );
5316                 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5317                         all :
5318                         jQuery.unique( all ) );
5319         },
5321         andSelf: function() {
5322                 return this.add( this.prevObject );
5323         }
5324 });
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;
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);
5381                 if ( !runtil.test( name ) ) {
5382                         selector = until;
5383                 }
5385                 if ( selector && typeof selector === "string" ) {
5386                         ret = jQuery.filter( selector, ret );
5387                 }
5389                 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5391                 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5392                         ret = ret.reverse();
5393                 }
5395                 return this.pushStack( ret, name, args.join(",") );
5396         };
5397 });
5399 jQuery.extend({
5400         filter: function( expr, elems, not ) {
5401                 if ( not ) {
5402                         expr = ":not(" + expr + ")";
5403                 }
5405                 return elems.length === 1 ?
5406                         jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5407                         jQuery.find.matches(expr, elems);
5408         },
5410         dir: function( elem, dir, until ) {
5411                 var matched = [],
5412                         cur = elem[ dir ];
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         },
5423         nth: function( cur, result, dir, elem ) {
5424                 result = result || 1;
5425                 var num = 0;
5427                 for ( ; cur; cur = cur[dir] ) {
5428                         if ( cur.nodeType === 1 && ++num === result ) {
5429                                 break;
5430                         }
5431                 }
5433                 return cur;
5434         },
5436         sibling: function( n, elem ) {
5437                 var r = [];
5439                 for ( ; n; n = n.nextSibling ) {
5440                         if ( n.nodeType === 1 && n !== elem ) {
5441                                 r.push( n );
5442                         }
5443                 }
5445                 return r;
5446         }
5447 });
5449 // Implement the identical functionality for filter and not
5450 function winnow( elements, qualifier, keep ) {
5452         // Can't pass null or undefined to indexOf in Firefox 4
5453         // Set to 0 to skip string check
5454         qualifier = qualifier || 0;
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                 });
5462         } else if ( qualifier.nodeType ) {
5463                 return jQuery.grep(elements, function( elem, i ) {
5464                         return (elem === qualifier) === keep;
5465                 });
5467         } else if ( typeof qualifier === "string" ) {
5468                 var filtered = jQuery.grep(elements, function( elem ) {
5469                         return elem.nodeType === 1;
5470                 });
5472                 if ( isSimple.test( qualifier ) ) {
5473                         return jQuery.filter(qualifier, filtered, !keep);
5474                 } else {
5475                         qualifier = jQuery.filter( qualifier, filtered );
5476                 }
5477         }
5479         return jQuery.grep(elements, function( elem, i ) {
5480                 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5481         });
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         };
5509 wrapMap.optgroup = wrapMap.option;
5510 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5511 wrapMap.th = wrapMap.td;
5513 // IE can't serialize <link> and <script> tags normally
5514 if ( !jQuery.support.htmlSerialize ) {
5515         wrapMap._default = [ 1, "div<div>", "</div>" ];
5518 jQuery.fn.extend({
5519         text: function( text ) {
5520                 if ( jQuery.isFunction(text) ) {
5521                         return this.each(function(i) {
5522                                 var self = jQuery( this );
5524                                 self.text( text.call(this, i, self.text()) );
5525                         });
5526                 }
5528                 if ( typeof text !== "object" && text !== undefined ) {
5529                         return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5530                 }
5532                 return jQuery.text( this );
5533         },
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                 }
5542                 if ( this[0] ) {
5543                         // The elements to wrap the target around
5544                         var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5546                         if ( this[0].parentNode ) {
5547                                 wrap.insertBefore( this[0] );
5548                         }
5550                         wrap.map(function() {
5551                                 var elem = this;
5553                                 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5554                                         elem = elem.firstChild;
5555                                 }
5557                                 return elem;
5558                         }).append( this );
5559                 }
5561                 return this;
5562         },
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                 }
5571                 return this.each(function() {
5572                         var self = jQuery( this ),
5573                                 contents = self.contents();
5575                         if ( contents.length ) {
5576                                 contents.wrapAll( html );
5578                         } else {
5579                                 self.append( html );
5580                         }
5581                 });
5582         },
5584         wrap: function( html ) {
5585                 return this.each(function() {
5586                         jQuery( this ).wrapAll( html );
5587                 });
5588         },
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         },
5598         append: function() {
5599                 return this.domManip(arguments, true, function( elem ) {
5600                         if ( this.nodeType === 1 ) {
5601                                 this.appendChild( elem );
5602                         }
5603                 });
5604         },
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         },
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         },
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         },
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                                 }
5647                                 if ( elem.parentNode ) {
5648                                         elem.parentNode.removeChild( elem );
5649                                 }
5650                         }
5651                 }
5653                 return this;
5654         },
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                         }
5663                         // Remove any remaining nodes
5664                         while ( elem.firstChild ) {
5665                                 elem.removeChild( elem.firstChild );
5666                         }
5667                 }
5669                 return this;
5670         },
5672         clone: function( dataAndEvents, deepDataAndEvents ) {
5673                 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5674                 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5676                 return this.map( function () {
5677                         return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5678                 });
5679         },
5681         html: function( value ) {
5682                 if ( value === undefined ) {
5683                         return this[0] && this[0].nodeType === 1 ?
5684                                 this[0].innerHTML.replace(rinlinejQuery, "") :
5685                                 null;
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() ] ) {
5692                         value = value.replace(rxhtmlTag, "<$1></$2>");
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                                 }
5703                         // If using innerHTML throws an exception, use the fallback method
5704                         } catch(e) {
5705                                 this.empty().append( value );
5706                         }
5708                 } else if ( jQuery.isFunction( value ) ) {
5709                         this.each(function(i){
5710                                 var self = jQuery( this );
5712                                 self.html( value.call(this, i, self.html()) );
5713                         });
5715                 } else {
5716                         this.empty().append( value );
5717                 }
5719                 return this;
5720         },
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                         }
5733                         if ( typeof value !== "string" ) {
5734                                 value = jQuery( value ).detach();
5735                         }
5737                         return this.each(function() {
5738                                 var next = this.nextSibling,
5739                                         parent = this.parentNode;
5741                                 jQuery( this ).remove();
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         },
5756         detach: function( selector ) {
5757                 return this.remove( selector, true );
5758         },
5760         domManip: function( args, table, callback ) {
5761                 var results, first, fragment, parent,
5762                         value = args[0],
5763                         scripts = [];
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                 }
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                 }
5780                 if ( this[0] ) {
5781                         parent = value && value.parentNode;
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 };
5787                         } else {
5788                                 results = jQuery.buildFragment( args, this, scripts );
5789                         }
5791                         fragment = results.fragment;
5793                         if ( fragment.childNodes.length === 1 ) {
5794                                 first = fragment = fragment.firstChild;
5795                         } else {
5796                                 first = fragment.firstChild;
5797                         }
5799                         if ( first ) {
5800                                 table = table && jQuery.nodeName( first, "tr" );
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                         }
5821                         if ( scripts.length ) {
5822                                 jQuery.each( scripts, evalScript );
5823                         }
5824                 }
5826                 return this;
5827         }
5828 });
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;
5837 function cloneCopyEvent( src, dest ) {
5839         if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5840                 return;
5841         }
5843         var internalKey = jQuery.expando,
5844                 oldData = jQuery.data( src ),
5845                 curData = jQuery.data( dest, oldData );
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);
5853                 if ( events ) {
5854                         delete curData.handle;
5855                         curData.events = {};
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         }
5866 function cloneFixAttributes( src, dest ) {
5867         var nodeName;
5869         // We do not need to do anything for non-Elements
5870         if ( dest.nodeType !== 1 ) {
5871                 return;
5872         }
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         }
5880         // mergeAttributes, in contrast, only merges back on the
5881         // original attributes, not the events
5882         if ( dest.mergeAttributes ) {
5883                 dest.mergeAttributes( src );
5884         }
5886         nodeName = dest.nodeName.toLowerCase();
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;
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                 }
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                 }
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;
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         }
5919         // Event data gets referenced instead of copied if the expando
5920         // gets copied too
5921         dest.removeAttribute( jQuery.expando );
5924 jQuery.buildFragment = function( args, nodes, scripts ) {
5925         var fragment, cacheable, cacheresults, doc;
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   }
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         }
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] )) ) {
5948                 cacheable = true;
5950                 cacheresults = jQuery.fragments[ args[0] ];
5951                 if ( cacheresults && cacheresults !== 1 ) {
5952                         fragment = cacheresults;
5953                 }
5954         }
5956         if ( !fragment ) {
5957                 fragment = doc.createDocumentFragment();
5958                 jQuery.clean( args, doc, fragment, scripts );
5959         }
5961         if ( cacheable ) {
5962                 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5963         }
5965         return { fragment: fragment, cacheable: cacheable };
5966 };
5968 jQuery.fragments = {};
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;
5982                 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5983                         insert[ original ]( this[0] );
5984                         return this;
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                         }
5993                         return this.pushStack( ret, name, insert.selector );
5994                 }
5995         };
5996 });
5998 function getAll( elem ) {
5999         if ( "getElementsByTagName" in elem ) {
6000                 return elem.getElementsByTagName( "*" );
6002         } else if ( "querySelectorAll" in elem ) {
6003                 return elem.querySelectorAll( "*" );
6005         } else {
6006                 return [];
6007         }
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         }
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         }
6025 jQuery.extend({
6026         clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6027                 var clone = elem.cloneNode(true),
6028                                 srcElements,
6029                                 destElements,
6030                                 i;
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.
6040                         cloneFixAttributes( elem, clone );
6042                         // Using Sizzle here is crazy slow, so we use getElementsByTagName
6043                         // instead
6044                         srcElements = getAll( elem );
6045                         destElements = getAll( clone );
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                 }
6055                 // Copy the events from the original to the clone
6056                 if ( dataAndEvents ) {
6057                         cloneCopyEvent( elem, clone );
6059                         if ( deepDataAndEvents ) {
6060                                 srcElements = getAll( elem );
6061                                 destElements = getAll( clone );
6063                                 for ( i = 0; srcElements[i]; ++i ) {
6064                                         cloneCopyEvent( srcElements[i], destElements[i] );
6065                                 }
6066                         }
6067                 }
6069                 srcElements = destElements = null;
6071                 // Return the cloned set
6072                 return clone;
6073         },
6075         clean: function( elems, context, fragment, scripts ) {
6076                 var checkScriptType;
6078                 context = context || document;
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                 }
6085                 var ret = [], j;
6087                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6088                         if ( typeof elem === "number" ) {
6089                                 elem += "";
6090                         }
6092                         if ( !elem ) {
6093                                 continue;
6094                         }
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>");
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");
6110                                         // Go to html and back, then peel off extra wrappers
6111                                         div.innerHTML = wrap[1] + elem + wrap[2];
6113                                         // Move to the right depth
6114                                         while ( depth-- ) {
6115                                                 div = div.lastChild;
6116                                         }
6118                                         // Remove IE's autoinserted <tbody> from table fragments
6119                                         if ( !jQuery.support.tbody ) {
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 :
6126                                                                 // String was a bare <thead> or <tfoot>
6127                                                                 wrap[1] === "<table>" && !hasBody ?
6128                                                                         div.childNodes :
6129                                                                         [];
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                                         }
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                                         }
6143                                         elem = div.childNodes;
6144                                 }
6145                         }
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                         }
6160                         if ( elem.nodeType ) {
6161                                 ret.push( elem );
6162                         } else {
6163                                 ret = jQuery.merge( ret, elem );
6164                         }
6165                 }
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] );
6175                                 } else {
6176                                         if ( ret[i].nodeType === 1 ) {
6177                                                 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6179                                                 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6180                                         }
6181                                         fragment.appendChild( ret[i] );
6182                                 }
6183                         }
6184                 }
6186                 return ret;
6187         },
6189         cleanData: function( elems ) {
6190                 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6191                         deleteExpando = jQuery.support.deleteExpando;
6193                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6194                         if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6195                                 continue;
6196                         }
6198                         id = elem[ jQuery.expando ];
6200                         if ( id ) {
6201                                 data = cache[ id ] && cache[ id ][ internalKey ];
6203                                 if ( data && data.events ) {
6204                                         for ( var type in data.events ) {
6205                                                 if ( special[ type ] ) {
6206                                                         jQuery.event.remove( elem, type );
6208                                                 // This is a shortcut to avoid jQuery.event.remove's overhead
6209                                                 } else {
6210                                                         jQuery.removeEvent( elem, type, data.handle );
6211                                                 }
6212                                         }
6214                                         // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6215                                         if ( data.handle ) {
6216                                                 data.handle.elem = null;
6217                                         }
6218                                 }
6220                                 if ( deleteExpando ) {
6221                                         delete elem[ jQuery.expando ];
6223                                 } else if ( elem.removeAttribute ) {
6224                                         elem.removeAttribute( jQuery.expando );
6225                                 }
6227                                 delete cache[ id ];
6228                         }
6229                 }
6230         }
6231 });
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         }
6244         if ( elem.parentNode ) {
6245                 elem.parentNode.removeChild( elem );
6246         }
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,
6260         cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6261         cssWidth = [ "Left", "Right" ],
6262         cssHeight = [ "Top", "Bottom" ],
6263         curCSS,
6265         getComputedStyle,
6266         currentStyle;
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         }
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 };
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;
6292                                 } else {
6293                                         return elem.style.opacity;
6294                                 }
6295                         }
6296                 }
6297         },
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         },
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         },
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                 }
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 ];
6329                 name = jQuery.cssProps[ origName ] || origName;
6331                 // Check if we're setting a value
6332                 if ( value !== undefined ) {
6333                         type = typeof value;
6335                         // Make sure that NaN and null values aren't set. See: #7116
6336                         if ( type === "number" && isNaN( value ) || value == null ) {
6337                                 return;
6338                         }
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                         }
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                         }
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                         }
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                         }
6367                         // Otherwise just get the value from the style object
6368                         return style[ name ];
6369                 }
6370         },
6372         css: function( elem, name, extra ) {
6373                 var ret, hooks;
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;
6380                 // cssFloat needs a special treatment
6381                 if ( name === "cssFloat" ) {
6382                         name = "float";
6383                 }
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;
6389                 // Otherwise, if a way to get the computed value exists, use that
6390                 } else if ( curCSS ) {
6391                         return curCSS( elem, name );
6392                 }
6393         },
6395         // A method for quickly swapping in/out CSS properties to get correct calculations
6396         swap: function( elem, options, callback ) {
6397                 var old = {};
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                 }
6405                 callback.call( elem );
6407                 // Revert the old values
6408                 for ( name in options ) {
6409                         elem.style[ name ] = old[ name ];
6410                 }
6411         }
6412 });
6414 // DEPRECATED, Use jQuery.css() instead
6415 jQuery.curCSS = jQuery.css;
6417 jQuery.each(["height", "width"], function( i, name ) {
6418         jQuery.cssHooks[ name ] = {
6419                 get: function( elem, computed, extra ) {
6420                         var val;
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                                 }
6431                                 return val;
6432                         }
6433                 },
6435                 set: function( elem, value ) {
6436                         if ( rnumpx.test( value ) ) {
6437                                 // ignore negative width and height values #1599
6438                                 value = parseFloat( value );
6440                                 if ( value >= 0 ) {
6441                                         return value + "px";
6442                                 }
6444                         } else {
6445                                 return value;
6446                         }
6447                 }
6448         };
6449 });
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                 },
6460                 set: function( elem, value ) {
6461                         var style = elem.style,
6462                                 currentStyle = elem.currentStyle;
6464                         // IE has trouble with opacity if it does not have layout
6465                         // Force it by setting the zoom level
6466                         style.zoom = 1;
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 || "";
6474                         style.filter = ralpha.test( filter ) ?
6475                                 filter.replace( ralpha, opacity ) :
6476                                 filter + " " + opacity;
6477                 }
6478         };
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 });
6503 if ( document.defaultView && document.defaultView.getComputedStyle ) {
6504         getComputedStyle = function( elem, name ) {
6505                 var ret, defaultView, computedStyle;
6507                 name = name.replace( rupper, "-$1" ).toLowerCase();
6509                 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6510                         return undefined;
6511                 }
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                 }
6520                 return ret;
6521         };
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;
6531                 // From the awesome hack by Dean Edwards
6532                 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
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;
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";
6547                         // Revert the changed values
6548                         style.left = left;
6549                         if ( rsLeft ) {
6550                                 elem.runtimeStyle.left = rsLeft;
6551                         }
6552                 }
6554                 return ret === "" ? "auto" : ret;
6555         };
6558 curCSS = getComputedStyle || currentStyle;
6560 function getWH( elem, name, extra ) {
6562         // Start with offset property
6563         var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6564                 which = name === "width" ? cssWidth : cssHeight;
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                 }
6580                 return val + "px";
6581         }
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;
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         }
6604         return val + "px";
6607 if ( jQuery.expr && jQuery.expr.filters ) {
6608         jQuery.expr.filters.hidden = function( elem ) {
6609                 var width = elem.offsetWidth,
6610                         height = elem.offsetHeight;
6612                 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
6613         };
6615         jQuery.expr.filters.visible = function( elem ) {
6616                 return !jQuery.expr.filters.hidden( elem );
6617         };
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+))?)?/,
6640         // Keep a copy of the old load method
6641         _load = jQuery.fn.load,
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 = {},
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 = {},
6661         // Document location
6662         ajaxLocation,
6664         // Document location segments
6665         ajaxLocParts;
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;
6679 // Segment location into parts
6680 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6682 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6683 function addToPrefiltersOrTransports( structure ) {
6685         // dataTypeExpression is optional and defaults to "*"
6686         return function( dataTypeExpression, func ) {
6688                 if ( typeof dataTypeExpression !== "string" ) {
6689                         func = dataTypeExpression;
6690                         dataTypeExpression = "*";
6691                 }
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;
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         };
6718 // Base inspection function for prefilters and transports
6719 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6720                 dataType /* internal */, inspected /* internal */ ) {
6722         dataType = dataType || options.dataTypes[ 0 ];
6723         inspected = inspected || {};
6725         inspected[ dataType ] = true;
6727         var list = structure[ dataType ],
6728                 i = 0,
6729                 length = list ? list.length : 0,
6730                 executeOnly = ( structure === prefilters ),
6731                 selection;
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;
6758 jQuery.fn.extend({
6759         load: function( url, params, callback ) {
6760                 if ( typeof url !== "string" && _load ) {
6761                         return _load.apply( this, arguments );
6763                 // Don't do a request if no elements are being requested
6764                 } else if ( !this.length ) {
6765                         return this;
6766                 }
6768                 var off = url.indexOf( " " );
6769                 if ( off >= 0 ) {
6770                         var selector = url.slice( off, url.length );
6771                         url = url.slice( 0, off );
6772                 }
6774                 // Default to a GET request
6775                 var type = "GET";
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;
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                 }
6792                 var self = this;
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, ""))
6819                                                         // Locate the specified elements
6820                                                         .find(selector) :
6822                                                 // If not, just inject the full result
6823                                                 responseText );
6824                                 }
6826                                 if ( callback ) {
6827                                         self.each( callback, [ responseText, status, jqXHR ] );
6828                                 }
6829                         }
6830                 });
6832                 return this;
6833         },
6835         serialize: function() {
6836                 return jQuery.param( this.serializeArray() );
6837         },
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();
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 });
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 });
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                 }
6878                 return jQuery.ajax({
6879                         type: method,
6880                         url: url,
6881                         data: data,
6882                         success: callback,
6883                         dataType: type
6884                 });
6885         };
6886 });
6888 jQuery.extend({
6890         getScript: function( url, callback ) {
6891                 return jQuery.get( url, undefined, callback, "script" );
6892         },
6894         getJSON: function( url, data, callback ) {
6895                 return jQuery.get( url, data, callback, "json" );
6896         },
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         },
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                 */
6940                 accepts: {
6941                         xml: "application/xml, text/xml",
6942                         html: "text/html",
6943                         text: "text/plain",
6944                         json: "application/json, text/javascript",
6945                         "*": "*/*"
6946                 },
6948                 contents: {
6949                         xml: /xml/,
6950                         html: /html/,
6951                         json: /json/
6952                 },
6954                 responseFields: {
6955                         xml: "responseXML",
6956                         text: "responseText"
6957                 },
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: {
6964                         // Convert anything to text
6965                         "* text": window.String,
6967                         // Text to html (true = no transformation)
6968                         "text html": true,
6970                         // Evaluate text as a json expression
6971                         "text json": jQuery.parseJSON,
6973                         // Parse text as xml
6974                         "text xml": jQuery.parseXML
6975                 }
6976         },
6978         ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
6979         ajaxTransport: addToPrefiltersOrTransports( transports ),
6981         // Main method
6982         ajax: function( url, options ) {
6984                 // If url is an object, simulate pre-1.5 signature
6985                 if ( typeof url === "object" ) {
6986                         options = url;
6987                         url = undefined;
6988                 }
6990                 // Force options to be an object
6991                 options = options || {};
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 = {
7031                                 readyState: 0,
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                                 },
7043                                 // Raw string
7044                                 getAllResponseHeaders: function() {
7045                                         return state === 2 ? responseHeadersString : null;
7046                                 },
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                                 },
7063                                 // Overrides response content-type header
7064                                 overrideMimeType: function( type ) {
7065                                         if ( !state ) {
7066                                                 s.mimeType = type;
7067                                         }
7068                                         return this;
7069                                 },
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                         };
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 ) {
7087                         // Called once
7088                         if ( state === 2 ) {
7089                                 return;
7090                         }
7092                         // State is "done" now
7093                         state = 2;
7095                         // Clear timeout if it exists
7096                         if ( timeoutTimer ) {
7097                                 clearTimeout( timeoutTimer );
7098                         }
7100                         // Dereference transport for early garbage collection
7101                         // (no matter how long the jqXHR object will be used)
7102                         transport = undefined;
7104                         // Cache response headers
7105                         responseHeadersString = headers || "";
7107                         // Set readyState
7108                         jqXHR.readyState = status ? 4 : 0;
7110                         var isSuccess,
7111                                 success,
7112                                 error,
7113                                 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7114                                 lastModified,
7115                                 etag;
7117                         // If successful, handle type chaining
7118                         if ( status >= 200 && status < 300 || status === 304 ) {
7120                                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7121                                 if ( s.ifModified ) {
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                                 }
7131                                 // If not modified
7132                                 if ( status === 304 ) {
7134                                         statusText = "notmodified";
7135                                         isSuccess = true;
7137                                 // If we have data
7138                                 } else {
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                         }
7162                         // Set data for the fake xhr object
7163                         jqXHR.status = status;
7164                         jqXHR.statusText = statusText;
7166                         // Success/Error
7167                         if ( isSuccess ) {
7168                                 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7169                         } else {
7170                                 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7171                         }
7173                         // Status-dependent callbacks
7174                         jqXHR.statusCode( statusCode );
7175                         statusCode = undefined;
7177                         if ( fireGlobals ) {
7178                                 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7179                                                 [ jqXHR, s, isSuccess ? success : error ] );
7180                         }
7182                         // Complete
7183                         completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
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                 }
7194                 // Attach deferreds
7195                 deferred.promise( jqXHR );
7196                 jqXHR.success = jqXHR.done;
7197                 jqXHR.error = jqXHR.fail;
7198                 jqXHR.complete = completeDeferred.done;
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                 };
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 ] + "//" );
7221                 // Extract dataTypes list
7222                 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
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                 }
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                 }
7239                 // Apply prefilters
7240                 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7242                 // If request was aborted inside a prefiler, stop there
7243                 if ( state === 2 ) {
7244                         return false;
7245                 }
7247                 // We can fire global events as of now if asked to
7248                 fireGlobals = s.global;
7250                 // Uppercase the type
7251                 s.type = s.type.toUpperCase();
7253                 // Determine if request has content
7254                 s.hasContent = !rnoContent.test( s.type );
7256                 // Watch for a new set of requests
7257                 if ( fireGlobals && jQuery.active++ === 0 ) {
7258                         jQuery.event.trigger( "ajaxStart" );
7259                 }
7261                 // More options handling for requests with no content
7262                 if ( !s.hasContent ) {
7264                         // If data is available, append data to url
7265                         if ( s.data ) {
7266                                 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7267                         }
7269                         // Get ifModifiedKey before adding the anti-cache parameter
7270                         ifModifiedKey = s.url;
7272                         // Add anti-cache in url if needed
7273                         if ( s.cache === false ) {
7275                                 var ts = jQuery.now(),
7276                                         // try replacing _= if it is there
7277                                         ret = s.url.replace( rts, "$1_=" + ts );
7279                                 // if nothing was replaced, add timestamp to the end
7280                                 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7281                         }
7282                 }
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                 }
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                 }
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                 );
7308                 // Check for headers option
7309                 for ( i in s.headers ) {
7310                         jqXHR.setRequestHeader( i, s.headers[ i ] );
7311                 }
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;
7319                 }
7321                 // Install callbacks on deferreds
7322                 for ( i in { success: 1, error: 1, complete: 1 } ) {
7323                         jqXHR[ i ]( s[ i ] );
7324                 }
7326                 // Get transport
7327                 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
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                         }
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                 }
7359                 return jqXHR;
7360         },
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                         };
7372                 // Set traditional to true for jQuery <= 1.3.2 behavior.
7373                 if ( traditional === undefined ) {
7374                         traditional = jQuery.ajaxSettings.traditional;
7375                 }
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                         });
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                 }
7392                 // Return the resulting serialization
7393                 return s.join( "&" ).replace( r20, "+" );
7394         }
7395 });
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 );
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                 });
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                 }
7423         } else {
7424                 // Serialize scalar item.
7425                 add( prefix, obj );
7426         }
7429 // This is still on the jQuery object... for now
7430 // Want to move this to jQuery.ajax some day
7431 jQuery.extend({
7433         // Counter for holding the number of active queries
7434         active: 0,
7436         // Last-Modified header cache for next request
7437         lastModified: {},
7438         etag: {}
7440 });
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 ) {
7449         var contents = s.contents,
7450                 dataTypes = s.dataTypes,
7451                 responseFields = s.responseFields,
7452                 ct,
7453                 type,
7454                 finalDataType,
7455                 firstDataType;
7457         // Fill responseXXX fields
7458         for( type in responseFields ) {
7459                 if ( type in responses ) {
7460                         jqXHR[ responseFields[type] ] = responses[ type ];
7461                 }
7462         }
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         }
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         }
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         }
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         }
7511 // Chain conversions given the request and the original response
7512 function ajaxConvert( s, response ) {
7514         // Apply the dataFilter if provided
7515         if ( s.dataFilter ) {
7516                 response = s.dataFilter( response, s.dataType );
7517         }
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;
7536         // For each dataType in the chain
7537         for( i = 1; i < length; i++ ) {
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                 }
7549                 // Get the dataTypes
7550                 prev = current;
7551                 current = dataTypes[ i ];
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 ) {
7559                         // Get the converter
7560                         conversion = prev + " " + current;
7561                         conv = converters[ conversion ] || converters[ "* " + current ];
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;
7599 var jsc = jQuery.now(),
7600         jsre = /(\=)\?(&|$)|\?\?/i;
7602 // Default jsonp settings
7603 jQuery.ajaxSetup({
7604         jsonp: "callback",
7605         jsonpCallback: function() {
7606                 return jQuery.expando + "_" + ( jsc++ );
7607         }
7608 });
7610 // Detect, normalize options and install callbacks for jsonp requests
7611 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7613         var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7614                 ( typeof s.data === "string" );
7616         if ( s.dataTypes[ 0 ] === "jsonp" ||
7617                 s.jsonp !== false && ( jsre.test( s.url ) ||
7618                                 inspectData && jsre.test( s.data ) ) ) {
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";
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                 }
7641                 s.url = url;
7642                 s.data = data;
7644                 // Install callback
7645                 window[ jsonpCallback ] = function( response ) {
7646                         responseContainer = [ response ];
7647                 };
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                 });
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                 };
7667                 // force json dataType
7668                 s.dataTypes[ 0 ] = "json";
7670                 // Delegate to script
7671                 return "script";
7672         }
7673 });
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 });
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 });
7705 // Bind script tag hack transport
7706 jQuery.ajaxTransport( "script", function(s) {
7708         // This transport only deals with cross domain requests
7709         if ( s.crossDomain ) {
7711                 var script,
7712                         head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7714                 return {
7716                         send: function( _, callback ) {
7718                                 script = document.createElement( "script" );
7720                                 script.async = "async";
7722                                 if ( s.scriptCharset ) {
7723                                         script.charset = s.scriptCharset;
7724                                 }
7726                                 script.src = s.url;
7728                                 // Attach handlers for all browsers
7729                                 script.onload = script.onreadystatechange = function( _, isAbort ) {
7731                                         if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7733                                                 // Handle memory leak in IE
7734                                                 script.onload = script.onreadystatechange = null;
7736                                                 // Remove the script
7737                                                 if ( head && script.parentNode ) {
7738                                                         head.removeChild( script );
7739                                                 }
7741                                                 // Dereference the script
7742                                                 script = undefined;
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                         },
7755                         abort: function() {
7756                                 if ( script ) {
7757                                         script.onload( 0, 1 );
7758                                 }
7759                         }
7760                 };
7761         }
7762 });
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;
7777 // Functions to create xhrs
7778 function createStandardXHR() {
7779         try {
7780                 return new window.XMLHttpRequest();
7781         } catch( e ) {}
7784 function createActiveXHR() {
7785         try {
7786                 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7787         } catch( e ) {}
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;
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() );
7813 // Create transport if the browser can provide an xhr
7814 if ( jQuery.support.ajax ) {
7816         jQuery.ajaxTransport(function( s ) {
7817                 // Cross domain only allowed if supported through XMLHttpRequest
7818                 if ( !s.crossDomain || jQuery.support.cors ) {
7820                         var callback;
7822                         return {
7823                                 send: function( headers, complete ) {
7825                                         // Get a new xhr
7826                                         var xhr = s.xhr(),
7827                                                 handle,
7828                                                 i;
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                                         }
7838                                         // Apply custom fields if provided
7839                                         if ( s.xhrFields ) {
7840                                                 for ( i in s.xhrFields ) {
7841                                                         xhr[ i ] = s.xhrFields[ i ];
7842                                                 }
7843                                         }
7845                                         // Override mime type if needed
7846                                         if ( s.mimeType && xhr.overrideMimeType ) {
7847                                                 xhr.overrideMimeType( s.mimeType );
7848                                         }
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                                         }
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( _ ) {}
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 );
7871                                         // Listener
7872                                         callback = function( _, isAbort ) {
7874                                                 var status,
7875                                                         statusText,
7876                                                         responseHeaders,
7877                                                         responses,
7878                                                         xml;
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 {
7885                                                         // Was never called and is aborted or complete
7886                                                         if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7888                                                                 // Only called once
7889                                                                 callback = undefined;
7891                                                                 // Do not keep as active anymore
7892                                                                 if ( handle ) {
7893                                                                         xhr.onreadystatechange = jQuery.noop;
7894                                                                         if ( xhrOnUnloadAbort ) {
7895                                                                                 delete xhrCallbacks[ handle ];
7896                                                                         }
7897                                                                 }
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;
7911                                                                         // Construct response list
7912                                                                         if ( xml && xml.documentElement /* #4958 */ ) {
7913                                                                                 responses.xml = xml;
7914                                                                         }
7915                                                                         responses.text = xhr.responseText;
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                                                                         }
7926                                                                         // Filter status for non standard behaviors
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                                                 }
7945                                                 // Call complete if needed
7946                                                 if ( responses ) {
7947                                                         complete( status, statusText, responses, responseHeaders );
7948                                                 }
7949                                         };
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                                 },
7972                                 abort: function() {
7973                                         if ( callback ) {
7974                                                 callback(0,1);
7975                                         }
7976                                 }
7977                         };
7978                 }
7979         });
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;
8003 jQuery.fn.extend({
8004         show: function( speed, easing, callback ) {
8005                 var elem, display;
8007                 if ( speed || speed === 0 ) {
8008                         return this.animate( genFx("show", 3), speed, easing, callback);
8010                 } else {
8011                         for ( var i = 0, j = this.length; i < j; i++ ) {
8012                                 elem = this[i];
8014                                 if ( elem.style ) {
8015                                         display = elem.style.display;
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                                         }
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                         }
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];
8037                                 if ( elem.style ) {
8038                                         display = elem.style.display;
8040                                         if ( display === "" || display === "none" ) {
8041                                                 elem.style.display = jQuery._data(elem, "olddisplay") || "";
8042                                         }
8043                                 }
8044                         }
8046                         return this;
8047                 }
8048         },
8050         hide: function( speed, easing, callback ) {
8051                 if ( speed || speed === 0 ) {
8052                         return this.animate( genFx("hide", 3), speed, easing, callback);
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" );
8059                                         if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8060                                                 jQuery._data( this[i], "olddisplay", display );
8061                                         }
8062                                 }
8063                         }
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                         }
8073                         return this;
8074                 }
8075         },
8077         // Save the old toggle function
8078         _toggle: jQuery.fn.toggle,
8080         toggle: function( fn, fn2, callback ) {
8081                 var bool = typeof fn === "boolean";
8083                 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8084                         this._toggle.apply( this, arguments );
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                         });
8092                 } else {
8093                         this.animate(genFx("toggle", 3), fn, fn2, callback);
8094                 }
8096                 return this;
8097         },
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         },
8104         animate: function( prop, speed, easing, callback ) {
8105                 var optall = jQuery.speed(speed, easing, callback);
8107                 if ( jQuery.isEmptyObject( prop ) ) {
8108                         return this.each( optall.complete, [ false ] );
8109                 }
8111                 // Do not change referenced properties as per-property easing will be lost
8112                 prop = jQuery.extend( {}, prop );
8114                 return this[ optall.queue === false ? "each" : "queue" ](function() {
8115                         // XXX 'this' does not always have a nodeName when running the
8116                         // test suite
8118                         if ( optall.queue === false ) {
8119                                 jQuery._mark( this );
8120                         }
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;
8129                         // will store per property easing and be used to determine when an animation is complete
8130                         opt.animatedProperties = {};
8132                         for ( p in prop ) {
8134                                 // property name normalization
8135                                 name = jQuery.camelCase( p );
8136                                 if ( p !== name ) {
8137                                         prop[ name ] = prop[ p ];
8138                                         delete prop[ p ];
8139                                 }
8141                                 val = prop[ name ];
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                                 }
8151                                 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8152                                         return opt.complete.call( this );
8153                                 }
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 ];
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";
8170                                                 } else {
8171                                                         display = defaultDisplay( this.nodeName );
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";
8178                                                         } else {
8179                                                                 this.style.display = "inline";
8180                                                                 this.style.zoom = 1;
8181                                                         }
8182                                                 }
8183                                         }
8184                                 }
8185                         }
8187                         if ( opt.overflow != null ) {
8188                                 this.style.overflow = "hidden";
8189                         }
8191                         for ( p in prop ) {
8192                                 e = new jQuery.fx( this, opt, p );
8193                                 val = prop[ p ];
8195                                 if ( rfxtypes.test(val) ) {
8196                                         e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8198                                 } else {
8199                                         parts = rfxnum.exec( val );
8200                                         start = e.cur();
8202                                         if ( parts ) {
8203                                                 end = parseFloat( parts[2] );
8204                                                 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
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                                                 }
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                                                 }
8218                                                 e.custom( start, end, unit );
8220                                         } else {
8221                                                 e.custom( start, val, "" );
8222                                         }
8223                                 }
8224                         }
8226                         // For JS strict compliance
8227                         return true;
8228                 });
8229         },
8231         stop: function( clearQueue, gotoEnd ) {
8232                 if ( clearQueue ) {
8233                         this.queue([]);
8234                 }
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                                         }
8250                                         timers.splice(i, 1);
8251                                 }
8252                         }
8253                 });
8255                 // start the next in the queue if the last step wasn't forced
8256                 if ( !gotoEnd ) {
8257                         this.dequeue();
8258                 }
8260                 return this;
8261         }
8263 });
8265 // Animations created synchronously will run synchronously
8266 function createFxNow() {
8267         setTimeout( clearFxNow, 0 );
8268         return ( fxNow = jQuery.now() );
8271 function clearFxNow() {
8272         fxNow = undefined;
8275 // Generate parameters to create a standard animation
8276 function genFx( type, num ) {
8277         var obj = {};
8279         jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8280                 obj[ this ] = type;
8281         });
8283         return obj;
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 });
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                 };
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;
8312                 // Queueing
8313                 opt.old = opt.complete;
8314                 opt.complete = function( noUnmark ) {
8315                         if ( jQuery.isFunction( opt.old ) ) {
8316                                 opt.old.call( this );
8317                         }
8319                         if ( opt.queue !== false ) {
8320                                 jQuery.dequeue( this );
8321                         } else if ( noUnmark !== false ) {
8322                                 jQuery._unmark( this );
8323                         }
8324                 };
8326                 return opt;
8327         },
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         },
8338         timers: [],
8340         fx: function( elem, options, prop ) {
8341                 this.options = options;
8342                 this.elem = elem;
8343                 this.prop = prop;
8345                 options.orig = options.orig || {};
8346         }
8348 });
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                 }
8357                 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8358         },
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                 }
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         },
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;
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;
8387                 function t( gotoEnd ) {
8388                         return self.step(gotoEnd);
8389                 }
8391                 t.elem = this.elem;
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         },
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;
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());
8422                 // Start by showing the element
8423                 jQuery( this.elem ).show();
8424         },
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;
8432                 // Begin the animation
8433                 this.custom(this.cur(), 0);
8434         },
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;
8444                 if ( gotoEnd || t >= options.duration + this.startTime ) {
8445                         this.now = this.end;
8446                         this.pos = this.state = 1;
8447                         this.update();
8449                         options.animatedProperties[ this.prop ] = true;
8451                         for ( i in options.animatedProperties ) {
8452                                 if ( options.animatedProperties[i] !== true ) {
8453                                         done = false;
8454                                 }
8455                         }
8457                         if ( done ) {
8458                                 // Reset the overflow
8459                                 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8461                                         jQuery.each( [ "", "X", "Y" ], function (index, value) {
8462                                                 elem.style[ "overflow" + value ] = options.overflow[index];
8463                                         });
8464                                 }
8466                                 // Hide the element if the "hide" operation was done
8467                                 if ( options.hide ) {
8468                                         jQuery(elem).hide();
8469                                 }
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                                 }
8478                                 // Execute the complete function
8479                                 options.complete.call( elem );
8480                         }
8482                         return false;
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;
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                 }
8500                 return true;
8501         }
8502 };
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                 }
8512                 if ( !timers.length ) {
8513                         jQuery.fx.stop();
8514                 }
8515         },
8517         interval: 13,
8519         stop: function() {
8520                 clearInterval( timerId );
8521                 timerId = null;
8522         },
8524         speeds: {
8525                 slow: 600,
8526                 fast: 200,
8527                 // Default speed
8528                 _default: 400
8529         },
8531         step: {
8532                 opacity: function( fx ) {
8533                         jQuery.style( fx.elem, "opacity", fx.now );
8534                 },
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 });
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         };
8554 // Try to restore the default display value of an element
8555 function defaultDisplay( nodeName ) {
8557         if ( !elemdisplay[ nodeName ] ) {
8559                 var body = document.body,
8560                         elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
8561                         display = elem.css( "display" );
8563                 elem.remove();
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                         }
8574                         body.appendChild( iframe );
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                         }
8585                         elem = iframeDoc.createElement( nodeName );
8587                         iframeDoc.body.appendChild( elem );
8589                         display = jQuery.css( elem, "display" );
8591                         body.removeChild( iframe );
8592                 }
8594                 // Store the correct default display
8595                 elemdisplay[ nodeName ] = display;
8596         }
8598         return elemdisplay[ nodeName ];
8604 var rtable = /^t(?:able|d|h)$/i,
8605         rroot = /^(?:body|html)$/i;
8607 if ( "getBoundingClientRect" in document.documentElement ) {
8608         jQuery.fn.offset = function( options ) {
8609                 var elem = this[0], box;
8611                 if ( options ) {
8612                         return this.each(function( i ) {
8613                                 jQuery.offset.setOffset( this, options, i );
8614                         });
8615                 }
8617                 if ( !elem || !elem.ownerDocument ) {
8618                         return null;
8619                 }
8621                 if ( elem === elem.ownerDocument.body ) {
8622                         return jQuery.offset.bodyOffset( elem );
8623                 }
8625                 try {
8626                         box = elem.getBoundingClientRect();
8627                 } catch(e) {}
8629                 var doc = elem.ownerDocument,
8630                         docElem = doc.documentElement;
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                 }
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;
8646                 return { top: top, left: left };
8647         };
8649 } else {
8650         jQuery.fn.offset = function( options ) {
8651                 var elem = this[0];
8653                 if ( options ) {
8654                         return this.each(function( i ) {
8655                                 jQuery.offset.setOffset( this, options, i );
8656                         });
8657                 }
8659                 if ( !elem || !elem.ownerDocument ) {
8660                         return null;
8661                 }
8663                 if ( elem === elem.ownerDocument.body ) {
8664                         return jQuery.offset.bodyOffset( elem );
8665                 }
8667                 jQuery.offset.initialize();
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;
8680                 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8681                         if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8682                                 break;
8683                         }
8685                         computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8686                         top  -= elem.scrollTop;
8687                         left -= elem.scrollLeft;
8689                         if ( elem === offsetParent ) {
8690                                 top  += elem.offsetTop;
8691                                 left += elem.offsetLeft;
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                                 }
8698                                 prevOffsetParent = offsetParent;
8699                                 offsetParent = elem.offsetParent;
8700                         }
8702                         if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8703                                 top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8704                                 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8705                         }
8707                         prevComputedStyle = computedStyle;
8708                 }
8710                 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8711                         top  += body.offsetTop;
8712                         left += body.offsetLeft;
8713                 }
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                 }
8720                 return { top: top, left: left };
8721         };
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>";
8729                 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8731                 container.innerHTML = html;
8732                 body.insertBefore( container, body.firstChild );
8733                 innerDiv = container.firstChild;
8734                 checkDiv = innerDiv.firstChild;
8735                 td = innerDiv.nextSibling.firstChild.firstChild;
8737                 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8738                 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8740                 checkDiv.style.position = "fixed";
8741                 checkDiv.style.top = "20px";
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 = "";
8747                 innerDiv.style.overflow = "hidden";
8748                 innerDiv.style.position = "relative";
8750                 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8752                 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8754                 body.removeChild( container );
8755                 jQuery.offset.initialize = jQuery.noop;
8756         },
8758         bodyOffset: function( body ) {
8759                 var top = body.offsetTop,
8760                         left = body.offsetLeft;
8762                 jQuery.offset.initialize();
8764                 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8765                         top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8766                         left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8767                 }
8769                 return { top: top, left: left };
8770         },
8772         setOffset: function( elem, options, i ) {
8773                 var position = jQuery.css( elem, "position" );
8775                 // set position first, in-case top/left are set even on static elem
8776                 if ( position === "static" ) {
8777                         elem.style.position = "relative";
8778                 }
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;
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                 }
8797                 if ( jQuery.isFunction( options ) ) {
8798                         options = options.call( elem, i, curOffset );
8799                 }
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                 }
8808                 if ( "using" in options ) {
8809                         options.using.call( elem, props );
8810                 } else {
8811                         curElem.css( props );
8812                 }
8813         }
8814 };
8817 jQuery.fn.extend({
8818         position: function() {
8819                 if ( !this[0] ) {
8820                         return null;
8821                 }
8823                 var elem = this[0],
8825                 // Get *real* offsetParent
8826                 offsetParent = this.offsetParent(),
8828                 // Get correct offsets
8829                 offset       = this.offset(),
8830                 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
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;
8838                 // Add offsetParent borders
8839                 parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8840                 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8842                 // Subtract the two offsets
8843                 return {
8844                         top:  offset.top  - parentOffset.top,
8845                         left: offset.left - parentOffset.left
8846                 };
8847         },
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 });
8861 // Create scrollLeft and scrollTop methods
8862 jQuery.each( ["Left", "Top"], function( i, name ) {
8863         var method = "scroll" + name;
8865         jQuery.fn[ method ] = function( val ) {
8866                 var elem, win;
8868                 if ( val === undefined ) {
8869                         elem = this[ 0 ];
8871                         if ( !elem ) {
8872                                 return null;
8873                         }
8875                         win = getWindow( elem );
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                 }
8884                 // Set the scroll offset
8885                 return this.each(function() {
8886                         win = getWindow( this );
8888                         if ( win ) {
8889                                 win.scrollTo(
8890                                         !i ? val : jQuery( win ).scrollLeft(),
8891                                          i ? val : jQuery( win ).scrollTop()
8892                                 );
8894                         } else {
8895                                 this[ method ] = val;
8896                         }
8897                 });
8898         };
8899 });
8901 function getWindow( elem ) {
8902         return jQuery.isWindow( elem ) ?
8903                 elem :
8904                 elem.nodeType === 9 ?
8905                         elem.defaultView || elem.parentWindow :
8906                         false;
8912 // Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
8913 jQuery.each([ "Height", "Width" ], function( i, name ) {
8915         var type = name.toLowerCase();
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         };
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         };
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                 }
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                 }
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;
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                         );
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 );
8968                         return jQuery.isNaN( ret ) ? orig : ret;
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         };
8976 });
8979 // Expose jQuery to the global object
8980 window.jQuery = window.$ = jQuery;
8981 })(window);