tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

jquery.js (100196B)


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