source: trunk/themes/default/js/jquery.js @ 12040

Last change on this file since 12040 was 12040, checked in by plg, 13 years ago

update jQuery to version 1.6.2

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