adding a semicolon... yay!
[cxgn-jslib.git] / jQuery.js
blob441847adec070a46f392e0b3e18a3824e75f4c39
1 (function(){
2 /*
3  * jQuery 1.2.6 - New Wave Javascript
4  *
5  * Copyright (c) 2008 John Resig (jquery.com)
6  * Dual licensed under the MIT (MIT-LICENSE.txt)
7  * and GPL (GPL-LICENSE.txt) licenses.
8  *
9  * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
10  * $Rev: 5685 $
11  */
12 /////////////////////////
13 /*Comment by Naama Menda (Feb. 2009): 
14  * calling jQeury.noConflict()  in jQuery.init() function
15  * so this object will not override the '$' namespace used in Prototype.js
16  * sub classes using jQuery (see thickbox.js) must use the jQuery namespace instead of '$'
17  */
18 ///////////////////////
20 // Map over jQuery in case of overwrite
21 var _jQuery = window.jQuery,
22 // Map over the $ in case of overwrite
23         _$ = window.$;
25 var jQuery = window.jQuery = window.$ = function( selector, context ) {
26         // The jQuery object is actually just the init constructor 'enhanced'
27         return new jQuery.fn.init( selector, context );
30 // A simple way to check for HTML strings or ID strings
31 // (both of which we optimize for)
32 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
34 // Is it a simple selector
35         isSimple = /^.[^:#\[\.]*$/,
37 // Will speed up references to undefined, and allows munging its name.
38         undefined;
40 jQuery.fn = jQuery.prototype = {
41         init: function( selector, context ) {
42                 // Make sure that a selection was provided
43                 selector = selector || document;
44                 ///////////////////
45                 //don't use the default '$' namespace for this object. Instead use 'jQuery' 
46                 jQuery.noConflict();
47                 /////////////////////
48                 // Handle $(DOMElement)
49                 if ( selector.nodeType ) {
50                         this[0] = selector;
51                         this.length = 1;
52                         return this;
53                 }
54                 // Handle HTML strings
55                 if ( typeof selector == "string" ) {
56                         // Are we dealing with HTML string or an ID?
57                         var match = quickExpr.exec( selector );
59                         // Verify a match, and that no context was specified for #id
60                         if ( match && (match[1] || !context) ) {
62                                 // HANDLE: $(html) -> $(array)
63                                 if ( match[1] )
64                                         selector = jQuery.clean( [ match[1] ], context );
66                                 // HANDLE: $("#id")
67                                 else {
68                                         var elem = document.getElementById( match[3] );
70                                         // Make sure an element was located
71                                         if ( elem ){
72                                                 // Handle the case where IE and Opera return items
73                                                 // by name instead of ID
74                                                 if ( elem.id != match[3] )
75                                                         return jQuery().find( selector );
77                                                 // Otherwise, we inject the element directly into the jQuery object
78                                                 return jQuery( elem );
79                                         }
80                                         selector = [];
81                                 }
83                         // HANDLE: $(expr, [context])
84                         // (which is just equivalent to: $(content).find(expr)
85                         } else
86                                 return jQuery( context ).find( selector );
88                 // HANDLE: $(function)
89                 // Shortcut for document ready
90                 } else if ( jQuery.isFunction( selector ) )
91                         return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
93                 return this.setArray(jQuery.makeArray(selector));
94         },
96         // The current version of jQuery being used
97         jquery: "1.2.6",
99         // The number of elements contained in the matched element set
100         size: function() {
101                 return this.length;
102         },
104         // The number of elements contained in the matched element set
105         length: 0,
107         // Get the Nth element in the matched element set OR
108         // Get the whole matched element set as a clean array
109         get: function( num ) {
110                 return num == undefined ?
112                         // Return a 'clean' array
113                         jQuery.makeArray( this ) :
115                         // Return just the object
116                         this[ num ];
117         },
119         // Take an array of elements and push it onto the stack
120         // (returning the new matched element set)
121         pushStack: function( elems ) {
122                 // Build a new jQuery matched element set
123                 var ret = jQuery( elems );
125                 // Add the old object onto the stack (as a reference)
126                 ret.prevObject = this;
128                 // Return the newly-formed element set
129                 return ret;
130         },
132         // Force the current matched set of elements to become
133         // the specified array of elements (destroying the stack in the process)
134         // You should use pushStack() in order to do this, but maintain the stack
135         setArray: function( elems ) {
136                 // Resetting the length to 0, then using the native Array push
137                 // is a super-fast way to populate an object with array-like properties
138                 this.length = 0;
139                 Array.prototype.push.apply( this, elems );
141                 return this;
142         },
144         // Execute a callback for every element in the matched set.
145         // (You can seed the arguments with an array of args, but this is
146         // only used internally.)
147         each: function( callback, args ) {
148                 return jQuery.each( this, callback, args );
149         },
151         // Determine the position of an element within
152         // the matched set of elements
153         index: function( elem ) {
154                 var ret = -1;
156                 // Locate the position of the desired element
157                 return jQuery.inArray(
158                         // If it receives a jQuery object, the first element is used
159                         elem && elem.jquery ? elem[0] : elem
160                 , this );
161         },
163         attr: function( name, value, type ) {
164                 var options = name;
166                 // Look for the case where we're accessing a style value
167                 if ( name.constructor == String )
168                         if ( value === undefined )
169                                 return this[0] && jQuery[ type || "attr" ]( this[0], name );
171                         else {
172                                 options = {};
173                                 options[ name ] = value;
174                         }
176                 // Check to see if we're setting style values
177                 return this.each(function(i){
178                         // Set all the styles
179                         for ( name in options )
180                                 jQuery.attr(
181                                         type ?
182                                                 this.style :
183                                                 this,
184                                         name, jQuery.prop( this, options[ name ], type, i, name )
185                                 );
186                 });
187         },
189         css: function( key, value ) {
190                 // ignore negative width and height values
191                 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
192                         value = undefined;
193                 return this.attr( key, value, "curCSS" );
194         },
196         text: function( text ) {
197                 if ( typeof text != "object" && text != null )
198                         return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
200                 var ret = "";
202                 jQuery.each( text || this, function(){
203                         jQuery.each( this.childNodes, function(){
204                                 if ( this.nodeType != 8 )
205                                         ret += this.nodeType != 1 ?
206                                                 this.nodeValue :
207                                                 jQuery.fn.text( [ this ] );
208                         });
209                 });
211                 return ret;
212         },
214         wrapAll: function( html ) {
215                 if ( this[0] )
216                         // The elements to wrap the target around
217                         jQuery( html, this[0].ownerDocument )
218                                 .clone()
219                                 .insertBefore( this[0] )
220                                 .map(function(){
221                                         var elem = this;
223                                         while ( elem.firstChild )
224                                                 elem = elem.firstChild;
226                                         return elem;
227                                 })
228                                 .append(this);
230                 return this;
231         },
233         wrapInner: function( html ) {
234                 return this.each(function(){
235                         jQuery( this ).contents().wrapAll( html );
236                 });
237         },
239         wrap: function( html ) {
240                 return this.each(function(){
241                         jQuery( this ).wrapAll( html );
242                 });
243         },
245         append: function() {
246                 return this.domManip(arguments, true, false, function(elem){
247                         if (this.nodeType == 1)
248                                 this.appendChild( elem );
249                 });
250         },
252         prepend: function() {
253                 return this.domManip(arguments, true, true, function(elem){
254                         if (this.nodeType == 1)
255                                 this.insertBefore( elem, this.firstChild );
256                 });
257         },
259         before: function() {
260                 return this.domManip(arguments, false, false, function(elem){
261                         this.parentNode.insertBefore( elem, this );
262                 });
263         },
265         after: function() {
266                 return this.domManip(arguments, false, true, function(elem){
267                         this.parentNode.insertBefore( elem, this.nextSibling );
268                 });
269         },
271         end: function() {
272                 return this.prevObject || jQuery( [] );
273         },
275         find: function( selector ) {
276                 var elems = jQuery.map(this, function(elem){
277                         return jQuery.find( selector, elem );
278                 });
280                 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
281                         jQuery.unique( elems ) :
282                         elems );
283         },
285         clone: function( events ) {
286                 // Do the clone
287                 var ret = this.map(function(){
288                         if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
289                                 // IE copies events bound via attachEvent when
290                                 // using cloneNode. Calling detachEvent on the
291                                 // clone will also remove the events from the orignal
292                                 // In order to get around this, we use innerHTML.
293                                 // Unfortunately, this means some modifications to
294                                 // attributes in IE that are actually only stored
295                                 // as properties will not be copied (such as the
296                                 // the name attribute on an input).
297                                 var clone = this.cloneNode(true),
298                                         container = document.createElement("div");
299                                 container.appendChild(clone);
300                                 return jQuery.clean([container.innerHTML])[0];
301                         } else
302                                 return this.cloneNode(true);
303                 });
305                 // Need to set the expando to null on the cloned set if it exists
306                 // removeData doesn't work here, IE removes it from the original as well
307                 // this is primarily for IE but the data expando shouldn't be copied over in any browser
308                 var clone = ret.find("*").andSelf().each(function(){
309                         if ( this[ expando ] != undefined )
310                                 this[ expando ] = null;
311                 });
313                 // Copy the events from the original to the clone
314                 if ( events === true )
315                         this.find("*").andSelf().each(function(i){
316                                 if (this.nodeType == 3)
317                                         return;
318                                 var events = jQuery.data( this, "events" );
320                                 for ( var type in events )
321                                         for ( var handler in events[ type ] )
322                                                 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
323                         });
325                 // Return the cloned set
326                 return ret;
327         },
329         filter: function( selector ) {
330                 return this.pushStack(
331                         jQuery.isFunction( selector ) &&
332                         jQuery.grep(this, function(elem, i){
333                                 return selector.call( elem, i );
334                         }) ||
336                         jQuery.multiFilter( selector, this ) );
337         },
339         not: function( selector ) {
340                 if ( selector.constructor == String )
341                         // test special case where just one selector is passed in
342                         if ( isSimple.test( selector ) )
343                                 return this.pushStack( jQuery.multiFilter( selector, this, true ) );
344                         else
345                                 selector = jQuery.multiFilter( selector, this );
347                 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
348                 return this.filter(function() {
349                         return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
350                 });
351         },
353         add: function( selector ) {
354                 return this.pushStack( jQuery.unique( jQuery.merge(
355                         this.get(),
356                         typeof selector == 'string' ?
357                                 jQuery( selector ) :
358                                 jQuery.makeArray( selector )
359                 )));
360         },
362         is: function( selector ) {
363                 return !!selector && jQuery.multiFilter( selector, this ).length > 0;
364         },
366         hasClass: function( selector ) {
367                 return this.is( "." + selector );
368         },
370         val: function( value ) {
371                 if ( value == undefined ) {
373                         if ( this.length ) {
374                                 var elem = this[0];
376                                 // We need to handle select boxes special
377                                 if ( jQuery.nodeName( elem, "select" ) ) {
378                                         var index = elem.selectedIndex,
379                                                 values = [],
380                                                 options = elem.options,
381                                                 one = elem.type == "select-one";
383                                         // Nothing was selected
384                                         if ( index < 0 )
385                                                 return null;
387                                         // Loop through all the selected options
388                                         for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
389                                                 var option = options[ i ];
391                                                 if ( option.selected ) {
392                                                         // Get the specifc value for the option
393                                                         value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
395                                                         // We don't need an array for one selects
396                                                         if ( one )
397                                                                 return value;
399                                                         // Multi-Selects return an array
400                                                         values.push( value );
401                                                 }
402                                         }
404                                         return values;
406                                 // Everything else, we just grab the value
407                                 } else
408                                         return (this[0].value || "").replace(/\r/g, "");
410                         }
412                         return undefined;
413                 }
415                 if( value.constructor == Number )
416                         value += '';
418                 return this.each(function(){
419                         if ( this.nodeType != 1 )
420                                 return;
422                         if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
423                                 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
424                                         jQuery.inArray(this.name, value) >= 0);
426                         else if ( jQuery.nodeName( this, "select" ) ) {
427                                 var values = jQuery.makeArray(value);
429                                 jQuery( "option", this ).each(function(){
430                                         this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
431                                                 jQuery.inArray( this.text, values ) >= 0);
432                                 });
434                                 if ( !values.length )
435                                         this.selectedIndex = -1;
437                         } else
438                                 this.value = value;
439                 });
440         },
442         html: function( value ) {
443                 return value == undefined ?
444                         (this[0] ?
445                                 this[0].innerHTML :
446                                 null) :
447                         this.empty().append( value );
448         },
450         replaceWith: function( value ) {
451                 return this.after( value ).remove();
452         },
454         eq: function( i ) {
455                 return this.slice( i, i + 1 );
456         },
458         slice: function() {
459                 return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
460         },
462         map: function( callback ) {
463                 return this.pushStack( jQuery.map(this, function(elem, i){
464                         return callback.call( elem, i, elem );
465                 }));
466         },
468         andSelf: function() {
469                 return this.add( this.prevObject );
470         },
472         data: function( key, value ){
473                 var parts = key.split(".");
474                 parts[1] = parts[1] ? "." + parts[1] : "";
476                 if ( value === undefined ) {
477                         var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
479                         if ( data === undefined && this.length )
480                                 data = jQuery.data( this[0], key );
482                         return data === undefined && parts[1] ?
483                                 this.data( parts[0] ) :
484                                 data;
485                 } else
486                         return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
487                                 jQuery.data( this, key, value );
488                         });
489         },
491         removeData: function( key ){
492                 return this.each(function(){
493                         jQuery.removeData( this, key );
494                 });
495         },
497         domManip: function( args, table, reverse, callback ) {
498                 var clone = this.length > 1, elems;
500                 return this.each(function(){
501                         if ( !elems ) {
502                                 elems = jQuery.clean( args, this.ownerDocument );
504                                 if ( reverse )
505                                         elems.reverse();
506                         }
508                         var obj = this;
510                         if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
511                                 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
513                         var scripts = jQuery( [] );
515                         jQuery.each(elems, function(){
516                                 var elem = clone ?
517                                         jQuery( this ).clone( true )[0] :
518                                         this;
520                                 // execute all scripts after the elements have been injected
521                                 if ( jQuery.nodeName( elem, "script" ) )
522                                         scripts = scripts.add( elem );
523                                 else {
524                                         // Remove any inner scripts for later evaluation
525                                         if ( elem.nodeType == 1 )
526                                                 scripts = scripts.add( jQuery( "script", elem ).remove() );
528                                         // Inject the elements into the document
529                                         callback.call( obj, elem );
530                                 }
531                         });
533                         scripts.each( evalScript );
534                 });
535         }
538 // Give the init function the jQuery prototype for later instantiation
539 jQuery.fn.init.prototype = jQuery.fn;
541 function evalScript( i, elem ) {
542         if ( elem.src )
543                 jQuery.ajax({
544                         url: elem.src,
545                         async: false,
546                         dataType: "script"
547                 });
549         else
550                 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
552         if ( elem.parentNode )
553                 elem.parentNode.removeChild( elem );
556 function now(){
557         return +new Date;
560 jQuery.extend = jQuery.fn.extend = function() {
561         // copy reference to target object
562         var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
564         // Handle a deep copy situation
565         if ( target.constructor == Boolean ) {
566                 deep = target;
567                 target = arguments[1] || {};
568                 // skip the boolean and the target
569                 i = 2;
570         }
572         // Handle case when target is a string or something (possible in deep copy)
573         if ( typeof target != "object" && typeof target != "function" )
574                 target = {};
576         // extend jQuery itself if only one argument is passed
577         if ( length == i ) {
578                 target = this;
579                 --i;
580         }
582         for ( ; i < length; i++ )
583                 // Only deal with non-null/undefined values
584                 if ( (options = arguments[ i ]) != null )
585                         // Extend the base object
586                         for ( var name in options ) {
587                                 var src = target[ name ], copy = options[ name ];
589                                 // Prevent never-ending loop
590                                 if ( target === copy )
591                                         continue;
593                                 // Recurse if we're merging object values
594                                 if ( deep && copy && typeof copy == "object" && !copy.nodeType )
595                                         target[ name ] = jQuery.extend( deep, 
596                                                 // Never move original objects, clone them
597                                                 src || ( copy.length != null ? [ ] : { } )
598                                         , copy );
600                                 // Don't bring in undefined values
601                                 else if ( copy !== undefined )
602                                         target[ name ] = copy;
604                         }
606         // Return the modified object
607         return target;
610 var expando = "jQuery" + now(), uuid = 0, windowData = {},
611         // exclude the following css properties to add px
612         exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
613         // cache defaultView
614         defaultView = document.defaultView || {};
616 jQuery.extend({
617         noConflict: function( deep ) {
618                 window.$ = _$;
620                 if ( deep )
621                         window.jQuery = _jQuery;
623                 return jQuery;
624         },
626         // See test/unit/core.js for details concerning this function.
627         isFunction: function( fn ) {
628                 return !!fn && typeof fn != "string" && !fn.nodeName &&
629                         fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
630         },
632         // check if an element is in a (or is an) XML document
633         isXMLDoc: function( elem ) {
634                 return elem.documentElement && !elem.body ||
635                         elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
636         },
638         // Evalulates a script in a global context
639         globalEval: function( data ) {
640                 data = jQuery.trim( data );
642                 if ( data ) {
643                         // Inspired by code by Andrea Giammarchi
644                         // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
645                         var head = document.getElementsByTagName("head")[0] || document.documentElement,
646                                 script = document.createElement("script");
648                         script.type = "text/javascript";
649                         if ( jQuery.browser.msie )
650                                 script.text = data;
651                         else
652                                 script.appendChild( document.createTextNode( data ) );
654                         // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
655                         // This arises when a base node is used (#2709).
656                         head.insertBefore( script, head.firstChild );
657                         head.removeChild( script );
658                 }
659         },
661         nodeName: function( elem, name ) {
662                 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
663         },
665         cache: {},
667         data: function( elem, name, data ) {
668                 elem = elem == window ?
669                         windowData :
670                         elem;
672                 var id = elem[ expando ];
674                 // Compute a unique ID for the element
675                 if ( !id )
676                         id = elem[ expando ] = ++uuid;
678                 // Only generate the data cache if we're
679                 // trying to access or manipulate it
680                 if ( name && !jQuery.cache[ id ] )
681                         jQuery.cache[ id ] = {};
683                 // Prevent overriding the named cache with undefined values
684                 if ( data !== undefined )
685                         jQuery.cache[ id ][ name ] = data;
687                 // Return the named cache data, or the ID for the element
688                 return name ?
689                         jQuery.cache[ id ][ name ] :
690                         id;
691         },
693         removeData: function( elem, name ) {
694                 elem = elem == window ?
695                         windowData :
696                         elem;
698                 var id = elem[ expando ];
700                 // If we want to remove a specific section of the element's data
701                 if ( name ) {
702                         if ( jQuery.cache[ id ] ) {
703                                 // Remove the section of cache data
704                                 delete jQuery.cache[ id ][ name ];
706                                 // If we've removed all the data, remove the element's cache
707                                 name = "";
709                                 for ( name in jQuery.cache[ id ] )
710                                         break;
712                                 if ( !name )
713                                         jQuery.removeData( elem );
714                         }
716                 // Otherwise, we want to remove all of the element's data
717                 } else {
718                         // Clean up the element expando
719                         try {
720                                 delete elem[ expando ];
721                         } catch(e){
722                                 // IE has trouble directly removing the expando
723                                 // but it's ok with using removeAttribute
724                                 if ( elem.removeAttribute )
725                                         elem.removeAttribute( expando );
726                         }
728                         // Completely remove the data cache
729                         delete jQuery.cache[ id ];
730                 }
731         },
733         // args is for internal usage only
734         each: function( object, callback, args ) {
735                 var name, i = 0, length = object.length;
737                 if ( args ) {
738                         if ( length == undefined ) {
739                                 for ( name in object )
740                                         if ( callback.apply( object[ name ], args ) === false )
741                                                 break;
742                         } else
743                                 for ( ; i < length; )
744                                         if ( callback.apply( object[ i++ ], args ) === false )
745                                                 break;
747                 // A special, fast, case for the most common use of each
748                 } else {
749                         if ( length == undefined ) {
750                                 for ( name in object )
751                                         if ( callback.call( object[ name ], name, object[ name ] ) === false )
752                                                 break;
753                         } else
754                                 for ( var value = object[0];
755                                         i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
756                 }
758                 return object;
759         },
761         prop: function( elem, value, type, i, name ) {
762                 // Handle executable functions
763                 if ( jQuery.isFunction( value ) )
764                         value = value.call( elem, i );
766                 // Handle passing in a number to a CSS property
767                 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
768                         value + "px" :
769                         value;
770         },
772         className: {
773                 // internal only, use addClass("class")
774                 add: function( elem, classNames ) {
775                         jQuery.each((classNames || "").split(/\s+/), function(i, className){
776                                 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
777                                         elem.className += (elem.className ? " " : "") + className;
778                         });
779                 },
781                 // internal only, use removeClass("class")
782                 remove: function( elem, classNames ) {
783                         if (elem.nodeType == 1)
784                                 elem.className = classNames != undefined ?
785                                         jQuery.grep(elem.className.split(/\s+/), function(className){
786                                                 return !jQuery.className.has( classNames, className );
787                                         }).join(" ") :
788                                         "";
789                 },
791                 // internal only, use hasClass("class")
792                 has: function( elem, className ) {
793                         return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
794                 }
795         },
797         // A method for quickly swapping in/out CSS properties to get correct calculations
798         swap: function( elem, options, callback ) {
799                 var old = {};
800                 // Remember the old values, and insert the new ones
801                 for ( var name in options ) {
802                         old[ name ] = elem.style[ name ];
803                         elem.style[ name ] = options[ name ];
804                 }
806                 callback.call( elem );
808                 // Revert the old values
809                 for ( var name in options )
810                         elem.style[ name ] = old[ name ];
811         },
813         css: function( elem, name, force ) {
814                 if ( name == "width" || name == "height" ) {
815                         var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
817                         function getWH() {
818                                 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
819                                 var padding = 0, border = 0;
820                                 jQuery.each( which, function() {
821                                         padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
822                                         border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
823                                 });
824                                 val -= Math.round(padding + border);
825                         }
827                         if ( jQuery(elem).is(":visible") )
828                                 getWH();
829                         else
830                                 jQuery.swap( elem, props, getWH );
832                         return Math.max(0, val);
833                 }
835                 return jQuery.curCSS( elem, name, force );
836         },
838         curCSS: function( elem, name, force ) {
839                 var ret, style = elem.style;
841                 // A helper method for determining if an element's values are broken
842                 function color( elem ) {
843                         if ( !jQuery.browser.safari )
844                                 return false;
846                         // defaultView is cached
847                         var ret = defaultView.getComputedStyle( elem, null );
848                         return !ret || ret.getPropertyValue("color") == "";
849                 }
851                 // We need to handle opacity special in IE
852                 if ( name == "opacity" && jQuery.browser.msie ) {
853                         ret = jQuery.attr( style, "opacity" );
855                         return ret == "" ?
856                                 "1" :
857                                 ret;
858                 }
859                 // Opera sometimes will give the wrong display answer, this fixes it, see #2037
860                 if ( jQuery.browser.opera && name == "display" ) {
861                         var save = style.outline;
862                         style.outline = "0 solid black";
863                         style.outline = save;
864                 }
866                 // Make sure we're using the right name for getting the float value
867                 if ( name.match( /float/i ) )
868                         name = styleFloat;
870                 if ( !force && style && style[ name ] )
871                         ret = style[ name ];
873                 else if ( defaultView.getComputedStyle ) {
875                         // Only "float" is needed here
876                         if ( name.match( /float/i ) )
877                                 name = "float";
879                         name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
881                         var computedStyle = defaultView.getComputedStyle( elem, null );
883                         if ( computedStyle && !color( elem ) )
884                                 ret = computedStyle.getPropertyValue( name );
886                         // If the element isn't reporting its values properly in Safari
887                         // then some display: none elements are involved
888                         else {
889                                 var swap = [], stack = [], a = elem, i = 0;
891                                 // Locate all of the parent display: none elements
892                                 for ( ; a && color(a); a = a.parentNode )
893                                         stack.unshift(a);
895                                 // Go through and make them visible, but in reverse
896                                 // (It would be better if we knew the exact display type that they had)
897                                 for ( ; i < stack.length; i++ )
898                                         if ( color( stack[ i ] ) ) {
899                                                 swap[ i ] = stack[ i ].style.display;
900                                                 stack[ i ].style.display = "block";
901                                         }
903                                 // Since we flip the display style, we have to handle that
904                                 // one special, otherwise get the value
905                                 ret = name == "display" && swap[ stack.length - 1 ] != null ?
906                                         "none" :
907                                         ( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
909                                 // Finally, revert the display styles back
910                                 for ( i = 0; i < swap.length; i++ )
911                                         if ( swap[ i ] != null )
912                                                 stack[ i ].style.display = swap[ i ];
913                         }
915                         // We should always get a number back from opacity
916                         if ( name == "opacity" && ret == "" )
917                                 ret = "1";
919                 } else if ( elem.currentStyle ) {
920                         var camelCase = name.replace(/\-(\w)/g, function(all, letter){
921                                 return letter.toUpperCase();
922                         });
924                         ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
926                         // From the awesome hack by Dean Edwards
927                         // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
929                         // If we're not dealing with a regular pixel number
930                         // but a number that has a weird ending, we need to convert it to pixels
931                         if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
932                                 // Remember the original values
933                                 var left = style.left, rsLeft = elem.runtimeStyle.left;
935                                 // Put in the new values to get a computed value out
936                                 elem.runtimeStyle.left = elem.currentStyle.left;
937                                 style.left = ret || 0;
938                                 ret = style.pixelLeft + "px";
940                                 // Revert the changed values
941                                 style.left = left;
942                                 elem.runtimeStyle.left = rsLeft;
943                         }
944                 }
946                 return ret;
947         },
949         clean: function( elems, context ) {
950                 var ret = [];
951                 context = context || document;
952                 // !context.createElement fails in IE with an error but returns typeof 'object'
953                 if (typeof context.createElement == 'undefined')
954                         context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
956                 jQuery.each(elems, function(i, elem){
957                         if ( !elem )
958                                 return;
960                         if ( elem.constructor == Number )
961                                 elem += '';
963                         // Convert html string into DOM nodes
964                         if ( typeof elem == "string" ) {
965                                 // Fix "XHTML"-style tags in all browsers
966                                 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
967                                         return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
968                                                 all :
969                                                 front + "></" + tag + ">";
970                                 });
972                                 // Trim whitespace, otherwise indexOf won't work as expected
973                                 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
975                                 var wrap =
976                                         // option or optgroup
977                                         !tags.indexOf("<opt") &&
978                                         [ 1, "<select multiple='multiple'>", "</select>" ] ||
980                                         !tags.indexOf("<leg") &&
981                                         [ 1, "<fieldset>", "</fieldset>" ] ||
983                                         tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
984                                         [ 1, "<table>", "</table>" ] ||
986                                         !tags.indexOf("<tr") &&
987                                         [ 2, "<table><tbody>", "</tbody></table>" ] ||
989                                         // <thead> matched above
990                                         (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
991                                         [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
993                                         !tags.indexOf("<col") &&
994                                         [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
996                                         // IE can't serialize <link> and <script> tags normally
997                                         jQuery.browser.msie &&
998                                         [ 1, "div<div>", "</div>" ] ||
1000                                         [ 0, "", "" ];
1002                                 // Go to html and back, then peel off extra wrappers
1003                                 div.innerHTML = wrap[1] + elem + wrap[2];
1005                                 // Move to the right depth
1006                                 while ( wrap[0]-- )
1007                                         div = div.lastChild;
1009                                 // Remove IE's autoinserted <tbody> from table fragments
1010                                 if ( jQuery.browser.msie ) {
1012                                         // String was a <table>, *may* have spurious <tbody>
1013                                         var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
1014                                                 div.firstChild && div.firstChild.childNodes :
1016                                                 // String was a bare <thead> or <tfoot>
1017                                                 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
1018                                                         div.childNodes :
1019                                                         [];
1021                                         for ( var j = tbody.length - 1; j >= 0 ; --j )
1022                                                 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
1023                                                         tbody[ j ].parentNode.removeChild( tbody[ j ] );
1025                                         // IE completely kills leading whitespace when innerHTML is used
1026                                         if ( /^\s/.test( elem ) )
1027                                                 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
1029                                 }
1031                                 elem = jQuery.makeArray( div.childNodes );
1032                         }
1034                         if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
1035                                 return;
1037                         if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
1038                                 ret.push( elem );
1040                         else
1041                                 ret = jQuery.merge( ret, elem );
1043                 });
1045                 return ret;
1046         },
1048         attr: function( elem, name, value ) {
1049                 // don't set attributes on text and comment nodes
1050                 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
1051                         return undefined;
1053                 var notxml = !jQuery.isXMLDoc( elem ),
1054                         // Whether we are setting (or getting)
1055                         set = value !== undefined,
1056                         msie = jQuery.browser.msie;
1058                 // Try to normalize/fix the name
1059                 name = notxml && jQuery.props[ name ] || name;
1061                 // Only do all the following if this is a node (faster for style)
1062                 // IE elem.getAttribute passes even for style
1063                 if ( elem.tagName ) {
1065                         // These attributes require special treatment
1066                         var special = /href|src|style/.test( name );
1068                         // Safari mis-reports the default selected property of a hidden option
1069                         // Accessing the parent's selectedIndex property fixes it
1070                         if ( name == "selected" && jQuery.browser.safari )
1071                                 elem.parentNode.selectedIndex;
1073                         // If applicable, access the attribute via the DOM 0 way
1074                         if ( name in elem && notxml && !special ) {
1075                                 if ( set ){
1076                                         // We can't allow the type property to be changed (since it causes problems in IE)
1077                                         if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
1078                                                 throw "type property can't be changed";
1080                                         elem[ name ] = value;
1081                                 }
1083                                 // browsers index elements by id/name on forms, give priority to attributes.
1084                                 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1085                                         return elem.getAttributeNode( name ).nodeValue;
1087                                 return elem[ name ];
1088                         }
1090                         if ( msie && notxml &&  name == "style" )
1091                                 return jQuery.attr( elem.style, "cssText", value );
1093                         if ( set )
1094                                 // convert the value to a string (all browsers do this but IE) see #1070
1095                                 elem.setAttribute( name, "" + value );
1097                         var attr = msie && notxml && special
1098                                         // Some attributes require a special call on IE
1099                                         ? elem.getAttribute( name, 2 )
1100                                         : elem.getAttribute( name );
1102                         // Non-existent attributes return null, we normalize to undefined
1103                         return attr === null ? undefined : attr;
1104                 }
1106                 // elem is actually elem.style ... set the style
1108                 // IE uses filters for opacity
1109                 if ( msie && name == "opacity" ) {
1110                         if ( set ) {
1111                                 // IE has trouble with opacity if it does not have layout
1112                                 // Force it by setting the zoom level
1113                                 elem.zoom = 1;
1115                                 // Set the alpha filter to set the opacity
1116                                 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1117                                         (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1118                         }
1120                         return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1121                                 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1122                                 "";
1123                 }
1125                 name = name.replace(/-([a-z])/ig, function(all, letter){
1126                         return letter.toUpperCase();
1127                 });
1129                 if ( set )
1130                         elem[ name ] = value;
1132                 return elem[ name ];
1133         },
1135         trim: function( text ) {
1136                 return (text || "").replace( /^\s+|\s+$/g, "" );
1137         },
1139         makeArray: function( array ) {
1140                 var ret = [];
1142                 if( array != null ){
1143                         var i = array.length;
1144                         //the window, strings and functions also have 'length'
1145                         if( i == null || array.split || array.setInterval || array.call )
1146                                 ret[0] = array;
1147                         else
1148                                 while( i )
1149                                         ret[--i] = array[i];
1150                 }
1152                 return ret;
1153         },
1155         inArray: function( elem, array ) {
1156                 for ( var i = 0, length = array.length; i < length; i++ )
1157                 // Use === because on IE, window == document
1158                         if ( array[ i ] === elem )
1159                                 return i;
1161                 return -1;
1162         },
1164         merge: function( first, second ) {
1165                 // We have to loop this way because IE & Opera overwrite the length
1166                 // expando of getElementsByTagName
1167                 var i = 0, elem, pos = first.length;
1168                 // Also, we need to make sure that the correct elements are being returned
1169                 // (IE returns comment nodes in a '*' query)
1170                 if ( jQuery.browser.msie ) {
1171                         while ( elem = second[ i++ ] )
1172                                 if ( elem.nodeType != 8 )
1173                                         first[ pos++ ] = elem;
1175                 } else
1176                         while ( elem = second[ i++ ] )
1177                                 first[ pos++ ] = elem;
1179                 return first;
1180         },
1182         unique: function( array ) {
1183                 var ret = [], done = {};
1185                 try {
1187                         for ( var i = 0, length = array.length; i < length; i++ ) {
1188                                 var id = jQuery.data( array[ i ] );
1190                                 if ( !done[ id ] ) {
1191                                         done[ id ] = true;
1192                                         ret.push( array[ i ] );
1193                                 }
1194                         }
1196                 } catch( e ) {
1197                         ret = array;
1198                 }
1200                 return ret;
1201         },
1203         grep: function( elems, callback, inv ) {
1204                 var ret = [];
1206                 // Go through the array, only saving the items
1207                 // that pass the validator function
1208                 for ( var i = 0, length = elems.length; i < length; i++ )
1209                         if ( !inv != !callback( elems[ i ], i ) )
1210                                 ret.push( elems[ i ] );
1212                 return ret;
1213         },
1215         map: function( elems, callback ) {
1216                 var ret = [];
1218                 // Go through the array, translating each of the items to their
1219                 // new value (or values).
1220                 for ( var i = 0, length = elems.length; i < length; i++ ) {
1221                         var value = callback( elems[ i ], i );
1223                         if ( value != null )
1224                                 ret[ ret.length ] = value;
1225                 }
1227                 return ret.concat.apply( [], ret );
1228         }
1231 var userAgent = navigator.userAgent.toLowerCase();
1233 // Figure out what browser is being used
1234 jQuery.browser = {
1235         version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
1236         safari: /webkit/.test( userAgent ),
1237         opera: /opera/.test( userAgent ),
1238         msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1239         mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1242 var styleFloat = jQuery.browser.msie ?
1243         "styleFloat" :
1244         "cssFloat";
1246 jQuery.extend({
1247         // Check to see if the W3C box model is being used
1248         boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
1250         props: {
1251                 "for": "htmlFor",
1252                 "class": "className",
1253                 "float": styleFloat,
1254                 cssFloat: styleFloat,
1255                 styleFloat: styleFloat,
1256                 readonly: "readOnly",
1257                 maxlength: "maxLength",
1258                 cellspacing: "cellSpacing"
1259         }
1262 jQuery.each({
1263         parent: function(elem){return elem.parentNode;},
1264         parents: function(elem){return jQuery.dir(elem,"parentNode");},
1265         next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1266         prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1267         nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1268         prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1269         siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1270         children: function(elem){return jQuery.sibling(elem.firstChild);},
1271         contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1272 }, function(name, fn){
1273         jQuery.fn[ name ] = function( selector ) {
1274                 var ret = jQuery.map( this, fn );
1276                 if ( selector && typeof selector == "string" )
1277                         ret = jQuery.multiFilter( selector, ret );
1279                 return this.pushStack( jQuery.unique( ret ) );
1280         };
1283 jQuery.each({
1284         appendTo: "append",
1285         prependTo: "prepend",
1286         insertBefore: "before",
1287         insertAfter: "after",
1288         replaceAll: "replaceWith"
1289 }, function(name, original){
1290         jQuery.fn[ name ] = function() {
1291                 var args = arguments;
1293                 return this.each(function(){
1294                         for ( var i = 0, length = args.length; i < length; i++ )
1295                                 jQuery( args[ i ] )[ original ]( this );
1296                 });
1297         };
1300 jQuery.each({
1301         removeAttr: function( name ) {
1302                 jQuery.attr( this, name, "" );
1303                 if (this.nodeType == 1)
1304                         this.removeAttribute( name );
1305         },
1307         addClass: function( classNames ) {
1308                 jQuery.className.add( this, classNames );
1309         },
1311         removeClass: function( classNames ) {
1312                 jQuery.className.remove( this, classNames );
1313         },
1315         toggleClass: function( classNames ) {
1316                 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
1317         },
1319         remove: function( selector ) {
1320                 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
1321                         // Prevent memory leaks
1322                         jQuery( "*", this ).add(this).each(function(){
1323                                 jQuery.event.remove(this);
1324                                 jQuery.removeData(this);
1325                         });
1326                         if (this.parentNode)
1327                                 this.parentNode.removeChild( this );
1328                 }
1329         },
1331         empty: function() {
1332                 // Remove element nodes and prevent memory leaks
1333                 jQuery( ">*", this ).remove();
1335                 // Remove any remaining nodes
1336                 while ( this.firstChild )
1337                         this.removeChild( this.firstChild );
1338         }
1339 }, function(name, fn){
1340         jQuery.fn[ name ] = function(){
1341                 return this.each( fn, arguments );
1342         };
1345 jQuery.each([ "Height", "Width" ], function(i, name){
1346         var type = name.toLowerCase();
1348         jQuery.fn[ type ] = function( size ) {
1349                 // Get window width or height
1350                 return this[0] == window ?
1351                         // Opera reports document.body.client[Width/Height] properly in both quirks and standards
1352                         jQuery.browser.opera && document.body[ "client" + name ] ||
1354                         // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
1355                         jQuery.browser.safari && window[ "inner" + name ] ||
1357                         // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
1358                         document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
1360                         // Get document width or height
1361                         this[0] == document ?
1362                                 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
1363                                 Math.max(
1364                                         Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
1365                                         Math.max(document.body["offset" + name], document.documentElement["offset" + name])
1366                                 ) :
1368                                 // Get or set width or height on the element
1369                                 size == undefined ?
1370                                         // Get width or height on the element
1371                                         (this.length ? jQuery.css( this[0], type ) : null) :
1373                                         // Set the width or height on the element (default to pixels if value is unitless)
1374                                         this.css( type, size.constructor == String ? size : size + "px" );
1375         };
1378 // Helper function used by the dimensions and offset modules
1379 function num(elem, prop) {
1380         return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1381 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
1382                 "(?:[\\w*_-]|\\\\.)" :
1383                 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
1384         quickChild = new RegExp("^>\\s*(" + chars + "+)"),
1385         quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
1386         quickClass = new RegExp("^([#.]?)(" + chars + "*)");
1388 jQuery.extend({
1389         expr: {
1390                 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
1391                 "#": function(a,i,m){return a.getAttribute("id")==m[2];},
1392                 ":": {
1393                         // Position Checks
1394                         lt: function(a,i,m){return i<m[3]-0;},
1395                         gt: function(a,i,m){return i>m[3]-0;},
1396                         nth: function(a,i,m){return m[3]-0==i;},
1397                         eq: function(a,i,m){return m[3]-0==i;},
1398                         first: function(a,i){return i==0;},
1399                         last: function(a,i,m,r){return i==r.length-1;},
1400                         even: function(a,i){return i%2==0;},
1401                         odd: function(a,i){return i%2;},
1403                         // Child Checks
1404                         "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
1405                         "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
1406                         "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
1408                         // Parent Checks
1409                         parent: function(a){return a.firstChild;},
1410                         empty: function(a){return !a.firstChild;},
1412                         // Text Check
1413                         contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
1415                         // Visibility
1416                         visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
1417                         hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
1419                         // Form attributes
1420                         enabled: function(a){return !a.disabled;},
1421                         disabled: function(a){return a.disabled;},
1422                         checked: function(a){return a.checked;},
1423                         selected: function(a){return a.selected||jQuery.attr(a,"selected");},
1425                         // Form elements
1426                         text: function(a){return "text"==a.type;},
1427                         radio: function(a){return "radio"==a.type;},
1428                         checkbox: function(a){return "checkbox"==a.type;},
1429                         file: function(a){return "file"==a.type;},
1430                         password: function(a){return "password"==a.type;},
1431                         submit: function(a){return "submit"==a.type;},
1432                         image: function(a){return "image"==a.type;},
1433                         reset: function(a){return "reset"==a.type;},
1434                         button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
1435                         input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
1437                         // :has()
1438                         has: function(a,i,m){return jQuery.find(m[3],a).length;},
1440                         // :header
1441                         header: function(a){return /h\d/i.test(a.nodeName);},
1443                         // :animated
1444                         animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
1445                 }
1446         },
1448         // The regular expressions that power the parsing engine
1449         parse: [
1450                 // Match: [@value='test'], [@foo]
1451                 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
1453                 // Match: :contains('foo')
1454                 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
1456                 // Match: :even, :last-child, #id, .class
1457                 new RegExp("^([:.#]*)(" + chars + "+)")
1458         ],
1460         multiFilter: function( expr, elems, not ) {
1461                 var old, cur = [];
1463                 while ( expr && expr != old ) {
1464                         old = expr;
1465                         var f = jQuery.filter( expr, elems, not );
1466                         expr = f.t.replace(/^\s*,\s*/, "" );
1467                         cur = not ? elems = f.r : jQuery.merge( cur, f.r );
1468                 }
1470                 return cur;
1471         },
1473         find: function( t, context ) {
1474                 // Quickly handle non-string expressions
1475                 if ( typeof t != "string" )
1476                         return [ t ];
1478                 // check to make sure context is a DOM element or a document
1479                 if ( context && context.nodeType != 1 && context.nodeType != 9)
1480                         return [ ];
1482                 // Set the correct context (if none is provided)
1483                 context = context || document;
1485                 // Initialize the search
1486                 var ret = [context], done = [], last, nodeName;
1488                 // Continue while a selector expression exists, and while
1489                 // we're no longer looping upon ourselves
1490                 while ( t && last != t ) {
1491                         var r = [];
1492                         last = t;
1494                         t = jQuery.trim(t);
1496                         var foundToken = false,
1498                         // An attempt at speeding up child selectors that
1499                         // point to a specific element tag
1500                                 re = quickChild,
1502                                 m = re.exec(t);
1504                         if ( m ) {
1505                                 nodeName = m[1].toUpperCase();
1507                                 // Perform our own iteration and filter
1508                                 for ( var i = 0; ret[i]; i++ )
1509                                         for ( var c = ret[i].firstChild; c; c = c.nextSibling )
1510                                                 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
1511                                                         r.push( c );
1513                                 ret = r;
1514                                 t = t.replace( re, "" );
1515                                 if ( t.indexOf(" ") == 0 ) continue;
1516                                 foundToken = true;
1517                         } else {
1518                                 re = /^([>+~])\s*(\w*)/i;
1520                                 if ( (m = re.exec(t)) != null ) {
1521                                         r = [];
1523                                         var merge = {};
1524                                         nodeName = m[2].toUpperCase();
1525                                         m = m[1];
1527                                         for ( var j = 0, rl = ret.length; j < rl; j++ ) {
1528                                                 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
1529                                                 for ( ; n; n = n.nextSibling )
1530                                                         if ( n.nodeType == 1 ) {
1531                                                                 var id = jQuery.data(n);
1533                                                                 if ( m == "~" && merge[id] ) break;
1535                                                                 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
1536                                                                         if ( m == "~" ) merge[id] = true;
1537                                                                         r.push( n );
1538                                                                 }
1540                                                                 if ( m == "+" ) break;
1541                                                         }
1542                                         }
1544                                         ret = r;
1546                                         // And remove the token
1547                                         t = jQuery.trim( t.replace( re, "" ) );
1548                                         foundToken = true;
1549                                 }
1550                         }
1552                         // See if there's still an expression, and that we haven't already
1553                         // matched a token
1554                         if ( t && !foundToken ) {
1555                                 // Handle multiple expressions
1556                                 if ( !t.indexOf(",") ) {
1557                                         // Clean the result set
1558                                         if ( context == ret[0] ) ret.shift();
1560                                         // Merge the result sets
1561                                         done = jQuery.merge( done, ret );
1563                                         // Reset the context
1564                                         r = ret = [context];
1566                                         // Touch up the selector string
1567                                         t = " " + t.substr(1,t.length);
1569                                 } else {
1570                                         // Optimize for the case nodeName#idName
1571                                         var re2 = quickID;
1572                                         var m = re2.exec(t);
1574                                         // Re-organize the results, so that they're consistent
1575                                         if ( m ) {
1576                                                 m = [ 0, m[2], m[3], m[1] ];
1578                                         } else {
1579                                                 // Otherwise, do a traditional filter check for
1580                                                 // ID, class, and element selectors
1581                                                 re2 = quickClass;
1582                                                 m = re2.exec(t);
1583                                         }
1585                                         m[2] = m[2].replace(/\\/g, "");
1587                                         var elem = ret[ret.length-1];
1589                                         // Try to do a global search by ID, where we can
1590                                         if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
1591                                                 // Optimization for HTML document case
1592                                                 var oid = elem.getElementById(m[2]);
1594                                                 // Do a quick check for the existence of the actual ID attribute
1595                                                 // to avoid selecting by the name attribute in IE
1596                                                 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
1597                                                 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
1598                                                         oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
1600                                                 // Do a quick check for node name (where applicable) so
1601                                                 // that div#foo searches will be really fast
1602                                                 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
1603                                         } else {
1604                                                 // We need to find all descendant elements
1605                                                 for ( var i = 0; ret[i]; i++ ) {
1606                                                         // Grab the tag name being searched for
1607                                                         var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
1609                                                         // Handle IE7 being really dumb about <object>s
1610                                                         if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
1611                                                                 tag = "param";
1613                                                         r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
1614                                                 }
1616                                                 // It's faster to filter by class and be done with it
1617                                                 if ( m[1] == "." )
1618                                                         r = jQuery.classFilter( r, m[2] );
1620                                                 // Same with ID filtering
1621                                                 if ( m[1] == "#" ) {
1622                                                         var tmp = [];
1624                                                         // Try to find the element with the ID
1625                                                         for ( var i = 0; r[i]; i++ )
1626                                                                 if ( r[i].getAttribute("id") == m[2] ) {
1627                                                                         tmp = [ r[i] ];
1628                                                                         break;
1629                                                                 }
1631                                                         r = tmp;
1632                                                 }
1634                                                 ret = r;
1635                                         }
1637                                         t = t.replace( re2, "" );
1638                                 }
1640                         }
1642                         // If a selector string still exists
1643                         if ( t ) {
1644                                 // Attempt to filter it
1645                                 var val = jQuery.filter(t,r);
1646                                 ret = r = val.r;
1647                                 t = jQuery.trim(val.t);
1648                         }
1649                 }
1651                 // An error occurred with the selector;
1652                 // just return an empty set instead
1653                 if ( t )
1654                         ret = [];
1656                 // Remove the root context
1657                 if ( ret && context == ret[0] )
1658                         ret.shift();
1660                 // And combine the results
1661                 done = jQuery.merge( done, ret );
1663                 return done;
1664         },
1666         classFilter: function(r,m,not){
1667                 m = " " + m + " ";
1668                 var tmp = [];
1669                 for ( var i = 0; r[i]; i++ ) {
1670                         var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
1671                         if ( !not && pass || not && !pass )
1672                                 tmp.push( r[i] );
1673                 }
1674                 return tmp;
1675         },
1677         filter: function(t,r,not) {
1678                 var last;
1680                 // Look for common filter expressions
1681                 while ( t && t != last ) {
1682                         last = t;
1684                         var p = jQuery.parse, m;
1686                         for ( var i = 0; p[i]; i++ ) {
1687                                 m = p[i].exec( t );
1689                                 if ( m ) {
1690                                         // Remove what we just matched
1691                                         t = t.substring( m[0].length );
1693                                         m[2] = m[2].replace(/\\/g, "");
1694                                         break;
1695                                 }
1696                         }
1698                         if ( !m )
1699                                 break;
1701                         // :not() is a special case that can be optimized by
1702                         // keeping it out of the expression list
1703                         if ( m[1] == ":" && m[2] == "not" )
1704                                 // optimize if only one selector found (most common case)
1705                                 r = isSimple.test( m[3] ) ?
1706                                         jQuery.filter(m[3], r, true).r :
1707                                         jQuery( r ).not( m[3] );
1709                         // We can get a big speed boost by filtering by class here
1710                         else if ( m[1] == "." )
1711                                 r = jQuery.classFilter(r, m[2], not);
1713                         else if ( m[1] == "[" ) {
1714                                 var tmp = [], type = m[3];
1716                                 for ( var i = 0, rl = r.length; i < rl; i++ ) {
1717                                         var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
1719                                         if ( z == null || /href|src|selected/.test(m[2]) )
1720                                                 z = jQuery.attr(a,m[2]) || '';
1722                                         if ( (type == "" && !!z ||
1723                                                  type == "=" && z == m[5] ||
1724                                                  type == "!=" && z != m[5] ||
1725                                                  type == "^=" && z && !z.indexOf(m[5]) ||
1726                                                  type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
1727                                                  (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
1728                                                         tmp.push( a );
1729                                 }
1731                                 r = tmp;
1733                         // We can get a speed boost by handling nth-child here
1734                         } else if ( m[1] == ":" && m[2] == "nth-child" ) {
1735                                 var merge = {}, tmp = [],
1736                                         // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1737                                         test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1738                                                 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
1739                                                 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
1740                                         // calculate the numbers (first)n+(last) including if they are negative
1741                                         first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
1743                                 // loop through all the elements left in the jQuery object
1744                                 for ( var i = 0, rl = r.length; i < rl; i++ ) {
1745                                         var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
1747                                         if ( !merge[id] ) {
1748                                                 var c = 1;
1750                                                 for ( var n = parentNode.firstChild; n; n = n.nextSibling )
1751                                                         if ( n.nodeType == 1 )
1752                                                                 n.nodeIndex = c++;
1754                                                 merge[id] = true;
1755                                         }
1757                                         var add = false;
1759                                         if ( first == 0 ) {
1760                                                 if ( node.nodeIndex == last )
1761                                                         add = true;
1762                                         } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
1763                                                 add = true;
1765                                         if ( add ^ not )
1766                                                 tmp.push( node );
1767                                 }
1769                                 r = tmp;
1771                         // Otherwise, find the expression to execute
1772                         } else {
1773                                 var fn = jQuery.expr[ m[1] ];
1774                                 if ( typeof fn == "object" )
1775                                         fn = fn[ m[2] ];
1777                                 if ( typeof fn == "string" )
1778                                         fn = eval("false||function(a,i){return " + fn + ";}");
1780                                 // Execute it against the current filter
1781                                 r = jQuery.grep( r, function(elem, i){
1782                                         return fn(elem, i, m, r);
1783                                 }, not );
1784                         }
1785                 }
1787                 // Return an array of filtered elements (r)
1788                 // and the modified expression string (t)
1789                 return { r: r, t: t };
1790         },
1792         dir: function( elem, dir ){
1793                 var matched = [],
1794                         cur = elem[dir];
1795                 while ( cur && cur != document ) {
1796                         if ( cur.nodeType == 1 )
1797                                 matched.push( cur );
1798                         cur = cur[dir];
1799                 }
1800                 return matched;
1801         },
1803         nth: function(cur,result,dir,elem){
1804                 result = result || 1;
1805                 var num = 0;
1807                 for ( ; cur; cur = cur[dir] )
1808                         if ( cur.nodeType == 1 && ++num == result )
1809                                 break;
1811                 return cur;
1812         },
1814         sibling: function( n, elem ) {
1815                 var r = [];
1817                 for ( ; n; n = n.nextSibling ) {
1818                         if ( n.nodeType == 1 && n != elem )
1819                                 r.push( n );
1820                 }
1822                 return r;
1823         }
1826  * A number of helper functions used for managing events.
1827  * Many of the ideas behind this code orignated from
1828  * Dean Edwards' addEvent library.
1829  */
1830 jQuery.event = {
1832         // Bind an event to an element
1833         // Original by Dean Edwards
1834         add: function(elem, types, handler, data) {
1835                 if ( elem.nodeType == 3 || elem.nodeType == 8 )
1836                         return;
1838                 // For whatever reason, IE has trouble passing the window object
1839                 // around, causing it to be cloned in the process
1840                 if ( jQuery.browser.msie && elem.setInterval )
1841                         elem = window;
1843                 // Make sure that the function being executed has a unique ID
1844                 if ( !handler.guid )
1845                         handler.guid = this.guid++;
1847                 // if data is passed, bind to handler
1848                 if( data != undefined ) {
1849                         // Create temporary function pointer to original handler
1850                         var fn = handler;
1852                         // Create unique handler function, wrapped around original handler
1853                         handler = this.proxy( fn, function() {
1854                                 // Pass arguments and context to original handler
1855                                 return fn.apply(this, arguments);
1856                         });
1858                         // Store data in unique handler
1859                         handler.data = data;
1860                 }
1862                 // Init the element's event structure
1863                 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
1864                         handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
1865                                 // Handle the second event of a trigger and when
1866                                 // an event is called after a page has unloaded
1867                                 if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
1868                                         return jQuery.event.handle.apply(arguments.callee.elem, arguments);
1869                         });
1870                 // Add elem as a property of the handle function
1871                 // This is to prevent a memory leak with non-native
1872                 // event in IE.
1873                 handle.elem = elem;
1875                 // Handle multiple events separated by a space
1876                 // jQuery(...).bind("mouseover mouseout", fn);
1877                 jQuery.each(types.split(/\s+/), function(index, type) {
1878                         // Namespaced event handlers
1879                         var parts = type.split(".");
1880                         type = parts[0];
1881                         handler.type = parts[1];
1883                         // Get the current list of functions bound to this event
1884                         var handlers = events[type];
1886                         // Init the event handler queue
1887                         if (!handlers) {
1888                                 handlers = events[type] = {};
1890                                 // Check for a special event handler
1891                                 // Only use addEventListener/attachEvent if the special
1892                                 // events handler returns false
1893                                 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
1894                                         // Bind the global event handler to the element
1895                                         if (elem.addEventListener)
1896                                                 elem.addEventListener(type, handle, false);
1897                                         else if (elem.attachEvent)
1898                                                 elem.attachEvent("on" + type, handle);
1899                                 }
1900                         }
1902                         // Add the function to the element's handler list
1903                         handlers[handler.guid] = handler;
1905                         // Keep track of which events have been used, for global triggering
1906                         jQuery.event.global[type] = true;
1907                 });
1909                 // Nullify elem to prevent memory leaks in IE
1910                 elem = null;
1911         },
1913         guid: 1,
1914         global: {},
1916         // Detach an event or set of events from an element
1917         remove: function(elem, types, handler) {
1918                 // don't do events on text and comment nodes
1919                 if ( elem.nodeType == 3 || elem.nodeType == 8 )
1920                         return;
1922                 var events = jQuery.data(elem, "events"), ret, index;
1924                 if ( events ) {
1925                         // Unbind all events for the element
1926                         if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
1927                                 for ( var type in events )
1928                                         this.remove( elem, type + (types || "") );
1929                         else {
1930                                 // types is actually an event object here
1931                                 if ( types.type ) {
1932                                         handler = types.handler;
1933                                         types = types.type;
1934                                 }
1936                                 // Handle multiple events seperated by a space
1937                                 // jQuery(...).unbind("mouseover mouseout", fn);
1938                                 jQuery.each(types.split(/\s+/), function(index, type){
1939                                         // Namespaced event handlers
1940                                         var parts = type.split(".");
1941                                         type = parts[0];
1943                                         if ( events[type] ) {
1944                                                 // remove the given handler for the given type
1945                                                 if ( handler )
1946                                                         delete events[type][handler.guid];
1948                                                 // remove all handlers for the given type
1949                                                 else
1950                                                         for ( handler in events[type] )
1951                                                                 // Handle the removal of namespaced events
1952                                                                 if ( !parts[1] || events[type][handler].type == parts[1] )
1953                                                                         delete events[type][handler];
1955                                                 // remove generic event handler if no more handlers exist
1956                                                 for ( ret in events[type] ) break;
1957                                                 if ( !ret ) {
1958                                                         if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
1959                                                                 if (elem.removeEventListener)
1960                                                                         elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
1961                                                                 else if (elem.detachEvent)
1962                                                                         elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
1963                                                         }
1964                                                         ret = null;
1965                                                         delete events[type];
1966                                                 }
1967                                         }
1968                                 });
1969                         }
1971                         // Remove the expando if it's no longer used
1972                         for ( ret in events ) break;
1973                         if ( !ret ) {
1974                                 var handle = jQuery.data( elem, "handle" );
1975                                 if ( handle ) handle.elem = null;
1976                                 jQuery.removeData( elem, "events" );
1977                                 jQuery.removeData( elem, "handle" );
1978                         }
1979                 }
1980         },
1982         trigger: function(type, data, elem, donative, extra) {
1983                 // Clone the incoming data, if any
1984                 data = jQuery.makeArray(data);
1986                 if ( type.indexOf("!") >= 0 ) {
1987                         type = type.slice(0, -1);
1988                         var exclusive = true;
1989                 }
1991                 // Handle a global trigger
1992                 if ( !elem ) {
1993                         // Only trigger if we've ever bound an event for it
1994                         if ( this.global[type] )
1995                                 jQuery("*").add([window, document]).trigger(type, data);
1997                 // Handle triggering a single element
1998                 } else {
1999                         // don't do events on text and comment nodes
2000                         if ( elem.nodeType == 3 || elem.nodeType == 8 )
2001                                 return undefined;
2003                         var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
2004                                 // Check to see if we need to provide a fake event, or not
2005                                 event = !data[0] || !data[0].preventDefault;
2007                         // Pass along a fake event
2008                         if ( event ) {
2009                                 data.unshift({
2010                                         type: type,
2011                                         target: elem,
2012                                         preventDefault: function(){},
2013                                         stopPropagation: function(){},
2014                                         timeStamp: now()
2015                                 });
2016                                 data[0][expando] = true; // no need to fix fake event
2017                         }
2019                         // Enforce the right trigger type
2020                         data[0].type = type;
2021                         if ( exclusive )
2022                                 data[0].exclusive = true;
2024                         // Trigger the event, it is assumed that "handle" is a function
2025                         var handle = jQuery.data(elem, "handle");
2026                         if ( handle )
2027                                 val = handle.apply( elem, data );
2029                         // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2030                         if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2031                                 val = false;
2033                         // Extra functions don't get the custom event object
2034                         if ( event )
2035                                 data.shift();
2037                         // Handle triggering of extra function
2038                         if ( extra && jQuery.isFunction( extra ) ) {
2039                                 // call the extra function and tack the current return value on the end for possible inspection
2040                                 ret = extra.apply( elem, val == null ? data : data.concat( val ) );
2041                                 // if anything is returned, give it precedence and have it overwrite the previous value
2042                                 if (ret !== undefined)
2043                                         val = ret;
2044                         }
2046                         // Trigger the native events (except for clicks on links)
2047                         if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2048                                 this.triggered = true;
2049                                 try {
2050                                         elem[ type ]();
2051                                 // prevent IE from throwing an error for some hidden elements
2052                                 } catch (e) {}
2053                         }
2055                         this.triggered = false;
2056                 }
2058                 return val;
2059         },
2061         handle: function(event) {
2062                 // returned undefined or false
2063                 var val, ret, namespace, all, handlers;
2065                 event = arguments[0] = jQuery.event.fix( event || window.event );
2067                 // Namespaced event handlers
2068                 namespace = event.type.split(".");
2069                 event.type = namespace[0];
2070                 namespace = namespace[1];
2071                 // Cache this now, all = true means, any handler
2072                 all = !namespace && !event.exclusive;
2074                 handlers = ( jQuery.data(this, "events") || {} )[event.type];
2076                 for ( var j in handlers ) {
2077                         var handler = handlers[j];
2079                         // Filter the functions by class
2080                         if ( all || handler.type == namespace ) {
2081                                 // Pass in a reference to the handler function itself
2082                                 // So that we can later remove it
2083                                 event.handler = handler;
2084                                 event.data = handler.data;
2086                                 ret = handler.apply( this, arguments );
2088                                 if ( val !== false )
2089                                         val = ret;
2091                                 if ( ret === false ) {
2092                                         event.preventDefault();
2093                                         event.stopPropagation();
2094                                 }
2095                         }
2096                 }
2098                 return val;
2099         },
2101         fix: function(event) {
2102                 if ( event[expando] == true )
2103                         return event;
2105                 // store a copy of the original event object
2106                 // and "clone" to set read-only properties
2107                 var originalEvent = event;
2108                 event = { originalEvent: originalEvent };
2109                 var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
2110                 for ( var i=props.length; i; i-- )
2111                         event[ props[i] ] = originalEvent[ props[i] ];
2113                 // Mark it as fixed
2114                 event[expando] = true;
2116                 // add preventDefault and stopPropagation since
2117                 // they will not work on the clone
2118                 event.preventDefault = function() {
2119                         // if preventDefault exists run it on the original event
2120                         if (originalEvent.preventDefault)
2121                                 originalEvent.preventDefault();
2122                         // otherwise set the returnValue property of the original event to false (IE)
2123                         originalEvent.returnValue = false;
2124                 };
2125                 event.stopPropagation = function() {
2126                         // if stopPropagation exists run it on the original event
2127                         if (originalEvent.stopPropagation)
2128                                 originalEvent.stopPropagation();
2129                         // otherwise set the cancelBubble property of the original event to true (IE)
2130                         originalEvent.cancelBubble = true;
2131                 };
2133                 // Fix timeStamp
2134                 event.timeStamp = event.timeStamp || now();
2136                 // Fix target property, if necessary
2137                 if ( !event.target )
2138                         event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2140                 // check if target is a textnode (safari)
2141                 if ( event.target.nodeType == 3 )
2142                         event.target = event.target.parentNode;
2144                 // Add relatedTarget, if necessary
2145                 if ( !event.relatedTarget && event.fromElement )
2146                         event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2148                 // Calculate pageX/Y if missing and clientX/Y available
2149                 if ( event.pageX == null && event.clientX != null ) {
2150                         var doc = document.documentElement, body = document.body;
2151                         event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2152                         event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2153                 }
2155                 // Add which for key events
2156                 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2157                         event.which = event.charCode || event.keyCode;
2159                 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2160                 if ( !event.metaKey && event.ctrlKey )
2161                         event.metaKey = event.ctrlKey;
2163                 // Add which for click: 1 == left; 2 == middle; 3 == right
2164                 // Note: button is not normalized, so don't use it
2165                 if ( !event.which && event.button )
2166                         event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2168                 return event;
2169         },
2171         proxy: function( fn, proxy ){
2172                 // Set the guid of unique handler to the same of original handler, so it can be removed
2173                 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2174                 // So proxy can be declared as an argument
2175                 return proxy;
2176         },
2178         special: {
2179                 ready: {
2180                         setup: function() {
2181                                 // Make sure the ready event is setup
2182                                 bindReady();
2183                                 return;
2184                         },
2186                         teardown: function() { return; }
2187                 },
2189                 mouseenter: {
2190                         setup: function() {
2191                                 if ( jQuery.browser.msie ) return false;
2192                                 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
2193                                 return true;
2194                         },
2196                         teardown: function() {
2197                                 if ( jQuery.browser.msie ) return false;
2198                                 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
2199                                 return true;
2200                         },
2202                         handler: function(event) {
2203                                 // If we actually just moused on to a sub-element, ignore it
2204                                 if ( withinElement(event, this) ) return true;
2205                                 // Execute the right handlers by setting the event type to mouseenter
2206                                 event.type = "mouseenter";
2207                                 return jQuery.event.handle.apply(this, arguments);
2208                         }
2209                 },
2211                 mouseleave: {
2212                         setup: function() {
2213                                 if ( jQuery.browser.msie ) return false;
2214                                 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
2215                                 return true;
2216                         },
2218                         teardown: function() {
2219                                 if ( jQuery.browser.msie ) return false;
2220                                 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
2221                                 return true;
2222                         },
2224                         handler: function(event) {
2225                                 // If we actually just moused on to a sub-element, ignore it
2226                                 if ( withinElement(event, this) ) return true;
2227                                 // Execute the right handlers by setting the event type to mouseleave
2228                                 event.type = "mouseleave";
2229                                 return jQuery.event.handle.apply(this, arguments);
2230                         }
2231                 }
2232         }
2235 jQuery.fn.extend({
2236         bind: function( type, data, fn ) {
2237                 return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2238                         jQuery.event.add( this, type, fn || data, fn && data );
2239                 });
2240         },
2242         one: function( type, data, fn ) {
2243                 var one = jQuery.event.proxy( fn || data, function(event) {
2244                         jQuery(this).unbind(event, one);
2245                         return (fn || data).apply( this, arguments );
2246                 });
2247                 return this.each(function(){
2248                         jQuery.event.add( this, type, one, fn && data);
2249                 });
2250         },
2252         unbind: function( type, fn ) {
2253                 return this.each(function(){
2254                         jQuery.event.remove( this, type, fn );
2255                 });
2256         },
2258         trigger: function( type, data, fn ) {
2259                 return this.each(function(){
2260                         jQuery.event.trigger( type, data, this, true, fn );
2261                 });
2262         },
2264         triggerHandler: function( type, data, fn ) {
2265                 return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
2266         },
2268         toggle: function( fn ) {
2269                 // Save reference to arguments for access in closure
2270                 var args = arguments, i = 1;
2272                 // link all the functions, so any of them can unbind this click handler
2273                 while( i < args.length )
2274                         jQuery.event.proxy( fn, args[i++] );
2276                 return this.click( jQuery.event.proxy( fn, function(event) {
2277                         // Figure out which function to execute
2278                         this.lastToggle = ( this.lastToggle || 0 ) % i;
2280                         // Make sure that clicks stop
2281                         event.preventDefault();
2283                         // and execute the function
2284                         return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2285                 }));
2286         },
2288         hover: function(fnOver, fnOut) {
2289                 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
2290         },
2292         ready: function(fn) {
2293                 // Attach the listeners
2294                 bindReady();
2296                 // If the DOM is already ready
2297                 if ( jQuery.isReady )
2298                         // Execute the function immediately
2299                         fn.call( document, jQuery );
2301                 // Otherwise, remember the function for later
2302                 else
2303                         // Add the function to the wait list
2304                         jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
2306                 return this;
2307         }
2310 jQuery.extend({
2311         isReady: false,
2312         readyList: [],
2313         // Handle when the DOM is ready
2314         ready: function() {
2315                 // Make sure that the DOM is not already loaded
2316                 if ( !jQuery.isReady ) {
2317                         // Remember that the DOM is ready
2318                         jQuery.isReady = true;
2320                         // If there are functions bound, to execute
2321                         if ( jQuery.readyList ) {
2322                                 // Execute all of them
2323                                 jQuery.each( jQuery.readyList, function(){
2324                                         this.call( document );
2325                                 });
2327                                 // Reset the list of functions
2328                                 jQuery.readyList = null;
2329                         }
2331                         // Trigger any bound ready events
2332                         jQuery(document).triggerHandler("ready");
2333                 }
2334         }
2337 var readyBound = false;
2339 function bindReady(){
2340         if ( readyBound ) return;
2341         readyBound = true;
2343         // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
2344         if ( document.addEventListener && !jQuery.browser.opera)
2345                 // Use the handy event callback
2346                 document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
2348         // If IE is used and is not in a frame
2349         // Continually check to see if the document is ready
2350         if ( jQuery.browser.msie && window == top ) (function(){
2351                 if (jQuery.isReady) return;
2352                 try {
2353                         // If IE is used, use the trick by Diego Perini
2354                         // http://javascript.nwbox.com/IEContentLoaded/
2355                         document.documentElement.doScroll("left");
2356                 } catch( error ) {
2357                         setTimeout( arguments.callee, 0 );
2358                         return;
2359                 }
2360                 // and execute any waiting functions
2361                 jQuery.ready();
2362         })();
2364         if ( jQuery.browser.opera )
2365                 document.addEventListener( "DOMContentLoaded", function () {
2366                         if (jQuery.isReady) return;
2367                         for (var i = 0; i < document.styleSheets.length; i++)
2368                                 if (document.styleSheets[i].disabled) {
2369                                         setTimeout( arguments.callee, 0 );
2370                                         return;
2371                                 }
2372                         // and execute any waiting functions
2373                         jQuery.ready();
2374                 }, false);
2376         if ( jQuery.browser.safari ) {
2377                 var numStyles;
2378                 (function(){
2379                         if (jQuery.isReady) return;
2380                         if ( document.readyState != "loaded" && document.readyState != "complete" ) {
2381                                 setTimeout( arguments.callee, 0 );
2382                                 return;
2383                         }
2384                         if ( numStyles === undefined )
2385                                 numStyles = jQuery("style, link[rel=stylesheet]").length;
2386                         if ( document.styleSheets.length != numStyles ) {
2387                                 setTimeout( arguments.callee, 0 );
2388                                 return;
2389                         }
2390                         // and execute any waiting functions
2391                         jQuery.ready();
2392                 })();
2393         }
2395         // A fallback to window.onload, that will always work
2396         jQuery.event.add( window, "load", jQuery.ready );
2399 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2400         "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
2401         "submit,keydown,keypress,keyup,error").split(","), function(i, name){
2403         // Handle event binding
2404         jQuery.fn[name] = function(fn){
2405                 return fn ? this.bind(name, fn) : this.trigger(name);
2406         };
2409 // Checks if an event happened on an element within another element
2410 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2411 var withinElement = function(event, elem) {
2412         // Check if mouse(over|out) are still within the same parent element
2413         var parent = event.relatedTarget;
2414         // Traverse up the tree
2415         while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
2416         // Return true if we actually just moused on to a sub-element
2417         return parent == elem;
2420 // Prevent memory leaks in IE
2421 // And prevent errors on refresh with events like mouseover in other browsers
2422 // Window isn't included so as not to unbind existing unload events
2423 jQuery(window).bind("unload", function() {
2424         jQuery("*").add(document).unbind();
2426 jQuery.fn.extend({
2427         // Keep a copy of the old load
2428         _load: jQuery.fn.load,
2430         load: function( url, params, callback ) {
2431                 if ( typeof url != 'string' )
2432                         return this._load( url );
2434                 var off = url.indexOf(" ");
2435                 if ( off >= 0 ) {
2436                         var selector = url.slice(off, url.length);
2437                         url = url.slice(0, off);
2438                 }
2440                 callback = callback || function(){};
2442                 // Default to a GET request
2443                 var type = "GET";
2445                 // If the second parameter was provided
2446                 if ( params )
2447                         // If it's a function
2448                         if ( jQuery.isFunction( params ) ) {
2449                                 // We assume that it's the callback
2450                                 callback = params;
2451                                 params = null;
2453                         // Otherwise, build a param string
2454                         } else {
2455                                 params = jQuery.param( params );
2456                                 type = "POST";
2457                         }
2459                 var self = this;
2461                 // Request the remote document
2462                 jQuery.ajax({
2463                         url: url,
2464                         type: type,
2465                         dataType: "html",
2466                         data: params,
2467                         complete: function(res, status){
2468                                 // If successful, inject the HTML into all the matched elements
2469                                 if ( status == "success" || status == "notmodified" )
2470                                         // See if a selector was specified
2471                                         self.html( selector ?
2472                                                 // Create a dummy div to hold the results
2473                                                 jQuery("<div/>")
2474                                                         // inject the contents of the document in, removing the scripts
2475                                                         // to avoid any 'Permission Denied' errors in IE
2476                                                         .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
2478                                                         // Locate the specified elements
2479                                                         .find(selector) :
2481                                                 // If not, just inject the full result
2482                                                 res.responseText );
2484                                 self.each( callback, [res.responseText, status, res] );
2485                         }
2486                 });
2487                 return this;
2488         },
2490         serialize: function() {
2491                 return jQuery.param(this.serializeArray());
2492         },
2493         serializeArray: function() {
2494                 return this.map(function(){
2495                         return jQuery.nodeName(this, "form") ?
2496                                 jQuery.makeArray(this.elements) : this;
2497                 })
2498                 .filter(function(){
2499                         return this.name && !this.disabled &&
2500                                 (this.checked || /select|textarea/i.test(this.nodeName) ||
2501                                         /text|hidden|password/i.test(this.type));
2502                 })
2503                 .map(function(i, elem){
2504                         var val = jQuery(this).val();
2505                         return val == null ? null :
2506                                 val.constructor == Array ?
2507                                         jQuery.map( val, function(val, i){
2508                                                 return {name: elem.name, value: val};
2509                                         }) :
2510                                         {name: elem.name, value: val};
2511                 }).get();
2512         }
2515 // Attach a bunch of functions for handling common AJAX events
2516 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
2517         jQuery.fn[o] = function(f){
2518                 return this.bind(o, f);
2519         };
2522 var jsc = now();
2524 jQuery.extend({
2525         get: function( url, data, callback, type ) {
2526                 // shift arguments if data argument was ommited
2527                 if ( jQuery.isFunction( data ) ) {
2528                         callback = data;
2529                         data = null;
2530                 }
2532                 return jQuery.ajax({
2533                         type: "GET",
2534                         url: url,
2535                         data: data,
2536                         success: callback,
2537                         dataType: type
2538                 });
2539         },
2541         getScript: function( url, callback ) {
2542                 return jQuery.get(url, null, callback, "script");
2543         },
2545         getJSON: function( url, data, callback ) {
2546                 return jQuery.get(url, data, callback, "json");
2547         },
2549         post: function( url, data, callback, type ) {
2550                 if ( jQuery.isFunction( data ) ) {
2551                         callback = data;
2552                         data = {};
2553                 }
2555                 return jQuery.ajax({
2556                         type: "POST",
2557                         url: url,
2558                         data: data,
2559                         success: callback,
2560                         dataType: type
2561                 });
2562         },
2564         ajaxSetup: function( settings ) {
2565                 jQuery.extend( jQuery.ajaxSettings, settings );
2566         },
2568         ajaxSettings: {
2569                 url: location.href,
2570                 global: true,
2571                 type: "GET",
2572                 timeout: 0,
2573                 contentType: "application/x-www-form-urlencoded",
2574                 processData: true,
2575                 async: true,
2576                 data: null,
2577                 username: null,
2578                 password: null,
2579                 accepts: {
2580                         xml: "application/xml, text/xml",
2581                         html: "text/html",
2582                         script: "text/javascript, application/javascript",
2583                         json: "application/json, text/javascript",
2584                         text: "text/plain",
2585                         _default: "*/*"
2586                 }
2587         },
2589         // Last-Modified header cache for next request
2590         lastModified: {},
2592         ajax: function( s ) {
2593                 // Extend the settings, but re-extend 's' so that it can be
2594                 // checked again later (in the test suite, specifically)
2595                 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
2597                 var jsonp, jsre = /=\?(&|$)/g, status, data,
2598                         type = s.type.toUpperCase();
2600                 // convert data if not already a string
2601                 if ( s.data && s.processData && typeof s.data != "string" )
2602                         s.data = jQuery.param(s.data);
2604                 // Handle JSONP Parameter Callbacks
2605                 if ( s.dataType == "jsonp" ) {
2606                         if ( type == "GET" ) {
2607                                 if ( !s.url.match(jsre) )
2608                                         s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
2609                         } else if ( !s.data || !s.data.match(jsre) )
2610                                 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
2611                         s.dataType = "json";
2612                 }
2614                 // Build temporary JSONP function
2615                 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
2616                         jsonp = "jsonp" + jsc++;
2618                         // Replace the =? sequence both in the query string and the data
2619                         if ( s.data )
2620                                 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
2621                         s.url = s.url.replace(jsre, "=" + jsonp + "$1");
2623                         // We need to make sure
2624                         // that a JSONP style response is executed properly
2625                         s.dataType = "script";
2627                         // Handle JSONP-style loading
2628                         window[ jsonp ] = function(tmp){
2629                                 data = tmp;
2630                                 success();
2631                                 complete();
2632                                 // Garbage collect
2633                                 window[ jsonp ] = undefined;
2634                                 try{ delete window[ jsonp ]; } catch(e){}
2635                                 if ( head )
2636                                         head.removeChild( script );
2637                         };
2638                 }
2640                 if ( s.dataType == "script" && s.cache == null )
2641                         s.cache = false;
2643                 if ( s.cache === false && type == "GET" ) {
2644                         var ts = now();
2645                         // try replacing _= if it is there
2646                         var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
2647                         // if nothing was replaced, add timestamp to the end
2648                         s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
2649                 }
2651                 // If data is available, append data to url for get requests
2652                 if ( s.data && type == "GET" ) {
2653                         s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
2655                         // IE likes to send both get and post data, prevent this
2656                         s.data = null;
2657                 }
2659                 // Watch for a new set of requests
2660                 if ( s.global && ! jQuery.active++ )
2661                         jQuery.event.trigger( "ajaxStart" );
2663                 // Matches an absolute URL, and saves the domain
2664                 var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
2666                 // If we're requesting a remote document
2667                 // and trying to load JSON or Script with a GET
2668                 if ( s.dataType == "script" && type == "GET"
2669                                 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
2670                         var head = document.getElementsByTagName("head")[0];
2671                         var script = document.createElement("script");
2672                         script.src = s.url;
2673                         if (s.scriptCharset)
2674                                 script.charset = s.scriptCharset;
2676                         // Handle Script loading
2677                         if ( !jsonp ) {
2678                                 var done = false;
2680                                 // Attach handlers for all browsers
2681                                 script.onload = script.onreadystatechange = function(){
2682                                         if ( !done && (!this.readyState ||
2683                                                         this.readyState == "loaded" || this.readyState == "complete") ) {
2684                                                 done = true;
2685                                                 success();
2686                                                 complete();
2687                                                 head.removeChild( script );
2688                                         }
2689                                 };
2690                         }
2692                         head.appendChild(script);
2694                         // We handle everything using the script element injection
2695                         return undefined;
2696                 }
2698                 var requestDone = false;
2700                 // Create the request object; Microsoft failed to properly
2701                 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
2702                 var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
2704                 // Open the socket
2705                 // Passing null username, generates a login popup on Opera (#2865)
2706                 if( s.username )
2707                         xhr.open(type, s.url, s.async, s.username, s.password);
2708                 else
2709                         xhr.open(type, s.url, s.async);
2711                 // Need an extra try/catch for cross domain requests in Firefox 3
2712                 try {
2713                         // Set the correct header, if data is being sent
2714                         if ( s.data )
2715                                 xhr.setRequestHeader("Content-Type", s.contentType);
2717                         // Set the If-Modified-Since header, if ifModified mode.
2718                         if ( s.ifModified )
2719                                 xhr.setRequestHeader("If-Modified-Since",
2720                                         jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
2722                         // Set header so the called script knows that it's an XMLHttpRequest
2723                         xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
2725                         // Set the Accepts header for the server, depending on the dataType
2726                         xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
2727                                 s.accepts[ s.dataType ] + ", */*" :
2728                                 s.accepts._default );
2729                 } catch(e){}
2731                 // Allow custom headers/mimetypes
2732                 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
2733                         // cleanup active request counter
2734                         s.global && jQuery.active--;
2735                         // close opended socket
2736                         xhr.abort();
2737                         return false;
2738                 }
2740                 if ( s.global )
2741                         jQuery.event.trigger("ajaxSend", [xhr, s]);
2743                 // Wait for a response to come back
2744                 var onreadystatechange = function(isTimeout){
2745                         // The transfer is complete and the data is available, or the request timed out
2746                         if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
2747                                 requestDone = true;
2749                                 // clear poll interval
2750                                 if (ival) {
2751                                         clearInterval(ival);
2752                                         ival = null;
2753                                 }
2755                                 status = isTimeout == "timeout" && "timeout" ||
2756                                         !jQuery.httpSuccess( xhr ) && "error" ||
2757                                         s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
2758                                         "success";
2760                                 if ( status == "success" ) {
2761                                         // Watch for, and catch, XML document parse errors
2762                                         try {
2763                                                 // process the data (runs the xml through httpData regardless of callback)
2764                                                 data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
2765                                         } catch(e) {
2766                                                 status = "parsererror";
2767                                         }
2768                                 }
2770                                 // Make sure that the request was successful or notmodified
2771                                 if ( status == "success" ) {
2772                                         // Cache Last-Modified header, if ifModified mode.
2773                                         var modRes;
2774                                         try {
2775                                                 modRes = xhr.getResponseHeader("Last-Modified");
2776                                         } catch(e) {} // swallow exception thrown by FF if header is not available
2778                                         if ( s.ifModified && modRes )
2779                                                 jQuery.lastModified[s.url] = modRes;
2781                                         // JSONP handles its own success callback
2782                                         if ( !jsonp )
2783                                                 success();
2784                                 } else
2785                                         jQuery.handleError(s, xhr, status);
2787                                 // Fire the complete handlers
2788                                 complete();
2790                                 // Stop memory leaks
2791                                 if ( s.async )
2792                                         xhr = null;
2793                         }
2794                 };
2796                 if ( s.async ) {
2797                         // don't attach the handler to the request, just poll it instead
2798                         var ival = setInterval(onreadystatechange, 13);
2800                         // Timeout checker
2801                         if ( s.timeout > 0 )
2802                                 setTimeout(function(){
2803                                         // Check to see if the request is still happening
2804                                         if ( xhr ) {
2805                                                 // Cancel the request
2806                                                 xhr.abort();
2808                                                 if( !requestDone )
2809                                                         onreadystatechange( "timeout" );
2810                                         }
2811                                 }, s.timeout);
2812                 }
2814                 // Send the data
2815                 try {
2816                         xhr.send(s.data);
2817                 } catch(e) {
2818                         jQuery.handleError(s, xhr, null, e);
2819                 }
2821                 // firefox 1.5 doesn't fire statechange for sync requests
2822                 if ( !s.async )
2823                         onreadystatechange();
2825                 function success(){
2826                         // If a local callback was specified, fire it and pass it the data
2827                         if ( s.success )
2828                                 s.success( data, status );
2830                         // Fire the global callback
2831                         if ( s.global )
2832                                 jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
2833                 }
2835                 function complete(){
2836                         // Process result
2837                         if ( s.complete )
2838                                 s.complete(xhr, status);
2840                         // The request was completed
2841                         if ( s.global )
2842                                 jQuery.event.trigger( "ajaxComplete", [xhr, s] );
2844                         // Handle the global AJAX counter
2845                         if ( s.global && ! --jQuery.active )
2846                                 jQuery.event.trigger( "ajaxStop" );
2847                 }
2849                 // return XMLHttpRequest to allow aborting the request etc.
2850                 return xhr;
2851         },
2853         handleError: function( s, xhr, status, e ) {
2854                 // If a local callback was specified, fire it
2855                 if ( s.error ) s.error( xhr, status, e );
2857                 // Fire the global callback
2858                 if ( s.global )
2859                         jQuery.event.trigger( "ajaxError", [xhr, s, e] );
2860         },
2862         // Counter for holding the number of active queries
2863         active: 0,
2865         // Determines if an XMLHttpRequest was successful or not
2866         httpSuccess: function( xhr ) {
2867                 try {
2868                         // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
2869                         return !xhr.status && location.protocol == "file:" ||
2870                                 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
2871                                 jQuery.browser.safari && xhr.status == undefined;
2872                 } catch(e){}
2873                 return false;
2874         },
2876         // Determines if an XMLHttpRequest returns NotModified
2877         httpNotModified: function( xhr, url ) {
2878                 try {
2879                         var xhrRes = xhr.getResponseHeader("Last-Modified");
2881                         // Firefox always returns 200. check Last-Modified date
2882                         return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
2883                                 jQuery.browser.safari && xhr.status == undefined;
2884                 } catch(e){}
2885                 return false;
2886         },
2888         httpData: function( xhr, type, filter ) {
2889                 var ct = xhr.getResponseHeader("content-type"),
2890                         xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
2891                         data = xml ? xhr.responseXML : xhr.responseText;
2893                 if ( xml && data.documentElement.tagName == "parsererror" )
2894                         throw "parsererror";
2895                         
2896                 // Allow a pre-filtering function to sanitize the response
2897                 if( filter )
2898                         data = filter( data, type );
2900                 // If the type is "script", eval it in global context
2901                 if ( type == "script" )
2902                         jQuery.globalEval( data );
2904                 // Get the JavaScript object, if JSON is used.
2905                 if ( type == "json" )
2906                         data = eval("(" + data + ")");
2908                 return data;
2909         },
2911         // Serialize an array of form elements or a set of
2912         // key/values into a query string
2913         param: function( a ) {
2914                 var s = [];
2916                 // If an array was passed in, assume that it is an array
2917                 // of form elements
2918                 if ( a.constructor == Array || a.jquery )
2919                         // Serialize the form elements
2920                         jQuery.each( a, function(){
2921                                 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
2922                         });
2924                 // Otherwise, assume that it's an object of key/value pairs
2925                 else
2926                         // Serialize the key/values
2927                         for ( var j in a )
2928                                 // If the value is an array then the key names need to be repeated
2929                                 if ( a[j] && a[j].constructor == Array )
2930                                         jQuery.each( a[j], function(){
2931                                                 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
2932                                         });
2933                                 else
2934                                         s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
2936                 // Return the resulting serialization
2937                 return s.join("&").replace(/%20/g, "+");
2938         }
2941 jQuery.fn.extend({
2942         show: function(speed,callback){
2943                 return speed ?
2944                         this.animate({
2945                                 height: "show", width: "show", opacity: "show"
2946                         }, speed, callback) :
2948                         this.filter(":hidden").each(function(){
2949                                 this.style.display = this.oldblock || "";
2950                                 if ( jQuery.css(this,"display") == "none" ) {
2951                                         var elem = jQuery("<" + this.tagName + " />").appendTo("body");
2952                                         this.style.display = elem.css("display");
2953                                         // handle an edge condition where css is - div { display:none; } or similar
2954                                         if (this.style.display == "none")
2955                                                 this.style.display = "block";
2956                                         elem.remove();
2957                                 }
2958                         }).end();
2959         },
2961         hide: function(speed,callback){
2962                 return speed ?
2963                         this.animate({
2964                                 height: "hide", width: "hide", opacity: "hide"
2965                         }, speed, callback) :
2967                         this.filter(":visible").each(function(){
2968                                 this.oldblock = this.oldblock || jQuery.css(this,"display");
2969                                 this.style.display = "none";
2970                         }).end();
2971         },
2973         // Save the old toggle function
2974         _toggle: jQuery.fn.toggle,
2976         toggle: function( fn, fn2 ){
2977                 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
2978                         this._toggle.apply( this, arguments ) :
2979                         fn ?
2980                                 this.animate({
2981                                         height: "toggle", width: "toggle", opacity: "toggle"
2982                                 }, fn, fn2) :
2983                                 this.each(function(){
2984                                         jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
2985                                 });
2986         },
2988         slideDown: function(speed,callback){
2989                 return this.animate({height: "show"}, speed, callback);
2990         },
2992         slideUp: function(speed,callback){
2993                 return this.animate({height: "hide"}, speed, callback);
2994         },
2996         slideToggle: function(speed, callback){
2997                 return this.animate({height: "toggle"}, speed, callback);
2998         },
3000         fadeIn: function(speed, callback){
3001                 return this.animate({opacity: "show"}, speed, callback);
3002         },
3004         fadeOut: function(speed, callback){
3005                 return this.animate({opacity: "hide"}, speed, callback);
3006         },
3008         fadeTo: function(speed,to,callback){
3009                 return this.animate({opacity: to}, speed, callback);
3010         },
3012         animate: function( prop, speed, easing, callback ) {
3013                 var optall = jQuery.speed(speed, easing, callback);
3015                 return this[ optall.queue === false ? "each" : "queue" ](function(){
3016                         if ( this.nodeType != 1)
3017                                 return false;
3019                         var opt = jQuery.extend({}, optall), p,
3020                                 hidden = jQuery(this).is(":hidden"), self = this;
3022                         for ( p in prop ) {
3023                                 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3024                                         return opt.complete.call(this);
3026                                 if ( p == "height" || p == "width" ) {
3027                                         // Store display property
3028                                         opt.display = jQuery.css(this, "display");
3030                                         // Make sure that nothing sneaks out
3031                                         opt.overflow = this.style.overflow;
3032                                 }
3033                         }
3035                         if ( opt.overflow != null )
3036                                 this.style.overflow = "hidden";
3038                         opt.curAnim = jQuery.extend({}, prop);
3040                         jQuery.each( prop, function(name, val){
3041                                 var e = new jQuery.fx( self, opt, name );
3043                                 if ( /toggle|show|hide/.test(val) )
3044                                         e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
3045                                 else {
3046                                         var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3047                                                 start = e.cur(true) || 0;
3049                                         if ( parts ) {
3050                                                 var end = parseFloat(parts[2]),
3051                                                         unit = parts[3] || "px";
3053                                                 // We need to compute starting value
3054                                                 if ( unit != "px" ) {
3055                                                         self.style[ name ] = (end || 1) + unit;
3056                                                         start = ((end || 1) / e.cur(true)) * start;
3057                                                         self.style[ name ] = start + unit;
3058                                                 }
3060                                                 // If a +=/-= token was provided, we're doing a relative animation
3061                                                 if ( parts[1] )
3062                                                         end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3064                                                 e.custom( start, end, unit );
3065                                         } else
3066                                                 e.custom( start, val, "" );
3067                                 }
3068                         });
3070                         // For JS strict compliance
3071                         return true;
3072                 });
3073         },
3075         queue: function(type, fn){
3076                 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
3077                         fn = type;
3078                         type = "fx";
3079                 }
3081                 if ( !type || (typeof type == "string" && !fn) )
3082                         return queue( this[0], type );
3084                 return this.each(function(){
3085                         if ( fn.constructor == Array )
3086                                 queue(this, type, fn);
3087                         else {
3088                                 queue(this, type).push( fn );
3090                                 if ( queue(this, type).length == 1 )
3091                                         fn.call(this);
3092                         }
3093                 });
3094         },
3096         stop: function(clearQueue, gotoEnd){
3097                 var timers = jQuery.timers;
3099                 if (clearQueue)
3100                         this.queue([]);
3102                 this.each(function(){
3103                         // go in reverse order so anything added to the queue during the loop is ignored
3104                         for ( var i = timers.length - 1; i >= 0; i-- )
3105                                 if ( timers[i].elem == this ) {
3106                                         if (gotoEnd)
3107                                                 // force the next step to be the last
3108                                                 timers[i](true);
3109                                         timers.splice(i, 1);
3110                                 }
3111                 });
3113                 // start the next in the queue if the last step wasn't forced
3114                 if (!gotoEnd)
3115                         this.dequeue();
3117                 return this;
3118         }
3122 var queue = function( elem, type, array ) {
3123         if ( elem ){
3125                 type = type || "fx";
3127                 var q = jQuery.data( elem, type + "queue" );
3129                 if ( !q || array )
3130                         q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
3132         }
3133         return q;
3136 jQuery.fn.dequeue = function(type){
3137         type = type || "fx";
3139         return this.each(function(){
3140                 var q = queue(this, type);
3142                 q.shift();
3144                 if ( q.length )
3145                         q[0].call( this );
3146         });
3149 jQuery.extend({
3151         speed: function(speed, easing, fn) {
3152                 var opt = speed && speed.constructor == Object ? speed : {
3153                         complete: fn || !fn && easing ||
3154                                 jQuery.isFunction( speed ) && speed,
3155                         duration: speed,
3156                         easing: fn && easing || easing && easing.constructor != Function && easing
3157                 };
3159                 opt.duration = (opt.duration && opt.duration.constructor == Number ?
3160                         opt.duration :
3161                         jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
3163                 // Queueing
3164                 opt.old = opt.complete;
3165                 opt.complete = function(){
3166                         if ( opt.queue !== false )
3167                                 jQuery(this).dequeue();
3168                         if ( jQuery.isFunction( opt.old ) )
3169                                 opt.old.call( this );
3170                 };
3172                 return opt;
3173         },
3175         easing: {
3176                 linear: function( p, n, firstNum, diff ) {
3177                         return firstNum + diff * p;
3178                 },
3179                 swing: function( p, n, firstNum, diff ) {
3180                         return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3181                 }
3182         },
3184         timers: [],
3185         timerId: null,
3187         fx: function( elem, options, prop ){
3188                 this.options = options;
3189                 this.elem = elem;
3190                 this.prop = prop;
3192                 if ( !options.orig )
3193                         options.orig = {};
3194         }
3198 jQuery.fx.prototype = {
3200         // Simple function for setting a style value
3201         update: function(){
3202                 if ( this.options.step )
3203                         this.options.step.call( this.elem, this.now, this );
3205                 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
3207                 // Set display property to block for height/width animations
3208                 if ( this.prop == "height" || this.prop == "width" )
3209                         this.elem.style.display = "block";
3210         },
3212         // Get the current size
3213         cur: function(force){
3214                 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
3215                         return this.elem[ this.prop ];
3217                 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
3218                 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
3219         },
3221         // Start an animation from one number to another
3222         custom: function(from, to, unit){
3223                 this.startTime = now();
3224                 this.start = from;
3225                 this.end = to;
3226                 this.unit = unit || this.unit || "px";
3227                 this.now = this.start;
3228                 this.pos = this.state = 0;
3229                 this.update();
3231                 var self = this;
3232                 function t(gotoEnd){
3233                         return self.step(gotoEnd);
3234                 }
3236                 t.elem = this.elem;
3238                 jQuery.timers.push(t);
3240                 if ( jQuery.timerId == null ) {
3241                         jQuery.timerId = setInterval(function(){
3242                                 var timers = jQuery.timers;
3244                                 for ( var i = 0; i < timers.length; i++ )
3245                                         if ( !timers[i]() )
3246                                                 timers.splice(i--, 1);
3248                                 if ( !timers.length ) {
3249                                         clearInterval( jQuery.timerId );
3250                                         jQuery.timerId = null;
3251                                 }
3252                         }, 13);
3253                 }
3254         },
3256         // Simple 'show' function
3257         show: function(){
3258                 // Remember where we started, so that we can go back to it later
3259                 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3260                 this.options.show = true;
3262                 // Begin the animation
3263                 this.custom(0, this.cur());
3265                 // Make sure that we start at a small width/height to avoid any
3266                 // flash of content
3267                 if ( this.prop == "width" || this.prop == "height" )
3268                         this.elem.style[this.prop] = "1px";
3270                 // Start by showing the element
3271                 jQuery(this.elem).show();
3272         },
3274         // Simple 'hide' function
3275         hide: function(){
3276                 // Remember where we started, so that we can go back to it later
3277                 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3278                 this.options.hide = true;
3280                 // Begin the animation
3281                 this.custom(this.cur(), 0);
3282         },
3284         // Each step of an animation
3285         step: function(gotoEnd){
3286                 var t = now();
3288                 if ( gotoEnd || t > this.options.duration + this.startTime ) {
3289                         this.now = this.end;
3290                         this.pos = this.state = 1;
3291                         this.update();
3293                         this.options.curAnim[ this.prop ] = true;
3295                         var done = true;
3296                         for ( var i in this.options.curAnim )
3297                                 if ( this.options.curAnim[i] !== true )
3298                                         done = false;
3300                         if ( done ) {
3301                                 if ( this.options.display != null ) {
3302                                         // Reset the overflow
3303                                         this.elem.style.overflow = this.options.overflow;
3305                                         // Reset the display
3306                                         this.elem.style.display = this.options.display;
3307                                         if ( jQuery.css(this.elem, "display") == "none" )
3308                                                 this.elem.style.display = "block";
3309                                 }
3311                                 // Hide the element if the "hide" operation was done
3312                                 if ( this.options.hide )
3313                                         this.elem.style.display = "none";
3315                                 // Reset the properties, if the item has been hidden or shown
3316                                 if ( this.options.hide || this.options.show )
3317                                         for ( var p in this.options.curAnim )
3318                                                 jQuery.attr(this.elem.style, p, this.options.orig[p]);
3319                         }
3321                         if ( done )
3322                                 // Execute the complete function
3323                                 this.options.complete.call( this.elem );
3325                         return false;
3326                 } else {
3327                         var n = t - this.startTime;
3328                         this.state = n / this.options.duration;
3330                         // Perform the easing function, defaults to swing
3331                         this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
3332                         this.now = this.start + ((this.end - this.start) * this.pos);
3334                         // Perform the next step of the animation
3335                         this.update();
3336                 }
3338                 return true;
3339         }
3343 jQuery.extend( jQuery.fx, {
3344         speeds:{
3345                 slow: 600,
3346                 fast: 200,
3347                 // Default speed
3348                 def: 400
3349         },
3350         step: {
3351                 scrollLeft: function(fx){
3352                         fx.elem.scrollLeft = fx.now;
3353                 },
3355                 scrollTop: function(fx){
3356                         fx.elem.scrollTop = fx.now;
3357                 },
3359                 opacity: function(fx){
3360                         jQuery.attr(fx.elem.style, "opacity", fx.now);
3361                 },
3363                 _default: function(fx){
3364                         fx.elem.style[ fx.prop ] = fx.now + fx.unit;
3365                 }
3366         }
3368 // The Offset Method
3369 // Originally By Brandon Aaron, part of the Dimension Plugin
3370 // http://jquery.com/plugins/project/dimensions
3371 jQuery.fn.offset = function() {
3372         var left = 0, top = 0, elem = this[0], results;
3374         if ( elem ) with ( jQuery.browser ) {
3375                 var parent       = elem.parentNode,
3376                     offsetChild  = elem,
3377                     offsetParent = elem.offsetParent,
3378                     doc          = elem.ownerDocument,
3379                     safari2      = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
3380                     css          = jQuery.curCSS,
3381                     fixed        = css(elem, "position") == "fixed";
3383                 // Use getBoundingClientRect if available
3384                 if ( elem.getBoundingClientRect ) {
3385                         var box = elem.getBoundingClientRect();
3387                         // Add the document scroll offsets
3388                         add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3389                                 box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
3391                         // IE adds the HTML element's border, by default it is medium which is 2px
3392                         // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
3393                         // IE 7 standards mode, the border is always 2px
3394                         // This border/offset is typically represented by the clientLeft and clientTop properties
3395                         // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
3396                         // Therefore this method will be off by 2px in IE while in quirksmode
3397                         add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
3399                 // Otherwise loop through the offsetParents and parentNodes
3400                 } else {
3402                         // Initial element offsets
3403                         add( elem.offsetLeft, elem.offsetTop );
3405                         // Get parent offsets
3406                         while ( offsetParent ) {
3407                                 // Add offsetParent offsets
3408                                 add( offsetParent.offsetLeft, offsetParent.offsetTop );
3410                                 // Mozilla and Safari > 2 does not include the border on offset parents
3411                                 // However Mozilla adds the border for table or table cells
3412                                 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
3413                                         border( offsetParent );
3415                                 // Add the document scroll offsets if position is fixed on any offsetParent
3416                                 if ( !fixed && css(offsetParent, "position") == "fixed" )
3417                                         fixed = true;
3419                                 // Set offsetChild to previous offsetParent unless it is the body element
3420                                 offsetChild  = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
3421                                 // Get next offsetParent
3422                                 offsetParent = offsetParent.offsetParent;
3423                         }
3425                         // Get parent scroll offsets
3426                         while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
3427                                 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
3428                                 if ( !/^inline|table.*$/i.test(css(parent, "display")) )
3429                                         // Subtract parent scroll offsets
3430                                         add( -parent.scrollLeft, -parent.scrollTop );
3432                                 // Mozilla does not add the border for a parent that has overflow != visible
3433                                 if ( mozilla && css(parent, "overflow") != "visible" )
3434                                         border( parent );
3436                                 // Get next parent
3437                                 parent = parent.parentNode;
3438                         }
3440                         // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
3441                         // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
3442                         if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
3443                                 (mozilla && css(offsetChild, "position") != "absolute") )
3444                                         add( -doc.body.offsetLeft, -doc.body.offsetTop );
3446                         // Add the document scroll offsets if position is fixed
3447                         if ( fixed )
3448                                 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3449                                         Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
3450                 }
3452                 // Return an object with top and left properties
3453                 results = { top: top, left: left };
3454         }
3456         function border(elem) {
3457                 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
3458         }
3460         function add(l, t) {
3461                 left += parseInt(l, 10) || 0;
3462                 top += parseInt(t, 10) || 0;
3463         }
3465         return results;
3469 jQuery.fn.extend({
3470         position: function() {
3471                 var left = 0, top = 0, results;
3473                 if ( this[0] ) {
3474                         // Get *real* offsetParent
3475                         var offsetParent = this.offsetParent(),
3477                         // Get correct offsets
3478                         offset       = this.offset(),
3479                         parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
3481                         // Subtract element margins
3482                         // note: when an element has margin: auto the offsetLeft and marginLeft 
3483                         // are the same in Safari causing offset.left to incorrectly be 0
3484                         offset.top  -= num( this, 'marginTop' );
3485                         offset.left -= num( this, 'marginLeft' );
3487                         // Add offsetParent borders
3488                         parentOffset.top  += num( offsetParent, 'borderTopWidth' );
3489                         parentOffset.left += num( offsetParent, 'borderLeftWidth' );
3491                         // Subtract the two offsets
3492                         results = {
3493                                 top:  offset.top  - parentOffset.top,
3494                                 left: offset.left - parentOffset.left
3495                         };
3496                 }
3498                 return results;
3499         },
3501         offsetParent: function() {
3502                 var offsetParent = this[0].offsetParent;
3503                 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
3504                         offsetParent = offsetParent.offsetParent;
3505                 return jQuery(offsetParent);
3506         }
3510 // Create scrollLeft and scrollTop methods
3511 jQuery.each( ['Left', 'Top'], function(i, name) {
3512         var method = 'scroll' + name;
3513         
3514         jQuery.fn[ method ] = function(val) {
3515                 if (!this[0]) return;
3517                 return val != undefined ?
3519                         // Set the scroll offset
3520                         this.each(function() {
3521                                 this == window || this == document ?
3522                                         window.scrollTo(
3523                                                 !i ? val : jQuery(window).scrollLeft(),
3524                                                  i ? val : jQuery(window).scrollTop()
3525                                         ) :
3526                                         this[ method ] = val;
3527                         }) :
3529                         // Return the scroll offset
3530                         this[0] == window || this[0] == document ?
3531                                 self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
3532                                         jQuery.boxModel && document.documentElement[ method ] ||
3533                                         document.body[ method ] :
3534                                 this[0][ method ];
3535         };
3537 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
3538 jQuery.each([ "Height", "Width" ], function(i, name){
3540         var tl = i ? "Left"  : "Top",  // top or left
3541                 br = i ? "Right" : "Bottom"; // bottom or right
3543         // innerHeight and innerWidth
3544         jQuery.fn["inner" + name] = function(){
3545                 return this[ name.toLowerCase() ]() +
3546                         num(this, "padding" + tl) +
3547                         num(this, "padding" + br);
3548         };
3550         // outerHeight and outerWidth
3551         jQuery.fn["outer" + name] = function(margin) {
3552                 return this["inner" + name]() +
3553                         num(this, "border" + tl + "Width") +
3554                         num(this, "border" + br + "Width") +
3555                         (margin ?
3556                                 num(this, "margin" + tl) + num(this, "margin" + br) : 0);
3557         };
3559 });})();