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