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