source: Dev/branches/rest-dojo-ui/Demo/d3/lib/jquery/jquery.js @ 312

Last change on this file since 312 was 312, checked in by jkraaijeveld, 13 years ago
File size: 176.2 KB
Line 
1/*!
2 * jQuery JavaScript Library v1.4.3
3 * http://jquery.com/
4 *
5 * Copyright 2010, 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 2010, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
13 *
14 * Date: Thu Oct 14 23:10:06 2010 -0400
15 */
16(function( window, undefined ) {
17
18// Use the correct document accordingly with window argument (sandbox)
19var document = window.document;
20var jQuery = (function() {
21
22// Define a local copy of jQuery
23var jQuery = function( selector, context ) {
24                // The jQuery object is actually just the init constructor 'enhanced'
25                return new jQuery.fn.init( selector, context );
26        },
27
28        // Map over jQuery in case of overwrite
29        _jQuery = window.jQuery,
30
31        // Map over the $ in case of overwrite
32        _$ = window.$,
33
34        // A central reference to the root jQuery(document)
35        rootjQuery,
36
37        // A simple way to check for HTML strings or ID strings
38        // (both of which we optimize for)
39        quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
40
41        // Is it a simple selector
42        isSimple = /^.[^:#\[\.,]*$/,
43
44        // Check if a string has a non-whitespace character in it
45        rnotwhite = /\S/,
46        rwhite = /\s/,
47
48        // Used for trimming whitespace
49        trimLeft = /^\s+/,
50        trimRight = /\s+$/,
51
52        // Check for non-word characters
53        rnonword = /\W/,
54
55        // Check for digits
56        rdigit = /\d/,
57
58        // Match a standalone tag
59        rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
60
61        // JSON RegExp
62        rvalidchars = /^[\],:{}\s]*$/,
63        rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
64        rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
65        rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
66
67        // Useragent RegExp
68        rwebkit = /(webkit)[ \/]([\w.]+)/,
69        ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
70        rmsie = /(msie) ([\w.]+)/,
71        rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
72
73        // Keep a UserAgent string for use with jQuery.browser
74        userAgent = navigator.userAgent,
75
76        // For matching the engine and version of the browser
77        browserMatch,
78       
79        // Has the ready events already been bound?
80        readyBound = false,
81       
82        // The functions to execute 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        init: function( selector, context ) {
101                var match, elem, ret, doc;
102
103                // Handle $(""), $(null), or $(undefined)
104                if ( !selector ) {
105                        return this;
106                }
107
108                // Handle $(DOMElement)
109                if ( selector.nodeType ) {
110                        this.context = this[0] = selector;
111                        this.length = 1;
112                        return this;
113                }
114               
115                // The body element only exists once, optimize finding it
116                if ( selector === "body" && !context && document.body ) {
117                        this.context = document;
118                        this[0] = document.body;
119                        this.selector = "body";
120                        this.length = 1;
121                        return this;
122                }
123
124                // Handle HTML strings
125                if ( typeof selector === "string" ) {
126                        // Are we dealing with HTML string or an ID?
127                        match = quickExpr.exec( selector );
128
129                        // Verify a match, and that no context was specified for #id
130                        if ( match && (match[1] || !context) ) {
131
132                                // HANDLE: $(html) -> $(array)
133                                if ( match[1] ) {
134                                        doc = (context ? context.ownerDocument || context : document);
135
136                                        // If a single string is passed in and it's a single tag
137                                        // just do a createElement and skip the rest
138                                        ret = rsingleTag.exec( selector );
139
140                                        if ( ret ) {
141                                                if ( jQuery.isPlainObject( context ) ) {
142                                                        selector = [ document.createElement( ret[1] ) ];
143                                                        jQuery.fn.attr.call( selector, context, true );
144
145                                                } else {
146                                                        selector = [ doc.createElement( ret[1] ) ];
147                                                }
148
149                                        } else {
150                                                ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
151                                                selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
152                                        }
153                                       
154                                        return jQuery.merge( this, selector );
155                                       
156                                // HANDLE: $("#id")
157                                } else {
158                                        elem = document.getElementById( match[2] );
159
160                                        // Check parentNode to catch when Blackberry 4.6 returns
161                                        // nodes that are no longer in the document #6963
162                                        if ( elem && elem.parentNode ) {
163                                                // Handle the case where IE and Opera return items
164                                                // by name instead of ID
165                                                if ( elem.id !== match[2] ) {
166                                                        return rootjQuery.find( selector );
167                                                }
168
169                                                // Otherwise, we inject the element directly into the jQuery object
170                                                this.length = 1;
171                                                this[0] = elem;
172                                        }
173
174                                        this.context = document;
175                                        this.selector = selector;
176                                        return this;
177                                }
178
179                        // HANDLE: $("TAG")
180                        } else if ( !context && !rnonword.test( selector ) ) {
181                                this.selector = selector;
182                                this.context = document;
183                                selector = document.getElementsByTagName( selector );
184                                return jQuery.merge( this, selector );
185
186                        // HANDLE: $(expr, $(...))
187                        } else if ( !context || context.jquery ) {
188                                return (context || rootjQuery).find( selector );
189
190                        // HANDLE: $(expr, context)
191                        // (which is just equivalent to: $(context).find(expr)
192                        } else {
193                                return jQuery( context ).find( selector );
194                        }
195
196                // HANDLE: $(function)
197                // Shortcut for document ready
198                } else if ( jQuery.isFunction( selector ) ) {
199                        return rootjQuery.ready( selector );
200                }
201
202                if (selector.selector !== undefined) {
203                        this.selector = selector.selector;
204                        this.context = selector.context;
205                }
206
207                return jQuery.makeArray( selector, this );
208        },
209
210        // Start with an empty selector
211        selector: "",
212
213        // The current version of jQuery being used
214        jquery: "1.4.3",
215
216        // The default length of a jQuery object is 0
217        length: 0,
218
219        // The number of elements contained in the matched element set
220        size: function() {
221                return this.length;
222        },
223
224        toArray: function() {
225                return slice.call( this, 0 );
226        },
227
228        // Get the Nth element in the matched element set OR
229        // Get the whole matched element set as a clean array
230        get: function( num ) {
231                return num == null ?
232
233                        // Return a 'clean' array
234                        this.toArray() :
235
236                        // Return just the object
237                        ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
238        },
239
240        // Take an array of elements and push it onto the stack
241        // (returning the new matched element set)
242        pushStack: function( elems, name, selector ) {
243                // Build a new jQuery matched element set
244                var ret = jQuery();
245
246                if ( jQuery.isArray( elems ) ) {
247                        push.apply( ret, elems );
248               
249                } else {
250                        jQuery.merge( ret, elems );
251                }
252
253                // Add the old object onto the stack (as a reference)
254                ret.prevObject = this;
255
256                ret.context = this.context;
257
258                if ( name === "find" ) {
259                        ret.selector = this.selector + (this.selector ? " " : "") + selector;
260                } else if ( name ) {
261                        ret.selector = this.selector + "." + name + "(" + selector + ")";
262                }
263
264                // Return the newly-formed element set
265                return ret;
266        },
267
268        // Execute a callback for every element in the matched set.
269        // (You can seed the arguments with an array of args, but this is
270        // only used internally.)
271        each: function( callback, args ) {
272                return jQuery.each( this, callback, args );
273        },
274       
275        ready: function( fn ) {
276                // Attach the listeners
277                jQuery.bindReady();
278
279                // If the DOM is already ready
280                if ( jQuery.isReady ) {
281                        // Execute the function immediately
282                        fn.call( document, jQuery );
283
284                // Otherwise, remember the function for later
285                } else if ( readyList ) {
286                        // Add the function to the wait list
287                        readyList.push( fn );
288                }
289
290                return this;
291        },
292       
293        eq: function( i ) {
294                return i === -1 ?
295                        this.slice( i ) :
296                        this.slice( i, +i + 1 );
297        },
298
299        first: function() {
300                return this.eq( 0 );
301        },
302
303        last: function() {
304                return this.eq( -1 );
305        },
306
307        slice: function() {
308                return this.pushStack( slice.apply( this, arguments ),
309                        "slice", slice.call(arguments).join(",") );
310        },
311
312        map: function( callback ) {
313                return this.pushStack( jQuery.map(this, function( elem, i ) {
314                        return callback.call( elem, i, elem );
315                }));
316        },
317       
318        end: function() {
319                return this.prevObject || jQuery(null);
320        },
321
322        // For internal use only.
323        // Behaves like an Array's method, not like a jQuery method.
324        push: push,
325        sort: [].sort,
326        splice: [].splice
327};
328
329// Give the init function the jQuery prototype for later instantiation
330jQuery.fn.init.prototype = jQuery.fn;
331
332jQuery.extend = jQuery.fn.extend = function() {
333        // copy reference to target object
334        var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy, copyIsArray;
335
336        // Handle a deep copy situation
337        if ( typeof target === "boolean" ) {
338                deep = target;
339                target = arguments[1] || {};
340                // skip the boolean and the target
341                i = 2;
342        }
343
344        // Handle case when target is a string or something (possible in deep copy)
345        if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
346                target = {};
347        }
348
349        // extend jQuery itself if only one argument is passed
350        if ( length === i ) {
351                target = this;
352                --i;
353        }
354
355        for ( ; i < length; i++ ) {
356                // Only deal with non-null/undefined values
357                if ( (options = arguments[ i ]) != null ) {
358                        // Extend the base object
359                        for ( name in options ) {
360                                src = target[ name ];
361                                copy = options[ name ];
362
363                                // Prevent never-ending loop
364                                if ( target === copy ) {
365                                        continue;
366                                }
367
368                                // Recurse if we're merging plain objects or arrays
369                                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
370                                        if ( copyIsArray ) {
371                                                copyIsArray = false;
372                                                clone = src && jQuery.isArray(src) ? src : [];
373
374                                        } else {
375                                                clone = src && jQuery.isPlainObject(src) ? src : {};
376                                        }
377
378                                        // Never move original objects, clone them
379                                        target[ name ] = jQuery.extend( deep, clone, copy );
380
381                                // Don't bring in undefined values
382                                } else if ( copy !== undefined ) {
383                                        target[ name ] = copy;
384                                }
385                        }
386                }
387        }
388
389        // Return the modified object
390        return target;
391};
392
393jQuery.extend({
394        noConflict: function( deep ) {
395                window.$ = _$;
396
397                if ( deep ) {
398                        window.jQuery = _jQuery;
399                }
400
401                return jQuery;
402        },
403       
404        // Is the DOM ready to be used? Set to true once it occurs.
405        isReady: false,
406
407        // A counter to track how many items to wait for before
408        // the ready event fires. See #6781
409        readyWait: 1,
410       
411        // Handle when the DOM is ready
412        ready: function( wait ) {
413                // A third-party is pushing the ready event forwards
414                if ( wait === true ) {
415                        jQuery.readyWait--;
416                }
417
418                // Make sure that the DOM is not already loaded
419                if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
420                        // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
421                        if ( !document.body ) {
422                                return setTimeout( jQuery.ready, 1 );
423                        }
424
425                        // Remember that the DOM is ready
426                        jQuery.isReady = true;
427
428                        // If a normal DOM Ready event fired, decrement, and wait if need be
429                        if ( wait !== true && --jQuery.readyWait > 0 ) {
430                                return;
431                        }
432
433                        // If there are functions bound, to execute
434                        if ( readyList ) {
435                                // Execute all of them
436                                var fn, i = 0;
437                                while ( (fn = readyList[ i++ ]) ) {
438                                        fn.call( document, jQuery );
439                                }
440
441                                // Reset the list of functions
442                                readyList = null;
443                        }
444
445                        // Trigger any bound ready events
446                        if ( jQuery.fn.triggerHandler ) {
447                                jQuery( document ).triggerHandler( "ready" );
448                        }
449                }
450        },
451       
452        bindReady: function() {
453                if ( readyBound ) {
454                        return;
455                }
456
457                readyBound = true;
458
459                // Catch cases where $(document).ready() is called after the
460                // browser event has already occurred.
461                if ( document.readyState === "complete" ) {
462                        // Handle it asynchronously to allow scripts the opportunity to delay ready
463                        return setTimeout( jQuery.ready, 1 );
464                }
465
466                // Mozilla, Opera and webkit nightlies currently support this event
467                if ( document.addEventListener ) {
468                        // Use the handy event callback
469                        document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
470                       
471                        // A fallback to window.onload, that will always work
472                        window.addEventListener( "load", jQuery.ready, false );
473
474                // If IE event model is used
475                } else if ( document.attachEvent ) {
476                        // ensure firing before onload,
477                        // maybe late but safe also for iframes
478                        document.attachEvent("onreadystatechange", DOMContentLoaded);
479                       
480                        // A fallback to window.onload, that will always work
481                        window.attachEvent( "onload", jQuery.ready );
482
483                        // If IE and not a frame
484                        // continually check to see if the document is ready
485                        var toplevel = false;
486
487                        try {
488                                toplevel = window.frameElement == null;
489                        } catch(e) {}
490
491                        if ( document.documentElement.doScroll && toplevel ) {
492                                doScrollCheck();
493                        }
494                }
495        },
496
497        // See test/unit/core.js for details concerning isFunction.
498        // Since version 1.3, DOM methods and functions like alert
499        // aren't supported. They return false on IE (#2968).
500        isFunction: function( obj ) {
501                return jQuery.type(obj) === "function";
502        },
503
504        isArray: Array.isArray || function( obj ) {
505                return jQuery.type(obj) === "array";
506        },
507
508        // A crude way of determining if an object is a window
509        isWindow: function( obj ) {
510                return obj && typeof obj === "object" && "setInterval" in obj;
511        },
512
513        isNaN: function( obj ) {
514                return obj == null || !rdigit.test( obj ) || isNaN( obj );
515        },
516
517        type: function( obj ) {
518                return obj == null ?
519                        String( obj ) :
520                        class2type[ toString.call(obj) ] || "object";
521        },
522
523        isPlainObject: function( obj ) {
524                // Must be an Object.
525                // Because of IE, we also have to check the presence of the constructor property.
526                // Make sure that DOM nodes and window objects don't pass through, as well
527                if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
528                        return false;
529                }
530               
531                // Not own constructor property must be Object
532                if ( obj.constructor &&
533                        !hasOwn.call(obj, "constructor") &&
534                        !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
535                        return false;
536                }
537               
538                // Own properties are enumerated firstly, so to speed up,
539                // if last one is own, then all properties are own.
540       
541                var key;
542                for ( key in obj ) {}
543               
544                return key === undefined || hasOwn.call( obj, key );
545        },
546
547        isEmptyObject: function( obj ) {
548                for ( var name in obj ) {
549                        return false;
550                }
551                return true;
552        },
553       
554        error: function( msg ) {
555                throw msg;
556        },
557       
558        parseJSON: function( data ) {
559                if ( typeof data !== "string" || !data ) {
560                        return null;
561                }
562
563                // Make sure leading/trailing whitespace is removed (IE can't handle it)
564                data = jQuery.trim( data );
565               
566                // Make sure the incoming data is actual JSON
567                // Logic borrowed from http://json.org/json2.js
568                if ( rvalidchars.test(data.replace(rvalidescape, "@")
569                        .replace(rvalidtokens, "]")
570                        .replace(rvalidbraces, "")) ) {
571
572                        // Try to use the native JSON parser first
573                        return window.JSON && window.JSON.parse ?
574                                window.JSON.parse( data ) :
575                                (new Function("return " + data))();
576
577                } else {
578                        jQuery.error( "Invalid JSON: " + data );
579                }
580        },
581
582        noop: function() {},
583
584        // Evalulates a script in a global context
585        globalEval: function( data ) {
586                if ( data && rnotwhite.test(data) ) {
587                        // Inspired by code by Andrea Giammarchi
588                        // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
589                        var head = document.getElementsByTagName("head")[0] || document.documentElement,
590                                script = document.createElement("script");
591
592                        script.type = "text/javascript";
593
594                        if ( jQuery.support.scriptEval ) {
595                                script.appendChild( document.createTextNode( data ) );
596                        } else {
597                                script.text = data;
598                        }
599
600                        // Use insertBefore instead of appendChild to circumvent an IE6 bug.
601                        // This arises when a base node is used (#2709).
602                        head.insertBefore( script, head.firstChild );
603                        head.removeChild( script );
604                }
605        },
606
607        nodeName: function( elem, name ) {
608                return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
609        },
610
611        // args is for internal usage only
612        each: function( object, callback, args ) {
613                var name, i = 0,
614                        length = object.length,
615                        isObj = length === undefined || jQuery.isFunction(object);
616
617                if ( args ) {
618                        if ( isObj ) {
619                                for ( name in object ) {
620                                        if ( callback.apply( object[ name ], args ) === false ) {
621                                                break;
622                                        }
623                                }
624                        } else {
625                                for ( ; i < length; ) {
626                                        if ( callback.apply( object[ i++ ], args ) === false ) {
627                                                break;
628                                        }
629                                }
630                        }
631
632                // A special, fast, case for the most common use of each
633                } else {
634                        if ( isObj ) {
635                                for ( name in object ) {
636                                        if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
637                                                break;
638                                        }
639                                }
640                        } else {
641                                for ( var value = object[0];
642                                        i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
643                        }
644                }
645
646                return object;
647        },
648
649        // Use native String.trim function wherever possible
650        trim: trim ?
651                function( text ) {
652                        return text == null ?
653                                "" :
654                                trim.call( text );
655                } :
656
657                // Otherwise use our own trimming functionality
658                function( text ) {
659                        return text == null ?
660                                "" :
661                                text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
662                },
663
664        // results is for internal usage only
665        makeArray: function( array, results ) {
666                var ret = results || [];
667
668                if ( array != null ) {
669                        // The window, strings (and functions) also have 'length'
670                        // The extra typeof function check is to prevent crashes
671                        // in Safari 2 (See: #3039)
672                        // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
673                        var type = jQuery.type(array);
674
675                        if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
676                                push.call( ret, array );
677                        } else {
678                                jQuery.merge( ret, array );
679                        }
680                }
681
682                return ret;
683        },
684
685        inArray: function( elem, array ) {
686                if ( array.indexOf ) {
687                        return array.indexOf( elem );
688                }
689
690                for ( var i = 0, length = array.length; i < length; i++ ) {
691                        if ( array[ i ] === elem ) {
692                                return i;
693                        }
694                }
695
696                return -1;
697        },
698
699        merge: function( first, second ) {
700                var i = first.length, j = 0;
701
702                if ( typeof second.length === "number" ) {
703                        for ( var l = second.length; j < l; j++ ) {
704                                first[ i++ ] = second[ j ];
705                        }
706               
707                } else {
708                        while ( second[j] !== undefined ) {
709                                first[ i++ ] = second[ j++ ];
710                        }
711                }
712
713                first.length = i;
714
715                return first;
716        },
717
718        grep: function( elems, callback, inv ) {
719                var ret = [], retVal;
720                inv = !!inv;
721
722                // Go through the array, only saving the items
723                // that pass the validator function
724                for ( var i = 0, length = elems.length; i < length; i++ ) {
725                        retVal = !!callback( elems[ i ], i );
726                        if ( inv !== retVal ) {
727                                ret.push( elems[ i ] );
728                        }
729                }
730
731                return ret;
732        },
733
734        // arg is for internal usage only
735        map: function( elems, callback, arg ) {
736                var ret = [], value;
737
738                // Go through the array, translating each of the items to their
739                // new value (or values).
740                for ( var i = 0, length = elems.length; i < length; i++ ) {
741                        value = callback( elems[ i ], i, arg );
742
743                        if ( value != null ) {
744                                ret[ ret.length ] = value;
745                        }
746                }
747
748                return ret.concat.apply( [], ret );
749        },
750
751        // A global GUID counter for objects
752        guid: 1,
753
754        proxy: function( fn, proxy, thisObject ) {
755                if ( arguments.length === 2 ) {
756                        if ( typeof proxy === "string" ) {
757                                thisObject = fn;
758                                fn = thisObject[ proxy ];
759                                proxy = undefined;
760
761                        } else if ( proxy && !jQuery.isFunction( proxy ) ) {
762                                thisObject = proxy;
763                                proxy = undefined;
764                        }
765                }
766
767                if ( !proxy && fn ) {
768                        proxy = function() {
769                                return fn.apply( thisObject || this, arguments );
770                        };
771                }
772
773                // Set the guid of unique handler to the same of original handler, so it can be removed
774                if ( fn ) {
775                        proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
776                }
777
778                // So proxy can be declared as an argument
779                return proxy;
780        },
781
782        // Mutifunctional method to get and set values to a collection
783        // The value/s can be optionally by executed if its a function
784        access: function( elems, key, value, exec, fn, pass ) {
785                var length = elems.length;
786       
787                // Setting many attributes
788                if ( typeof key === "object" ) {
789                        for ( var k in key ) {
790                                jQuery.access( elems, k, key[k], exec, fn, value );
791                        }
792                        return elems;
793                }
794       
795                // Setting one attribute
796                if ( value !== undefined ) {
797                        // Optionally, function values get executed if exec is true
798                        exec = !pass && exec && jQuery.isFunction(value);
799               
800                        for ( var i = 0; i < length; i++ ) {
801                                fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
802                        }
803               
804                        return elems;
805                }
806       
807                // Getting an attribute
808                return length ? fn( elems[0], key ) : undefined;
809        },
810
811        now: function() {
812                return (new Date()).getTime();
813        },
814
815        // Use of jQuery.browser is frowned upon.
816        // More details: http://docs.jquery.com/Utilities/jQuery.browser
817        uaMatch: function( ua ) {
818                ua = ua.toLowerCase();
819
820                var match = rwebkit.exec( ua ) ||
821                        ropera.exec( ua ) ||
822                        rmsie.exec( ua ) ||
823                        ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
824                        [];
825
826                return { browser: match[1] || "", version: match[2] || "0" };
827        },
828
829        browser: {}
830});
831
832// Populate the class2type map
833jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
834        class2type[ "[object " + name + "]" ] = name.toLowerCase();
835});
836
837browserMatch = jQuery.uaMatch( userAgent );
838if ( browserMatch.browser ) {
839        jQuery.browser[ browserMatch.browser ] = true;
840        jQuery.browser.version = browserMatch.version;
841}
842
843// Deprecated, use jQuery.browser.webkit instead
844if ( jQuery.browser.webkit ) {
845        jQuery.browser.safari = true;
846}
847
848if ( indexOf ) {
849        jQuery.inArray = function( elem, array ) {
850                return indexOf.call( array, elem );
851        };
852}
853
854// Verify that \s matches non-breaking spaces
855// (IE fails on this test)
856if ( !rwhite.test( "\xA0" ) ) {
857        trimLeft = /^[\s\xA0]+/;
858        trimRight = /[\s\xA0]+$/;
859}
860
861// All jQuery objects should point back to these
862rootjQuery = jQuery(document);
863
864// Cleanup functions for the document ready method
865if ( document.addEventListener ) {
866        DOMContentLoaded = function() {
867                document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
868                jQuery.ready();
869        };
870
871} else if ( document.attachEvent ) {
872        DOMContentLoaded = function() {
873                // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
874                if ( document.readyState === "complete" ) {
875                        document.detachEvent( "onreadystatechange", DOMContentLoaded );
876                        jQuery.ready();
877                }
878        };
879}
880
881// The DOM ready check for Internet Explorer
882function doScrollCheck() {
883        if ( jQuery.isReady ) {
884                return;
885        }
886
887        try {
888                // If IE is used, use the trick by Diego Perini
889                // http://javascript.nwbox.com/IEContentLoaded/
890                document.documentElement.doScroll("left");
891        } catch(e) {
892                setTimeout( doScrollCheck, 1 );
893                return;
894        }
895
896        // and execute any waiting functions
897        jQuery.ready();
898}
899
900// Expose jQuery to the global object
901return (window.jQuery = window.$ = jQuery);
902
903})();
904
905
906(function() {
907
908        jQuery.support = {};
909
910        var root = document.documentElement,
911                script = document.createElement("script"),
912                div = document.createElement("div"),
913                id = "script" + jQuery.now();
914
915        div.style.display = "none";
916        div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
917
918        var all = div.getElementsByTagName("*"),
919                a = div.getElementsByTagName("a")[0],
920                select = document.createElement("select"),
921                opt = select.appendChild( document.createElement("option") );
922
923        // Can't get basic test support
924        if ( !all || !all.length || !a ) {
925                return;
926        }
927
928        jQuery.support = {
929                // IE strips leading whitespace when .innerHTML is used
930                leadingWhitespace: div.firstChild.nodeType === 3,
931
932                // Make sure that tbody elements aren't automatically inserted
933                // IE will insert them into empty tables
934                tbody: !div.getElementsByTagName("tbody").length,
935
936                // Make sure that link elements get serialized correctly by innerHTML
937                // This requires a wrapper element in IE
938                htmlSerialize: !!div.getElementsByTagName("link").length,
939
940                // Get the style information from getAttribute
941                // (IE uses .cssText insted)
942                style: /red/.test( a.getAttribute("style") ),
943
944                // Make sure that URLs aren't manipulated
945                // (IE normalizes it by default)
946                hrefNormalized: a.getAttribute("href") === "/a",
947
948                // Make sure that element opacity exists
949                // (IE uses filter instead)
950                // Use a regex to work around a WebKit issue. See #5145
951                opacity: /^0.55$/.test( a.style.opacity ),
952
953                // Verify style float existence
954                // (IE uses styleFloat instead of cssFloat)
955                cssFloat: !!a.style.cssFloat,
956
957                // Make sure that if no value is specified for a checkbox
958                // that it defaults to "on".
959                // (WebKit defaults to "" instead)
960                checkOn: div.getElementsByTagName("input")[0].value === "on",
961
962                // Make sure that a selected-by-default option has a working selected property.
963                // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
964                optSelected: opt.selected,
965
966                // Will be defined later
967                optDisabled: false,
968                checkClone: false,
969                scriptEval: false,
970                noCloneEvent: true,
971                boxModel: null,
972                inlineBlockNeedsLayout: false,
973                shrinkWrapBlocks: false,
974                reliableHiddenOffsets: true
975        };
976
977        // Make sure that the options inside disabled selects aren't marked as disabled
978        // (WebKit marks them as diabled)
979        select.disabled = true;
980        jQuery.support.optDisabled = !opt.disabled;
981
982        script.type = "text/javascript";
983        try {
984                script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
985        } catch(e) {}
986
987        root.insertBefore( script, root.firstChild );
988
989        // Make sure that the execution of code works by injecting a script
990        // tag with appendChild/createTextNode
991        // (IE doesn't support this, fails, and uses .text instead)
992        if ( window[ id ] ) {
993                jQuery.support.scriptEval = true;
994                delete window[ id ];
995        }
996
997        root.removeChild( script );
998
999        if ( div.attachEvent && div.fireEvent ) {
1000                div.attachEvent("onclick", function click() {
1001                        // Cloning a node shouldn't copy over any
1002                        // bound event handlers (IE does this)
1003                        jQuery.support.noCloneEvent = false;
1004                        div.detachEvent("onclick", click);
1005                });
1006                div.cloneNode(true).fireEvent("onclick");
1007        }
1008
1009        div = document.createElement("div");
1010        div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
1011
1012        var fragment = document.createDocumentFragment();
1013        fragment.appendChild( div.firstChild );
1014
1015        // WebKit doesn't clone checked state correctly in fragments
1016        jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
1017
1018        // Figure out if the W3C box model works as expected
1019        // document.body must exist before we can do this
1020        jQuery(function() {
1021                var div = document.createElement("div");
1022                div.style.width = div.style.paddingLeft = "1px";
1023
1024                document.body.appendChild( div );
1025                jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
1026
1027                if ( "zoom" in div.style ) {
1028                        // Check if natively block-level elements act like inline-block
1029                        // elements when setting their display to 'inline' and giving
1030                        // them layout
1031                        // (IE < 8 does this)
1032                        div.style.display = "inline";
1033                        div.style.zoom = 1;
1034                        jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
1035
1036                        // Check if elements with layout shrink-wrap their children
1037                        // (IE 6 does this)
1038                        div.style.display = "";
1039                        div.innerHTML = "<div style='width:4px;'></div>";
1040                        jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
1041                }
1042
1043                div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
1044                var tds = div.getElementsByTagName("td");
1045
1046                // Check if table cells still have offsetWidth/Height when they are set
1047                // to display:none and there are still other visible table cells in a
1048                // table row; if so, offsetWidth/Height are not reliable for use when
1049                // determining if an element has been hidden directly using
1050                // display:none (it is still safe to use offsets if a parent element is
1051                // hidden; don safety goggles and see bug #4512 for more information).
1052                // (only IE 8 fails this test)
1053                jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
1054
1055                tds[0].style.display = "";
1056                tds[1].style.display = "none";
1057
1058                // Check if empty table cells still have offsetWidth/Height
1059                // (IE < 8 fail this test)
1060                jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
1061                div.innerHTML = "";
1062
1063                document.body.removeChild( div ).style.display = "none";
1064                div = tds = null;
1065        });
1066
1067        // Technique from Juriy Zaytsev
1068        // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1069        var eventSupported = function( eventName ) {
1070                var el = document.createElement("div");
1071                eventName = "on" + eventName;
1072
1073                var isSupported = (eventName in el);
1074                if ( !isSupported ) {
1075                        el.setAttribute(eventName, "return;");
1076                        isSupported = typeof el[eventName] === "function";
1077                }
1078                el = null;
1079
1080                return isSupported;
1081        };
1082
1083        jQuery.support.submitBubbles = eventSupported("submit");
1084        jQuery.support.changeBubbles = eventSupported("change");
1085
1086        // release memory in IE
1087        root = script = div = all = a = null;
1088})();
1089
1090jQuery.props = {
1091        "for": "htmlFor",
1092        "class": "className",
1093        readonly: "readOnly",
1094        maxlength: "maxLength",
1095        cellspacing: "cellSpacing",
1096        rowspan: "rowSpan",
1097        colspan: "colSpan",
1098        tabindex: "tabIndex",
1099        usemap: "useMap",
1100        frameborder: "frameBorder"
1101};
1102
1103
1104
1105
1106var windowData = {},
1107        rbrace = /^(?:\{.*\}|\[.*\])$/;
1108
1109jQuery.extend({
1110        cache: {},
1111
1112        // Please use with caution
1113        uuid: 0,
1114
1115        // Unique for each copy of jQuery on the page   
1116        expando: "jQuery" + jQuery.now(),
1117
1118        // The following elements throw uncatchable exceptions if you
1119        // attempt to add expando properties to them.
1120        noData: {
1121                "embed": true,
1122                // Ban all objects except for Flash (which handle expandos)
1123                "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1124                "applet": true
1125        },
1126
1127        data: function( elem, name, data ) {
1128                if ( !jQuery.acceptData( elem ) ) {
1129                        return;
1130                }
1131
1132                elem = elem == window ?
1133                        windowData :
1134                        elem;
1135
1136                var isNode = elem.nodeType,
1137                        id = isNode ? elem[ jQuery.expando ] : null,
1138                        cache = jQuery.cache, thisCache;
1139
1140                if ( isNode && !id && typeof name === "string" && data === undefined ) {
1141                        return;
1142                }
1143
1144                // Get the data from the object directly
1145                if ( !isNode ) {
1146                        cache = elem;
1147
1148                // Compute a unique ID for the element
1149                } else if ( !id ) {
1150                        elem[ jQuery.expando ] = id = ++jQuery.uuid;
1151                }
1152
1153                // Avoid generating a new cache unless none exists and we
1154                // want to manipulate it.
1155                if ( typeof name === "object" ) {
1156                        if ( isNode ) {
1157                                cache[ id ] = jQuery.extend(cache[ id ], name);
1158
1159                        } else {
1160                                jQuery.extend( cache, name );
1161                        }
1162
1163                } else if ( isNode && !cache[ id ] ) {
1164                        cache[ id ] = {};
1165                }
1166
1167                thisCache = isNode ? cache[ id ] : cache;
1168
1169                // Prevent overriding the named cache with undefined values
1170                if ( data !== undefined ) {
1171                        thisCache[ name ] = data;
1172                }
1173
1174                return typeof name === "string" ? thisCache[ name ] : thisCache;
1175        },
1176
1177        removeData: function( elem, name ) {
1178                if ( !jQuery.acceptData( elem ) ) {
1179                        return;
1180                }
1181
1182                elem = elem == window ?
1183                        windowData :
1184                        elem;
1185
1186                var isNode = elem.nodeType,
1187                        id = isNode ? elem[ jQuery.expando ] : elem,
1188                        cache = jQuery.cache,
1189                        thisCache = isNode ? cache[ id ] : id;
1190
1191                // If we want to remove a specific section of the element's data
1192                if ( name ) {
1193                        if ( thisCache ) {
1194                                // Remove the section of cache data
1195                                delete thisCache[ name ];
1196
1197                                // If we've removed all the data, remove the element's cache
1198                                if ( isNode && jQuery.isEmptyObject(thisCache) ) {
1199                                        jQuery.removeData( elem );
1200                                }
1201                        }
1202
1203                // Otherwise, we want to remove all of the element's data
1204                } else {
1205                        if ( isNode && jQuery.support.deleteExpando ) {
1206                                delete elem[ jQuery.expando ];
1207
1208                        } else if ( elem.removeAttribute ) {
1209                                elem.removeAttribute( jQuery.expando );
1210
1211                        // Completely remove the data cache
1212                        } else if ( isNode ) {
1213                                delete cache[ id ];
1214
1215                        // Remove all fields from the object
1216                        } else {
1217                                for ( var n in elem ) {
1218                                        delete elem[ n ];
1219                                }
1220                        }
1221                }
1222        },
1223
1224        // A method for determining if a DOM node can handle the data expando
1225        acceptData: function( elem ) {
1226                if ( elem.nodeName ) {
1227                        var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1228
1229                        if ( match ) {
1230                                return !(match === true || elem.getAttribute("classid") !== match);
1231                        }
1232                }
1233
1234                return true;
1235        }
1236});
1237
1238jQuery.fn.extend({
1239        data: function( key, value ) {
1240                if ( typeof key === "undefined" ) {
1241                        return this.length ? jQuery.data( this[0] ) : null;
1242
1243                } else if ( typeof key === "object" ) {
1244                        return this.each(function() {
1245                                jQuery.data( this, key );
1246                        });
1247                }
1248
1249                var parts = key.split(".");
1250                parts[1] = parts[1] ? "." + parts[1] : "";
1251
1252                if ( value === undefined ) {
1253                        var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1254
1255                        // Try to fetch any internally stored data first
1256                        if ( data === undefined && this.length ) {
1257                                data = jQuery.data( this[0], key );
1258
1259                                // If nothing was found internally, try to fetch any
1260                                // data from the HTML5 data-* attribute
1261                                if ( data === undefined && this[0].nodeType === 1 ) {
1262                                        data = this[0].getAttribute( "data-" + key );
1263
1264                                        if ( typeof data === "string" ) {
1265                                                try {
1266                                                        data = data === "true" ? true :
1267                                                                data === "false" ? false :
1268                                                                data === "null" ? null :
1269                                                                !jQuery.isNaN( data ) ? parseFloat( data ) :
1270                                                                rbrace.test( data ) ? jQuery.parseJSON( data ) :
1271                                                                data;
1272                                                } catch( e ) {}
1273
1274                                        } else {
1275                                                data = undefined;
1276                                        }
1277                                }
1278                        }
1279
1280                        return data === undefined && parts[1] ?
1281                                this.data( parts[0] ) :
1282                                data;
1283
1284                } else {
1285                        return this.each(function() {
1286                                var $this = jQuery( this ), args = [ parts[0], value ];
1287
1288                                $this.triggerHandler( "setData" + parts[1] + "!", args );
1289                                jQuery.data( this, key, value );
1290                                $this.triggerHandler( "changeData" + parts[1] + "!", args );
1291                        });
1292                }
1293        },
1294
1295        removeData: function( key ) {
1296                return this.each(function() {
1297                        jQuery.removeData( this, key );
1298                });
1299        }
1300});
1301
1302
1303
1304
1305jQuery.extend({
1306        queue: function( elem, type, data ) {
1307                if ( !elem ) {
1308                        return;
1309                }
1310
1311                type = (type || "fx") + "queue";
1312                var q = jQuery.data( elem, type );
1313
1314                // Speed up dequeue by getting out quickly if this is just a lookup
1315                if ( !data ) {
1316                        return q || [];
1317                }
1318
1319                if ( !q || jQuery.isArray(data) ) {
1320                        q = jQuery.data( elem, type, jQuery.makeArray(data) );
1321
1322                } else {
1323                        q.push( data );
1324                }
1325
1326                return q;
1327        },
1328
1329        dequeue: function( elem, type ) {
1330                type = type || "fx";
1331
1332                var queue = jQuery.queue( elem, type ), fn = queue.shift();
1333
1334                // If the fx queue is dequeued, always remove the progress sentinel
1335                if ( fn === "inprogress" ) {
1336                        fn = queue.shift();
1337                }
1338
1339                if ( fn ) {
1340                        // Add a progress sentinel to prevent the fx queue from being
1341                        // automatically dequeued
1342                        if ( type === "fx" ) {
1343                                queue.unshift("inprogress");
1344                        }
1345
1346                        fn.call(elem, function() {
1347                                jQuery.dequeue(elem, type);
1348                        });
1349                }
1350        }
1351});
1352
1353jQuery.fn.extend({
1354        queue: function( type, data ) {
1355                if ( typeof type !== "string" ) {
1356                        data = type;
1357                        type = "fx";
1358                }
1359
1360                if ( data === undefined ) {
1361                        return jQuery.queue( this[0], type );
1362                }
1363                return this.each(function( i ) {
1364                        var queue = jQuery.queue( this, type, data );
1365
1366                        if ( type === "fx" && queue[0] !== "inprogress" ) {
1367                                jQuery.dequeue( this, type );
1368                        }
1369                });
1370        },
1371        dequeue: function( type ) {
1372                return this.each(function() {
1373                        jQuery.dequeue( this, type );
1374                });
1375        },
1376
1377        // Based off of the plugin by Clint Helfers, with permission.
1378        // http://blindsignals.com/index.php/2009/07/jquery-delay/
1379        delay: function( time, type ) {
1380                time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1381                type = type || "fx";
1382
1383                return this.queue( type, function() {
1384                        var elem = this;
1385                        setTimeout(function() {
1386                                jQuery.dequeue( elem, type );
1387                        }, time );
1388                });
1389        },
1390
1391        clearQueue: function( type ) {
1392                return this.queue( type || "fx", [] );
1393        }
1394});
1395
1396
1397
1398
1399var rclass = /[\n\t]/g,
1400        rspaces = /\s+/,
1401        rreturn = /\r/g,
1402        rspecialurl = /^(?:href|src|style)$/,
1403        rtype = /^(?:button|input)$/i,
1404        rfocusable = /^(?:button|input|object|select|textarea)$/i,
1405        rclickable = /^a(?:rea)?$/i,
1406        rradiocheck = /^(?:radio|checkbox)$/i;
1407
1408jQuery.fn.extend({
1409        attr: function( name, value ) {
1410                return jQuery.access( this, name, value, true, jQuery.attr );
1411        },
1412
1413        removeAttr: function( name, fn ) {
1414                return this.each(function(){
1415                        jQuery.attr( this, name, "" );
1416                        if ( this.nodeType === 1 ) {
1417                                this.removeAttribute( name );
1418                        }
1419                });
1420        },
1421
1422        addClass: function( value ) {
1423                if ( jQuery.isFunction(value) ) {
1424                        return this.each(function(i) {
1425                                var self = jQuery(this);
1426                                self.addClass( value.call(this, i, self.attr("class")) );
1427                        });
1428                }
1429
1430                if ( value && typeof value === "string" ) {
1431                        var classNames = (value || "").split( rspaces );
1432
1433                        for ( var i = 0, l = this.length; i < l; i++ ) {
1434                                var elem = this[i];
1435
1436                                if ( elem.nodeType === 1 ) {
1437                                        if ( !elem.className ) {
1438                                                elem.className = value;
1439
1440                                        } else {
1441                                                var className = " " + elem.className + " ", setClass = elem.className;
1442                                                for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1443                                                        if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1444                                                                setClass += " " + classNames[c];
1445                                                        }
1446                                                }
1447                                                elem.className = jQuery.trim( setClass );
1448                                        }
1449                                }
1450                        }
1451                }
1452
1453                return this;
1454        },
1455
1456        removeClass: function( value ) {
1457                if ( jQuery.isFunction(value) ) {
1458                        return this.each(function(i) {
1459                                var self = jQuery(this);
1460                                self.removeClass( value.call(this, i, self.attr("class")) );
1461                        });
1462                }
1463
1464                if ( (value && typeof value === "string") || value === undefined ) {
1465                        var classNames = (value || "").split( rspaces );
1466
1467                        for ( var i = 0, l = this.length; i < l; i++ ) {
1468                                var elem = this[i];
1469
1470                                if ( elem.nodeType === 1 && elem.className ) {
1471                                        if ( value ) {
1472                                                var className = (" " + elem.className + " ").replace(rclass, " ");
1473                                                for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1474                                                        className = className.replace(" " + classNames[c] + " ", " ");
1475                                                }
1476                                                elem.className = jQuery.trim( className );
1477
1478                                        } else {
1479                                                elem.className = "";
1480                                        }
1481                                }
1482                        }
1483                }
1484
1485                return this;
1486        },
1487
1488        toggleClass: function( value, stateVal ) {
1489                var type = typeof value, isBool = typeof stateVal === "boolean";
1490
1491                if ( jQuery.isFunction( value ) ) {
1492                        return this.each(function(i) {
1493                                var self = jQuery(this);
1494                                self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1495                        });
1496                }
1497
1498                return this.each(function() {
1499                        if ( type === "string" ) {
1500                                // toggle individual class names
1501                                var className, i = 0, self = jQuery(this),
1502                                        state = stateVal,
1503                                        classNames = value.split( rspaces );
1504
1505                                while ( (className = classNames[ i++ ]) ) {
1506                                        // check each className given, space seperated list
1507                                        state = isBool ? state : !self.hasClass( className );
1508                                        self[ state ? "addClass" : "removeClass" ]( className );
1509                                }
1510
1511                        } else if ( type === "undefined" || type === "boolean" ) {
1512                                if ( this.className ) {
1513                                        // store className if set
1514                                        jQuery.data( this, "__className__", this.className );
1515                                }
1516
1517                                // toggle whole className
1518                                this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1519                        }
1520                });
1521        },
1522
1523        hasClass: function( selector ) {
1524                var className = " " + selector + " ";
1525                for ( var i = 0, l = this.length; i < l; i++ ) {
1526                        if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1527                                return true;
1528                        }
1529                }
1530
1531                return false;
1532        },
1533
1534        val: function( value ) {
1535                if ( !arguments.length ) {
1536                        var elem = this[0];
1537
1538                        if ( elem ) {
1539                                if ( jQuery.nodeName( elem, "option" ) ) {
1540                                        // attributes.value is undefined in Blackberry 4.7 but
1541                                        // uses .value. See #6932
1542                                        var val = elem.attributes.value;
1543                                        return !val || val.specified ? elem.value : elem.text;
1544                                }
1545
1546                                // We need to handle select boxes special
1547                                if ( jQuery.nodeName( elem, "select" ) ) {
1548                                        var index = elem.selectedIndex,
1549                                                values = [],
1550                                                options = elem.options,
1551                                                one = elem.type === "select-one";
1552
1553                                        // Nothing was selected
1554                                        if ( index < 0 ) {
1555                                                return null;
1556                                        }
1557
1558                                        // Loop through all the selected options
1559                                        for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1560                                                var option = options[ i ];
1561
1562                                                // Don't return options that are disabled or in a disabled optgroup
1563                                                if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
1564                                                                (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
1565
1566                                                        // Get the specific value for the option
1567                                                        value = jQuery(option).val();
1568
1569                                                        // We don't need an array for one selects
1570                                                        if ( one ) {
1571                                                                return value;
1572                                                        }
1573
1574                                                        // Multi-Selects return an array
1575                                                        values.push( value );
1576                                                }
1577                                        }
1578
1579                                        return values;
1580                                }
1581
1582                                // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1583                                if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1584                                        return elem.getAttribute("value") === null ? "on" : elem.value;
1585                                }
1586                               
1587
1588                                // Everything else, we just grab the value
1589                                return (elem.value || "").replace(rreturn, "");
1590
1591                        }
1592
1593                        return undefined;
1594                }
1595
1596                var isFunction = jQuery.isFunction(value);
1597
1598                return this.each(function(i) {
1599                        var self = jQuery(this), val = value;
1600
1601                        if ( this.nodeType !== 1 ) {
1602                                return;
1603                        }
1604
1605                        if ( isFunction ) {
1606                                val = value.call(this, i, self.val());
1607                        }
1608
1609                        // Treat null/undefined as ""; convert numbers to string
1610                        if ( val == null ) {
1611                                val = "";
1612                        } else if ( typeof val === "number" ) {
1613                                val += "";
1614                        } else if ( jQuery.isArray(val) ) {
1615                                val = jQuery.map(val, function (value) {
1616                                        return value == null ? "" : value + "";
1617                                });
1618                        }
1619
1620                        if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1621                                this.checked = jQuery.inArray( self.val(), val ) >= 0;
1622
1623                        } else if ( jQuery.nodeName( this, "select" ) ) {
1624                                var values = jQuery.makeArray(val);
1625
1626                                jQuery( "option", this ).each(function() {
1627                                        this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1628                                });
1629
1630                                if ( !values.length ) {
1631                                        this.selectedIndex = -1;
1632                                }
1633
1634                        } else {
1635                                this.value = val;
1636                        }
1637                });
1638        }
1639});
1640
1641jQuery.extend({
1642        attrFn: {
1643                val: true,
1644                css: true,
1645                html: true,
1646                text: true,
1647                data: true,
1648                width: true,
1649                height: true,
1650                offset: true
1651        },
1652               
1653        attr: function( elem, name, value, pass ) {
1654                // don't set attributes on text and comment nodes
1655                if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1656                        return undefined;
1657                }
1658
1659                if ( pass && name in jQuery.attrFn ) {
1660                        return jQuery(elem)[name](value);
1661                }
1662
1663                var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1664                        // Whether we are setting (or getting)
1665                        set = value !== undefined;
1666
1667                // Try to normalize/fix the name
1668                name = notxml && jQuery.props[ name ] || name;
1669
1670                // Only do all the following if this is a node (faster for style)
1671                if ( elem.nodeType === 1 ) {
1672                        // These attributes require special treatment
1673                        var special = rspecialurl.test( name );
1674
1675                        // Safari mis-reports the default selected property of an option
1676                        // Accessing the parent's selectedIndex property fixes it
1677                        if ( name === "selected" && !jQuery.support.optSelected ) {
1678                                var parent = elem.parentNode;
1679                                if ( parent ) {
1680                                        parent.selectedIndex;
1681       
1682                                        // Make sure that it also works with optgroups, see #5701
1683                                        if ( parent.parentNode ) {
1684                                                parent.parentNode.selectedIndex;
1685                                        }
1686                                }
1687                        }
1688
1689                        // If applicable, access the attribute via the DOM 0 way
1690                        // 'in' checks fail in Blackberry 4.7 #6931
1691                        if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
1692                                if ( set ) {
1693                                        // We can't allow the type property to be changed (since it causes problems in IE)
1694                                        if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1695                                                jQuery.error( "type property can't be changed" );
1696                                        }
1697
1698                                        if ( value === null ) {
1699                                                if ( elem.nodeType === 1 ) {
1700                                                        elem.removeAttribute( name );
1701                                                }
1702
1703                                        } else {
1704                                                elem[ name ] = value;
1705                                        }
1706                                }
1707
1708                                // browsers index elements by id/name on forms, give priority to attributes.
1709                                if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1710                                        return elem.getAttributeNode( name ).nodeValue;
1711                                }
1712
1713                                // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1714                                // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1715                                if ( name === "tabIndex" ) {
1716                                        var attributeNode = elem.getAttributeNode( "tabIndex" );
1717
1718                                        return attributeNode && attributeNode.specified ?
1719                                                attributeNode.value :
1720                                                rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1721                                                        0 :
1722                                                        undefined;
1723                                }
1724
1725                                return elem[ name ];
1726                        }
1727
1728                        if ( !jQuery.support.style && notxml && name === "style" ) {
1729                                if ( set ) {
1730                                        elem.style.cssText = "" + value;
1731                                }
1732
1733                                return elem.style.cssText;
1734                        }
1735
1736                        if ( set ) {
1737                                // convert the value to a string (all browsers do this but IE) see #1070
1738                                elem.setAttribute( name, "" + value );
1739                        }
1740
1741                        // Ensure that missing attributes return undefined
1742                        // Blackberry 4.7 returns "" from getAttribute #6938
1743                        if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
1744                                return undefined;
1745                        }
1746
1747                        var attr = !jQuery.support.hrefNormalized && notxml && special ?
1748                                        // Some attributes require a special call on IE
1749                                        elem.getAttribute( name, 2 ) :
1750                                        elem.getAttribute( name );
1751
1752                        // Non-existent attributes return null, we normalize to undefined
1753                        return attr === null ? undefined : attr;
1754                }
1755        }
1756});
1757
1758
1759
1760
1761var rnamespaces = /\.(.*)$/,
1762        rformElems = /^(?:textarea|input|select)$/i,
1763        rperiod = /\./g,
1764        rspace = / /g,
1765        rescape = /[^\w\s.|`]/g,
1766        fcleanup = function( nm ) {
1767                return nm.replace(rescape, "\\$&");
1768        },
1769        focusCounts = { focusin: 0, focusout: 0 };
1770
1771/*
1772 * A number of helper functions used for managing events.
1773 * Many of the ideas behind this code originated from
1774 * Dean Edwards' addEvent library.
1775 */
1776jQuery.event = {
1777
1778        // Bind an event to an element
1779        // Original by Dean Edwards
1780        add: function( elem, types, handler, data ) {
1781                if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1782                        return;
1783                }
1784
1785                // For whatever reason, IE has trouble passing the window object
1786                // around, causing it to be cloned in the process
1787                if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
1788                        elem = window;
1789                }
1790
1791                if ( handler === false ) {
1792                        handler = returnFalse;
1793                }
1794
1795                var handleObjIn, handleObj;
1796
1797                if ( handler.handler ) {
1798                        handleObjIn = handler;
1799                        handler = handleObjIn.handler;
1800                }
1801
1802                // Make sure that the function being executed has a unique ID
1803                if ( !handler.guid ) {
1804                        handler.guid = jQuery.guid++;
1805                }
1806
1807                // Init the element's event structure
1808                var elemData = jQuery.data( elem );
1809
1810                // If no elemData is found then we must be trying to bind to one of the
1811                // banned noData elements
1812                if ( !elemData ) {
1813                        return;
1814                }
1815
1816                // Use a key less likely to result in collisions for plain JS objects.
1817                // Fixes bug #7150.
1818                var eventKey = elem.nodeType ? "events" : "__events__",
1819                        events = elemData[ eventKey ],
1820                        eventHandle = elemData.handle;
1821                       
1822                if ( typeof events === "function" ) {
1823                        // On plain objects events is a fn that holds the the data
1824                        // which prevents this data from being JSON serialized
1825                        // the function does not need to be called, it just contains the data
1826                        eventHandle = events.handle;
1827                        events = events.events;
1828
1829                } else if ( !events ) {
1830                        if ( !elem.nodeType ) {
1831                                // On plain objects, create a fn that acts as the holder
1832                                // of the values to avoid JSON serialization of event data
1833                                elemData[ eventKey ] = elemData = function(){};
1834                        }
1835
1836                        elemData.events = events = {};
1837                }
1838
1839                if ( !eventHandle ) {
1840                        elemData.handle = eventHandle = function() {
1841                                // Handle the second event of a trigger and when
1842                                // an event is called after a page has unloaded
1843                                return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
1844                                        jQuery.event.handle.apply( eventHandle.elem, arguments ) :
1845                                        undefined;
1846                        };
1847                }
1848
1849                // Add elem as a property of the handle function
1850                // This is to prevent a memory leak with non-native events in IE.
1851                eventHandle.elem = elem;
1852
1853                // Handle multiple events separated by a space
1854                // jQuery(...).bind("mouseover mouseout", fn);
1855                types = types.split(" ");
1856
1857                var type, i = 0, namespaces;
1858
1859                while ( (type = types[ i++ ]) ) {
1860                        handleObj = handleObjIn ?
1861                                jQuery.extend({}, handleObjIn) :
1862                                { handler: handler, data: data };
1863
1864                        // Namespaced event handlers
1865                        if ( type.indexOf(".") > -1 ) {
1866                                namespaces = type.split(".");
1867                                type = namespaces.shift();
1868                                handleObj.namespace = namespaces.slice(0).sort().join(".");
1869
1870                        } else {
1871                                namespaces = [];
1872                                handleObj.namespace = "";
1873                        }
1874
1875                        handleObj.type = type;
1876                        if ( !handleObj.guid ) {
1877                                handleObj.guid = handler.guid;
1878                        }
1879
1880                        // Get the current list of functions bound to this event
1881                        var handlers = events[ type ],
1882                                special = jQuery.event.special[ type ] || {};
1883
1884                        // Init the event handler queue
1885                        if ( !handlers ) {
1886                                handlers = events[ type ] = [];
1887
1888                                // Check for a special event handler
1889                                // Only use addEventListener/attachEvent if the special
1890                                // events handler returns false
1891                                if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
1892                                        // Bind the global event handler to the element
1893                                        if ( elem.addEventListener ) {
1894                                                elem.addEventListener( type, eventHandle, false );
1895
1896                                        } else if ( elem.attachEvent ) {
1897                                                elem.attachEvent( "on" + type, eventHandle );
1898                                        }
1899                                }
1900                        }
1901                       
1902                        if ( special.add ) {
1903                                special.add.call( elem, handleObj );
1904
1905                                if ( !handleObj.handler.guid ) {
1906                                        handleObj.handler.guid = handler.guid;
1907                                }
1908                        }
1909
1910                        // Add the function to the element's handler list
1911                        handlers.push( handleObj );
1912
1913                        // Keep track of which events have been used, for global triggering
1914                        jQuery.event.global[ type ] = true;
1915                }
1916
1917                // Nullify elem to prevent memory leaks in IE
1918                elem = null;
1919        },
1920
1921        global: {},
1922
1923        // Detach an event or set of events from an element
1924        remove: function( elem, types, handler, pos ) {
1925                // don't do events on text and comment nodes
1926                if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1927                        return;
1928                }
1929
1930                if ( handler === false ) {
1931                        handler = returnFalse;
1932                }
1933
1934                var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
1935                        eventKey = elem.nodeType ? "events" : "__events__",
1936                        elemData = jQuery.data( elem ),
1937                        events = elemData && elemData[ eventKey ];
1938
1939                if ( !elemData || !events ) {
1940                        return;
1941                }
1942               
1943                if ( typeof events === "function" ) {
1944                        elemData = events;
1945                        events = events.events;
1946                }
1947
1948                // types is actually an event object here
1949                if ( types && types.type ) {
1950                        handler = types.handler;
1951                        types = types.type;
1952                }
1953
1954                // Unbind all events for the element
1955                if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
1956                        types = types || "";
1957
1958                        for ( type in events ) {
1959                                jQuery.event.remove( elem, type + types );
1960                        }
1961
1962                        return;
1963                }
1964
1965                // Handle multiple events separated by a space
1966                // jQuery(...).unbind("mouseover mouseout", fn);
1967                types = types.split(" ");
1968
1969                while ( (type = types[ i++ ]) ) {
1970                        origType = type;
1971                        handleObj = null;
1972                        all = type.indexOf(".") < 0;
1973                        namespaces = [];
1974
1975                        if ( !all ) {
1976                                // Namespaced event handlers
1977                                namespaces = type.split(".");
1978                                type = namespaces.shift();
1979
1980                                namespace = new RegExp("(^|\\.)" +
1981                                        jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
1982                        }
1983
1984                        eventType = events[ type ];
1985
1986                        if ( !eventType ) {
1987                                continue;
1988                        }
1989
1990                        if ( !handler ) {
1991                                for ( j = 0; j < eventType.length; j++ ) {
1992                                        handleObj = eventType[ j ];
1993
1994                                        if ( all || namespace.test( handleObj.namespace ) ) {
1995                                                jQuery.event.remove( elem, origType, handleObj.handler, j );
1996                                                eventType.splice( j--, 1 );
1997                                        }
1998                                }
1999
2000                                continue;
2001                        }
2002
2003                        special = jQuery.event.special[ type ] || {};
2004
2005                        for ( j = pos || 0; j < eventType.length; j++ ) {
2006                                handleObj = eventType[ j ];
2007
2008                                if ( handler.guid === handleObj.guid ) {
2009                                        // remove the given handler for the given type
2010                                        if ( all || namespace.test( handleObj.namespace ) ) {
2011                                                if ( pos == null ) {
2012                                                        eventType.splice( j--, 1 );
2013                                                }
2014
2015                                                if ( special.remove ) {
2016                                                        special.remove.call( elem, handleObj );
2017                                                }
2018                                        }
2019
2020                                        if ( pos != null ) {
2021                                                break;
2022                                        }
2023                                }
2024                        }
2025
2026                        // remove generic event handler if no more handlers exist
2027                        if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2028                                if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2029                                        jQuery.removeEvent( elem, type, elemData.handle );
2030                                }
2031
2032                                ret = null;
2033                                delete events[ type ];
2034                        }
2035                }
2036
2037                // Remove the expando if it's no longer used
2038                if ( jQuery.isEmptyObject( events ) ) {
2039                        var handle = elemData.handle;
2040                        if ( handle ) {
2041                                handle.elem = null;
2042                        }
2043
2044                        delete elemData.events;
2045                        delete elemData.handle;
2046
2047                        if ( typeof elemData === "function" ) {
2048                                jQuery.removeData( elem, eventKey );
2049
2050                        } else if ( jQuery.isEmptyObject( elemData ) ) {
2051                                jQuery.removeData( elem );
2052                        }
2053                }
2054        },
2055
2056        // bubbling is internal
2057        trigger: function( event, data, elem /*, bubbling */ ) {
2058                // Event object or event type
2059                var type = event.type || event,
2060                        bubbling = arguments[3];
2061
2062                if ( !bubbling ) {
2063                        event = typeof event === "object" ?
2064                                // jQuery.Event object
2065                                event[ jQuery.expando ] ? event :
2066                                // Object literal
2067                                jQuery.extend( jQuery.Event(type), event ) :
2068                                // Just the event type (string)
2069                                jQuery.Event(type);
2070
2071                        if ( type.indexOf("!") >= 0 ) {
2072                                event.type = type = type.slice(0, -1);
2073                                event.exclusive = true;
2074                        }
2075
2076                        // Handle a global trigger
2077                        if ( !elem ) {
2078                                // Don't bubble custom events when global (to avoid too much overhead)
2079                                event.stopPropagation();
2080
2081                                // Only trigger if we've ever bound an event for it
2082                                if ( jQuery.event.global[ type ] ) {
2083                                        jQuery.each( jQuery.cache, function() {
2084                                                if ( this.events && this.events[type] ) {
2085                                                        jQuery.event.trigger( event, data, this.handle.elem );
2086                                                }
2087                                        });
2088                                }
2089                        }
2090
2091                        // Handle triggering a single element
2092
2093                        // don't do events on text and comment nodes
2094                        if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
2095                                return undefined;
2096                        }
2097
2098                        // Clean up in case it is reused
2099                        event.result = undefined;
2100                        event.target = elem;
2101
2102                        // Clone the incoming data, if any
2103                        data = jQuery.makeArray( data );
2104                        data.unshift( event );
2105                }
2106
2107                event.currentTarget = elem;
2108
2109                // Trigger the event, it is assumed that "handle" is a function
2110                var handle = elem.nodeType ?
2111                        jQuery.data( elem, "handle" ) :
2112                        (jQuery.data( elem, "__events__" ) || {}).handle;
2113
2114                if ( handle ) {
2115                        handle.apply( elem, data );
2116                }
2117
2118                var parent = elem.parentNode || elem.ownerDocument;
2119
2120                // Trigger an inline bound script
2121                try {
2122                        if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
2123                                if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
2124                                        event.result = false;
2125                                        event.preventDefault();
2126                                }
2127                        }
2128
2129                // prevent IE from throwing an error for some elements with some event types, see #3533
2130                } catch (inlineError) {}
2131
2132                if ( !event.isPropagationStopped() && parent ) {
2133                        jQuery.event.trigger( event, data, parent, true );
2134
2135                } else if ( !event.isDefaultPrevented() ) {
2136                        var target = event.target, old, targetType = type.replace(rnamespaces, ""),
2137                                isClick = jQuery.nodeName(target, "a") && targetType === "click",
2138                                special = jQuery.event.special[ targetType ] || {};
2139
2140                        if ( (!special._default || special._default.call( elem, event ) === false) &&
2141                                !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
2142
2143                                try {
2144                                        if ( target[ targetType ] ) {
2145                                                // Make sure that we don't accidentally re-trigger the onFOO events
2146                                                old = target[ "on" + targetType ];
2147
2148                                                if ( old ) {
2149                                                        target[ "on" + targetType ] = null;
2150                                                }
2151
2152                                                jQuery.event.triggered = true;
2153                                                target[ targetType ]();
2154                                        }
2155
2156                                // prevent IE from throwing an error for some elements with some event types, see #3533
2157                                } catch (triggerError) {}
2158
2159                                if ( old ) {
2160                                        target[ "on" + targetType ] = old;
2161                                }
2162
2163                                jQuery.event.triggered = false;
2164                        }
2165                }
2166        },
2167
2168        handle: function( event ) {
2169                var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
2170
2171                event = args[0] = jQuery.event.fix( event || window.event );
2172                event.currentTarget = this;
2173
2174                // Namespaced event handlers
2175                all = event.type.indexOf(".") < 0 && !event.exclusive;
2176
2177                if ( !all ) {
2178                        namespaces = event.type.split(".");
2179                        event.type = namespaces.shift();
2180                        namespace_sort = namespaces.slice(0).sort();
2181                        namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
2182                }
2183
2184                event.namespace = event.namespace || namespace_sort.join(".");
2185
2186                events = jQuery.data(this, this.nodeType ? "events" : "__events__");
2187
2188                if ( typeof events === "function" ) {
2189                        events = events.events;
2190                }
2191
2192                handlers = (events || {})[ event.type ];
2193
2194                if ( events && handlers ) {
2195                        // Clone the handlers to prevent manipulation
2196                        handlers = handlers.slice(0);
2197
2198                        for ( var j = 0, l = handlers.length; j < l; j++ ) {
2199                                var handleObj = handlers[ j ];
2200
2201                                // Filter the functions by class
2202                                if ( all || namespace_re.test( handleObj.namespace ) ) {
2203                                        // Pass in a reference to the handler function itself
2204                                        // So that we can later remove it
2205                                        event.handler = handleObj.handler;
2206                                        event.data = handleObj.data;
2207                                        event.handleObj = handleObj;
2208       
2209                                        var ret = handleObj.handler.apply( this, args );
2210
2211                                        if ( ret !== undefined ) {
2212                                                event.result = ret;
2213                                                if ( ret === false ) {
2214                                                        event.preventDefault();
2215                                                        event.stopPropagation();
2216                                                }
2217                                        }
2218
2219                                        if ( event.isImmediatePropagationStopped() ) {
2220                                                break;
2221                                        }
2222                                }
2223                        }
2224                }
2225
2226                return event.result;
2227        },
2228
2229        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(" "),
2230
2231        fix: function( event ) {
2232                if ( event[ jQuery.expando ] ) {
2233                        return event;
2234                }
2235
2236                // store a copy of the original event object
2237                // and "clone" to set read-only properties
2238                var originalEvent = event;
2239                event = jQuery.Event( originalEvent );
2240
2241                for ( var i = this.props.length, prop; i; ) {
2242                        prop = this.props[ --i ];
2243                        event[ prop ] = originalEvent[ prop ];
2244                }
2245
2246                // Fix target property, if necessary
2247                if ( !event.target ) {
2248                        event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2249                }
2250
2251                // check if target is a textnode (safari)
2252                if ( event.target.nodeType === 3 ) {
2253                        event.target = event.target.parentNode;
2254                }
2255
2256                // Add relatedTarget, if necessary
2257                if ( !event.relatedTarget && event.fromElement ) {
2258                        event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2259                }
2260
2261                // Calculate pageX/Y if missing and clientX/Y available
2262                if ( event.pageX == null && event.clientX != null ) {
2263                        var doc = document.documentElement, body = document.body;
2264                        event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2265                        event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
2266                }
2267
2268                // Add which for key events
2269                if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2270                        event.which = event.charCode != null ? event.charCode : event.keyCode;
2271                }
2272
2273                // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2274                if ( !event.metaKey && event.ctrlKey ) {
2275                        event.metaKey = event.ctrlKey;
2276                }
2277
2278                // Add which for click: 1 === left; 2 === middle; 3 === right
2279                // Note: button is not normalized, so don't use it
2280                if ( !event.which && event.button !== undefined ) {
2281                        event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2282                }
2283
2284                return event;
2285        },
2286
2287        // Deprecated, use jQuery.guid instead
2288        guid: 1E8,
2289
2290        // Deprecated, use jQuery.proxy instead
2291        proxy: jQuery.proxy,
2292
2293        special: {
2294                ready: {
2295                        // Make sure the ready event is setup
2296                        setup: jQuery.bindReady,
2297                        teardown: jQuery.noop
2298                },
2299
2300                live: {
2301                        add: function( handleObj ) {
2302                                jQuery.event.add( this,
2303                                        liveConvert( handleObj.origType, handleObj.selector ),
2304                                        jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
2305                        },
2306
2307                        remove: function( handleObj ) {
2308                                jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
2309                        }
2310                },
2311
2312                beforeunload: {
2313                        setup: function( data, namespaces, eventHandle ) {
2314                                // We only want to do this special case on windows
2315                                if ( jQuery.isWindow( this ) ) {
2316                                        this.onbeforeunload = eventHandle;
2317                                }
2318                        },
2319
2320                        teardown: function( namespaces, eventHandle ) {
2321                                if ( this.onbeforeunload === eventHandle ) {
2322                                        this.onbeforeunload = null;
2323                                }
2324                        }
2325                }
2326        }
2327};
2328
2329jQuery.removeEvent = document.removeEventListener ?
2330        function( elem, type, handle ) {
2331                if ( elem.removeEventListener ) {
2332                        elem.removeEventListener( type, handle, false );
2333                }
2334        } :
2335        function( elem, type, handle ) {
2336                if ( elem.detachEvent ) {
2337                        elem.detachEvent( "on" + type, handle );
2338                }
2339        };
2340
2341jQuery.Event = function( src ) {
2342        // Allow instantiation without the 'new' keyword
2343        if ( !this.preventDefault ) {
2344                return new jQuery.Event( src );
2345        }
2346
2347        // Event object
2348        if ( src && src.type ) {
2349                this.originalEvent = src;
2350                this.type = src.type;
2351        // Event type
2352        } else {
2353                this.type = src;
2354        }
2355
2356        // timeStamp is buggy for some events on Firefox(#3843)
2357        // So we won't rely on the native value
2358        this.timeStamp = jQuery.now();
2359
2360        // Mark it as fixed
2361        this[ jQuery.expando ] = true;
2362};
2363
2364function returnFalse() {
2365        return false;
2366}
2367function returnTrue() {
2368        return true;
2369}
2370
2371// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2372// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2373jQuery.Event.prototype = {
2374        preventDefault: function() {
2375                this.isDefaultPrevented = returnTrue;
2376
2377                var e = this.originalEvent;
2378                if ( !e ) {
2379                        return;
2380                }
2381               
2382                // if preventDefault exists run it on the original event
2383                if ( e.preventDefault ) {
2384                        e.preventDefault();
2385
2386                // otherwise set the returnValue property of the original event to false (IE)
2387                } else {
2388                        e.returnValue = false;
2389                }
2390        },
2391        stopPropagation: function() {
2392                this.isPropagationStopped = returnTrue;
2393
2394                var e = this.originalEvent;
2395                if ( !e ) {
2396                        return;
2397                }
2398                // if stopPropagation exists run it on the original event
2399                if ( e.stopPropagation ) {
2400                        e.stopPropagation();
2401                }
2402                // otherwise set the cancelBubble property of the original event to true (IE)
2403                e.cancelBubble = true;
2404        },
2405        stopImmediatePropagation: function() {
2406                this.isImmediatePropagationStopped = returnTrue;
2407                this.stopPropagation();
2408        },
2409        isDefaultPrevented: returnFalse,
2410        isPropagationStopped: returnFalse,
2411        isImmediatePropagationStopped: returnFalse
2412};
2413
2414// Checks if an event happened on an element within another element
2415// Used in jQuery.event.special.mouseenter and mouseleave handlers
2416var withinElement = function( event ) {
2417        // Check if mouse(over|out) are still within the same parent element
2418        var parent = event.relatedTarget;
2419
2420        // Firefox sometimes assigns relatedTarget a XUL element
2421        // which we cannot access the parentNode property of
2422        try {
2423                // Traverse up the tree
2424                while ( parent && parent !== this ) {
2425                        parent = parent.parentNode;
2426                }
2427
2428                if ( parent !== this ) {
2429                        // set the correct event type
2430                        event.type = event.data;
2431
2432                        // handle event if we actually just moused on to a non sub-element
2433                        jQuery.event.handle.apply( this, arguments );
2434                }
2435
2436        // assuming we've left the element since we most likely mousedover a xul element
2437        } catch(e) { }
2438},
2439
2440// In case of event delegation, we only need to rename the event.type,
2441// liveHandler will take care of the rest.
2442delegate = function( event ) {
2443        event.type = event.data;
2444        jQuery.event.handle.apply( this, arguments );
2445};
2446
2447// Create mouseenter and mouseleave events
2448jQuery.each({
2449        mouseenter: "mouseover",
2450        mouseleave: "mouseout"
2451}, function( orig, fix ) {
2452        jQuery.event.special[ orig ] = {
2453                setup: function( data ) {
2454                        jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2455                },
2456                teardown: function( data ) {
2457                        jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2458                }
2459        };
2460});
2461
2462// submit delegation
2463if ( !jQuery.support.submitBubbles ) {
2464
2465        jQuery.event.special.submit = {
2466                setup: function( data, namespaces ) {
2467                        if ( this.nodeName.toLowerCase() !== "form" ) {
2468                                jQuery.event.add(this, "click.specialSubmit", function( e ) {
2469                                        var elem = e.target, type = elem.type;
2470
2471                                        if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2472                                                e.liveFired = undefined;
2473                                                return trigger( "submit", this, arguments );
2474                                        }
2475                                });
2476         
2477                                jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
2478                                        var elem = e.target, type = elem.type;
2479
2480                                        if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2481                                                e.liveFired = undefined;
2482                                                return trigger( "submit", this, arguments );
2483                                        }
2484                                });
2485
2486                        } else {
2487                                return false;
2488                        }
2489                },
2490
2491                teardown: function( namespaces ) {
2492                        jQuery.event.remove( this, ".specialSubmit" );
2493                }
2494        };
2495
2496}
2497
2498// change delegation, happens here so we have bind.
2499if ( !jQuery.support.changeBubbles ) {
2500
2501        var changeFilters,
2502
2503        getVal = function( elem ) {
2504                var type = elem.type, val = elem.value;
2505
2506                if ( type === "radio" || type === "checkbox" ) {
2507                        val = elem.checked;
2508
2509                } else if ( type === "select-multiple" ) {
2510                        val = elem.selectedIndex > -1 ?
2511                                jQuery.map( elem.options, function( elem ) {
2512                                        return elem.selected;
2513                                }).join("-") :
2514                                "";
2515
2516                } else if ( elem.nodeName.toLowerCase() === "select" ) {
2517                        val = elem.selectedIndex;
2518                }
2519
2520                return val;
2521        },
2522
2523        testChange = function testChange( e ) {
2524                var elem = e.target, data, val;
2525
2526                if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
2527                        return;
2528                }
2529
2530                data = jQuery.data( elem, "_change_data" );
2531                val = getVal(elem);
2532
2533                // the current data will be also retrieved by beforeactivate
2534                if ( e.type !== "focusout" || elem.type !== "radio" ) {
2535                        jQuery.data( elem, "_change_data", val );
2536                }
2537               
2538                if ( data === undefined || val === data ) {
2539                        return;
2540                }
2541
2542                if ( data != null || val ) {
2543                        e.type = "change";
2544                        e.liveFired = undefined;
2545                        return jQuery.event.trigger( e, arguments[1], elem );
2546                }
2547        };
2548
2549        jQuery.event.special.change = {
2550                filters: {
2551                        focusout: testChange,
2552
2553                        beforedeactivate: testChange,
2554
2555                        click: function( e ) {
2556                                var elem = e.target, type = elem.type;
2557
2558                                if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2559                                        return testChange.call( this, e );
2560                                }
2561                        },
2562
2563                        // Change has to be called before submit
2564                        // Keydown will be called before keypress, which is used in submit-event delegation
2565                        keydown: function( e ) {
2566                                var elem = e.target, type = elem.type;
2567
2568                                if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2569                                        (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2570                                        type === "select-multiple" ) {
2571                                        return testChange.call( this, e );
2572                                }
2573                        },
2574
2575                        // Beforeactivate happens also before the previous element is blurred
2576                        // with this event you can't trigger a change event, but you can store
2577                        // information
2578                        beforeactivate: function( e ) {
2579                                var elem = e.target;
2580                                jQuery.data( elem, "_change_data", getVal(elem) );
2581                        }
2582                },
2583
2584                setup: function( data, namespaces ) {
2585                        if ( this.type === "file" ) {
2586                                return false;
2587                        }
2588
2589                        for ( var type in changeFilters ) {
2590                                jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
2591                        }
2592
2593                        return rformElems.test( this.nodeName );
2594                },
2595
2596                teardown: function( namespaces ) {
2597                        jQuery.event.remove( this, ".specialChange" );
2598
2599                        return rformElems.test( this.nodeName );
2600                }
2601        };
2602
2603        changeFilters = jQuery.event.special.change.filters;
2604
2605        // Handle when the input is .focus()'d
2606        changeFilters.focus = changeFilters.beforeactivate;
2607}
2608
2609function trigger( type, elem, args ) {
2610        args[0].type = type;
2611        return jQuery.event.handle.apply( elem, args );
2612}
2613
2614// Create "bubbling" focus and blur events
2615if ( document.addEventListener ) {
2616        jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2617                jQuery.event.special[ fix ] = {
2618                        setup: function() {
2619                                if ( focusCounts[fix]++ === 0 ) {
2620                                        document.addEventListener( orig, handler, true );
2621                                }
2622                        },
2623                        teardown: function() {
2624                                if ( --focusCounts[fix] === 0 ) {
2625                                        document.removeEventListener( orig, handler, true );
2626                                }
2627                        }
2628                };
2629
2630                function handler( e ) {
2631                        e = jQuery.event.fix( e );
2632                        e.type = fix;
2633                        return jQuery.event.trigger( e, null, e.target );
2634                }
2635        });
2636}
2637
2638jQuery.each(["bind", "one"], function( i, name ) {
2639        jQuery.fn[ name ] = function( type, data, fn ) {
2640                // Handle object literals
2641                if ( typeof type === "object" ) {
2642                        for ( var key in type ) {
2643                                this[ name ](key, data, type[key], fn);
2644                        }
2645                        return this;
2646                }
2647               
2648                if ( jQuery.isFunction( data ) || data === false ) {
2649                        fn = data;
2650                        data = undefined;
2651                }
2652
2653                var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2654                        jQuery( this ).unbind( event, handler );
2655                        return fn.apply( this, arguments );
2656                }) : fn;
2657
2658                if ( type === "unload" && name !== "one" ) {
2659                        this.one( type, data, fn );
2660
2661                } else {
2662                        for ( var i = 0, l = this.length; i < l; i++ ) {
2663                                jQuery.event.add( this[i], type, handler, data );
2664                        }
2665                }
2666
2667                return this;
2668        };
2669});
2670
2671jQuery.fn.extend({
2672        unbind: function( type, fn ) {
2673                // Handle object literals
2674                if ( typeof type === "object" && !type.preventDefault ) {
2675                        for ( var key in type ) {
2676                                this.unbind(key, type[key]);
2677                        }
2678
2679                } else {
2680                        for ( var i = 0, l = this.length; i < l; i++ ) {
2681                                jQuery.event.remove( this[i], type, fn );
2682                        }
2683                }
2684
2685                return this;
2686        },
2687       
2688        delegate: function( selector, types, data, fn ) {
2689                return this.live( types, data, fn, selector );
2690        },
2691       
2692        undelegate: function( selector, types, fn ) {
2693                if ( arguments.length === 0 ) {
2694                                return this.unbind( "live" );
2695               
2696                } else {
2697                        return this.die( types, null, fn, selector );
2698                }
2699        },
2700       
2701        trigger: function( type, data ) {
2702                return this.each(function() {
2703                        jQuery.event.trigger( type, data, this );
2704                });
2705        },
2706
2707        triggerHandler: function( type, data ) {
2708                if ( this[0] ) {
2709                        var event = jQuery.Event( type );
2710                        event.preventDefault();
2711                        event.stopPropagation();
2712                        jQuery.event.trigger( event, data, this[0] );
2713                        return event.result;
2714                }
2715        },
2716
2717        toggle: function( fn ) {
2718                // Save reference to arguments for access in closure
2719                var args = arguments, i = 1;
2720
2721                // link all the functions, so any of them can unbind this click handler
2722                while ( i < args.length ) {
2723                        jQuery.proxy( fn, args[ i++ ] );
2724                }
2725
2726                return this.click( jQuery.proxy( fn, function( event ) {
2727                        // Figure out which function to execute
2728                        var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2729                        jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2730
2731                        // Make sure that clicks stop
2732                        event.preventDefault();
2733
2734                        // and execute the function
2735                        return args[ lastToggle ].apply( this, arguments ) || false;
2736                }));
2737        },
2738
2739        hover: function( fnOver, fnOut ) {
2740                return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2741        }
2742});
2743
2744var liveMap = {
2745        focus: "focusin",
2746        blur: "focusout",
2747        mouseenter: "mouseover",
2748        mouseleave: "mouseout"
2749};
2750
2751jQuery.each(["live", "die"], function( i, name ) {
2752        jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
2753                var type, i = 0, match, namespaces, preType,
2754                        selector = origSelector || this.selector,
2755                        context = origSelector ? this : jQuery( this.context );
2756               
2757                if ( typeof types === "object" && !types.preventDefault ) {
2758                        for ( var key in types ) {
2759                                context[ name ]( key, data, types[key], selector );
2760                        }
2761                       
2762                        return this;
2763                }
2764
2765                if ( jQuery.isFunction( data ) ) {
2766                        fn = data;
2767                        data = undefined;
2768                }
2769
2770                types = (types || "").split(" ");
2771
2772                while ( (type = types[ i++ ]) != null ) {
2773                        match = rnamespaces.exec( type );
2774                        namespaces = "";
2775
2776                        if ( match )  {
2777                                namespaces = match[0];
2778                                type = type.replace( rnamespaces, "" );
2779                        }
2780
2781                        if ( type === "hover" ) {
2782                                types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
2783                                continue;
2784                        }
2785
2786                        preType = type;
2787
2788                        if ( type === "focus" || type === "blur" ) {
2789                                types.push( liveMap[ type ] + namespaces );
2790                                type = type + namespaces;
2791
2792                        } else {
2793                                type = (liveMap[ type ] || type) + namespaces;
2794                        }
2795
2796                        if ( name === "live" ) {
2797                                // bind live handler
2798                                for ( var j = 0, l = context.length; j < l; j++ ) {
2799                                        jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
2800                                                { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
2801                                }
2802
2803                        } else {
2804                                // unbind live handler
2805                                context.unbind( "live." + liveConvert( type, selector ), fn );
2806                        }
2807                }
2808               
2809                return this;
2810        };
2811});
2812
2813function liveHandler( event ) {
2814        var stop, maxLevel, elems = [], selectors = [],
2815                related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
2816                events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
2817
2818        if ( typeof events === "function" ) {
2819                events = events.events;
2820        }
2821
2822        // Make sure we avoid non-left-click bubbling in Firefox (#3861)
2823        if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
2824                return;
2825        }
2826
2827        if ( event.namespace ) {
2828                namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
2829        }
2830
2831        event.liveFired = this;
2832
2833        var live = events.live.slice(0);
2834
2835        for ( j = 0; j < live.length; j++ ) {
2836                handleObj = live[j];
2837
2838                if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
2839                        selectors.push( handleObj.selector );
2840
2841                } else {
2842                        live.splice( j--, 1 );
2843                }
2844        }
2845
2846        match = jQuery( event.target ).closest( selectors, event.currentTarget );
2847
2848        for ( i = 0, l = match.length; i < l; i++ ) {
2849                close = match[i];
2850
2851                for ( j = 0; j < live.length; j++ ) {
2852                        handleObj = live[j];
2853
2854                        if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
2855                                elem = close.elem;
2856                                related = null;
2857
2858                                // Those two events require additional checking
2859                                if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
2860                                        event.type = handleObj.preType;
2861                                        related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
2862                                }
2863
2864                                if ( !related || related !== elem ) {
2865                                        elems.push({ elem: elem, handleObj: handleObj, level: close.level });
2866                                }
2867                        }
2868                }
2869        }
2870
2871        for ( i = 0, l = elems.length; i < l; i++ ) {
2872                match = elems[i];
2873
2874                if ( maxLevel && match.level > maxLevel ) {
2875                        break;
2876                }
2877
2878                event.currentTarget = match.elem;
2879                event.data = match.handleObj.data;
2880                event.handleObj = match.handleObj;
2881
2882                ret = match.handleObj.origHandler.apply( match.elem, arguments );
2883
2884                if ( ret === false || event.isPropagationStopped() ) {
2885                        maxLevel = match.level;
2886
2887                        if ( ret === false ) {
2888                                stop = false;
2889                        }
2890                }
2891        }
2892
2893        return stop;
2894}
2895
2896function liveConvert( type, selector ) {
2897        return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
2898}
2899
2900jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
2901        "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
2902        "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
2903
2904        // Handle event binding
2905        jQuery.fn[ name ] = function( data, fn ) {
2906                if ( fn == null ) {
2907                        fn = data;
2908                        data = null;
2909                }
2910
2911                return arguments.length > 0 ?
2912                        this.bind( name, data, fn ) :
2913                        this.trigger( name );
2914        };
2915
2916        if ( jQuery.attrFn ) {
2917                jQuery.attrFn[ name ] = true;
2918        }
2919});
2920
2921// Prevent memory leaks in IE
2922// Window isn't included so as not to unbind existing unload events
2923// More info:
2924//  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2925if ( window.attachEvent && !window.addEventListener ) {
2926        jQuery(window).bind("unload", function() {
2927                for ( var id in jQuery.cache ) {
2928                        if ( jQuery.cache[ id ].handle ) {
2929                                // Try/Catch is to handle iframes being unloaded, see #4280
2930                                try {
2931                                        jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2932                                } catch(e) {}
2933                        }
2934                }
2935        });
2936}
2937
2938
2939/*!
2940 * Sizzle CSS Selector Engine - v1.0
2941 *  Copyright 2009, The Dojo Foundation
2942 *  Released under the MIT, BSD, and GPL Licenses.
2943 *  More information: http://sizzlejs.com/
2944 */
2945(function(){
2946
2947var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
2948        done = 0,
2949        toString = Object.prototype.toString,
2950        hasDuplicate = false,
2951        baseHasDuplicate = true;
2952
2953// Here we check if the JavaScript engine is using some sort of
2954// optimization where it does not always call our comparision
2955// function. If that is the case, discard the hasDuplicate value.
2956//   Thus far that includes Google Chrome.
2957[0, 0].sort(function(){
2958        baseHasDuplicate = false;
2959        return 0;
2960});
2961
2962var Sizzle = function(selector, context, results, seed) {
2963        results = results || [];
2964        context = context || document;
2965
2966        var origContext = context;
2967
2968        if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
2969                return [];
2970        }
2971       
2972        if ( !selector || typeof selector !== "string" ) {
2973                return results;
2974        }
2975
2976        var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context),
2977                soFar = selector, ret, cur, pop, i;
2978       
2979        // Reset the position of the chunker regexp (start from head)
2980        do {
2981                chunker.exec("");
2982                m = chunker.exec(soFar);
2983
2984                if ( m ) {
2985                        soFar = m[3];
2986               
2987                        parts.push( m[1] );
2988               
2989                        if ( m[2] ) {
2990                                extra = m[3];
2991                                break;
2992                        }
2993                }
2994        } while ( m );
2995
2996        if ( parts.length > 1 && origPOS.exec( selector ) ) {
2997                if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
2998                        set = posProcess( parts[0] + parts[1], context );
2999                } else {
3000                        set = Expr.relative[ parts[0] ] ?
3001                                [ context ] :
3002                                Sizzle( parts.shift(), context );
3003
3004                        while ( parts.length ) {
3005                                selector = parts.shift();
3006
3007                                if ( Expr.relative[ selector ] ) {
3008                                        selector += parts.shift();
3009                                }
3010                               
3011                                set = posProcess( selector, set );
3012                        }
3013                }
3014        } else {
3015                // Take a shortcut and set the context if the root selector is an ID
3016                // (but not if it'll be faster if the inner selector is an ID)
3017                if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3018                                Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3019                        ret = Sizzle.find( parts.shift(), context, contextXML );
3020                        context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
3021                }
3022
3023                if ( context ) {
3024                        ret = seed ?
3025                                { expr: parts.pop(), set: makeArray(seed) } :
3026                                Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3027                        set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
3028
3029                        if ( parts.length > 0 ) {
3030                                checkSet = makeArray(set);
3031                        } else {
3032                                prune = false;
3033                        }
3034
3035                        while ( parts.length ) {
3036                                cur = parts.pop();
3037                                pop = cur;
3038
3039                                if ( !Expr.relative[ cur ] ) {
3040                                        cur = "";
3041                                } else {
3042                                        pop = parts.pop();
3043                                }
3044
3045                                if ( pop == null ) {
3046                                        pop = context;
3047                                }
3048
3049                                Expr.relative[ cur ]( checkSet, pop, contextXML );
3050                        }
3051                } else {
3052                        checkSet = parts = [];
3053                }
3054        }
3055
3056        if ( !checkSet ) {
3057                checkSet = set;
3058        }
3059
3060        if ( !checkSet ) {
3061                Sizzle.error( cur || selector );
3062        }
3063
3064        if ( toString.call(checkSet) === "[object Array]" ) {
3065                if ( !prune ) {
3066                        results.push.apply( results, checkSet );
3067                } else if ( context && context.nodeType === 1 ) {
3068                        for ( i = 0; checkSet[i] != null; i++ ) {
3069                                if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3070                                        results.push( set[i] );
3071                                }
3072                        }
3073                } else {
3074                        for ( i = 0; checkSet[i] != null; i++ ) {
3075                                if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3076                                        results.push( set[i] );
3077                                }
3078                        }
3079                }
3080        } else {
3081                makeArray( checkSet, results );
3082        }
3083
3084        if ( extra ) {
3085                Sizzle( extra, origContext, results, seed );
3086                Sizzle.uniqueSort( results );
3087        }
3088
3089        return results;
3090};
3091
3092Sizzle.uniqueSort = function(results){
3093        if ( sortOrder ) {
3094                hasDuplicate = baseHasDuplicate;
3095                results.sort(sortOrder);
3096
3097                if ( hasDuplicate ) {
3098                        for ( var i = 1; i < results.length; i++ ) {
3099                                if ( results[i] === results[i-1] ) {
3100                                        results.splice(i--, 1);
3101                                }
3102                        }
3103                }
3104        }
3105
3106        return results;
3107};
3108
3109Sizzle.matches = function(expr, set){
3110        return Sizzle(expr, null, null, set);
3111};
3112
3113Sizzle.matchesSelector = function(node, expr){
3114        return Sizzle(expr, null, null, [node]).length > 0;
3115};
3116
3117Sizzle.find = function(expr, context, isXML){
3118        var set;
3119
3120        if ( !expr ) {
3121                return [];
3122        }
3123
3124        for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3125                var type = Expr.order[i], match;
3126               
3127                if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3128                        var left = match[1];
3129                        match.splice(1,1);
3130
3131                        if ( left.substr( left.length - 1 ) !== "\\" ) {
3132                                match[1] = (match[1] || "").replace(/\\/g, "");
3133                                set = Expr.find[ type ]( match, context, isXML );
3134                                if ( set != null ) {
3135                                        expr = expr.replace( Expr.match[ type ], "" );
3136                                        break;
3137                                }
3138                        }
3139                }
3140        }
3141
3142        if ( !set ) {
3143                set = context.getElementsByTagName("*");
3144        }
3145
3146        return {set: set, expr: expr};
3147};
3148
3149Sizzle.filter = function(expr, set, inplace, not){
3150        var old = expr, result = [], curLoop = set, match, anyFound,
3151                isXMLFilter = set && set[0] && Sizzle.isXML(set[0]);
3152
3153        while ( expr && set.length ) {
3154                for ( var type in Expr.filter ) {
3155                        if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3156                                var filter = Expr.filter[ type ], found, item, left = match[1];
3157                                anyFound = false;
3158
3159                                match.splice(1,1);
3160
3161                                if ( left.substr( left.length - 1 ) === "\\" ) {
3162                                        continue;
3163                                }
3164
3165                                if ( curLoop === result ) {
3166                                        result = [];
3167                                }
3168
3169                                if ( Expr.preFilter[ type ] ) {
3170                                        match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3171
3172                                        if ( !match ) {
3173                                                anyFound = found = true;
3174                                        } else if ( match === true ) {
3175                                                continue;
3176                                        }
3177                                }
3178
3179                                if ( match ) {
3180                                        for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3181                                                if ( item ) {
3182                                                        found = filter( item, match, i, curLoop );
3183                                                        var pass = not ^ !!found;
3184
3185                                                        if ( inplace && found != null ) {
3186                                                                if ( pass ) {
3187                                                                        anyFound = true;
3188                                                                } else {
3189                                                                        curLoop[i] = false;
3190                                                                }
3191                                                        } else if ( pass ) {
3192                                                                result.push( item );
3193                                                                anyFound = true;
3194                                                        }
3195                                                }
3196                                        }
3197                                }
3198
3199                                if ( found !== undefined ) {
3200                                        if ( !inplace ) {
3201                                                curLoop = result;
3202                                        }
3203
3204                                        expr = expr.replace( Expr.match[ type ], "" );
3205
3206                                        if ( !anyFound ) {
3207                                                return [];
3208                                        }
3209
3210                                        break;
3211                                }
3212                        }
3213                }
3214
3215                // Improper expression
3216                if ( expr === old ) {
3217                        if ( anyFound == null ) {
3218                                Sizzle.error( expr );
3219                        } else {
3220                                break;
3221                        }
3222                }
3223
3224                old = expr;
3225        }
3226
3227        return curLoop;
3228};
3229
3230Sizzle.error = function( msg ) {
3231        throw "Syntax error, unrecognized expression: " + msg;
3232};
3233
3234var Expr = Sizzle.selectors = {
3235        order: [ "ID", "NAME", "TAG" ],
3236        match: {
3237                ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3238                CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3239                NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
3240                ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
3241                TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
3242                CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
3243                POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
3244                PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
3245        },
3246        leftMatch: {},
3247        attrMap: {
3248                "class": "className",
3249                "for": "htmlFor"
3250        },
3251        attrHandle: {
3252                href: function(elem){
3253                        return elem.getAttribute("href");
3254                }
3255        },
3256        relative: {
3257                "+": function(checkSet, part){
3258                        var isPartStr = typeof part === "string",
3259                                isTag = isPartStr && !/\W/.test(part),
3260                                isPartStrNotTag = isPartStr && !isTag;
3261
3262                        if ( isTag ) {
3263                                part = part.toLowerCase();
3264                        }
3265
3266                        for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
3267                                if ( (elem = checkSet[i]) ) {
3268                                        while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
3269
3270                                        checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
3271                                                elem || false :
3272                                                elem === part;
3273                                }
3274                        }
3275
3276                        if ( isPartStrNotTag ) {
3277                                Sizzle.filter( part, checkSet, true );
3278                        }
3279                },
3280                ">": function(checkSet, part){
3281                        var isPartStr = typeof part === "string",
3282                                elem, i = 0, l = checkSet.length;
3283
3284                        if ( isPartStr && !/\W/.test(part) ) {
3285                                part = part.toLowerCase();
3286
3287                                for ( ; i < l; i++ ) {
3288                                        elem = checkSet[i];
3289                                        if ( elem ) {
3290                                                var parent = elem.parentNode;
3291                                                checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
3292                                        }
3293                                }
3294                        } else {
3295                                for ( ; i < l; i++ ) {
3296                                        elem = checkSet[i];
3297                                        if ( elem ) {
3298                                                checkSet[i] = isPartStr ?
3299                                                        elem.parentNode :
3300                                                        elem.parentNode === part;
3301                                        }
3302                                }
3303
3304                                if ( isPartStr ) {
3305                                        Sizzle.filter( part, checkSet, true );
3306                                }
3307                        }
3308                },
3309                "": function(checkSet, part, isXML){
3310                        var doneName = done++, checkFn = dirCheck, nodeCheck;
3311
3312                        if ( typeof part === "string" && !/\W/.test(part) ) {
3313                                part = part.toLowerCase();
3314                                nodeCheck = part;
3315                                checkFn = dirNodeCheck;
3316                        }
3317
3318                        checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
3319                },
3320                "~": function(checkSet, part, isXML){
3321                        var doneName = done++, checkFn = dirCheck, nodeCheck;
3322
3323                        if ( typeof part === "string" && !/\W/.test(part) ) {
3324                                part = part.toLowerCase();
3325                                nodeCheck = part;
3326                                checkFn = dirNodeCheck;
3327                        }
3328
3329                        checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
3330                }
3331        },
3332        find: {
3333                ID: function(match, context, isXML){
3334                        if ( typeof context.getElementById !== "undefined" && !isXML ) {
3335                                var m = context.getElementById(match[1]);
3336                                // Check parentNode to catch when Blackberry 4.6 returns
3337                                // nodes that are no longer in the document #6963
3338                                return m && m.parentNode ? [m] : [];
3339                        }
3340                },
3341                NAME: function(match, context){
3342                        if ( typeof context.getElementsByName !== "undefined" ) {
3343                                var ret = [], results = context.getElementsByName(match[1]);
3344
3345                                for ( var i = 0, l = results.length; i < l; i++ ) {
3346                                        if ( results[i].getAttribute("name") === match[1] ) {
3347                                                ret.push( results[i] );
3348                                        }
3349                                }
3350
3351                                return ret.length === 0 ? null : ret;
3352                        }
3353                },
3354                TAG: function(match, context){
3355                        return context.getElementsByTagName(match[1]);
3356                }
3357        },
3358        preFilter: {
3359                CLASS: function(match, curLoop, inplace, result, not, isXML){
3360                        match = " " + match[1].replace(/\\/g, "") + " ";
3361
3362                        if ( isXML ) {
3363                                return match;
3364                        }
3365
3366                        for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
3367                                if ( elem ) {
3368                                        if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
3369                                                if ( !inplace ) {
3370                                                        result.push( elem );
3371                                                }
3372                                        } else if ( inplace ) {
3373                                                curLoop[i] = false;
3374                                        }
3375                                }
3376                        }
3377
3378                        return false;
3379                },
3380                ID: function(match){
3381                        return match[1].replace(/\\/g, "");
3382                },
3383                TAG: function(match, curLoop){
3384                        return match[1].toLowerCase();
3385                },
3386                CHILD: function(match){
3387                        if ( match[1] === "nth" ) {
3388                                // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
3389                                var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
3390                                        match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
3391                                        !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
3392
3393                                // calculate the numbers (first)n+(last) including if they are negative
3394                                match[2] = (test[1] + (test[2] || 1)) - 0;
3395                                match[3] = test[3] - 0;
3396                        }
3397
3398                        // TODO: Move to normal caching system
3399                        match[0] = done++;
3400
3401                        return match;
3402                },
3403                ATTR: function(match, curLoop, inplace, result, not, isXML){
3404                        var name = match[1].replace(/\\/g, "");
3405                       
3406                        if ( !isXML && Expr.attrMap[name] ) {
3407                                match[1] = Expr.attrMap[name];
3408                        }
3409
3410                        if ( match[2] === "~=" ) {
3411                                match[4] = " " + match[4] + " ";
3412                        }
3413
3414                        return match;
3415                },
3416                PSEUDO: function(match, curLoop, inplace, result, not){
3417                        if ( match[1] === "not" ) {
3418                                // If we're dealing with a complex expression, or a simple one
3419                                if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
3420                                        match[3] = Sizzle(match[3], null, null, curLoop);
3421                                } else {
3422                                        var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
3423                                        if ( !inplace ) {
3424                                                result.push.apply( result, ret );
3425                                        }
3426                                        return false;
3427                                }
3428                        } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
3429                                return true;
3430                        }
3431                       
3432                        return match;
3433                },
3434                POS: function(match){
3435                        match.unshift( true );
3436                        return match;
3437                }
3438        },
3439        filters: {
3440                enabled: function(elem){
3441                        return elem.disabled === false && elem.type !== "hidden";
3442                },
3443                disabled: function(elem){
3444                        return elem.disabled === true;
3445                },
3446                checked: function(elem){
3447                        return elem.checked === true;
3448                },
3449                selected: function(elem){
3450                        // Accessing this property makes selected-by-default
3451                        // options in Safari work properly
3452                        elem.parentNode.selectedIndex;
3453                        return elem.selected === true;
3454                },
3455                parent: function(elem){
3456                        return !!elem.firstChild;
3457                },
3458                empty: function(elem){
3459                        return !elem.firstChild;
3460                },
3461                has: function(elem, i, match){
3462                        return !!Sizzle( match[3], elem ).length;
3463                },
3464                header: function(elem){
3465                        return (/h\d/i).test( elem.nodeName );
3466                },
3467                text: function(elem){
3468                        return "text" === elem.type;
3469                },
3470                radio: function(elem){
3471                        return "radio" === elem.type;
3472                },
3473                checkbox: function(elem){
3474                        return "checkbox" === elem.type;
3475                },
3476                file: function(elem){
3477                        return "file" === elem.type;
3478                },
3479                password: function(elem){
3480                        return "password" === elem.type;
3481                },
3482                submit: function(elem){
3483                        return "submit" === elem.type;
3484                },
3485                image: function(elem){
3486                        return "image" === elem.type;
3487                },
3488                reset: function(elem){
3489                        return "reset" === elem.type;
3490                },
3491                button: function(elem){
3492                        return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
3493                },
3494                input: function(elem){
3495                        return (/input|select|textarea|button/i).test(elem.nodeName);
3496                }
3497        },
3498        setFilters: {
3499                first: function(elem, i){
3500                        return i === 0;
3501                },
3502                last: function(elem, i, match, array){
3503                        return i === array.length - 1;
3504                },
3505                even: function(elem, i){
3506                        return i % 2 === 0;
3507                },
3508                odd: function(elem, i){
3509                        return i % 2 === 1;
3510                },
3511                lt: function(elem, i, match){
3512                        return i < match[3] - 0;
3513                },
3514                gt: function(elem, i, match){
3515                        return i > match[3] - 0;
3516                },
3517                nth: function(elem, i, match){
3518                        return match[3] - 0 === i;
3519                },
3520                eq: function(elem, i, match){
3521                        return match[3] - 0 === i;
3522                }
3523        },
3524        filter: {
3525                PSEUDO: function(elem, match, i, array){
3526                        var name = match[1], filter = Expr.filters[ name ];
3527
3528                        if ( filter ) {
3529                                return filter( elem, i, match, array );
3530                        } else if ( name === "contains" ) {
3531                                return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
3532                        } else if ( name === "not" ) {
3533                                var not = match[3];
3534
3535                                for ( var j = 0, l = not.length; j < l; j++ ) {
3536                                        if ( not[j] === elem ) {
3537                                                return false;
3538                                        }
3539                                }
3540
3541                                return true;
3542                        } else {
3543                                Sizzle.error( "Syntax error, unrecognized expression: " + name );
3544                        }
3545                },
3546                CHILD: function(elem, match){
3547                        var type = match[1], node = elem;
3548                        switch (type) {
3549                                case 'only':
3550                                case 'first':
3551                                        while ( (node = node.previousSibling) )  {
3552                                                if ( node.nodeType === 1 ) {
3553                                                        return false;
3554                                                }
3555                                        }
3556                                        if ( type === "first" ) {
3557                                                return true;
3558                                        }
3559                                        node = elem;
3560                                case 'last':
3561                                        while ( (node = node.nextSibling) )      {
3562                                                if ( node.nodeType === 1 ) {
3563                                                        return false;
3564                                                }
3565                                        }
3566                                        return true;
3567                                case 'nth':
3568                                        var first = match[2], last = match[3];
3569
3570                                        if ( first === 1 && last === 0 ) {
3571                                                return true;
3572                                        }
3573                                       
3574                                        var doneName = match[0],
3575                                                parent = elem.parentNode;
3576       
3577                                        if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3578                                                var count = 0;
3579                                                for ( node = parent.firstChild; node; node = node.nextSibling ) {
3580                                                        if ( node.nodeType === 1 ) {
3581                                                                node.nodeIndex = ++count;
3582                                                        }
3583                                                }
3584                                                parent.sizcache = doneName;
3585                                        }
3586                                       
3587                                        var diff = elem.nodeIndex - last;
3588                                        if ( first === 0 ) {
3589                                                return diff === 0;
3590                                        } else {
3591                                                return ( diff % first === 0 && diff / first >= 0 );
3592                                        }
3593                        }
3594                },
3595                ID: function(elem, match){
3596                        return elem.nodeType === 1 && elem.getAttribute("id") === match;
3597                },
3598                TAG: function(elem, match){
3599                        return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3600                },
3601                CLASS: function(elem, match){
3602                        return (" " + (elem.className || elem.getAttribute("class")) + " ")
3603                                .indexOf( match ) > -1;
3604                },
3605                ATTR: function(elem, match){
3606                        var name = match[1],
3607                                result = Expr.attrHandle[ name ] ?
3608                                        Expr.attrHandle[ name ]( elem ) :
3609                                        elem[ name ] != null ?
3610                                                elem[ name ] :
3611                                                elem.getAttribute( name ),
3612                                value = result + "",
3613                                type = match[2],
3614                                check = match[4];
3615
3616                        return result == null ?
3617                                type === "!=" :
3618                                type === "=" ?
3619                                value === check :
3620                                type === "*=" ?
3621                                value.indexOf(check) >= 0 :
3622                                type === "~=" ?
3623                                (" " + value + " ").indexOf(check) >= 0 :
3624                                !check ?
3625                                value && result !== false :
3626                                type === "!=" ?
3627                                value !== check :
3628                                type === "^=" ?
3629                                value.indexOf(check) === 0 :
3630                                type === "$=" ?
3631                                value.substr(value.length - check.length) === check :
3632                                type === "|=" ?
3633                                value === check || value.substr(0, check.length + 1) === check + "-" :
3634                                false;
3635                },
3636                POS: function(elem, match, i, array){
3637                        var name = match[2], filter = Expr.setFilters[ name ];
3638
3639                        if ( filter ) {
3640                                return filter( elem, i, match, array );
3641                        }
3642                }
3643        }
3644};
3645
3646var origPOS = Expr.match.POS,
3647        fescape = function(all, num){
3648                return "\\" + (num - 0 + 1);
3649        };
3650
3651for ( var type in Expr.match ) {
3652        Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
3653        Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
3654}
3655
3656var makeArray = function(array, results) {
3657        array = Array.prototype.slice.call( array, 0 );
3658
3659        if ( results ) {
3660                results.push.apply( results, array );
3661                return results;
3662        }
3663       
3664        return array;
3665};
3666
3667// Perform a simple check to determine if the browser is capable of
3668// converting a NodeList to an array using builtin methods.
3669// Also verifies that the returned array holds DOM nodes
3670// (which is not the case in the Blackberry browser)
3671try {
3672        Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
3673
3674// Provide a fallback method if it does not work
3675} catch(e){
3676        makeArray = function(array, results) {
3677                var ret = results || [], i = 0;
3678
3679                if ( toString.call(array) === "[object Array]" ) {
3680                        Array.prototype.push.apply( ret, array );
3681                } else {
3682                        if ( typeof array.length === "number" ) {
3683                                for ( var l = array.length; i < l; i++ ) {
3684                                        ret.push( array[i] );
3685                                }
3686                        } else {
3687                                for ( ; array[i]; i++ ) {
3688                                        ret.push( array[i] );
3689                                }
3690                        }
3691                }
3692
3693                return ret;
3694        };
3695}
3696
3697var sortOrder, siblingCheck;
3698
3699if ( document.documentElement.compareDocumentPosition ) {
3700        sortOrder = function( a, b ) {
3701                if ( a === b ) {
3702                        hasDuplicate = true;
3703                        return 0;
3704                }
3705
3706                if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
3707                        return a.compareDocumentPosition ? -1 : 1;
3708                }
3709
3710                return a.compareDocumentPosition(b) & 4 ? -1 : 1;
3711        };
3712} else {
3713        sortOrder = function( a, b ) {
3714                var ap = [], bp = [], aup = a.parentNode, bup = b.parentNode,
3715                        cur = aup, al, bl;
3716
3717                // The nodes are identical, we can exit early
3718                if ( a === b ) {
3719                        hasDuplicate = true;
3720                        return 0;
3721
3722                // If the nodes are siblings (or identical) we can do a quick check
3723                } else if ( aup === bup ) {
3724                        return siblingCheck( a, b );
3725
3726                // If no parents were found then the nodes are disconnected
3727                } else if ( !aup ) {
3728                        return -1;
3729
3730                } else if ( !bup ) {
3731                        return 1;
3732                }
3733
3734                // Otherwise they're somewhere else in the tree so we need
3735                // to build up a full list of the parentNodes for comparison
3736                while ( cur ) {
3737                        ap.unshift( cur );
3738                        cur = cur.parentNode;
3739                }
3740
3741                cur = bup;
3742
3743                while ( cur ) {
3744                        bp.unshift( cur );
3745                        cur = cur.parentNode;
3746                }
3747
3748                al = ap.length;
3749                bl = bp.length;
3750
3751                // Start walking down the tree looking for a discrepancy
3752                for ( var i = 0; i < al && i < bl; i++ ) {
3753                        if ( ap[i] !== bp[i] ) {
3754                                return siblingCheck( ap[i], bp[i] );
3755                        }
3756                }
3757
3758                // We ended someplace up the tree so do a sibling check
3759                return i === al ?
3760                        siblingCheck( a, bp[i], -1 ) :
3761                        siblingCheck( ap[i], b, 1 );
3762        };
3763
3764        siblingCheck = function( a, b, ret ) {
3765                if ( a === b ) {
3766                        return ret;
3767                }
3768
3769                var cur = a.nextSibling;
3770
3771                while ( cur ) {
3772                        if ( cur === b ) {
3773                                return -1;
3774                        }
3775
3776                        cur = cur.nextSibling;
3777                }
3778
3779                return 1;
3780        };
3781}
3782
3783// Utility function for retreiving the text value of an array of DOM nodes
3784Sizzle.getText = function( elems ) {
3785        var ret = "", elem;
3786
3787        for ( var i = 0; elems[i]; i++ ) {
3788                elem = elems[i];
3789
3790                // Get the text from text nodes and CDATA nodes
3791                if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
3792                        ret += elem.nodeValue;
3793
3794                // Traverse everything else, except comment nodes
3795                } else if ( elem.nodeType !== 8 ) {
3796                        ret += Sizzle.getText( elem.childNodes );
3797                }
3798        }
3799
3800        return ret;
3801};
3802
3803// Check to see if the browser returns elements by name when
3804// querying by getElementById (and provide a workaround)
3805(function(){
3806        // We're going to inject a fake input element with a specified name
3807        var form = document.createElement("div"),
3808                id = "script" + (new Date()).getTime();
3809        form.innerHTML = "<a name='" + id + "'/>";
3810
3811        // Inject it into the root element, check its status, and remove it quickly
3812        var root = document.documentElement;
3813        root.insertBefore( form, root.firstChild );
3814
3815        // The workaround has to do additional checks after a getElementById
3816        // Which slows things down for other browsers (hence the branching)
3817        if ( document.getElementById( id ) ) {
3818                Expr.find.ID = function(match, context, isXML){
3819                        if ( typeof context.getElementById !== "undefined" && !isXML ) {
3820                                var m = context.getElementById(match[1]);
3821                                return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
3822                        }
3823                };
3824
3825                Expr.filter.ID = function(elem, match){
3826                        var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
3827                        return elem.nodeType === 1 && node && node.nodeValue === match;
3828                };
3829        }
3830
3831        root.removeChild( form );
3832        root = form = null; // release memory in IE
3833})();
3834
3835(function(){
3836        // Check to see if the browser returns only elements
3837        // when doing getElementsByTagName("*")
3838
3839        // Create a fake element
3840        var div = document.createElement("div");
3841        div.appendChild( document.createComment("") );
3842
3843        // Make sure no comments are found
3844        if ( div.getElementsByTagName("*").length > 0 ) {
3845                Expr.find.TAG = function(match, context){
3846                        var results = context.getElementsByTagName(match[1]);
3847
3848                        // Filter out possible comments
3849                        if ( match[1] === "*" ) {
3850                                var tmp = [];
3851
3852                                for ( var i = 0; results[i]; i++ ) {
3853                                        if ( results[i].nodeType === 1 ) {
3854                                                tmp.push( results[i] );
3855                                        }
3856                                }
3857
3858                                results = tmp;
3859                        }
3860
3861                        return results;
3862                };
3863        }
3864
3865        // Check to see if an attribute returns normalized href attributes
3866        div.innerHTML = "<a href='#'></a>";
3867        if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
3868                        div.firstChild.getAttribute("href") !== "#" ) {
3869                Expr.attrHandle.href = function(elem){
3870                        return elem.getAttribute("href", 2);
3871                };
3872        }
3873
3874        div = null; // release memory in IE
3875})();
3876
3877if ( document.querySelectorAll ) {
3878        (function(){
3879                var oldSizzle = Sizzle, div = document.createElement("div");
3880                div.innerHTML = "<p class='TEST'></p>";
3881
3882                // Safari can't handle uppercase or unicode characters when
3883                // in quirks mode.
3884                if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
3885                        return;
3886                }
3887       
3888                Sizzle = function(query, context, extra, seed){
3889                        context = context || document;
3890
3891                        // Only use querySelectorAll on non-XML documents
3892                        // (ID selectors don't work in non-HTML documents)
3893                        if ( !seed && !Sizzle.isXML(context) ) {
3894                                if ( context.nodeType === 9 ) {
3895                                        try {
3896                                                return makeArray( context.querySelectorAll(query), extra );
3897                                        } catch(qsaError) {}
3898
3899                                // qSA works strangely on Element-rooted queries
3900                                // We can work around this by specifying an extra ID on the root
3901                                // and working up from there (Thanks to Andrew Dupont for the technique)
3902                                // IE 8 doesn't work on object elements
3903                                } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
3904                                        var old = context.id, id = context.id = "__sizzle__";
3905
3906                                        try {
3907                                                return makeArray( context.querySelectorAll( "#" + id + " " + query ), extra );
3908
3909                                        } catch(pseudoError) {
3910                                        } finally {
3911                                                if ( old ) {
3912                                                        context.id = old;
3913
3914                                                } else {
3915                                                        context.removeAttribute( "id" );
3916                                                }
3917                                        }
3918                                }
3919                        }
3920               
3921                        return oldSizzle(query, context, extra, seed);
3922                };
3923
3924                for ( var prop in oldSizzle ) {
3925                        Sizzle[ prop ] = oldSizzle[ prop ];
3926                }
3927
3928                div = null; // release memory in IE
3929        })();
3930}
3931
3932(function(){
3933        var html = document.documentElement,
3934                matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
3935                pseudoWorks = false;
3936
3937        try {
3938                // This should fail with an exception
3939                // Gecko does not error, returns false instead
3940                matches.call( document.documentElement, ":sizzle" );
3941       
3942        } catch( pseudoError ) {
3943                pseudoWorks = true;
3944        }
3945
3946        if ( matches ) {
3947                Sizzle.matchesSelector = function( node, expr ) {
3948                                try {
3949                                        if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) ) {
3950                                                return matches.call( node, expr );
3951                                        }
3952                                } catch(e) {}
3953
3954                                return Sizzle(expr, null, null, [node]).length > 0;
3955                };
3956        }
3957})();
3958
3959(function(){
3960        var div = document.createElement("div");
3961
3962        div.innerHTML = "<div class='test e'></div><div class='test'></div>";
3963
3964        // Opera can't find a second classname (in 9.6)
3965        // Also, make sure that getElementsByClassName actually exists
3966        if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
3967                return;
3968        }
3969
3970        // Safari caches class attributes, doesn't catch changes (in 3.2)
3971        div.lastChild.className = "e";
3972
3973        if ( div.getElementsByClassName("e").length === 1 ) {
3974                return;
3975        }
3976       
3977        Expr.order.splice(1, 0, "CLASS");
3978        Expr.find.CLASS = function(match, context, isXML) {
3979                if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
3980                        return context.getElementsByClassName(match[1]);
3981                }
3982        };
3983
3984        div = null; // release memory in IE
3985})();
3986
3987function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
3988        for ( var i = 0, l = checkSet.length; i < l; i++ ) {
3989                var elem = checkSet[i];
3990                if ( elem ) {
3991                        elem = elem[dir];
3992                        var match = false;
3993
3994                        while ( elem ) {
3995                                if ( elem.sizcache === doneName ) {
3996                                        match = checkSet[elem.sizset];
3997                                        break;
3998                                }
3999
4000                                if ( elem.nodeType === 1 && !isXML ){
4001                                        elem.sizcache = doneName;
4002                                        elem.sizset = i;
4003                                }
4004
4005                                if ( elem.nodeName.toLowerCase() === cur ) {
4006                                        match = elem;
4007                                        break;
4008                                }
4009
4010                                elem = elem[dir];
4011                        }
4012
4013                        checkSet[i] = match;
4014                }
4015        }
4016}
4017
4018function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4019        for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4020                var elem = checkSet[i];
4021                if ( elem ) {
4022                        elem = elem[dir];
4023                        var match = false;
4024
4025                        while ( elem ) {
4026                                if ( elem.sizcache === doneName ) {
4027                                        match = checkSet[elem.sizset];
4028                                        break;
4029                                }
4030
4031                                if ( elem.nodeType === 1 ) {
4032                                        if ( !isXML ) {
4033                                                elem.sizcache = doneName;
4034                                                elem.sizset = i;
4035                                        }
4036                                        if ( typeof cur !== "string" ) {
4037                                                if ( elem === cur ) {
4038                                                        match = true;
4039                                                        break;
4040                                                }
4041
4042                                        } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4043                                                match = elem;
4044                                                break;
4045                                        }
4046                                }
4047
4048                                elem = elem[dir];
4049                        }
4050
4051                        checkSet[i] = match;
4052                }
4053        }
4054}
4055
4056Sizzle.contains = document.documentElement.contains ? function(a, b){
4057        return a !== b && (a.contains ? a.contains(b) : true);
4058} : function(a, b){
4059        return !!(a.compareDocumentPosition(b) & 16);
4060};
4061
4062Sizzle.isXML = function(elem){
4063        // documentElement is verified for cases where it doesn't yet exist
4064        // (such as loading iframes in IE - #4833)
4065        var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
4066        return documentElement ? documentElement.nodeName !== "HTML" : false;
4067};
4068
4069var posProcess = function(selector, context){
4070        var tmpSet = [], later = "", match,
4071                root = context.nodeType ? [context] : context;
4072
4073        // Position selectors must be done after the filter
4074        // And so must :not(positional) so we move all PSEUDOs to the end
4075        while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4076                later += match[0];
4077                selector = selector.replace( Expr.match.PSEUDO, "" );
4078        }
4079
4080        selector = Expr.relative[selector] ? selector + "*" : selector;
4081
4082        for ( var i = 0, l = root.length; i < l; i++ ) {
4083                Sizzle( selector, root[i], tmpSet );
4084        }
4085
4086        return Sizzle.filter( later, tmpSet );
4087};
4088
4089// EXPOSE
4090jQuery.find = Sizzle;
4091jQuery.expr = Sizzle.selectors;
4092jQuery.expr[":"] = jQuery.expr.filters;
4093jQuery.unique = Sizzle.uniqueSort;
4094jQuery.text = Sizzle.getText;
4095jQuery.isXMLDoc = Sizzle.isXML;
4096jQuery.contains = Sizzle.contains;
4097
4098
4099})();
4100
4101
4102var runtil = /Until$/,
4103        rparentsprev = /^(?:parents|prevUntil|prevAll)/,
4104        // Note: This RegExp should be improved, or likely pulled from Sizzle
4105        rmultiselector = /,/,
4106        isSimple = /^.[^:#\[\.,]*$/,
4107        slice = Array.prototype.slice,
4108        POS = jQuery.expr.match.POS;
4109
4110jQuery.fn.extend({
4111        find: function( selector ) {
4112                var ret = this.pushStack( "", "find", selector ), length = 0;
4113
4114                for ( var i = 0, l = this.length; i < l; i++ ) {
4115                        length = ret.length;
4116                        jQuery.find( selector, this[i], ret );
4117
4118                        if ( i > 0 ) {
4119                                // Make sure that the results are unique
4120                                for ( var n = length; n < ret.length; n++ ) {
4121                                        for ( var r = 0; r < length; r++ ) {
4122                                                if ( ret[r] === ret[n] ) {
4123                                                        ret.splice(n--, 1);
4124                                                        break;
4125                                                }
4126                                        }
4127                                }
4128                        }
4129                }
4130
4131                return ret;
4132        },
4133
4134        has: function( target ) {
4135                var targets = jQuery( target );
4136                return this.filter(function() {
4137                        for ( var i = 0, l = targets.length; i < l; i++ ) {
4138                                if ( jQuery.contains( this, targets[i] ) ) {
4139                                        return true;
4140                                }
4141                        }
4142                });
4143        },
4144
4145        not: function( selector ) {
4146                return this.pushStack( winnow(this, selector, false), "not", selector);
4147        },
4148
4149        filter: function( selector ) {
4150                return this.pushStack( winnow(this, selector, true), "filter", selector );
4151        },
4152       
4153        is: function( selector ) {
4154                return !!selector && jQuery.filter( selector, this ).length > 0;
4155        },
4156
4157        closest: function( selectors, context ) {
4158                var ret = [], i, l, cur = this[0];
4159
4160                if ( jQuery.isArray( selectors ) ) {
4161                        var match, matches = {}, selector, level = 1;
4162
4163                        if ( cur && selectors.length ) {
4164                                for ( i = 0, l = selectors.length; i < l; i++ ) {
4165                                        selector = selectors[i];
4166
4167                                        if ( !matches[selector] ) {
4168                                                matches[selector] = jQuery.expr.match.POS.test( selector ) ?
4169                                                        jQuery( selector, context || this.context ) :
4170                                                        selector;
4171                                        }
4172                                }
4173
4174                                while ( cur && cur.ownerDocument && cur !== context ) {
4175                                        for ( selector in matches ) {
4176                                                match = matches[selector];
4177
4178                                                if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
4179                                                        ret.push({ selector: selector, elem: cur, level: level });
4180                                                }
4181                                        }
4182
4183                                        cur = cur.parentNode;
4184                                        level++;
4185                                }
4186                        }
4187
4188                        return ret;
4189                }
4190
4191                var pos = POS.test( selectors ) ?
4192                        jQuery( selectors, context || this.context ) : null;
4193
4194                for ( i = 0, l = this.length; i < l; i++ ) {
4195                        cur = this[i];
4196
4197                        while ( cur ) {
4198                                if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
4199                                        ret.push( cur );
4200                                        break;
4201
4202                                } else {
4203                                        cur = cur.parentNode;
4204                                        if ( !cur || !cur.ownerDocument || cur === context ) {
4205                                                break;
4206                                        }
4207                                }
4208                        }
4209                }
4210
4211                ret = ret.length > 1 ? jQuery.unique(ret) : ret;
4212               
4213                return this.pushStack( ret, "closest", selectors );
4214        },
4215       
4216        // Determine the position of an element within
4217        // the matched set of elements
4218        index: function( elem ) {
4219                if ( !elem || typeof elem === "string" ) {
4220                        return jQuery.inArray( this[0],
4221                                // If it receives a string, the selector is used
4222                                // If it receives nothing, the siblings are used
4223                                elem ? jQuery( elem ) : this.parent().children() );
4224                }
4225                // Locate the position of the desired element
4226                return jQuery.inArray(
4227                        // If it receives a jQuery object, the first element is used
4228                        elem.jquery ? elem[0] : elem, this );
4229        },
4230
4231        add: function( selector, context ) {
4232                var set = typeof selector === "string" ?
4233                                jQuery( selector, context || this.context ) :
4234                                jQuery.makeArray( selector ),
4235                        all = jQuery.merge( this.get(), set );
4236
4237                return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
4238                        all :
4239                        jQuery.unique( all ) );
4240        },
4241
4242        andSelf: function() {
4243                return this.add( this.prevObject );
4244        }
4245});
4246
4247// A painfully simple check to see if an element is disconnected
4248// from a document (should be improved, where feasible).
4249function isDisconnected( node ) {
4250        return !node || !node.parentNode || node.parentNode.nodeType === 11;
4251}
4252
4253jQuery.each({
4254        parent: function( elem ) {
4255                var parent = elem.parentNode;
4256                return parent && parent.nodeType !== 11 ? parent : null;
4257        },
4258        parents: function( elem ) {
4259                return jQuery.dir( elem, "parentNode" );
4260        },
4261        parentsUntil: function( elem, i, until ) {
4262                return jQuery.dir( elem, "parentNode", until );
4263        },
4264        next: function( elem ) {
4265                return jQuery.nth( elem, 2, "nextSibling" );
4266        },
4267        prev: function( elem ) {
4268                return jQuery.nth( elem, 2, "previousSibling" );
4269        },
4270        nextAll: function( elem ) {
4271                return jQuery.dir( elem, "nextSibling" );
4272        },
4273        prevAll: function( elem ) {
4274                return jQuery.dir( elem, "previousSibling" );
4275        },
4276        nextUntil: function( elem, i, until ) {
4277                return jQuery.dir( elem, "nextSibling", until );
4278        },
4279        prevUntil: function( elem, i, until ) {
4280                return jQuery.dir( elem, "previousSibling", until );
4281        },
4282        siblings: function( elem ) {
4283                return jQuery.sibling( elem.parentNode.firstChild, elem );
4284        },
4285        children: function( elem ) {
4286                return jQuery.sibling( elem.firstChild );
4287        },
4288        contents: function( elem ) {
4289                return jQuery.nodeName( elem, "iframe" ) ?
4290                        elem.contentDocument || elem.contentWindow.document :
4291                        jQuery.makeArray( elem.childNodes );
4292        }
4293}, function( name, fn ) {
4294        jQuery.fn[ name ] = function( until, selector ) {
4295                var ret = jQuery.map( this, fn, until );
4296               
4297                if ( !runtil.test( name ) ) {
4298                        selector = until;
4299                }
4300
4301                if ( selector && typeof selector === "string" ) {
4302                        ret = jQuery.filter( selector, ret );
4303                }
4304
4305                ret = this.length > 1 ? jQuery.unique( ret ) : ret;
4306
4307                if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
4308                        ret = ret.reverse();
4309                }
4310
4311                return this.pushStack( ret, name, slice.call(arguments).join(",") );
4312        };
4313});
4314
4315jQuery.extend({
4316        filter: function( expr, elems, not ) {
4317                if ( not ) {
4318                        expr = ":not(" + expr + ")";
4319                }
4320
4321                return elems.length === 1 ?
4322                        jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
4323                        jQuery.find.matches(expr, elems);
4324        },
4325       
4326        dir: function( elem, dir, until ) {
4327                var matched = [], cur = elem[dir];
4328                while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
4329                        if ( cur.nodeType === 1 ) {
4330                                matched.push( cur );
4331                        }
4332                        cur = cur[dir];
4333                }
4334                return matched;
4335        },
4336
4337        nth: function( cur, result, dir, elem ) {
4338                result = result || 1;
4339                var num = 0;
4340
4341                for ( ; cur; cur = cur[dir] ) {
4342                        if ( cur.nodeType === 1 && ++num === result ) {
4343                                break;
4344                        }
4345                }
4346
4347                return cur;
4348        },
4349
4350        sibling: function( n, elem ) {
4351                var r = [];
4352
4353                for ( ; n; n = n.nextSibling ) {
4354                        if ( n.nodeType === 1 && n !== elem ) {
4355                                r.push( n );
4356                        }
4357                }
4358
4359                return r;
4360        }
4361});
4362
4363// Implement the identical functionality for filter and not
4364function winnow( elements, qualifier, keep ) {
4365        if ( jQuery.isFunction( qualifier ) ) {
4366                return jQuery.grep(elements, function( elem, i ) {
4367                        var retVal = !!qualifier.call( elem, i, elem );
4368                        return retVal === keep;
4369                });
4370
4371        } else if ( qualifier.nodeType ) {
4372                return jQuery.grep(elements, function( elem, i ) {
4373                        return (elem === qualifier) === keep;
4374                });
4375
4376        } else if ( typeof qualifier === "string" ) {
4377                var filtered = jQuery.grep(elements, function( elem ) {
4378                        return elem.nodeType === 1;
4379                });
4380
4381                if ( isSimple.test( qualifier ) ) {
4382                        return jQuery.filter(qualifier, filtered, !keep);
4383                } else {
4384                        qualifier = jQuery.filter( qualifier, filtered );
4385                }
4386        }
4387
4388        return jQuery.grep(elements, function( elem, i ) {
4389                return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
4390        });
4391}
4392
4393
4394
4395
4396var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
4397        rleadingWhitespace = /^\s+/,
4398        rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
4399        rtagName = /<([\w:]+)/,
4400        rtbody = /<tbody/i,
4401        rhtml = /<|&#?\w+;/,
4402        rnocache = /<(?:script|object|embed|option|style)/i,
4403        rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,  // checked="checked" or checked (html5)
4404        raction = /\=([^="'>\s]+\/)>/g,
4405        wrapMap = {
4406                option: [ 1, "<select multiple='multiple'>", "</select>" ],
4407                legend: [ 1, "<fieldset>", "</fieldset>" ],
4408                thead: [ 1, "<table>", "</table>" ],
4409                tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4410                td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4411                col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4412                area: [ 1, "<map>", "</map>" ],
4413                _default: [ 0, "", "" ]
4414        };
4415
4416wrapMap.optgroup = wrapMap.option;
4417wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4418wrapMap.th = wrapMap.td;
4419
4420// IE can't serialize <link> and <script> tags normally
4421if ( !jQuery.support.htmlSerialize ) {
4422        wrapMap._default = [ 1, "div<div>", "</div>" ];
4423}
4424
4425jQuery.fn.extend({
4426        text: function( text ) {
4427                if ( jQuery.isFunction(text) ) {
4428                        return this.each(function(i) {
4429                                var self = jQuery(this);
4430                                self.text( text.call(this, i, self.text()) );
4431                        });
4432                }
4433
4434                if ( typeof text !== "object" && text !== undefined ) {
4435                        return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
4436                }
4437
4438                return jQuery.text( this );
4439        },
4440
4441        wrapAll: function( html ) {
4442                if ( jQuery.isFunction( html ) ) {
4443                        return this.each(function(i) {
4444                                jQuery(this).wrapAll( html.call(this, i) );
4445                        });
4446                }
4447
4448                if ( this[0] ) {
4449                        // The elements to wrap the target around
4450                        var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
4451
4452                        if ( this[0].parentNode ) {
4453                                wrap.insertBefore( this[0] );
4454                        }
4455
4456                        wrap.map(function() {
4457                                var elem = this;
4458
4459                                while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
4460                                        elem = elem.firstChild;
4461                                }
4462
4463                                return elem;
4464                        }).append(this);
4465                }
4466
4467                return this;
4468        },
4469
4470        wrapInner: function( html ) {
4471                if ( jQuery.isFunction( html ) ) {
4472                        return this.each(function(i) {
4473                                jQuery(this).wrapInner( html.call(this, i) );
4474                        });
4475                }
4476
4477                return this.each(function() {
4478                        var self = jQuery( this ), contents = self.contents();
4479
4480                        if ( contents.length ) {
4481                                contents.wrapAll( html );
4482
4483                        } else {
4484                                self.append( html );
4485                        }
4486                });
4487        },
4488
4489        wrap: function( html ) {
4490                return this.each(function() {
4491                        jQuery( this ).wrapAll( html );
4492                });
4493        },
4494
4495        unwrap: function() {
4496                return this.parent().each(function() {
4497                        if ( !jQuery.nodeName( this, "body" ) ) {
4498                                jQuery( this ).replaceWith( this.childNodes );
4499                        }
4500                }).end();
4501        },
4502
4503        append: function() {
4504                return this.domManip(arguments, true, function( elem ) {
4505                        if ( this.nodeType === 1 ) {
4506                                this.appendChild( elem );
4507                        }
4508                });
4509        },
4510
4511        prepend: function() {
4512                return this.domManip(arguments, true, function( elem ) {
4513                        if ( this.nodeType === 1 ) {
4514                                this.insertBefore( elem, this.firstChild );
4515                        }
4516                });
4517        },
4518
4519        before: function() {
4520                if ( this[0] && this[0].parentNode ) {
4521                        return this.domManip(arguments, false, function( elem ) {
4522                                this.parentNode.insertBefore( elem, this );
4523                        });
4524                } else if ( arguments.length ) {
4525                        var set = jQuery(arguments[0]);
4526                        set.push.apply( set, this.toArray() );
4527                        return this.pushStack( set, "before", arguments );
4528                }
4529        },
4530
4531        after: function() {
4532                if ( this[0] && this[0].parentNode ) {
4533                        return this.domManip(arguments, false, function( elem ) {
4534                                this.parentNode.insertBefore( elem, this.nextSibling );
4535                        });
4536                } else if ( arguments.length ) {
4537                        var set = this.pushStack( this, "after", arguments );
4538                        set.push.apply( set, jQuery(arguments[0]).toArray() );
4539                        return set;
4540                }
4541        },
4542       
4543        // keepData is for internal use only--do not document
4544        remove: function( selector, keepData ) {
4545                for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4546                        if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
4547                                if ( !keepData && elem.nodeType === 1 ) {
4548                                        jQuery.cleanData( elem.getElementsByTagName("*") );
4549                                        jQuery.cleanData( [ elem ] );
4550                                }
4551
4552                                if ( elem.parentNode ) {
4553                                         elem.parentNode.removeChild( elem );
4554                                }
4555                        }
4556                }
4557               
4558                return this;
4559        },
4560
4561        empty: function() {
4562                for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4563                        // Remove element nodes and prevent memory leaks
4564                        if ( elem.nodeType === 1 ) {
4565                                jQuery.cleanData( elem.getElementsByTagName("*") );
4566                        }
4567
4568                        // Remove any remaining nodes
4569                        while ( elem.firstChild ) {
4570                                elem.removeChild( elem.firstChild );
4571                        }
4572                }
4573               
4574                return this;
4575        },
4576
4577        clone: function( events ) {
4578                // Do the clone
4579                var ret = this.map(function() {
4580                        if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
4581                                // IE copies events bound via attachEvent when
4582                                // using cloneNode. Calling detachEvent on the
4583                                // clone will also remove the events from the orignal
4584                                // In order to get around this, we use innerHTML.
4585                                // Unfortunately, this means some modifications to
4586                                // attributes in IE that are actually only stored
4587                                // as properties will not be copied (such as the
4588                                // the name attribute on an input).
4589                                var html = this.outerHTML, ownerDocument = this.ownerDocument;
4590                                if ( !html ) {
4591                                        var div = ownerDocument.createElement("div");
4592                                        div.appendChild( this.cloneNode(true) );
4593                                        html = div.innerHTML;
4594                                }
4595
4596                                return jQuery.clean([html.replace(rinlinejQuery, "")
4597                                        // Handle the case in IE 8 where action=/test/> self-closes a tag
4598                                        .replace(raction, '="$1">')
4599                                        .replace(rleadingWhitespace, "")], ownerDocument)[0];
4600                        } else {
4601                                return this.cloneNode(true);
4602                        }
4603                });
4604
4605                // Copy the events from the original to the clone
4606                if ( events === true ) {
4607                        cloneCopyEvent( this, ret );
4608                        cloneCopyEvent( this.find("*"), ret.find("*") );
4609                }
4610
4611                // Return the cloned set
4612                return ret;
4613        },
4614
4615        html: function( value ) {
4616                if ( value === undefined ) {
4617                        return this[0] && this[0].nodeType === 1 ?
4618                                this[0].innerHTML.replace(rinlinejQuery, "") :
4619                                null;
4620
4621                // See if we can take a shortcut and just use innerHTML
4622                } else if ( typeof value === "string" && !rnocache.test( value ) &&
4623                        (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
4624                        !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
4625
4626                        value = value.replace(rxhtmlTag, "<$1></$2>");
4627
4628                        try {
4629                                for ( var i = 0, l = this.length; i < l; i++ ) {
4630                                        // Remove element nodes and prevent memory leaks
4631                                        if ( this[i].nodeType === 1 ) {
4632                                                jQuery.cleanData( this[i].getElementsByTagName("*") );
4633                                                this[i].innerHTML = value;
4634                                        }
4635                                }
4636
4637                        // If using innerHTML throws an exception, use the fallback method
4638                        } catch(e) {
4639                                this.empty().append( value );
4640                        }
4641
4642                } else if ( jQuery.isFunction( value ) ) {
4643                        this.each(function(i){
4644                                var self = jQuery(this);
4645                                self.html( value.call(this, i, self.html()) );
4646                        });
4647
4648                } else {
4649                        this.empty().append( value );
4650                }
4651
4652                return this;
4653        },
4654
4655        replaceWith: function( value ) {
4656                if ( this[0] && this[0].parentNode ) {
4657                        // Make sure that the elements are removed from the DOM before they are inserted
4658                        // this can help fix replacing a parent with child elements
4659                        if ( jQuery.isFunction( value ) ) {
4660                                return this.each(function(i) {
4661                                        var self = jQuery(this), old = self.html();
4662                                        self.replaceWith( value.call( this, i, old ) );
4663                                });
4664                        }
4665
4666                        if ( typeof value !== "string" ) {
4667                                value = jQuery(value).detach();
4668                        }
4669
4670                        return this.each(function() {
4671                                var next = this.nextSibling, parent = this.parentNode;
4672
4673                                jQuery(this).remove();
4674
4675                                if ( next ) {
4676                                        jQuery(next).before( value );
4677                                } else {
4678                                        jQuery(parent).append( value );
4679                                }
4680                        });
4681                } else {
4682                        return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
4683                }
4684        },
4685
4686        detach: function( selector ) {
4687                return this.remove( selector, true );
4688        },
4689
4690        domManip: function( args, table, callback ) {
4691                var results, first, value = args[0], scripts = [], fragment, parent;
4692
4693                // We can't cloneNode fragments that contain checked, in WebKit
4694                if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
4695                        return this.each(function() {
4696                                jQuery(this).domManip( args, table, callback, true );
4697                        });
4698                }
4699
4700                if ( jQuery.isFunction(value) ) {
4701                        return this.each(function(i) {
4702                                var self = jQuery(this);
4703                                args[0] = value.call(this, i, table ? self.html() : undefined);
4704                                self.domManip( args, table, callback );
4705                        });
4706                }
4707
4708                if ( this[0] ) {
4709                        parent = value && value.parentNode;
4710
4711                        // If we're in a fragment, just use that instead of building a new one
4712                        if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
4713                                results = { fragment: parent };
4714
4715                        } else {
4716                                results = jQuery.buildFragment( args, this, scripts );
4717                        }
4718                       
4719                        fragment = results.fragment;
4720                       
4721                        if ( fragment.childNodes.length === 1 ) {
4722                                first = fragment = fragment.firstChild;
4723                        } else {
4724                                first = fragment.firstChild;
4725                        }
4726
4727                        if ( first ) {
4728                                table = table && jQuery.nodeName( first, "tr" );
4729
4730                                for ( var i = 0, l = this.length; i < l; i++ ) {
4731                                        callback.call(
4732                                                table ?
4733                                                        root(this[i], first) :
4734                                                        this[i],
4735                                                i > 0 || results.cacheable || this.length > 1  ?
4736                                                        fragment.cloneNode(true) :
4737                                                        fragment
4738                                        );
4739                                }
4740                        }
4741
4742                        if ( scripts.length ) {
4743                                jQuery.each( scripts, evalScript );
4744                        }
4745                }
4746
4747                return this;
4748        }
4749});
4750
4751function root( elem, cur ) {
4752        return jQuery.nodeName(elem, "table") ?
4753                (elem.getElementsByTagName("tbody")[0] ||
4754                elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
4755                elem;
4756}
4757
4758function cloneCopyEvent(orig, ret) {
4759        var i = 0;
4760
4761        ret.each(function() {
4762                if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
4763                        return;
4764                }
4765
4766                var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
4767
4768                if ( events ) {
4769                        delete curData.handle;
4770                        curData.events = {};
4771
4772                        for ( var type in events ) {
4773                                for ( var handler in events[ type ] ) {
4774                                        jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
4775                                }
4776                        }
4777                }
4778        });
4779}
4780
4781jQuery.buildFragment = function( args, nodes, scripts ) {
4782        var fragment, cacheable, cacheresults,
4783                doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
4784
4785        // Only cache "small" (1/2 KB) strings that are associated with the main document
4786        // Cloning options loses the selected state, so don't cache them
4787        // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
4788        // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
4789        if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
4790                !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
4791
4792                cacheable = true;
4793                cacheresults = jQuery.fragments[ args[0] ];
4794                if ( cacheresults ) {
4795                        if ( cacheresults !== 1 ) {
4796                                fragment = cacheresults;
4797                        }
4798                }
4799        }
4800
4801        if ( !fragment ) {
4802                fragment = doc.createDocumentFragment();
4803                jQuery.clean( args, doc, fragment, scripts );
4804        }
4805
4806        if ( cacheable ) {
4807                jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
4808        }
4809
4810        return { fragment: fragment, cacheable: cacheable };
4811};
4812
4813jQuery.fragments = {};
4814
4815jQuery.each({
4816        appendTo: "append",
4817        prependTo: "prepend",
4818        insertBefore: "before",
4819        insertAfter: "after",
4820        replaceAll: "replaceWith"
4821}, function( name, original ) {
4822        jQuery.fn[ name ] = function( selector ) {
4823                var ret = [], insert = jQuery( selector ),
4824                        parent = this.length === 1 && this[0].parentNode;
4825               
4826                if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
4827                        insert[ original ]( this[0] );
4828                        return this;
4829                       
4830                } else {
4831                        for ( var i = 0, l = insert.length; i < l; i++ ) {
4832                                var elems = (i > 0 ? this.clone(true) : this).get();
4833                                jQuery( insert[i] )[ original ]( elems );
4834                                ret = ret.concat( elems );
4835                        }
4836               
4837                        return this.pushStack( ret, name, insert.selector );
4838                }
4839        };
4840});
4841
4842jQuery.extend({
4843        clean: function( elems, context, fragment, scripts ) {
4844                context = context || document;
4845
4846                // !context.createElement fails in IE with an error but returns typeof 'object'
4847                if ( typeof context.createElement === "undefined" ) {
4848                        context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
4849                }
4850
4851                var ret = [];
4852
4853                for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
4854                        if ( typeof elem === "number" ) {
4855                                elem += "";
4856                        }
4857
4858                        if ( !elem ) {
4859                                continue;
4860                        }
4861
4862                        // Convert html string into DOM nodes
4863                        if ( typeof elem === "string" && !rhtml.test( elem ) ) {
4864                                elem = context.createTextNode( elem );
4865
4866                        } else if ( typeof elem === "string" ) {
4867                                // Fix "XHTML"-style tags in all browsers
4868                                elem = elem.replace(rxhtmlTag, "<$1></$2>");
4869
4870                                // Trim whitespace, otherwise indexOf won't work as expected
4871                                var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
4872                                        wrap = wrapMap[ tag ] || wrapMap._default,
4873                                        depth = wrap[0],
4874                                        div = context.createElement("div");
4875
4876                                // Go to html and back, then peel off extra wrappers
4877                                div.innerHTML = wrap[1] + elem + wrap[2];
4878
4879                                // Move to the right depth
4880                                while ( depth-- ) {
4881                                        div = div.lastChild;
4882                                }
4883
4884                                // Remove IE's autoinserted <tbody> from table fragments
4885                                if ( !jQuery.support.tbody ) {
4886
4887                                        // String was a <table>, *may* have spurious <tbody>
4888                                        var hasBody = rtbody.test(elem),
4889                                                tbody = tag === "table" && !hasBody ?
4890                                                        div.firstChild && div.firstChild.childNodes :
4891
4892                                                        // String was a bare <thead> or <tfoot>
4893                                                        wrap[1] === "<table>" && !hasBody ?
4894                                                                div.childNodes :
4895                                                                [];
4896
4897                                        for ( var j = tbody.length - 1; j >= 0 ; --j ) {
4898                                                if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
4899                                                        tbody[ j ].parentNode.removeChild( tbody[ j ] );
4900                                                }
4901                                        }
4902
4903                                }
4904
4905                                // IE completely kills leading whitespace when innerHTML is used
4906                                if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
4907                                        div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
4908                                }
4909
4910                                elem = div.childNodes;
4911                        }
4912
4913                        if ( elem.nodeType ) {
4914                                ret.push( elem );
4915                        } else {
4916                                ret = jQuery.merge( ret, elem );
4917                        }
4918                }
4919
4920                if ( fragment ) {
4921                        for ( i = 0; ret[i]; i++ ) {
4922                                if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
4923                                        scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
4924                               
4925                                } else {
4926                                        if ( ret[i].nodeType === 1 ) {
4927                                                ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
4928                                        }
4929                                        fragment.appendChild( ret[i] );
4930                                }
4931                        }
4932                }
4933
4934                return ret;
4935        },
4936       
4937        cleanData: function( elems ) {
4938                var data, id, cache = jQuery.cache,
4939                        special = jQuery.event.special,
4940                        deleteExpando = jQuery.support.deleteExpando;
4941               
4942                for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
4943                        if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
4944                                continue;
4945                        }
4946
4947                        id = elem[ jQuery.expando ];
4948                       
4949                        if ( id ) {
4950                                data = cache[ id ];
4951                               
4952                                if ( data && data.events ) {
4953                                        for ( var type in data.events ) {
4954                                                if ( special[ type ] ) {
4955                                                        jQuery.event.remove( elem, type );
4956
4957                                                } else {
4958                                                        jQuery.removeEvent( elem, type, data.handle );
4959                                                }
4960                                        }
4961                                }
4962                               
4963                                if ( deleteExpando ) {
4964                                        delete elem[ jQuery.expando ];
4965
4966                                } else if ( elem.removeAttribute ) {
4967                                        elem.removeAttribute( jQuery.expando );
4968                                }
4969                               
4970                                delete cache[ id ];
4971                        }
4972                }
4973        }
4974});
4975
4976function evalScript( i, elem ) {
4977        if ( elem.src ) {
4978                jQuery.ajax({
4979                        url: elem.src,
4980                        async: false,
4981                        dataType: "script"
4982                });
4983        } else {
4984                jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
4985        }
4986
4987        if ( elem.parentNode ) {
4988                elem.parentNode.removeChild( elem );
4989        }
4990}
4991
4992
4993
4994
4995var ralpha = /alpha\([^)]*\)/i,
4996        ropacity = /opacity=([^)]*)/,
4997        rdashAlpha = /-([a-z])/ig,
4998        rupper = /([A-Z])/g,
4999        rnumpx = /^-?\d+(?:px)?$/i,
5000        rnum = /^-?\d/,
5001
5002        cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5003        cssWidth = [ "Left", "Right" ],
5004        cssHeight = [ "Top", "Bottom" ],
5005        curCSS,
5006
5007        // cache check for defaultView.getComputedStyle
5008        getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
5009
5010        fcamelCase = function( all, letter ) {
5011                return letter.toUpperCase();
5012        };
5013
5014jQuery.fn.css = function( name, value ) {
5015        // Setting 'undefined' is a no-op
5016        if ( arguments.length === 2 && value === undefined ) {
5017                return this;
5018        }
5019
5020        return jQuery.access( this, name, value, true, function( elem, name, value ) {
5021                return value !== undefined ?
5022                        jQuery.style( elem, name, value ) :
5023                        jQuery.css( elem, name );
5024        });
5025};
5026
5027jQuery.extend({
5028        // Add in style property hooks for overriding the default
5029        // behavior of getting and setting a style property
5030        cssHooks: {
5031                opacity: {
5032                        get: function( elem, computed ) {
5033                                if ( computed ) {
5034                                        // We should always get a number back from opacity
5035                                        var ret = curCSS( elem, "opacity", "opacity" );
5036                                        return ret === "" ? "1" : ret;
5037
5038                                } else {
5039                                        return elem.style.opacity;
5040                                }
5041                        }
5042                }
5043        },
5044
5045        // Exclude the following css properties to add px
5046        cssNumber: {
5047                "zIndex": true,
5048                "fontWeight": true,
5049                "opacity": true,
5050                "zoom": true,
5051                "lineHeight": true
5052        },
5053
5054        // Add in properties whose names you wish to fix before
5055        // setting or getting the value
5056        cssProps: {
5057                // normalize float css property
5058                "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
5059        },
5060
5061        // Get and set the style property on a DOM Node
5062        style: function( elem, name, value, extra ) {
5063                // Don't set styles on text and comment nodes
5064                if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5065                        return;
5066                }
5067
5068                // Make sure that we're working with the right name
5069                var ret, origName = jQuery.camelCase( name ),
5070                        style = elem.style, hooks = jQuery.cssHooks[ origName ];
5071
5072                name = jQuery.cssProps[ origName ] || origName;
5073
5074                // Check if we're setting a value
5075                if ( value !== undefined ) {
5076                        // Make sure that NaN and null values aren't set. See: #7116
5077                        if ( typeof value === "number" && isNaN( value ) || value == null ) {
5078                                return;
5079                        }
5080
5081                        // If a number was passed in, add 'px' to the (except for certain CSS properties)
5082                        if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
5083                                value += "px";
5084                        }
5085
5086                        // If a hook was provided, use that value, otherwise just set the specified value
5087                        if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
5088                                // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
5089                                // Fixes bug #5509
5090                                try {
5091                                        style[ name ] = value;
5092                                } catch(e) {}
5093                        }
5094
5095                } else {
5096                        // If a hook was provided get the non-computed value from there
5097                        if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
5098                                return ret;
5099                        }
5100
5101                        // Otherwise just get the value from the style object
5102                        return style[ name ];
5103                }
5104        },
5105
5106        css: function( elem, name, extra ) {
5107                // Make sure that we're working with the right name
5108                var ret, origName = jQuery.camelCase( name ),
5109                        hooks = jQuery.cssHooks[ origName ];
5110
5111                name = jQuery.cssProps[ origName ] || origName;
5112
5113                // If a hook was provided get the computed value from there
5114                if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
5115                        return ret;
5116
5117                // Otherwise, if a way to get the computed value exists, use that
5118                } else if ( curCSS ) {
5119                        return curCSS( elem, name, origName );
5120                }
5121        },
5122
5123        // A method for quickly swapping in/out CSS properties to get correct calculations
5124        swap: function( elem, options, callback ) {
5125                var old = {};
5126
5127                // Remember the old values, and insert the new ones
5128                for ( var name in options ) {
5129                        old[ name ] = elem.style[ name ];
5130                        elem.style[ name ] = options[ name ];
5131                }
5132
5133                callback.call( elem );
5134
5135                // Revert the old values
5136                for ( name in options ) {
5137                        elem.style[ name ] = old[ name ];
5138                }
5139        },
5140
5141        camelCase: function( string ) {
5142                return string.replace( rdashAlpha, fcamelCase );
5143        }
5144});
5145
5146// DEPRECATED, Use jQuery.css() instead
5147jQuery.curCSS = jQuery.css;
5148
5149jQuery.each(["height", "width"], function( i, name ) {
5150        jQuery.cssHooks[ name ] = {
5151                get: function( elem, computed, extra ) {
5152                        var val;
5153
5154                        if ( computed ) {
5155                                if ( elem.offsetWidth !== 0 ) {
5156                                        val = getWH( elem, name, extra );
5157
5158                                } else {
5159                                        jQuery.swap( elem, cssShow, function() {
5160                                                val = getWH( elem, name, extra );
5161                                        });
5162                                }
5163
5164                                return val + "px";
5165                        }
5166                },
5167
5168                set: function( elem, value ) {
5169                        if ( rnumpx.test( value ) ) {
5170                                // ignore negative width and height values #1599
5171                                value = parseFloat(value);
5172
5173                                if ( value >= 0 ) {
5174                                        return value + "px";
5175                                }
5176
5177                        } else {
5178                                return value;
5179                        }
5180                }
5181        };
5182});
5183
5184if ( !jQuery.support.opacity ) {
5185        jQuery.cssHooks.opacity = {
5186                get: function( elem, computed ) {
5187                        // IE uses filters for opacity
5188                        return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
5189                                (parseFloat(RegExp.$1) / 100) + "" :
5190                                computed ? "1" : "";
5191                },
5192
5193                set: function( elem, value ) {
5194                        var style = elem.style;
5195
5196                        // IE has trouble with opacity if it does not have layout
5197                        // Force it by setting the zoom level
5198                        style.zoom = 1;
5199
5200                        // Set the alpha filter to set the opacity
5201                        var opacity = jQuery.isNaN(value) ?
5202                                "" :
5203                                "alpha(opacity=" + value * 100 + ")",
5204                                filter = style.filter || "";
5205
5206                        style.filter = ralpha.test(filter) ?
5207                                filter.replace(ralpha, opacity) :
5208                                style.filter + ' ' + opacity;
5209                }
5210        };
5211}
5212
5213if ( getComputedStyle ) {
5214        curCSS = function( elem, newName, name ) {
5215                var ret, defaultView, computedStyle;
5216
5217                name = name.replace( rupper, "-$1" ).toLowerCase();
5218
5219                if ( !(defaultView = elem.ownerDocument.defaultView) ) {
5220                        return undefined;
5221                }
5222
5223                if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
5224                        ret = computedStyle.getPropertyValue( name );
5225                        if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
5226                                ret = jQuery.style( elem, name );
5227                        }
5228                }
5229
5230                return ret;
5231        };
5232
5233} else if ( document.documentElement.currentStyle ) {
5234        curCSS = function( elem, name ) {
5235                var left, rsLeft, ret = elem.currentStyle && elem.currentStyle[ name ], style = elem.style;
5236
5237                // From the awesome hack by Dean Edwards
5238                // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
5239
5240                // If we're not dealing with a regular pixel number
5241                // but a number that has a weird ending, we need to convert it to pixels
5242                if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
5243                        // Remember the original values
5244                        left = style.left;
5245                        rsLeft = elem.runtimeStyle.left;
5246
5247                        // Put in the new values to get a computed value out
5248                        elem.runtimeStyle.left = elem.currentStyle.left;
5249                        style.left = name === "fontSize" ? "1em" : (ret || 0);
5250                        ret = style.pixelLeft + "px";
5251
5252                        // Revert the changed values
5253                        style.left = left;
5254                        elem.runtimeStyle.left = rsLeft;
5255                }
5256
5257                return ret;
5258        };
5259}
5260
5261function getWH( elem, name, extra ) {
5262        var which = name === "width" ? cssWidth : cssHeight,
5263                val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
5264
5265        if ( extra === "border" ) {
5266                return val;
5267        }
5268
5269        jQuery.each( which, function() {
5270                if ( !extra ) {
5271                        val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
5272                }
5273
5274                if ( extra === "margin" ) {
5275                        val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
5276
5277                } else {
5278                        val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
5279                }
5280        });
5281
5282        return val;
5283}
5284
5285if ( jQuery.expr && jQuery.expr.filters ) {
5286        jQuery.expr.filters.hidden = function( elem ) {
5287                var width = elem.offsetWidth, height = elem.offsetHeight;
5288
5289                return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
5290        };
5291
5292        jQuery.expr.filters.visible = function( elem ) {
5293                return !jQuery.expr.filters.hidden( elem );
5294        };
5295}
5296
5297
5298
5299
5300var jsc = jQuery.now(),
5301        rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
5302        rselectTextarea = /^(?:select|textarea)/i,
5303        rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
5304        rnoContent = /^(?:GET|HEAD|DELETE)$/,
5305        rbracket = /\[\]$/,
5306        jsre = /\=\?(&|$)/,
5307        rquery = /\?/,
5308        rts = /([?&])_=[^&]*/,
5309        rurl = /^(\w+:)?\/\/([^\/?#]+)/,
5310        r20 = /%20/g,
5311        rhash = /#.*$/,
5312
5313        // Keep a copy of the old load method
5314        _load = jQuery.fn.load;
5315
5316jQuery.fn.extend({
5317        load: function( url, params, callback ) {
5318                if ( typeof url !== "string" && _load ) {
5319                        return _load.apply( this, arguments );
5320
5321                // Don't do a request if no elements are being requested
5322                } else if ( !this.length ) {
5323                        return this;
5324                }
5325
5326                var off = url.indexOf(" ");
5327                if ( off >= 0 ) {
5328                        var selector = url.slice(off, url.length);
5329                        url = url.slice(0, off);
5330                }
5331
5332                // Default to a GET request
5333                var type = "GET";
5334
5335                // If the second parameter was provided
5336                if ( params ) {
5337                        // If it's a function
5338                        if ( jQuery.isFunction( params ) ) {
5339                                // We assume that it's the callback
5340                                callback = params;
5341                                params = null;
5342
5343                        // Otherwise, build a param string
5344                        } else if ( typeof params === "object" ) {
5345                                params = jQuery.param( params, jQuery.ajaxSettings.traditional );
5346                                type = "POST";
5347                        }
5348                }
5349
5350                var self = this;
5351
5352                // Request the remote document
5353                jQuery.ajax({
5354                        url: url,
5355                        type: type,
5356                        dataType: "html",
5357                        data: params,
5358                        complete: function( res, status ) {
5359                                // If successful, inject the HTML into all the matched elements
5360                                if ( status === "success" || status === "notmodified" ) {
5361                                        // See if a selector was specified
5362                                        self.html( selector ?
5363                                                // Create a dummy div to hold the results
5364                                                jQuery("<div>")
5365                                                        // inject the contents of the document in, removing the scripts
5366                                                        // to avoid any 'Permission Denied' errors in IE
5367                                                        .append(res.responseText.replace(rscript, ""))
5368
5369                                                        // Locate the specified elements
5370                                                        .find(selector) :
5371
5372                                                // If not, just inject the full result
5373                                                res.responseText );
5374                                }
5375
5376                                if ( callback ) {
5377                                        self.each( callback, [res.responseText, status, res] );
5378                                }
5379                        }
5380                });
5381
5382                return this;
5383        },
5384
5385        serialize: function() {
5386                return jQuery.param(this.serializeArray());
5387        },
5388
5389        serializeArray: function() {
5390                return this.map(function() {
5391                        return this.elements ? jQuery.makeArray(this.elements) : this;
5392                })
5393                .filter(function() {
5394                        return this.name && !this.disabled &&
5395                                (this.checked || rselectTextarea.test(this.nodeName) ||
5396                                        rinput.test(this.type));
5397                })
5398                .map(function( i, elem ) {
5399                        var val = jQuery(this).val();
5400
5401                        return val == null ?
5402                                null :
5403                                jQuery.isArray(val) ?
5404                                        jQuery.map( val, function( val, i ) {
5405                                                return { name: elem.name, value: val };
5406                                        }) :
5407                                        { name: elem.name, value: val };
5408                }).get();
5409        }
5410});
5411
5412// Attach a bunch of functions for handling common AJAX events
5413jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
5414        jQuery.fn[o] = function( f ) {
5415                return this.bind(o, f);
5416        };
5417});
5418
5419jQuery.extend({
5420        get: function( url, data, callback, type ) {
5421                // shift arguments if data argument was omited
5422                if ( jQuery.isFunction( data ) ) {
5423                        type = type || callback;
5424                        callback = data;
5425                        data = null;
5426                }
5427
5428                return jQuery.ajax({
5429                        type: "GET",
5430                        url: url,
5431                        data: data,
5432                        success: callback,
5433                        dataType: type
5434                });
5435        },
5436
5437        getScript: function( url, callback ) {
5438                return jQuery.get(url, null, callback, "script");
5439        },
5440
5441        getJSON: function( url, data, callback ) {
5442                return jQuery.get(url, data, callback, "json");
5443        },
5444
5445        post: function( url, data, callback, type ) {
5446                // shift arguments if data argument was omited
5447                if ( jQuery.isFunction( data ) ) {
5448                        type = type || callback;
5449                        callback = data;
5450                        data = {};
5451                }
5452
5453                return jQuery.ajax({
5454                        type: "POST",
5455                        url: url,
5456                        data: data,
5457                        success: callback,
5458                        dataType: type
5459                });
5460        },
5461
5462        ajaxSetup: function( settings ) {
5463                jQuery.extend( jQuery.ajaxSettings, settings );
5464        },
5465
5466        ajaxSettings: {
5467                url: location.href,
5468                global: true,
5469                type: "GET",
5470                contentType: "application/x-www-form-urlencoded",
5471                processData: true,
5472                async: true,
5473                /*
5474                timeout: 0,
5475                data: null,
5476                username: null,
5477                password: null,
5478                traditional: false,
5479                */
5480                // This function can be overriden by calling jQuery.ajaxSetup
5481                xhr: function() {
5482                        return new window.XMLHttpRequest();
5483                },
5484                accepts: {
5485                        xml: "application/xml, text/xml",
5486                        html: "text/html",
5487                        script: "text/javascript, application/javascript",
5488                        json: "application/json, text/javascript",
5489                        text: "text/plain",
5490                        _default: "*/*"
5491                }
5492        },
5493
5494        ajax: function( origSettings ) {
5495                var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
5496                        jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
5497
5498                s.url = s.url.replace( rhash, "" );
5499
5500                // Use original (not extended) context object if it was provided
5501                s.context = origSettings && origSettings.context != null ? origSettings.context : s;
5502
5503                // convert data if not already a string
5504                if ( s.data && s.processData && typeof s.data !== "string" ) {
5505                        s.data = jQuery.param( s.data, s.traditional );
5506                }
5507
5508                // Handle JSONP Parameter Callbacks
5509                if ( s.dataType === "jsonp" ) {
5510                        if ( type === "GET" ) {
5511                                if ( !jsre.test( s.url ) ) {
5512                                        s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
5513                                }
5514                        } else if ( !s.data || !jsre.test(s.data) ) {
5515                                s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
5516                        }
5517                        s.dataType = "json";
5518                }
5519
5520                // Build temporary JSONP function
5521                if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
5522                        jsonp = s.jsonpCallback || ("jsonp" + jsc++);
5523
5524                        // Replace the =? sequence both in the query string and the data
5525                        if ( s.data ) {
5526                                s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
5527                        }
5528
5529                        s.url = s.url.replace(jsre, "=" + jsonp + "$1");
5530
5531                        // We need to make sure
5532                        // that a JSONP style response is executed properly
5533                        s.dataType = "script";
5534
5535                        // Handle JSONP-style loading
5536                        var customJsonp = window[ jsonp ];
5537
5538                        window[ jsonp ] = function( tmp ) {
5539                                data = tmp;
5540                                jQuery.handleSuccess( s, xhr, status, data );
5541                                jQuery.handleComplete( s, xhr, status, data );
5542
5543                                if ( jQuery.isFunction( customJsonp ) ) {
5544                                        customJsonp( tmp );
5545
5546                                } else {
5547                                        // Garbage collect
5548                                        window[ jsonp ] = undefined;
5549
5550                                        try {
5551                                                delete window[ jsonp ];
5552                                        } catch( jsonpError ) {}
5553                                }
5554                               
5555                                if ( head ) {
5556                                        head.removeChild( script );
5557                                }
5558                        };
5559                }
5560
5561                if ( s.dataType === "script" && s.cache === null ) {
5562                        s.cache = false;
5563                }
5564
5565                if ( s.cache === false && type === "GET" ) {
5566                        var ts = jQuery.now();
5567
5568                        // try replacing _= if it is there
5569                        var ret = s.url.replace(rts, "$1_=" + ts);
5570
5571                        // if nothing was replaced, add timestamp to the end
5572                        s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
5573                }
5574
5575                // If data is available, append data to url for get requests
5576                if ( s.data && type === "GET" ) {
5577                        s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
5578                }
5579
5580                // Watch for a new set of requests
5581                if ( s.global && jQuery.active++ === 0 ) {
5582                        jQuery.event.trigger( "ajaxStart" );
5583                }
5584
5585                // Matches an absolute URL, and saves the domain
5586                var parts = rurl.exec( s.url ),
5587                        remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
5588
5589                // If we're requesting a remote document
5590                // and trying to load JSON or Script with a GET
5591                if ( s.dataType === "script" && type === "GET" && remote ) {
5592                        var head = document.getElementsByTagName("head")[0] || document.documentElement;
5593                        var script = document.createElement("script");
5594                        if ( s.scriptCharset ) {
5595                                script.charset = s.scriptCharset;
5596                        }
5597                        script.src = s.url;
5598
5599                        // Handle Script loading
5600                        if ( !jsonp ) {
5601                                var done = false;
5602
5603                                // Attach handlers for all browsers
5604                                script.onload = script.onreadystatechange = function() {
5605                                        if ( !done && (!this.readyState ||
5606                                                        this.readyState === "loaded" || this.readyState === "complete") ) {
5607                                                done = true;
5608                                                jQuery.handleSuccess( s, xhr, status, data );
5609                                                jQuery.handleComplete( s, xhr, status, data );
5610
5611                                                // Handle memory leak in IE
5612                                                script.onload = script.onreadystatechange = null;
5613                                                if ( head && script.parentNode ) {
5614                                                        head.removeChild( script );
5615                                                }
5616                                        }
5617                                };
5618                        }
5619
5620                        // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
5621                        // This arises when a base node is used (#2709 and #4378).
5622                        head.insertBefore( script, head.firstChild );
5623
5624                        // We handle everything using the script element injection
5625                        return undefined;
5626                }
5627
5628                var requestDone = false;
5629
5630                // Create the request object
5631                var xhr = s.xhr();
5632
5633                if ( !xhr ) {
5634                        return;
5635                }
5636
5637                // Open the socket
5638                // Passing null username, generates a login popup on Opera (#2865)
5639                if ( s.username ) {
5640                        xhr.open(type, s.url, s.async, s.username, s.password);
5641                } else {
5642                        xhr.open(type, s.url, s.async);
5643                }
5644
5645                // Need an extra try/catch for cross domain requests in Firefox 3
5646                try {
5647                        // Set content-type if data specified and content-body is valid for this type
5648                        if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
5649                                xhr.setRequestHeader("Content-Type", s.contentType);
5650                        }
5651
5652                        // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
5653                        if ( s.ifModified ) {
5654                                if ( jQuery.lastModified[s.url] ) {
5655                                        xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
5656                                }
5657
5658                                if ( jQuery.etag[s.url] ) {
5659                                        xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
5660                                }
5661                        }
5662
5663                        // Set header so the called script knows that it's an XMLHttpRequest
5664                        // Only send the header if it's not a remote XHR
5665                        if ( !remote ) {
5666                                xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
5667                        }
5668
5669                        // Set the Accepts header for the server, depending on the dataType
5670                        xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
5671                                s.accepts[ s.dataType ] + ", */*; q=0.01" :
5672                                s.accepts._default );
5673                } catch( headerError ) {}
5674
5675                // Allow custom headers/mimetypes and early abort
5676                if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
5677                        // Handle the global AJAX counter
5678                        if ( s.global && jQuery.active-- === 1 ) {
5679                                jQuery.event.trigger( "ajaxStop" );
5680                        }
5681
5682                        // close opended socket
5683                        xhr.abort();
5684                        return false;
5685                }
5686
5687                if ( s.global ) {
5688                        jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
5689                }
5690
5691                // Wait for a response to come back
5692                var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
5693                        // The request was aborted
5694                        if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
5695                                // Opera doesn't call onreadystatechange before this point
5696                                // so we simulate the call
5697                                if ( !requestDone ) {
5698                                        jQuery.handleComplete( s, xhr, status, data );
5699                                }
5700
5701                                requestDone = true;
5702                                if ( xhr ) {
5703                                        xhr.onreadystatechange = jQuery.noop;
5704                                }
5705
5706                        // The transfer is complete and the data is available, or the request timed out
5707                        } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
5708                                requestDone = true;
5709                                xhr.onreadystatechange = jQuery.noop;
5710
5711                                status = isTimeout === "timeout" ?
5712                                        "timeout" :
5713                                        !jQuery.httpSuccess( xhr ) ?
5714                                                "error" :
5715                                                s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
5716                                                        "notmodified" :
5717                                                        "success";
5718
5719                                var errMsg;
5720
5721                                if ( status === "success" ) {
5722                                        // Watch for, and catch, XML document parse errors
5723                                        try {
5724                                                // process the data (runs the xml through httpData regardless of callback)
5725                                                data = jQuery.httpData( xhr, s.dataType, s );
5726                                        } catch( parserError ) {
5727                                                status = "parsererror";
5728                                                errMsg = parserError;
5729                                        }
5730                                }
5731
5732                                // Make sure that the request was successful or notmodified
5733                                if ( status === "success" || status === "notmodified" ) {
5734                                        // JSONP handles its own success callback
5735                                        if ( !jsonp ) {
5736                                                jQuery.handleSuccess( s, xhr, status, data );
5737                                        }
5738                                } else {
5739                                        jQuery.handleError( s, xhr, status, errMsg );
5740                                }
5741
5742                                // Fire the complete handlers
5743                                if ( !jsonp ) {
5744                                        jQuery.handleComplete( s, xhr, status, data );
5745                                }
5746
5747                                if ( isTimeout === "timeout" ) {
5748                                        xhr.abort();
5749                                }
5750
5751                                // Stop memory leaks
5752                                if ( s.async ) {
5753                                        xhr = null;
5754                                }
5755                        }
5756                };
5757
5758                // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
5759                // Opera doesn't fire onreadystatechange at all on abort
5760                try {
5761                        var oldAbort = xhr.abort;
5762                        xhr.abort = function() {
5763                                // xhr.abort in IE7 is not a native JS function
5764                                // and does not have a call property
5765                                if ( xhr && oldAbort.call ) {
5766                                        oldAbort.call( xhr );
5767                                }
5768
5769                                onreadystatechange( "abort" );
5770                        };
5771                } catch( abortError ) {}
5772
5773                // Timeout checker
5774                if ( s.async && s.timeout > 0 ) {
5775                        setTimeout(function() {
5776                                // Check to see if the request is still happening
5777                                if ( xhr && !requestDone ) {
5778                                        onreadystatechange( "timeout" );
5779                                }
5780                        }, s.timeout);
5781                }
5782
5783                // Send the data
5784                try {
5785                        xhr.send( noContent || s.data == null ? null : s.data );
5786
5787                } catch( sendError ) {
5788                        jQuery.handleError( s, xhr, null, sendError );
5789
5790                        // Fire the complete handlers
5791                        jQuery.handleComplete( s, xhr, status, data );
5792                }
5793
5794                // firefox 1.5 doesn't fire statechange for sync requests
5795                if ( !s.async ) {
5796                        onreadystatechange();
5797                }
5798
5799                // return XMLHttpRequest to allow aborting the request etc.
5800                return xhr;
5801        },
5802
5803        // Serialize an array of form elements or a set of
5804        // key/values into a query string
5805        param: function( a, traditional ) {
5806                var s = [], add = function( key, value ) {
5807                        // If value is a function, invoke it and return its value
5808                        value = jQuery.isFunction(value) ? value() : value;
5809                        s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
5810                };
5811               
5812                // Set traditional to true for jQuery <= 1.3.2 behavior.
5813                if ( traditional === undefined ) {
5814                        traditional = jQuery.ajaxSettings.traditional;
5815                }
5816               
5817                // If an array was passed in, assume that it is an array of form elements.
5818                if ( jQuery.isArray(a) || a.jquery ) {
5819                        // Serialize the form elements
5820                        jQuery.each( a, function() {
5821                                add( this.name, this.value );
5822                        });
5823                       
5824                } else {
5825                        // If traditional, encode the "old" way (the way 1.3.2 or older
5826                        // did it), otherwise encode params recursively.
5827                        for ( var prefix in a ) {
5828                                buildParams( prefix, a[prefix], traditional, add );
5829                        }
5830                }
5831
5832                // Return the resulting serialization
5833                return s.join("&").replace(r20, "+");
5834        }
5835});
5836
5837function buildParams( prefix, obj, traditional, add ) {
5838        if ( jQuery.isArray(obj) && obj.length ) {
5839                // Serialize array item.
5840                jQuery.each( obj, function( i, v ) {
5841                        if ( traditional || rbracket.test( prefix ) ) {
5842                                // Treat each array item as a scalar.
5843                                add( prefix, v );
5844
5845                        } else {
5846                                // If array item is non-scalar (array or object), encode its
5847                                // numeric index to resolve deserialization ambiguity issues.
5848                                // Note that rack (as of 1.0.0) can't currently deserialize
5849                                // nested arrays properly, and attempting to do so may cause
5850                                // a server error. Possible fixes are to modify rack's
5851                                // deserialization algorithm or to provide an option or flag
5852                                // to force array serialization to be shallow.
5853                                buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
5854                        }
5855                });
5856                       
5857        } else if ( !traditional && obj != null && typeof obj === "object" ) {
5858                if ( jQuery.isEmptyObject( obj ) ) {
5859                        add( prefix, "" );
5860
5861                // Serialize object item.
5862                } else {
5863                        jQuery.each( obj, function( k, v ) {
5864                                buildParams( prefix + "[" + k + "]", v, traditional, add );
5865                        });
5866                }
5867                                       
5868        } else {
5869                // Serialize scalar item.
5870                add( prefix, obj );
5871        }
5872}
5873
5874// This is still on the jQuery object... for now
5875// Want to move this to jQuery.ajax some day
5876jQuery.extend({
5877
5878        // Counter for holding the number of active queries
5879        active: 0,
5880
5881        // Last-Modified header cache for next request
5882        lastModified: {},
5883        etag: {},
5884
5885        handleError: function( s, xhr, status, e ) {
5886                // If a local callback was specified, fire it
5887                if ( s.error ) {
5888                        s.error.call( s.context, xhr, status, e );
5889                }
5890
5891                // Fire the global callback
5892                if ( s.global ) {
5893                        jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
5894                }
5895        },
5896
5897        handleSuccess: function( s, xhr, status, data ) {
5898                // If a local callback was specified, fire it and pass it the data
5899                if ( s.success ) {
5900                        s.success.call( s.context, data, status, xhr );
5901                }
5902
5903                // Fire the global callback
5904                if ( s.global ) {
5905                        jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
5906                }
5907        },
5908
5909        handleComplete: function( s, xhr, status ) {
5910                // Process result
5911                if ( s.complete ) {
5912                        s.complete.call( s.context, xhr, status );
5913                }
5914
5915                // The request was completed
5916                if ( s.global ) {
5917                        jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
5918                }
5919
5920                // Handle the global AJAX counter
5921                if ( s.global && jQuery.active-- === 1 ) {
5922                        jQuery.event.trigger( "ajaxStop" );
5923                }
5924        },
5925               
5926        triggerGlobal: function( s, type, args ) {
5927                (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
5928        },
5929
5930        // Determines if an XMLHttpRequest was successful or not
5931        httpSuccess: function( xhr ) {
5932                try {
5933                        // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
5934                        return !xhr.status && location.protocol === "file:" ||
5935                                xhr.status >= 200 && xhr.status < 300 ||
5936                                xhr.status === 304 || xhr.status === 1223;
5937                } catch(e) {}
5938
5939                return false;
5940        },
5941
5942        // Determines if an XMLHttpRequest returns NotModified
5943        httpNotModified: function( xhr, url ) {
5944                var lastModified = xhr.getResponseHeader("Last-Modified"),
5945                        etag = xhr.getResponseHeader("Etag");
5946
5947                if ( lastModified ) {
5948                        jQuery.lastModified[url] = lastModified;
5949                }
5950
5951                if ( etag ) {
5952                        jQuery.etag[url] = etag;
5953                }
5954
5955                return xhr.status === 304;
5956        },
5957
5958        httpData: function( xhr, type, s ) {
5959                var ct = xhr.getResponseHeader("content-type") || "",
5960                        xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
5961                        data = xml ? xhr.responseXML : xhr.responseText;
5962
5963                if ( xml && data.documentElement.nodeName === "parsererror" ) {
5964                        jQuery.error( "parsererror" );
5965                }
5966
5967                // Allow a pre-filtering function to sanitize the response
5968                // s is checked to keep backwards compatibility
5969                if ( s && s.dataFilter ) {
5970                        data = s.dataFilter( data, type );
5971                }
5972
5973                // The filter can actually parse the response
5974                if ( typeof data === "string" ) {
5975                        // Get the JavaScript object, if JSON is used.
5976                        if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
5977                                data = jQuery.parseJSON( data );
5978
5979                        // If the type is "script", eval it in global context
5980                        } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
5981                                jQuery.globalEval( data );
5982                        }
5983                }
5984
5985                return data;
5986        }
5987
5988});
5989
5990/*
5991 * Create the request object; Microsoft failed to properly
5992 * implement the XMLHttpRequest in IE7 (can't request local files),
5993 * so we use the ActiveXObject when it is available
5994 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
5995 * we need a fallback.
5996 */
5997if ( window.ActiveXObject ) {
5998        jQuery.ajaxSettings.xhr = function() {
5999                if ( window.location.protocol !== "file:" ) {
6000                        try {
6001                                return new window.XMLHttpRequest();
6002                        } catch(xhrError) {}
6003                }
6004
6005                try {
6006                        return new window.ActiveXObject("Microsoft.XMLHTTP");
6007                } catch(activeError) {}
6008        };
6009}
6010
6011// Does this browser support XHR requests?
6012jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
6013
6014
6015
6016
6017var elemdisplay = {},
6018        rfxtypes = /^(?:toggle|show|hide)$/,
6019        rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
6020        timerId,
6021        fxAttrs = [
6022                // height animations
6023                [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
6024                // width animations
6025                [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
6026                // opacity animations
6027                [ "opacity" ]
6028        ];
6029
6030jQuery.fn.extend({
6031        show: function( speed, easing, callback ) {
6032                if ( speed || speed === 0 ) {
6033                        return this.animate( genFx("show", 3), speed, easing, callback);
6034                } else {
6035                        for ( var i = 0, j = this.length; i < j; i++ ) {
6036                                // Reset the inline display of this element to learn if it is
6037                                // being hidden by cascaded rules or not
6038                                if ( !jQuery.data(this[i], "olddisplay") && this[i].style.display === "none" ) {
6039                                        this[i].style.display = "";
6040                                }
6041
6042                                // Set elements which have been overridden with display: none
6043                                // in a stylesheet to whatever the default browser style is
6044                                // for such an element
6045                                if ( this[i].style.display === "" && jQuery.css( this[i], "display" ) === "none" ) {
6046                                        jQuery.data(this[i], "olddisplay", defaultDisplay(this[i].nodeName));
6047                                }
6048                        }
6049
6050                        // Set the display of most of the elements in a second loop
6051                        // to avoid the constant reflow
6052                        for ( i = 0; i < j; i++ ) {
6053                                this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
6054                        }
6055
6056                        return this;
6057                }
6058        },
6059
6060        hide: function( speed, easing, callback ) {
6061                if ( speed || speed === 0 ) {
6062                        return this.animate( genFx("hide", 3), speed, easing, callback);
6063
6064                } else {
6065                        for ( var i = 0, j = this.length; i < j; i++ ) {
6066                                var display = jQuery.css( this[i], "display" );
6067
6068                                if ( display !== "none" ) {
6069                                        jQuery.data( this[i], "olddisplay", display );
6070                                }
6071                        }
6072
6073                        // Set the display of the elements in a second loop
6074                        // to avoid the constant reflow
6075                        for ( i = 0; i < j; i++ ) {
6076                                this[i].style.display = "none";
6077                        }
6078
6079                        return this;
6080                }
6081        },
6082
6083        // Save the old toggle function
6084        _toggle: jQuery.fn.toggle,
6085
6086        toggle: function( fn, fn2, callback ) {
6087                var bool = typeof fn === "boolean";
6088
6089                if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
6090                        this._toggle.apply( this, arguments );
6091
6092                } else if ( fn == null || bool ) {
6093                        this.each(function() {
6094                                var state = bool ? fn : jQuery(this).is(":hidden");
6095                                jQuery(this)[ state ? "show" : "hide" ]();
6096                        });
6097
6098                } else {
6099                        this.animate(genFx("toggle", 3), fn, fn2, callback);
6100                }
6101
6102                return this;
6103        },
6104
6105        fadeTo: function( speed, to, easing, callback ) {
6106                return this.filter(":hidden").css("opacity", 0).show().end()
6107                                        .animate({opacity: to}, speed, easing, callback);
6108        },
6109
6110        animate: function( prop, speed, easing, callback ) {
6111                var optall = jQuery.speed(speed, easing, callback);
6112
6113                if ( jQuery.isEmptyObject( prop ) ) {
6114                        return this.each( optall.complete );
6115                }
6116
6117                return this[ optall.queue === false ? "each" : "queue" ](function() {
6118                        // XXX ‘this’ does not always have a nodeName when running the
6119                        // test suite
6120
6121                        var opt = jQuery.extend({}, optall), p,
6122                                isElement = this.nodeType === 1,
6123                                hidden = isElement && jQuery(this).is(":hidden"),
6124                                self = this;
6125
6126                        for ( p in prop ) {
6127                                var name = jQuery.camelCase( p );
6128
6129                                if ( p !== name ) {
6130                                        prop[ name ] = prop[ p ];
6131                                        delete prop[ p ];
6132                                        p = name;
6133                                }
6134
6135                                if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
6136                                        return opt.complete.call(this);
6137                                }
6138
6139                                if ( isElement && ( p === "height" || p === "width" ) ) {
6140                                        // Make sure that nothing sneaks out
6141                                        // Record all 3 overflow attributes because IE does not
6142                                        // change the overflow attribute when overflowX and
6143                                        // overflowY are set to the same value
6144                                        opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
6145
6146                                        // Set display property to inline-block for height/width
6147                                        // animations on inline elements that are having width/height
6148                                        // animated
6149                                        if ( jQuery.css( this, "display" ) === "inline" &&
6150                                                        jQuery.css( this, "float" ) === "none" ) {
6151                                                if ( !jQuery.support.inlineBlockNeedsLayout ) {
6152                                                        this.style.display = "inline-block";
6153
6154                                                } else {
6155                                                        var display = defaultDisplay(this.nodeName);
6156
6157                                                        // inline-level elements accept inline-block;
6158                                                        // block-level elements need to be inline with layout
6159                                                        if ( display === "inline" ) {
6160                                                                this.style.display = "inline-block";
6161
6162                                                        } else {
6163                                                                this.style.display = "inline";
6164                                                                this.style.zoom = 1;
6165                                                        }
6166                                                }
6167                                        }
6168                                }
6169
6170                                if ( jQuery.isArray( prop[p] ) ) {
6171                                        // Create (if needed) and add to specialEasing
6172                                        (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
6173                                        prop[p] = prop[p][0];
6174                                }
6175                        }
6176
6177                        if ( opt.overflow != null ) {
6178                                this.style.overflow = "hidden";
6179                        }
6180
6181                        opt.curAnim = jQuery.extend({}, prop);
6182
6183                        jQuery.each( prop, function( name, val ) {
6184                                var e = new jQuery.fx( self, opt, name );
6185
6186                                if ( rfxtypes.test(val) ) {
6187                                        e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
6188
6189                                } else {
6190                                        var parts = rfxnum.exec(val),
6191                                                start = e.cur(true) || 0;
6192
6193                                        if ( parts ) {
6194                                                var end = parseFloat( parts[2] ),
6195                                                        unit = parts[3] || "px";
6196
6197                                                // We need to compute starting value
6198                                                if ( unit !== "px" ) {
6199                                                        jQuery.style( self, name, (end || 1) + unit);
6200                                                        start = ((end || 1) / e.cur(true)) * start;
6201                                                        jQuery.style( self, name, start + unit);
6202                                                }
6203
6204                                                // If a +=/-= token was provided, we're doing a relative animation
6205                                                if ( parts[1] ) {
6206                                                        end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
6207                                                }
6208
6209                                                e.custom( start, end, unit );
6210
6211                                        } else {
6212                                                e.custom( start, val, "" );
6213                                        }
6214                                }
6215                        });
6216
6217                        // For JS strict compliance
6218                        return true;
6219                });
6220        },
6221
6222        stop: function( clearQueue, gotoEnd ) {
6223                var timers = jQuery.timers;
6224
6225                if ( clearQueue ) {
6226                        this.queue([]);
6227                }
6228
6229                this.each(function() {
6230                        // go in reverse order so anything added to the queue during the loop is ignored
6231                        for ( var i = timers.length - 1; i >= 0; i-- ) {
6232                                if ( timers[i].elem === this ) {
6233                                        if (gotoEnd) {
6234                                                // force the next step to be the last
6235                                                timers[i](true);
6236                                        }
6237
6238                                        timers.splice(i, 1);
6239                                }
6240                        }
6241                });
6242
6243                // start the next in the queue if the last step wasn't forced
6244                if ( !gotoEnd ) {
6245                        this.dequeue();
6246                }
6247
6248                return this;
6249        }
6250
6251});
6252
6253function genFx( type, num ) {
6254        var obj = {};
6255
6256        jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
6257                obj[ this ] = type;
6258        });
6259
6260        return obj;
6261}
6262
6263// Generate shortcuts for custom animations
6264jQuery.each({
6265        slideDown: genFx("show", 1),
6266        slideUp: genFx("hide", 1),
6267        slideToggle: genFx("toggle", 1),
6268        fadeIn: { opacity: "show" },
6269        fadeOut: { opacity: "hide" }
6270}, function( name, props ) {
6271        jQuery.fn[ name ] = function( speed, easing, callback ) {
6272                return this.animate( props, speed, easing, callback );
6273        };
6274});
6275
6276jQuery.extend({
6277        speed: function( speed, easing, fn ) {
6278                var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
6279                        complete: fn || !fn && easing ||
6280                                jQuery.isFunction( speed ) && speed,
6281                        duration: speed,
6282                        easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
6283                };
6284
6285                opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6286                        opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
6287
6288                // Queueing
6289                opt.old = opt.complete;
6290                opt.complete = function() {
6291                        if ( opt.queue !== false ) {
6292                                jQuery(this).dequeue();
6293                        }
6294                        if ( jQuery.isFunction( opt.old ) ) {
6295                                opt.old.call( this );
6296                        }
6297                };
6298
6299                return opt;
6300        },
6301
6302        easing: {
6303                linear: function( p, n, firstNum, diff ) {
6304                        return firstNum + diff * p;
6305                },
6306                swing: function( p, n, firstNum, diff ) {
6307                        return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
6308                }
6309        },
6310
6311        timers: [],
6312
6313        fx: function( elem, options, prop ) {
6314                this.options = options;
6315                this.elem = elem;
6316                this.prop = prop;
6317
6318                if ( !options.orig ) {
6319                        options.orig = {};
6320                }
6321        }
6322
6323});
6324
6325jQuery.fx.prototype = {
6326        // Simple function for setting a style value
6327        update: function() {
6328                if ( this.options.step ) {
6329                        this.options.step.call( this.elem, this.now, this );
6330                }
6331
6332                (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
6333        },
6334
6335        // Get the current size
6336        cur: function() {
6337                if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
6338                        return this.elem[ this.prop ];
6339                }
6340
6341                var r = parseFloat( jQuery.css( this.elem, this.prop ) );
6342                return r && r > -10000 ? r : 0;
6343        },
6344
6345        // Start an animation from one number to another
6346        custom: function( from, to, unit ) {
6347                this.startTime = jQuery.now();
6348                this.start = from;
6349                this.end = to;
6350                this.unit = unit || this.unit || "px";
6351                this.now = this.start;
6352                this.pos = this.state = 0;
6353
6354                var self = this, fx = jQuery.fx;
6355                function t( gotoEnd ) {
6356                        return self.step(gotoEnd);
6357                }
6358
6359                t.elem = this.elem;
6360
6361                if ( t() && jQuery.timers.push(t) && !timerId ) {
6362                        timerId = setInterval(fx.tick, fx.interval);
6363                }
6364        },
6365
6366        // Simple 'show' function
6367        show: function() {
6368                // Remember where we started, so that we can go back to it later
6369                this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6370                this.options.show = true;
6371
6372                // Begin the animation
6373                // Make sure that we start at a small width/height to avoid any
6374                // flash of content
6375                this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
6376
6377                // Start by showing the element
6378                jQuery( this.elem ).show();
6379        },
6380
6381        // Simple 'hide' function
6382        hide: function() {
6383                // Remember where we started, so that we can go back to it later
6384                this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6385                this.options.hide = true;
6386
6387                // Begin the animation
6388                this.custom(this.cur(), 0);
6389        },
6390
6391        // Each step of an animation
6392        step: function( gotoEnd ) {
6393                var t = jQuery.now(), done = true;
6394
6395                if ( gotoEnd || t >= this.options.duration + this.startTime ) {
6396                        this.now = this.end;
6397                        this.pos = this.state = 1;
6398                        this.update();
6399
6400                        this.options.curAnim[ this.prop ] = true;
6401
6402                        for ( var i in this.options.curAnim ) {
6403                                if ( this.options.curAnim[i] !== true ) {
6404                                        done = false;
6405                                }
6406                        }
6407
6408                        if ( done ) {
6409                                // Reset the overflow
6410                                if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
6411                                        var elem = this.elem, options = this.options;
6412                                        jQuery.each( [ "", "X", "Y" ], function (index, value) {
6413                                                elem.style[ "overflow" + value ] = options.overflow[index];
6414                                        } );
6415                                }
6416
6417                                // Hide the element if the "hide" operation was done
6418                                if ( this.options.hide ) {
6419                                        jQuery(this.elem).hide();
6420                                }
6421
6422                                // Reset the properties, if the item has been hidden or shown
6423                                if ( this.options.hide || this.options.show ) {
6424                                        for ( var p in this.options.curAnim ) {
6425                                                jQuery.style( this.elem, p, this.options.orig[p] );
6426                                        }
6427                                }
6428
6429                                // Execute the complete function
6430                                this.options.complete.call( this.elem );
6431                        }
6432
6433                        return false;
6434
6435                } else {
6436                        var n = t - this.startTime;
6437                        this.state = n / this.options.duration;
6438
6439                        // Perform the easing function, defaults to swing
6440                        var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
6441                        var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
6442                        this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
6443                        this.now = this.start + ((this.end - this.start) * this.pos);
6444
6445                        // Perform the next step of the animation
6446                        this.update();
6447                }
6448
6449                return true;
6450        }
6451};
6452
6453jQuery.extend( jQuery.fx, {
6454        tick: function() {
6455                var timers = jQuery.timers;
6456
6457                for ( var i = 0; i < timers.length; i++ ) {
6458                        if ( !timers[i]() ) {
6459                                timers.splice(i--, 1);
6460                        }
6461                }
6462
6463                if ( !timers.length ) {
6464                        jQuery.fx.stop();
6465                }
6466        },
6467
6468        interval: 13,
6469
6470        stop: function() {
6471                clearInterval( timerId );
6472                timerId = null;
6473        },
6474
6475        speeds: {
6476                slow: 600,
6477                fast: 200,
6478                // Default speed
6479                _default: 400
6480        },
6481
6482        step: {
6483                opacity: function( fx ) {
6484                        jQuery.style( fx.elem, "opacity", fx.now );
6485                },
6486
6487                _default: function( fx ) {
6488                        if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
6489                                fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
6490                        } else {
6491                                fx.elem[ fx.prop ] = fx.now;
6492                        }
6493                }
6494        }
6495});
6496
6497if ( jQuery.expr && jQuery.expr.filters ) {
6498        jQuery.expr.filters.animated = function( elem ) {
6499                return jQuery.grep(jQuery.timers, function( fn ) {
6500                        return elem === fn.elem;
6501                }).length;
6502        };
6503}
6504
6505function defaultDisplay( nodeName ) {
6506        if ( !elemdisplay[ nodeName ] ) {
6507                var elem = jQuery("<" + nodeName + ">").appendTo("body"),
6508                        display = elem.css("display");
6509
6510                elem.remove();
6511
6512                if ( display === "none" || display === "" ) {
6513                        display = "block";
6514                }
6515
6516                elemdisplay[ nodeName ] = display;
6517        }
6518
6519        return elemdisplay[ nodeName ];
6520}
6521
6522
6523
6524
6525var rtable = /^t(?:able|d|h)$/i,
6526        rroot = /^(?:body|html)$/i;
6527
6528if ( "getBoundingClientRect" in document.documentElement ) {
6529        jQuery.fn.offset = function( options ) {
6530                var elem = this[0], box;
6531
6532                if ( options ) {
6533                        return this.each(function( i ) {
6534                                jQuery.offset.setOffset( this, options, i );
6535                        });
6536                }
6537
6538                if ( !elem || !elem.ownerDocument ) {
6539                        return null;
6540                }
6541
6542                if ( elem === elem.ownerDocument.body ) {
6543                        return jQuery.offset.bodyOffset( elem );
6544                }
6545
6546                try {
6547                        box = elem.getBoundingClientRect();
6548                } catch(e) {}
6549
6550                var doc = elem.ownerDocument,
6551                        docElem = doc.documentElement;
6552
6553                // Make sure we're not dealing with a disconnected DOM node
6554                if ( !box || !jQuery.contains( docElem, elem ) ) {
6555                        return box || { top: 0, left: 0 };
6556                }
6557
6558                var body = doc.body,
6559                        win = getWindow(doc),
6560                        clientTop  = docElem.clientTop  || body.clientTop  || 0,
6561                        clientLeft = docElem.clientLeft || body.clientLeft || 0,
6562                        scrollTop  = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ),
6563                        scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
6564                        top  = box.top  + scrollTop  - clientTop,
6565                        left = box.left + scrollLeft - clientLeft;
6566
6567                return { top: top, left: left };
6568        };
6569
6570} else {
6571        jQuery.fn.offset = function( options ) {
6572                var elem = this[0];
6573
6574                if ( options ) {
6575                        return this.each(function( i ) {
6576                                jQuery.offset.setOffset( this, options, i );
6577                        });
6578                }
6579
6580                if ( !elem || !elem.ownerDocument ) {
6581                        return null;
6582                }
6583
6584                if ( elem === elem.ownerDocument.body ) {
6585                        return jQuery.offset.bodyOffset( elem );
6586                }
6587
6588                jQuery.offset.initialize();
6589
6590                var offsetParent = elem.offsetParent, prevOffsetParent = elem,
6591                        doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
6592                        body = doc.body, defaultView = doc.defaultView,
6593                        prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
6594                        top = elem.offsetTop, left = elem.offsetLeft;
6595
6596                while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
6597                        if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6598                                break;
6599                        }
6600
6601                        computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
6602                        top  -= elem.scrollTop;
6603                        left -= elem.scrollLeft;
6604
6605                        if ( elem === offsetParent ) {
6606                                top  += elem.offsetTop;
6607                                left += elem.offsetLeft;
6608
6609                                if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
6610                                        top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
6611                                        left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6612                                }
6613
6614                                prevOffsetParent = offsetParent;
6615                                offsetParent = elem.offsetParent;
6616                        }
6617
6618                        if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
6619                                top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
6620                                left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6621                        }
6622
6623                        prevComputedStyle = computedStyle;
6624                }
6625
6626                if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
6627                        top  += body.offsetTop;
6628                        left += body.offsetLeft;
6629                }
6630
6631                if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6632                        top  += Math.max( docElem.scrollTop, body.scrollTop );
6633                        left += Math.max( docElem.scrollLeft, body.scrollLeft );
6634                }
6635
6636                return { top: top, left: left };
6637        };
6638}
6639
6640jQuery.offset = {
6641        initialize: function() {
6642                var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
6643                        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>";
6644
6645                jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
6646
6647                container.innerHTML = html;
6648                body.insertBefore( container, body.firstChild );
6649                innerDiv = container.firstChild;
6650                checkDiv = innerDiv.firstChild;
6651                td = innerDiv.nextSibling.firstChild.firstChild;
6652
6653                this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
6654                this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
6655
6656                checkDiv.style.position = "fixed";
6657                checkDiv.style.top = "20px";
6658
6659                // safari subtracts parent border width here which is 5px
6660                this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
6661                checkDiv.style.position = checkDiv.style.top = "";
6662
6663                innerDiv.style.overflow = "hidden";
6664                innerDiv.style.position = "relative";
6665
6666                this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
6667
6668                this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
6669
6670                body.removeChild( container );
6671                body = container = innerDiv = checkDiv = table = td = null;
6672                jQuery.offset.initialize = jQuery.noop;
6673        },
6674
6675        bodyOffset: function( body ) {
6676                var top = body.offsetTop, left = body.offsetLeft;
6677
6678                jQuery.offset.initialize();
6679
6680                if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
6681                        top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
6682                        left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
6683                }
6684
6685                return { top: top, left: left };
6686        },
6687       
6688        setOffset: function( elem, options, i ) {
6689                var position = jQuery.css( elem, "position" );
6690
6691                // set position first, in-case top/left are set even on static elem
6692                if ( position === "static" ) {
6693                        elem.style.position = "relative";
6694                }
6695
6696                var curElem = jQuery( elem ),
6697                        curOffset = curElem.offset(),
6698                        curCSSTop = jQuery.css( elem, "top" ),
6699                        curCSSLeft = jQuery.css( elem, "left" ),
6700                        calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
6701                        props = {}, curPosition = {}, curTop, curLeft;
6702
6703                // need to be able to calculate position if either top or left is auto and position is absolute
6704                if ( calculatePosition ) {
6705                        curPosition = curElem.position();
6706                }
6707
6708                curTop  = calculatePosition ? curPosition.top  : parseInt( curCSSTop,  10 ) || 0;
6709                curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
6710
6711                if ( jQuery.isFunction( options ) ) {
6712                        options = options.call( elem, i, curOffset );
6713                }
6714
6715                if (options.top != null) {
6716                        props.top = (options.top - curOffset.top) + curTop;
6717                }
6718                if (options.left != null) {
6719                        props.left = (options.left - curOffset.left) + curLeft;
6720                }
6721               
6722                if ( "using" in options ) {
6723                        options.using.call( elem, props );
6724                } else {
6725                        curElem.css( props );
6726                }
6727        }
6728};
6729
6730
6731jQuery.fn.extend({
6732        position: function() {
6733                if ( !this[0] ) {
6734                        return null;
6735                }
6736
6737                var elem = this[0],
6738
6739                // Get *real* offsetParent
6740                offsetParent = this.offsetParent(),
6741
6742                // Get correct offsets
6743                offset       = this.offset(),
6744                parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
6745
6746                // Subtract element margins
6747                // note: when an element has margin: auto the offsetLeft and marginLeft
6748                // are the same in Safari causing offset.left to incorrectly be 0
6749                offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
6750                offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
6751
6752                // Add offsetParent borders
6753                parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
6754                parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
6755
6756                // Subtract the two offsets
6757                return {
6758                        top:  offset.top  - parentOffset.top,
6759                        left: offset.left - parentOffset.left
6760                };
6761        },
6762
6763        offsetParent: function() {
6764                return this.map(function() {
6765                        var offsetParent = this.offsetParent || document.body;
6766                        while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
6767                                offsetParent = offsetParent.offsetParent;
6768                        }
6769                        return offsetParent;
6770                });
6771        }
6772});
6773
6774
6775// Create scrollLeft and scrollTop methods
6776jQuery.each( ["Left", "Top"], function( i, name ) {
6777        var method = "scroll" + name;
6778
6779        jQuery.fn[ method ] = function(val) {
6780                var elem = this[0], win;
6781               
6782                if ( !elem ) {
6783                        return null;
6784                }
6785
6786                if ( val !== undefined ) {
6787                        // Set the scroll offset
6788                        return this.each(function() {
6789                                win = getWindow( this );
6790
6791                                if ( win ) {
6792                                        win.scrollTo(
6793                                                !i ? val : jQuery(win).scrollLeft(),
6794                                                 i ? val : jQuery(win).scrollTop()
6795                                        );
6796
6797                                } else {
6798                                        this[ method ] = val;
6799                                }
6800                        });
6801                } else {
6802                        win = getWindow( elem );
6803
6804                        // Return the scroll offset
6805                        return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
6806                                jQuery.support.boxModel && win.document.documentElement[ method ] ||
6807                                        win.document.body[ method ] :
6808                                elem[ method ];
6809                }
6810        };
6811});
6812
6813function getWindow( elem ) {
6814        return jQuery.isWindow( elem ) ?
6815                elem :
6816                elem.nodeType === 9 ?
6817                        elem.defaultView || elem.parentWindow :
6818                        false;
6819}
6820
6821
6822
6823
6824// Create innerHeight, innerWidth, outerHeight and outerWidth methods
6825jQuery.each([ "Height", "Width" ], function( i, name ) {
6826
6827        var type = name.toLowerCase();
6828
6829        // innerHeight and innerWidth
6830        jQuery.fn["inner" + name] = function() {
6831                return this[0] ?
6832                        parseFloat( jQuery.css( this[0], type, "padding" ) ) :
6833                        null;
6834        };
6835
6836        // outerHeight and outerWidth
6837        jQuery.fn["outer" + name] = function( margin ) {
6838                return this[0] ?
6839                        parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
6840                        null;
6841        };
6842
6843        jQuery.fn[ type ] = function( size ) {
6844                // Get window width or height
6845                var elem = this[0];
6846                if ( !elem ) {
6847                        return size == null ? null : this;
6848                }
6849               
6850                if ( jQuery.isFunction( size ) ) {
6851                        return this.each(function( i ) {
6852                                var self = jQuery( this );
6853                                self[ type ]( size.call( this, i, self[ type ]() ) );
6854                        });
6855                }
6856
6857                return jQuery.isWindow( elem ) ?
6858                        // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
6859                        elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
6860                        elem.document.body[ "client" + name ] :
6861
6862                        // Get document width or height
6863                        (elem.nodeType === 9) ? // is it a document
6864                                // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
6865                                Math.max(
6866                                        elem.documentElement["client" + name],
6867                                        elem.body["scroll" + name], elem.documentElement["scroll" + name],
6868                                        elem.body["offset" + name], elem.documentElement["offset" + name]
6869                                ) :
6870
6871                                // Get or set width or height on the element
6872                                size === undefined ?
6873                                        // Get width or height on the element
6874                                        parseFloat( jQuery.css( elem, type ) ) :
6875
6876                                        // Set the width or height on the element (default to pixels if value is unitless)
6877                                        this.css( type, typeof size === "string" ? size : size + "px" );
6878        };
6879
6880});
6881
6882
6883})(window);
Note: See TracBrowser for help on using the repository browser.