tor-browser

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

lib_jquery_1.1.js (56993B)


      1 /* prevent execution of jQuery if included more than once */
      2 if(typeof window.jQuery == "undefined") {
      3 /*
      4 * jQuery 1.1 - New Wave Javascript
      5 *
      6 * Copyright (c) 2007 John Resig (jquery.com)
      7 * Dual licensed under the MIT (MIT-LICENSE.txt)
      8 * and GPL (GPL-LICENSE.txt) licenses.
      9 *
     10 * $Date: 2007-01-14 17:37:33 -0500 (Sun, 14 Jan 2007) $
     11 * $Rev: 1073 $
     12 */
     13 
     14 // Global undefined variable
     15 window.undefined = window.undefined;
     16 var jQuery = function(a,c) {
     17 // If the context is global, return a new object
     18 if ( window == this )
     19 	return new jQuery(a,c);
     20 
     21 // Make sure that a selection was provided
     22 a = a || document;
     23 
     24 // HANDLE: $(function)
     25 // Shortcut for document ready
     26 // Safari reports typeof on DOM NodeLists as a function
     27 if ( jQuery.isFunction(a) && !a.nodeType && a[0] == undefined )
     28 	return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( a );
     29 
     30 // Handle HTML strings
     31 if ( typeof a  == "string" ) {
     32 	var m = /^[^<]*(<.+>)[^>]*$/.exec(a);
     33 
     34 	a = m ?
     35 		// HANDLE: $(html) -> $(array)
     36 		jQuery.clean( [ m[1] ] ) :
     37 	
     38 		// HANDLE: $(expr)
     39 		jQuery.find( a, c );
     40 }
     41 
     42 return this.setArray(
     43 	// HANDLE: $(array)
     44 	a.constructor == Array && a ||
     45 
     46 	// HANDLE: $(arraylike)
     47 	// Watch for when an array-like object is passed as the selector
     48 	(a.jquery || a.length && a != window && !a.nodeType && a[0] != undefined && a[0].nodeType) && jQuery.makeArray( a ) ||
     49 
     50 	// HANDLE: $(*)
     51 	[ a ] );
     52 };
     53 
     54 // Map over the $ in case of overwrite
     55 if ( typeof $ != "undefined" )
     56 jQuery._$ = $;
     57 
     58 // Map the jQuery namespace to the '$' one
     59 var $ = jQuery;
     60 
     61 jQuery.fn = jQuery.prototype = {
     62 jquery: "1.1",
     63 
     64 size: function() {
     65 	return this.length;
     66 },
     67 
     68 length: 0,
     69 
     70 get: function( num ) {
     71 	return num == undefined ?
     72 
     73 		// Return a 'clean' array
     74 		jQuery.makeArray( this ) :
     75 
     76 		// Return just the object
     77 		this[num];
     78 },
     79 pushStack: function( a ) {
     80 	var ret = jQuery(this);
     81 	ret.prevObject = this;
     82 	return ret.setArray( a );
     83 },
     84 setArray: function( a ) {
     85 	this.length = 0;
     86 	[].push.apply( this, a );
     87 	return this;
     88 },
     89 each: function( fn, args ) {
     90 	return jQuery.each( this, fn, args );
     91 },
     92 index: function( obj ) {
     93 	var pos = -1;
     94 	this.each(function(i){
     95 		if ( this == obj ) pos = i;
     96 	});
     97 	return pos;
     98 },
     99 
    100 attr: function( key, value, type ) {
    101 	var obj = key;
    102 	
    103 	// Look for the case where we're accessing a style value
    104 	if ( key.constructor == String )
    105 		if ( value == undefined )
    106 			return jQuery[ type || "attr" ]( this[0], key );
    107 		else {
    108 			obj = {};
    109 			obj[ key ] = value;
    110 		}
    111 	
    112 	// Check to see if we're setting style values
    113 	return this.each(function(){
    114 		// Set all the styles
    115 		for ( var prop in obj )
    116 			jQuery.attr(
    117 				type ? this.style : this,
    118 				prop, jQuery.prop(this, obj[prop], type)
    119 			);
    120 	});
    121 },
    122 
    123 css: function( key, value ) {
    124 	return this.attr( key, value, "curCSS" );
    125 },
    126 
    127 text: function(e) {
    128 	if ( typeof e == "string" )
    129 		return this.empty().append( document.createTextNode( e ) );
    130 
    131 	var t = "";
    132 	jQuery.each( e || this, function(){
    133 		jQuery.each( this.childNodes, function(){
    134 			if ( this.nodeType != 8 )
    135 				t += this.nodeType != 1 ?
    136 					this.nodeValue : jQuery.fn.text([ this ]);
    137 		});
    138 	});
    139 	return t;
    140 },
    141 
    142 wrap: function() {
    143 	// The elements to wrap the target around
    144 	var a = jQuery.clean(arguments);
    145 
    146 	// Wrap each of the matched elements individually
    147 	return this.each(function(){
    148 		// Clone the structure that we're using to wrap
    149 		var b = a[0].cloneNode(true);
    150 
    151 		// Insert it before the element to be wrapped
    152 		this.parentNode.insertBefore( b, this );
    153 
    154 		// Find the deepest point in the wrap structure
    155 		while ( b.firstChild )
    156 			b = b.firstChild;
    157 
    158 		// Move the matched element to within the wrap structure
    159 		b.appendChild( this );
    160 	});
    161 },
    162 append: function() {
    163 	return this.domManip(arguments, true, 1, function(a){
    164 		this.appendChild( a );
    165 	});
    166 },
    167 prepend: function() {
    168 	return this.domManip(arguments, true, -1, function(a){
    169 		this.insertBefore( a, this.firstChild );
    170 	});
    171 },
    172 before: function() {
    173 	return this.domManip(arguments, false, 1, function(a){
    174 		this.parentNode.insertBefore( a, this );
    175 	});
    176 },
    177 after: function() {
    178 	return this.domManip(arguments, false, -1, function(a){
    179 		this.parentNode.insertBefore( a, this.nextSibling );
    180 	});
    181 },
    182 end: function() {
    183 	return this.prevObject || jQuery([]);
    184 },
    185 find: function(t) {
    186 	return this.pushStack( jQuery.map( this, function(a){
    187 		return jQuery.find(t,a);
    188 	}) );
    189 },
    190 clone: function(deep) {
    191 	return this.pushStack( jQuery.map( this, function(a){
    192 		return a.cloneNode( deep != undefined ? deep : true );
    193 	}) );
    194 },
    195 
    196 filter: function(t) {
    197 	return this.pushStack(
    198 		jQuery.isFunction( t ) &&
    199 		jQuery.grep(this, function(el, index){
    200 			return t.apply(el, [index])
    201 		}) ||
    202 
    203 		jQuery.multiFilter(t,this) );
    204 },
    205 
    206 not: function(t) {
    207 	return this.pushStack(
    208 		t.constructor == String &&
    209 		jQuery.multiFilter(t,this,true) ||
    210 
    211 		jQuery.grep(this,function(a){
    212 				if ( t.constructor == Array || t.jquery )
    213 					return jQuery.inArray( t, a ) < 0;
    214 				else
    215 					return a != t;
    216 		}) );
    217 },
    218 
    219 add: function(t) {
    220 	return this.pushStack( jQuery.merge(
    221 		this.get(),
    222 		typeof t == "string" ? jQuery(t).get() : t )
    223 	);
    224 },
    225 is: function(expr) {
    226 	return expr ? jQuery.filter(expr,this).r.length > 0 : false;
    227 },
    228 
    229 val: function( val ) {
    230 	return val == undefined ?
    231 		( this.length ? this[0].value : null ) :
    232 		this.attr( "value", val );
    233 },
    234 
    235 html: function( val ) {
    236 	return val == undefined ?
    237 		( this.length ? this[0].innerHTML : null ) :
    238 		this.empty().append( val );
    239 },
    240 domManip: function(args, table, dir, fn){
    241 	var clone = this.length > 1; 
    242 	var a = jQuery.clean(args);
    243 	if ( dir < 0 )
    244 		a.reverse();
    245 
    246 	return this.each(function(){
    247 		var obj = this;
    248 
    249 		if ( table && this.nodeName.toUpperCase() == "TABLE" && a[0].nodeName.toUpperCase() == "TR" )
    250 			obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));
    251 
    252 		jQuery.each( a, function(){
    253 			fn.apply( obj, [ clone ? this.cloneNode(true) : this ] );
    254 		});
    255 
    256 	});
    257 }
    258 };
    259 
    260 jQuery.extend = jQuery.fn.extend = function() {
    261 // copy reference to target object
    262 var target = arguments[0],
    263 	a = 1;
    264 
    265 // extend jQuery itself if only one argument is passed
    266 if ( arguments.length == 1 ) {
    267 	target = this;
    268 	a = 0;
    269 }
    270 var prop;
    271 while (prop = arguments[a++])
    272 	// Extend the base object
    273 	for ( var i in prop ) target[i] = prop[i];
    274 
    275 // Return the modified object
    276 return target;
    277 };
    278 
    279 jQuery.extend({
    280 noConflict: function() {
    281 	if ( jQuery._$ )
    282 		$ = jQuery._$;
    283 },
    284 
    285 isFunction: function( fn ) {
    286 	return fn && typeof fn == "function";
    287 },
    288 // args is for internal usage only
    289 each: function( obj, fn, args ) {
    290 	if ( obj.length == undefined )
    291 		for ( var i in obj )
    292 			fn.apply( obj[i], args || [i, obj[i]] );
    293 	else
    294 		for ( var i = 0, ol = obj.length; i < ol; i++ )
    295 			if ( fn.apply( obj[i], args || [i, obj[i]] ) === false ) break;
    296 	return obj;
    297 },
    298 
    299 prop: function(elem, value, type){
    300 		// Handle executable functions
    301 		if ( jQuery.isFunction( value ) )
    302 			return value.call( elem );
    303 
    304 		// Handle passing in a number to a CSS property
    305 		if ( value.constructor == Number && type == "curCSS" )
    306 			return value + "px";
    307 
    308 		return value;
    309 },
    310 
    311 className: {
    312 	// internal only, use addClass("class")
    313 	add: function( elem, c ){
    314 		jQuery.each( c.split(/\s+/), function(i, cur){
    315 			if ( !jQuery.className.has( elem.className, cur ) )
    316 				elem.className += ( elem.className ? " " : "" ) + cur;
    317 		});
    318 	},
    319 
    320 	// internal only, use removeClass("class")
    321 	remove: function( elem, c ){
    322 		elem.className = c ?
    323 			jQuery.grep( elem.className.split(/\s+/), function(cur){
    324 				return !jQuery.className.has( c, cur );	
    325 			}).join(" ") : "";
    326 	},
    327 
    328 	// internal only, use is(".class")
    329 	has: function( t, c ) {
    330 		t = t.className || t;
    331 		return t && new RegExp("(^|\\s)" + c + "(\\s|$)").test( t );
    332 	}
    333 },
    334 swap: function(e,o,f) {
    335 	for ( var i in o ) {
    336 		e.style["old"+i] = e.style[i];
    337 		e.style[i] = o[i];
    338 	}
    339 	f.apply( e, [] );
    340 	for ( var i in o )
    341 		e.style[i] = e.style["old"+i];
    342 },
    343 
    344 css: function(e,p) {
    345 	if ( p == "height" || p == "width" ) {
    346 		var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
    347 
    348 		jQuery.each( d, function(){
    349 			old["padding" + this] = 0;
    350 			old["border" + this + "Width"] = 0;
    351 		});
    352 
    353 		jQuery.swap( e, old, function() {
    354 			if (jQuery.css(e,"display") != "none") {
    355 				oHeight = e.offsetHeight;
    356 				oWidth = e.offsetWidth;
    357 			} else {
    358 				e = jQuery(e.cloneNode(true))
    359 					.find(":radio").removeAttr("checked").end()
    360 					.css({
    361 						visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0"
    362 					}).appendTo(e.parentNode)[0];
    363 
    364 				var parPos = jQuery.css(e.parentNode,"position");
    365 				if ( parPos == "" || parPos == "static" )
    366 					e.parentNode.style.position = "relative";
    367 
    368 				oHeight = e.clientHeight;
    369 				oWidth = e.clientWidth;
    370 
    371 				if ( parPos == "" || parPos == "static" )
    372 					e.parentNode.style.position = "static";
    373 
    374 				e.parentNode.removeChild(e);
    375 			}
    376 		});
    377 
    378 		return p == "height" ? oHeight : oWidth;
    379 	}
    380 
    381 	return jQuery.curCSS( e, p );
    382 },
    383 
    384 curCSS: function(elem, prop, force) {
    385 	var ret;
    386 	
    387 	if (prop == "opacity" && jQuery.browser.msie)
    388 		return jQuery.attr(elem.style, "opacity");
    389 		
    390 	if (prop == "float" || prop == "cssFloat")
    391 	    prop = jQuery.browser.msie ? "styleFloat" : "cssFloat";
    392 
    393 	if (!force && elem.style[prop])
    394 		ret = elem.style[prop];
    395 
    396 	else if (document.defaultView && document.defaultView.getComputedStyle) {
    397 
    398 		if (prop == "cssFloat" || prop == "styleFloat")
    399 			prop = "float";
    400 
    401 		prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
    402 		var cur = document.defaultView.getComputedStyle(elem, null);
    403 
    404 		if ( cur )
    405 			ret = cur.getPropertyValue(prop);
    406 		else if ( prop == "display" )
    407 			ret = "none";
    408 		else
    409 			jQuery.swap(elem, { display: "block" }, function() {
    410 			    var c = document.defaultView.getComputedStyle(this, "");
    411 			    ret = c && c.getPropertyValue(prop) || "";
    412 			});
    413 
    414 	} else if (elem.currentStyle) {
    415 
    416 		var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});
    417 		ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
    418 		
    419 	}
    420 
    421 	return ret;
    422 },
    423 
    424 clean: function(a) {
    425 	var r = [];
    426 
    427 	jQuery.each( a, function(i,arg){
    428 		if ( !arg ) return;
    429 
    430 		if ( arg.constructor == Number )
    431 			arg = arg.toString();
    432 		
    433 		 // Convert html string into DOM nodes
    434 		if ( typeof arg == "string" ) {
    435 			// Trim whitespace, otherwise indexOf won't work as expected
    436 			var s = jQuery.trim(arg), div = document.createElement("div"), tb = [];
    437 
    438 			var wrap =
    439 				 // option or optgroup
    440 				!s.indexOf("<opt") &&
    441 				[1, "<select>", "</select>"] ||
    442 				
    443 				(!s.indexOf("<thead") || !s.indexOf("<tbody") || !s.indexOf("<tfoot")) &&
    444 				[1, "<table>", "</table>"] ||
    445 				
    446 				!s.indexOf("<tr") &&
    447 				[2, "<table><tbody>", "</tbody></table>"] ||
    448 				
    449 			 	// <thead> matched above
    450 				(!s.indexOf("<td") || !s.indexOf("<th")) &&
    451 				[3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
    452 				
    453 				[0,"",""];
    454 
    455 			// Go to html and back, then peel off extra wrappers
    456 			div.innerHTML = wrap[1] + s + wrap[2];
    457 			
    458 			// Move to the right depth
    459 			while ( wrap[0]-- )
    460 				div = div.firstChild;
    461 			
    462 			// Remove IE's autoinserted <tbody> from table fragments
    463 			if ( jQuery.browser.msie ) {
    464 				
    465 				// String was a <table>, *may* have spurious <tbody>
    466 				if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 ) 
    467 					tb = div.firstChild && div.firstChild.childNodes;
    468 					
    469 				// String was a bare <thead> or <tfoot>
    470 				else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )
    471 					tb = div.childNodes;
    472 
    473 				for ( var n = tb.length-1; n >= 0 ; --n )
    474 					if ( tb[n].nodeName.toUpperCase() == "TBODY" && !tb[n].childNodes.length )
    475 						tb[n].parentNode.removeChild(tb[n]);
    476 				
    477 			}
    478 			
    479 			arg = div.childNodes;
    480 		}
    481 
    482 		if ( arg.length === 0 )
    483 			return;
    484 		
    485 		if ( arg[0] == undefined )
    486 			r.push( arg );
    487 		else
    488 			r = jQuery.merge( r, arg );
    489 
    490 	});
    491 
    492 	return r;
    493 },
    494 
    495 attr: function(elem, name, value){
    496 	var fix = {
    497 		"for": "htmlFor",
    498 		"class": "className",
    499 		"float": jQuery.browser.msie ? "styleFloat" : "cssFloat",
    500 		cssFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat",
    501 		innerHTML: "innerHTML",
    502 		className: "className",
    503 		value: "value",
    504 		disabled: "disabled",
    505 		checked: "checked",
    506 		readonly: "readOnly",
    507 		selected: "selected"
    508 	};
    509 	
    510 	// IE actually uses filters for opacity ... elem is actually elem.style
    511 	if ( name == "opacity" && jQuery.browser.msie && value != undefined ) {
    512 		// IE has trouble with opacity if it does not have layout
    513 		// Force it by setting the zoom level
    514 		elem.zoom = 1; 
    515 
    516 		// Set the alpha filter to set the opacity
    517 		return elem.filter = elem.filter.replace(/alpha\([^\)]*\)/gi,"") +
    518 			( value == 1 ? "" : "alpha(opacity=" + value * 100 + ")" );
    519 
    520 	} else if ( name == "opacity" && jQuery.browser.msie )
    521 		return elem.filter ? 
    522 			parseFloat( elem.filter.match(/alpha\(opacity=(.*)\)/)[1] ) / 100 : 1;
    523 	
    524 	// Mozilla doesn't play well with opacity 1
    525 	if ( name == "opacity" && jQuery.browser.mozilla && value == 1 )
    526 		value = 0.9999;
    527 
    528 	// Certain attributes only work when accessed via the old DOM 0 way
    529 	if ( fix[name] ) {
    530 		if ( value != undefined ) elem[fix[name]] = value;
    531 		return elem[fix[name]];
    532 
    533 	} else if ( value == undefined && jQuery.browser.msie && elem.nodeName && elem.nodeName.toUpperCase() == "FORM" && (name == "action" || name == "method") )
    534 		return elem.getAttributeNode(name).nodeValue;
    535 
    536 	// IE elem.getAttribute passes even for style
    537 	else if ( elem.tagName ) {
    538 		if ( value != undefined ) elem.setAttribute( name, value );
    539 		return elem.getAttribute( name );
    540 
    541 	} else {
    542 		name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
    543 		if ( value != undefined ) elem[name] = value;
    544 		return elem[name];
    545 	}
    546 },
    547 trim: function(t){
    548 	return t.replace(/^\s+|\s+$/g, "");
    549 },
    550 
    551 makeArray: function( a ) {
    552 	var r = [];
    553 
    554 	if ( a.constructor != Array )
    555 		for ( var i = 0, al = a.length; i < al; i++ )
    556 			r.push( a[i] );
    557 	else
    558 		r = a.slice( 0 );
    559 
    560 	return r;
    561 },
    562 
    563 inArray: function( b, a ) {
    564 	for ( var i = 0, al = a.length; i < al; i++ )
    565 		if ( a[i] == b )
    566 			return i;
    567 	return -1;
    568 },
    569 merge: function(first, second) {
    570 	var r = [].slice.call( first, 0 );
    571 
    572 	// Now check for duplicates between the two arrays
    573 	// and only add the unique items
    574 	for ( var i = 0, sl = second.length; i < sl; i++ )
    575 		// Check for duplicates
    576 		if ( jQuery.inArray( second[i], r ) == -1 )
    577 			// The item is unique, add it
    578 			first.push( second[i] );
    579 
    580 	return first;
    581 },
    582 grep: function(elems, fn, inv) {
    583 	// If a string is passed in for the function, make a function
    584 	// for it (a handy shortcut)
    585 	if ( typeof fn == "string" )
    586 		fn = new Function("a","i","return " + fn);
    587 
    588 	var result = [];
    589 
    590 	// Go through the array, only saving the items
    591 	// that pass the validator function
    592 	for ( var i = 0, el = elems.length; i < el; i++ )
    593 		if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
    594 			result.push( elems[i] );
    595 
    596 	return result;
    597 },
    598 map: function(elems, fn) {
    599 	// If a string is passed in for the function, make a function
    600 	// for it (a handy shortcut)
    601 	if ( typeof fn == "string" )
    602 		fn = new Function("a","return " + fn);
    603 
    604 	var result = [], r = [];
    605 
    606 	// Go through the array, translating each of the items to their
    607 	// new value (or values).
    608 	for ( var i = 0, el = elems.length; i < el; i++ ) {
    609 		var val = fn(elems[i],i);
    610 
    611 		if ( val !== null && val != undefined ) {
    612 			if ( val.constructor != Array ) val = [val];
    613 			result = result.concat( val );
    614 		}
    615 	}
    616 
    617 	var r = result.length ? [ result[0] ] : [];
    618 
    619 	check: for ( var i = 1, rl = result.length; i < rl; i++ ) {
    620 		for ( var j = 0; j < i; j++ )
    621 			if ( result[i] == r[j] )
    622 				continue check;
    623 
    624 		r.push( result[i] );
    625 	}
    626 
    627 	return r;
    628 }
    629 });
    630 
    631 /*
    632 * Whether the W3C compliant box model is being used.
    633 *
    634 * @property
    635 * @name $.boxModel
    636 * @type Boolean
    637 * @cat JavaScript
    638 */
    639 new function() {
    640 var b = navigator.userAgent.toLowerCase();
    641 
    642 // Figure out what browser is being used
    643 jQuery.browser = {
    644 	safari: /webkit/.test(b),
    645 	opera: /opera/.test(b),
    646 	msie: /msie/.test(b) && !/opera/.test(b),
    647 	mozilla: /mozilla/.test(b) && !/(compatible|webkit)/.test(b)
    648 };
    649 
    650 // Check to see if the W3C box model is being used
    651 jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat";
    652 };
    653 
    654 jQuery.each({
    655 parent: "a.parentNode",
    656 parents: "jQuery.parents(a)",
    657 next: "jQuery.nth(a,2,'nextSibling')",
    658 prev: "jQuery.nth(a,2,'previousSibling')",
    659 siblings: "jQuery.sibling(a.parentNode.firstChild,a)",
    660 children: "jQuery.sibling(a.firstChild)"
    661 }, function(i,n){
    662 jQuery.fn[ i ] = function(a) {
    663 	var ret = jQuery.map(this,n);
    664 	if ( a && typeof a == "string" )
    665 		ret = jQuery.multiFilter(a,ret);
    666 	return this.pushStack( ret );
    667 };
    668 });
    669 
    670 jQuery.each({
    671 appendTo: "append",
    672 prependTo: "prepend",
    673 insertBefore: "before",
    674 insertAfter: "after"
    675 }, function(i,n){
    676 jQuery.fn[ i ] = function(){
    677 	var a = arguments;
    678 	return this.each(function(){
    679 		for ( var j = 0, al = a.length; j < al; j++ )
    680 			jQuery(a[j])[n]( this );
    681 	});
    682 };
    683 });
    684 
    685 jQuery.each( {
    686 removeAttr: function( key ) {
    687 	jQuery.attr( this, key, "" );
    688 	this.removeAttribute( key );
    689 },
    690 addClass: function(c){
    691 	jQuery.className.add(this,c);
    692 },
    693 removeClass: function(c){
    694 	jQuery.className.remove(this,c);
    695 },
    696 toggleClass: function( c ){
    697 	jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c);
    698 },
    699 remove: function(a){
    700 	if ( !a || jQuery.filter( a, [this] ).r.length )
    701 		this.parentNode.removeChild( this );
    702 },
    703 empty: function() {
    704 	while ( this.firstChild )
    705 		this.removeChild( this.firstChild );
    706 }
    707 }, function(i,n){
    708 jQuery.fn[ i ] = function() {
    709 	return this.each( n, arguments );
    710 };
    711 });
    712 
    713 jQuery.each( [ "eq", "lt", "gt", "contains" ], function(i,n){
    714 jQuery.fn[ n ] = function(num,fn) {
    715 	return this.filter( ":" + n + "(" + num + ")", fn );
    716 };
    717 });
    718 
    719 jQuery.each( [ "height", "width" ], function(i,n){
    720 jQuery.fn[ n ] = function(h) {
    721 	return h == undefined ?
    722 		( this.length ? jQuery.css( this[0], n ) : null ) :
    723 		this.css( n, h.constructor == String ? h : h + "px" );
    724 };
    725 });
    726 jQuery.extend({
    727 expr: {
    728 	"": "m[2]=='*'||a.nodeName.toUpperCase()==m[2].toUpperCase()",
    729 	"#": "a.getAttribute('id')==m[2]",
    730 	":": {
    731 		// Position Checks
    732 		lt: "i<m[3]-0",
    733 		gt: "i>m[3]-0",
    734 		nth: "m[3]-0==i",
    735 		eq: "m[3]-0==i",
    736 		first: "i==0",
    737 		last: "i==r.length-1",
    738 		even: "i%2==0",
    739 		odd: "i%2",
    740 
    741 		// Child Checks
    742 		"nth-child": "jQuery.nth(a.parentNode.firstChild,m[3],'nextSibling',a)==a",
    743 		"first-child": "jQuery.nth(a.parentNode.firstChild,1,'nextSibling')==a",
    744 		"last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a",
    745 		"only-child": "jQuery.sibling(a.parentNode.firstChild).length==1",
    746 
    747 		// Parent Checks
    748 		parent: "a.firstChild",
    749 		empty: "!a.firstChild",
    750 
    751 		// Text Check
    752 		contains: "jQuery.fn.text.apply([a]).indexOf(m[3])>=0",
    753 
    754 		// Visibility
    755 		visible: 'a.type!="hidden"&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',
    756 		hidden: 'a.type=="hidden"||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',
    757 
    758 		// Form attributes
    759 		enabled: "!a.disabled",
    760 		disabled: "a.disabled",
    761 		checked: "a.checked",
    762 		selected: "a.selected||jQuery.attr(a,'selected')",
    763 
    764 		// Form elements
    765 		text: "a.type=='text'",
    766 		radio: "a.type=='radio'",
    767 		checkbox: "a.type=='checkbox'",
    768 		file: "a.type=='file'",
    769 		password: "a.type=='password'",
    770 		submit: "a.type=='submit'",
    771 		image: "a.type=='image'",
    772 		reset: "a.type=='reset'",
    773 		button: 'a.type=="button"||a.nodeName=="BUTTON"',
    774 		input: "/input|select|textarea|button/i.test(a.nodeName)"
    775 	},
    776 	".": "jQuery.className.has(a,m[2])",
    777 	"@": {
    778 		"=": "z==m[4]",
    779 		"!=": "z!=m[4]",
    780 		"^=": "z&&!z.indexOf(m[4])",
    781 		"$=": "z&&z.substr(z.length - m[4].length,m[4].length)==m[4]",
    782 		"*=": "z&&z.indexOf(m[4])>=0",
    783 		"": "z",
    784 		_resort: function(m){
    785 			return ["", m[1], m[3], m[2], m[5]];
    786 		},
    787 		_prefix: "z=a[m[3]]||jQuery.attr(a,m[3]);"
    788 	},
    789 	"[": "jQuery.find(m[2],a).length"
    790 },
    791 
    792 // The regular expressions that power the parsing engine
    793 parse: [
    794 	// Match: [@value='test'], [@foo]
    795 	/^\[ *(@)([a-z0-9_-]*) *([!*$^=]*) *('?"?)(.*?)\4 *\]/i,
    796 
    797 	// Match: [div], [div p]
    798 	/^(\[)\s*(.*?(\[.*?\])?[^[]*?)\s*\]/,
    799 
    800 	// Match: :contains('foo')
    801 	/^(:)([a-z0-9_-]*)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/i,
    802 
    803 	// Match: :even, :last-chlid
    804 	/^([:.#]*)([a-z0-9_*-]*)/i
    805 ],
    806 
    807 token: [
    808 	/^(\/?\.\.)/, "a.parentNode",
    809 	/^(>|\/)/, "jQuery.sibling(a.firstChild)",
    810 	/^(\+)/, "jQuery.nth(a,2,'nextSibling')",
    811 	/^(~)/, function(a){
    812 		var s = jQuery.sibling(a.parentNode.firstChild);
    813 		return s.slice(0, jQuery.inArray(a,s));
    814 	}
    815 ],
    816 
    817 multiFilter: function( expr, elems, not ) {
    818 	var old, cur = [];
    819 
    820 	while ( expr && expr != old ) {
    821 		old = expr;
    822 		var f = jQuery.filter( expr, elems, not );
    823 		expr = f.t.replace(/^\s*,\s*/, "" );
    824 		cur = not ? elems = f.r : jQuery.merge( cur, f.r );
    825 	}
    826 
    827 	return cur;
    828 },
    829 find: function( t, context ) {
    830 	// Quickly handle non-string expressions
    831 	if ( typeof t != "string" )
    832 		return [ t ];
    833 
    834 	// Make sure that the context is a DOM Element
    835 	if ( context && !context.nodeType )
    836 		context = null;
    837 
    838 	// Set the correct context (if none is provided)
    839 	context = context || document;
    840 
    841 	// Handle the common XPath // expression
    842 	if ( !t.indexOf("//") ) {
    843 		context = context.documentElement;
    844 		t = t.substr(2,t.length);
    845 
    846 	// And the / root expression
    847 	} else if ( !t.indexOf("/") ) {
    848 		context = context.documentElement;
    849 		t = t.substr(1,t.length);
    850 		if ( t.indexOf("/") >= 1 )
    851 			t = t.substr(t.indexOf("/"),t.length);
    852 	}
    853 
    854 	// Initialize the search
    855 	var ret = [context], done = [], last = null;
    856 
    857 	// Continue while a selector expression exists, and while
    858 	// we're no longer looping upon ourselves
    859 	while ( t && last != t ) {
    860 		var r = [];
    861 		last = t;
    862 
    863 		t = jQuery.trim(t).replace( /^\/\//i, "" );
    864 
    865 		var foundToken = false;
    866 
    867 		// An attempt at speeding up child selectors that
    868 		// point to a specific element tag
    869 		var re = /^[\/>]\s*([a-z0-9*-]+)/i;
    870 		var m = re.exec(t);
    871 
    872 		if ( m ) {
    873 			// Perform our own iteration and filter
    874 			jQuery.each( ret, function(){
    875 				for ( var c = this.firstChild; c; c = c.nextSibling )
    876 					if ( c.nodeType == 1 && ( c.nodeName == m[1].toUpperCase() || m[1] == "*" ) )
    877 						r.push( c );
    878 			});
    879 
    880 			ret = r;
    881 			t = jQuery.trim( t.replace( re, "" ) );
    882 			foundToken = true;
    883 		} else {
    884 			// Look for pre-defined expression tokens
    885 			for ( var i = 0; i < jQuery.token.length; i += 2 ) {
    886 				// Attempt to match each, individual, token in
    887 				// the specified order
    888 				var re = jQuery.token[i];
    889 				var m = re.exec(t);
    890 
    891 				// If the token match was found
    892 				if ( m ) {
    893 					// Map it against the token's handler
    894 					r = ret = jQuery.map( ret, jQuery.isFunction( jQuery.token[i+1] ) ?
    895 						jQuery.token[i+1] :
    896 						function(a){ return eval(jQuery.token[i+1]); });
    897 
    898 					// And remove the token
    899 					t = jQuery.trim( t.replace( re, "" ) );
    900 					foundToken = true;
    901 					break;
    902 				}
    903 			}
    904 		}
    905 
    906 		// See if there's still an expression, and that we haven't already
    907 		// matched a token
    908 		if ( t && !foundToken ) {
    909 			// Handle multiple expressions
    910 			if ( !t.indexOf(",") ) {
    911 				// Clean the result set
    912 				if ( ret[0] == context ) ret.shift();
    913 
    914 				// Merge the result sets
    915 				jQuery.merge( done, ret );
    916 
    917 				// Reset the context
    918 				r = ret = [context];
    919 
    920 				// Touch up the selector string
    921 				t = " " + t.substr(1,t.length);
    922 
    923 			} else {
    924 				// Optomize for the case nodeName#idName
    925 				var re2 = /^([a-z0-9_-]+)(#)([a-z0-9\\*_-]*)/i;
    926 				var m = re2.exec(t);
    927 				
    928 				// Re-organize the results, so that they're consistent
    929 				if ( m ) {
    930 				   m = [ 0, m[2], m[3], m[1] ];
    931 
    932 				} else {
    933 					// Otherwise, do a traditional filter check for
    934 					// ID, class, and element selectors
    935 					re2 = /^([#.]?)([a-z0-9\\*_-]*)/i;
    936 					m = re2.exec(t);
    937 				}
    938 
    939 				// Try to do a global search by ID, where we can
    940 				if ( m[1] == "#" && ret[ret.length-1].getElementById ) {
    941 					// Optimization for HTML document case
    942 					var oid = ret[ret.length-1].getElementById(m[2]);
    943 
    944 					// Do a quick check for node name (where applicable) so
    945 					// that div#foo searches will be really fast
    946 					ret = r = oid && 
    947 					  (!m[3] || oid.nodeName == m[3].toUpperCase()) ? [oid] : [];
    948 
    949 				} else {
    950 					// Pre-compile a regular expression to handle class searches
    951 					if ( m[1] == "." )
    952 						var rec = new RegExp("(^|\\s)" + m[2] + "(\\s|$)");
    953 
    954 					// We need to find all descendant elements, it is more
    955 					// efficient to use getAll() when we are already further down
    956 					// the tree - we try to recognize that here
    957 					jQuery.each( ret, function(){
    958 						// Grab the tag name being searched for
    959 						var tag = m[1] != "" || m[0] == "" ? "*" : m[2];
    960 
    961 						// Handle IE7 being really dumb about <object>s
    962 						if ( this.nodeName.toUpperCase() == "OBJECT" && tag == "*" )
    963 							tag = "param";
    964 
    965 						jQuery.merge( r,
    966 							m[1] != "" && ret.length != 1 ?
    967 								jQuery.getAll( this, [], m[1], m[2], rec ) :
    968 								this.getElementsByTagName( tag )
    969 						);
    970 					});
    971 
    972 					// It's faster to filter by class and be done with it
    973 					if ( m[1] == "." && ret.length == 1 )
    974 						r = jQuery.grep( r, function(e) {
    975 							return rec.test(e.className);
    976 						});
    977 
    978 					// Same with ID filtering
    979 					if ( m[1] == "#" && ret.length == 1 ) {
    980 						// Remember, then wipe out, the result set
    981 						var tmp = r;
    982 						r = [];
    983 
    984 						// Then try to find the element with the ID
    985 						jQuery.each( tmp, function(){
    986 							if ( this.getAttribute("id") == m[2] ) {
    987 								r = [ this ];
    988 								return false;
    989 							}
    990 						});
    991 					}
    992 
    993 					ret = r;
    994 				}
    995 
    996 				t = t.replace( re2, "" );
    997 			}
    998 
    999 		}
   1000 
   1001 		// If a selector string still exists
   1002 		if ( t ) {
   1003 			// Attempt to filter it
   1004 			var val = jQuery.filter(t,r);
   1005 			ret = r = val.r;
   1006 			t = jQuery.trim(val.t);
   1007 		}
   1008 	}
   1009 
   1010 	// Remove the root context
   1011 	if ( ret && ret[0] == context ) ret.shift();
   1012 
   1013 	// And combine the results
   1014 	jQuery.merge( done, ret );
   1015 
   1016 	return done;
   1017 },
   1018 
   1019 filter: function(t,r,not) {
   1020 	// Look for common filter expressions
   1021 	while ( t && /^[a-z[({<*:.#]/i.test(t) ) {
   1022 
   1023 		var p = jQuery.parse, m;
   1024 
   1025 		jQuery.each( p, function(i,re){
   1026 	
   1027 			// Look for, and replace, string-like sequences
   1028 			// and finally build a regexp out of it
   1029 			m = re.exec( t );
   1030 
   1031 			if ( m ) {
   1032 				// Remove what we just matched
   1033 				t = t.substring( m[0].length );
   1034 
   1035 				// Re-organize the first match
   1036 				if ( jQuery.expr[ m[1] ]._resort )
   1037 					m = jQuery.expr[ m[1] ]._resort( m );
   1038 
   1039 				return false;
   1040 			}
   1041 		});
   1042 
   1043 		// :not() is a special case that can be optimized by
   1044 		// keeping it out of the expression list
   1045 		if ( m[1] == ":" && m[2] == "not" )
   1046 			r = jQuery.filter(m[3], r, true).r;
   1047 
   1048 		// Handle classes as a special case (this will help to
   1049 		// improve the speed, as the regexp will only be compiled once)
   1050 		else if ( m[1] == "." ) {
   1051 
   1052 			var re = new RegExp("(^|\\s)" + m[2] + "(\\s|$)");
   1053 			r = jQuery.grep( r, function(e){
   1054 				return re.test(e.className || "");
   1055 			}, not);
   1056 
   1057 		// Otherwise, find the expression to execute
   1058 		} else {
   1059 			var f = jQuery.expr[m[1]];
   1060 			if ( typeof f != "string" )
   1061 				f = jQuery.expr[m[1]][m[2]];
   1062 
   1063 			// Build a custom macro to enclose it
   1064 			eval("f = function(a,i){" +
   1065 				( jQuery.expr[ m[1] ]._prefix || "" ) +
   1066 				"return " + f + "}");
   1067 
   1068 			// Execute it against the current filter
   1069 			r = jQuery.grep( r, f, not );
   1070 		}
   1071 	}
   1072 
   1073 	// Return an array of filtered elements (r)
   1074 	// and the modified expression string (t)
   1075 	return { r: r, t: t };
   1076 },
   1077 
   1078 getAll: function( o, r, token, name, re ) {
   1079 	for ( var s = o.firstChild; s; s = s.nextSibling )
   1080 		if ( s.nodeType == 1 ) {
   1081 			var add = true;
   1082 
   1083 			if ( token == "." )
   1084 				add = s.className && re.test(s.className);
   1085 			else if ( token == "#" )
   1086 				add = s.getAttribute("id") == name;
   1087 
   1088 			if ( add )
   1089 				r.push( s );
   1090 
   1091 			if ( token == "#" && r.length ) break;
   1092 
   1093 			if ( s.firstChild )
   1094 				jQuery.getAll( s, r, token, name, re );
   1095 		}
   1096 
   1097 	return r;
   1098 },
   1099 parents: function( elem ){
   1100 	var matched = [];
   1101 	var cur = elem.parentNode;
   1102 	while ( cur && cur != document ) {
   1103 		matched.push( cur );
   1104 		cur = cur.parentNode;
   1105 	}
   1106 	return matched;
   1107 },
   1108 nth: function(cur,result,dir,elem){
   1109 	result = result || 1;
   1110 	var num = 0;
   1111 	for ( ; cur; cur = cur[dir] ) {
   1112 		if ( cur.nodeType == 1 ) num++;
   1113 		if ( num == result || result == "even" && num % 2 == 0 && num > 1 && cur == elem ||
   1114 			result == "odd" && num % 2 == 1 && cur == elem ) return cur;
   1115 	}
   1116 },
   1117 sibling: function( n, elem ) {
   1118 	var r = [];
   1119 
   1120 	for ( ; n; n = n.nextSibling ) {
   1121 		if ( n.nodeType == 1 && (!elem || n != elem) )
   1122 			r.push( n );
   1123 	}
   1124 
   1125 	return r;
   1126 }
   1127 });
   1128 /*
   1129 * A number of helper functions used for managing events.
   1130 * Many of the ideas behind this code orignated from 
   1131 * Dean Edwards' addEvent library.
   1132 */
   1133 jQuery.event = {
   1134 
   1135 // Bind an event to an element
   1136 // Original by Dean Edwards
   1137 add: function(element, type, handler, data) {
   1138 	// For whatever reason, IE has trouble passing the window object
   1139 	// around, causing it to be cloned in the process
   1140 	if ( jQuery.browser.msie && element.setInterval != undefined )
   1141 		element = window;
   1142 
   1143 	// if data is passed, bind to handler
   1144 	if( data ) 
   1145 		handler.data = data;
   1146 
   1147 	// Make sure that the function being executed has a unique ID
   1148 	if ( !handler.guid )
   1149 		handler.guid = this.guid++;
   1150 
   1151 	// Init the element's event structure
   1152 	if (!element.events)
   1153 		element.events = {};
   1154 
   1155 	// Get the current list of functions bound to this event
   1156 	var handlers = element.events[type];
   1157 
   1158 	// If it hasn't been initialized yet
   1159 	if (!handlers) {
   1160 		// Init the event handler queue
   1161 		handlers = element.events[type] = {};
   1162 
   1163 		// Remember an existing handler, if it's already there
   1164 		if (element["on" + type])
   1165 			handlers[0] = element["on" + type];
   1166 	}
   1167 
   1168 	// Add the function to the element's handler list
   1169 	handlers[handler.guid] = handler;
   1170 
   1171 	// And bind the global event handler to the element
   1172 	element["on" + type] = this.handle;
   1173 
   1174 	// Remember the function in a global list (for triggering)
   1175 	if (!this.global[type])
   1176 		this.global[type] = [];
   1177 	this.global[type].push( element );
   1178 },
   1179 
   1180 guid: 1,
   1181 global: {},
   1182 
   1183 // Detach an event or set of events from an element
   1184 remove: function(element, type, handler) {
   1185 	if (element.events)
   1186 		if ( type && type.type )
   1187 			delete element.events[ type.type ][ type.handler.guid ];
   1188 		else if (type && element.events[type])
   1189 			if ( handler )
   1190 				delete element.events[type][handler.guid];
   1191 			else
   1192 				for ( var i in element.events[type] )
   1193 					delete element.events[type][i];
   1194 		else
   1195 			for ( var j in element.events )
   1196 				this.remove( element, j );
   1197 },
   1198 
   1199 trigger: function(type,data,element) {
   1200 	// Clone the incoming data, if any
   1201 	data = jQuery.makeArray(data || []);
   1202 
   1203 	// Handle a global trigger
   1204 	if ( !element ) {
   1205 		var g = this.global[type];
   1206 		if ( g )
   1207 			jQuery.each( g, function(){
   1208 				jQuery.event.trigger( type, data, this );
   1209 			});
   1210 
   1211 	// Handle triggering a single element
   1212 	} else if ( element["on" + type] ) {
   1213 		// Pass along a fake event
   1214 		data.unshift( this.fix({ type: type, target: element }) );
   1215 
   1216 		// Trigger the event
   1217 		var val = element["on" + type].apply( element, data );
   1218 
   1219 		if ( val !== false && jQuery.isFunction( element[ type ] ) )
   1220 			element[ type ]();
   1221 	}
   1222 },
   1223 
   1224 handle: function(event) {
   1225 	if ( typeof jQuery == "undefined" ) return false;
   1226 
   1227 	// Empty object is for triggered events with no data
   1228 	event = jQuery.event.fix( event || window.event || {} ); 
   1229 
   1230 	// returned undefined or false
   1231 	var returnValue;
   1232 
   1233 	var c = this.events[event.type];
   1234 
   1235 	var args = [].slice.call( arguments, 1 );
   1236 	args.unshift( event );
   1237 
   1238 	for ( var j in c ) {
   1239 		// Pass in a reference to the handler function itself
   1240 		// So that we can later remove it
   1241 		args[0].handler = c[j];
   1242 		args[0].data = c[j].data;
   1243 
   1244 		if ( c[j].apply( this, args ) === false ) {
   1245 			event.preventDefault();
   1246 			event.stopPropagation();
   1247 			returnValue = false;
   1248 		}
   1249 	}
   1250 
   1251 	// Clean up added properties in IE to prevent memory leak
   1252 	if (jQuery.browser.msie) event.target = event.preventDefault = event.stopPropagation = event.handler = event.data = null;
   1253 
   1254 	return returnValue;
   1255 },
   1256 
   1257 fix: function(event) {
   1258 	// Fix target property, if necessary
   1259 	if ( !event.target && event.srcElement )
   1260 		event.target = event.srcElement;
   1261 
   1262 	// Calculate pageX/Y if missing and clientX/Y available
   1263 	if ( event.pageX == undefined && event.clientX != undefined ) {
   1264 		var e = document.documentElement, b = document.body;
   1265 		event.pageX = event.clientX + (e.scrollLeft || b.scrollLeft);
   1266 		event.pageY = event.clientY + (e.scrollTop || b.scrollTop);
   1267 	}
   1268 			
   1269 	// check if target is a textnode (safari)
   1270 	if (jQuery.browser.safari && event.target.nodeType == 3) {
   1271 		// store a copy of the original event object 
   1272 		// and clone because target is read only
   1273 		var originalEvent = event;
   1274 		event = jQuery.extend({}, originalEvent);
   1275 		
   1276 		// get parentnode from textnode
   1277 		event.target = originalEvent.target.parentNode;
   1278 		
   1279 		// add preventDefault and stopPropagation since 
   1280 		// they will not work on the clone
   1281 		event.preventDefault = function() {
   1282 			return originalEvent.preventDefault();
   1283 		};
   1284 		event.stopPropagation = function() {
   1285 			return originalEvent.stopPropagation();
   1286 		};
   1287 	}
   1288 	
   1289 	// fix preventDefault and stopPropagation
   1290 	if (!event.preventDefault)
   1291 		event.preventDefault = function() {
   1292 			this.returnValue = false;
   1293 		};
   1294 		
   1295 	if (!event.stopPropagation)
   1296 		event.stopPropagation = function() {
   1297 			this.cancelBubble = true;
   1298 		};
   1299 		
   1300 	return event;
   1301 }
   1302 };
   1303 
   1304 jQuery.fn.extend({
   1305 bind: function( type, data, fn ) {
   1306 	return this.each(function(){
   1307 		jQuery.event.add( this, type, fn || data, data );
   1308 	});
   1309 },
   1310 one: function( type, data, fn ) {
   1311 	return this.each(function(){
   1312 		jQuery.event.add( this, type, function(event) {
   1313 			jQuery(this).unbind(event);
   1314 			return (fn || data).apply( this, arguments);
   1315 		}, data);
   1316 	});
   1317 },
   1318 unbind: function( type, fn ) {
   1319 	return this.each(function(){
   1320 		jQuery.event.remove( this, type, fn );
   1321 	});
   1322 },
   1323 trigger: function( type, data ) {
   1324 	return this.each(function(){
   1325 		jQuery.event.trigger( type, data, this );
   1326 	});
   1327 },
   1328 toggle: function() {
   1329 	// Save reference to arguments for access in closure
   1330 	var a = arguments;
   1331 
   1332 	return this.click(function(e) {
   1333 		// Figure out which function to execute
   1334 		this.lastToggle = this.lastToggle == 0 ? 1 : 0;
   1335 		
   1336 		// Make sure that clicks stop
   1337 		e.preventDefault();
   1338 		
   1339 		// and execute the function
   1340 		return a[this.lastToggle].apply( this, [e] ) || false;
   1341 	});
   1342 },
   1343 hover: function(f,g) {
   1344 	
   1345 	// A private function for handling mouse 'hovering'
   1346 	function handleHover(e) {
   1347 		// Check if mouse(over|out) are still within the same parent element
   1348 		var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
   1349 
   1350 		// Traverse up the tree
   1351 		while ( p && p != this ) try { p = p.parentNode } catch(e) { p = this; };
   1352 		
   1353 		// If we actually just moused on to a sub-element, ignore it
   1354 		if ( p == this ) return false;
   1355 		
   1356 		// Execute the right function
   1357 		return (e.type == "mouseover" ? f : g).apply(this, [e]);
   1358 	}
   1359 	
   1360 	// Bind the function to the two event listeners
   1361 	return this.mouseover(handleHover).mouseout(handleHover);
   1362 },
   1363 ready: function(f) {
   1364 	// If the DOM is already ready
   1365 	if ( jQuery.isReady )
   1366 		// Execute the function immediately
   1367 		f.apply( document, [jQuery] );
   1368 		
   1369 	// Otherwise, remember the function for later
   1370 	else {
   1371 		// Add the function to the wait list
   1372 		jQuery.readyList.push( function() { return f.apply(this, [jQuery]) } );
   1373 	}
   1374 
   1375 	return this;
   1376 }
   1377 });
   1378 
   1379 jQuery.extend({
   1380 /*
   1381  * All the code that makes DOM Ready work nicely.
   1382  */
   1383 isReady: false,
   1384 readyList: [],
   1385 
   1386 // Handle when the DOM is ready
   1387 ready: function() {
   1388 	// Make sure that the DOM is not already loaded
   1389 	if ( !jQuery.isReady ) {
   1390 		// Remember that the DOM is ready
   1391 		jQuery.isReady = true;
   1392 		
   1393 		// If there are functions bound, to execute
   1394 		if ( jQuery.readyList ) {
   1395 			// Execute all of them
   1396 			jQuery.each( jQuery.readyList, function(){
   1397 				this.apply( document );
   1398 			});
   1399 			
   1400 			// Reset the list of functions
   1401 			jQuery.readyList = null;
   1402 		}
   1403 		// Remove event lisenter to avoid memory leak
   1404 		if ( jQuery.browser.mozilla || jQuery.browser.opera )
   1405 			document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
   1406 	}
   1407 }
   1408 });
   1409 
   1410 new function(){
   1411 
   1412 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
   1413 	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 
   1414 	"submit,keydown,keypress,keyup,error").split(","), function(i,o){
   1415 	
   1416 	// Handle event binding
   1417 	jQuery.fn[o] = function(f){
   1418 		return f ? this.bind(o, f) : this.trigger(o);
   1419 	};
   1420 		
   1421 });
   1422 
   1423 // If Mozilla is used
   1424 if ( jQuery.browser.mozilla || jQuery.browser.opera )
   1425 	// Use the handy event callback
   1426 	document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
   1427 
   1428 // If IE is used, use the excellent hack by Matthias Miller
   1429 // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
   1430 else if ( jQuery.browser.msie ) {
   1431 
   1432 	// Only works if you document.write() it
   1433 	document.write("<scr" + "ipt id=__ie_init defer=true " + 
   1434 		"src=//:><\/script>");
   1435 
   1436 	// Use the defer script hack
   1437 	var script = document.getElementById("__ie_init");
   1438 	
   1439 	// script does not exist if jQuery is loaded dynamically
   1440 	if ( script ) 
   1441 		script.onreadystatechange = function() {
   1442 			if ( this.readyState != "complete" ) return;
   1443 			this.parentNode.removeChild( this );
   1444 			jQuery.ready();
   1445 		};
   1446 
   1447 	// Clear from memory
   1448 	script = null;
   1449 
   1450 // If Safari  is used
   1451 } else if ( jQuery.browser.safari )
   1452 	// Continually check to see if the document.readyState is valid
   1453 	jQuery.safariTimer = setInterval(function(){
   1454 		// loaded and complete are both valid states
   1455 		if ( document.readyState == "loaded" || 
   1456 			document.readyState == "complete" ) {
   1457 
   1458 			// If either one are found, remove the timer
   1459 			clearInterval( jQuery.safariTimer );
   1460 			jQuery.safariTimer = null;
   1461 
   1462 			// and execute any waiting functions
   1463 			jQuery.ready();
   1464 		}
   1465 	}, 10); 
   1466 
   1467 // A fallback to window.onload, that will always work
   1468 jQuery.event.add( window, "load", jQuery.ready );
   1469 
   1470 };
   1471 
   1472 // Clean up after IE to avoid memory leaks
   1473 if (jQuery.browser.msie)
   1474 jQuery(window).one("unload", function() {
   1475 	var global = jQuery.event.global;
   1476 	for ( var type in global ) {
   1477 		var els = global[type], i = els.length;
   1478 		if ( i && type != 'unload' )
   1479 			do
   1480 				jQuery.event.remove(els[i-1], type);
   1481 			while (--i);
   1482 	}
   1483 });
   1484 jQuery.fn.extend({
   1485 
   1486 show: function(speed,callback){
   1487 	var hidden = this.filter(":hidden");
   1488 	return speed ?
   1489 		hidden.animate({
   1490 			height: "show", width: "show", opacity: "show"
   1491 		}, speed, callback) :
   1492 		
   1493 		hidden.each(function(){
   1494 			this.style.display = this.oldblock ? this.oldblock : "";
   1495 			if ( jQuery.css(this,"display") == "none" )
   1496 				this.style.display = "block";
   1497 		});
   1498 },
   1499 
   1500 hide: function(speed,callback){
   1501 	var visible = this.filter(":visible");
   1502 	return speed ?
   1503 		visible.animate({
   1504 			height: "hide", width: "hide", opacity: "hide"
   1505 		}, speed, callback) :
   1506 		
   1507 		visible.each(function(){
   1508 			this.oldblock = this.oldblock || jQuery.css(this,"display");
   1509 			if ( this.oldblock == "none" )
   1510 				this.oldblock = "block";
   1511 			this.style.display = "none";
   1512 		});
   1513 },
   1514 
   1515 // Save the old toggle function
   1516 _toggle: jQuery.fn.toggle,
   1517 toggle: function( fn, fn2 ){
   1518 	var args = arguments;
   1519 	return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
   1520 		this._toggle( fn, fn2 ) :
   1521 		this.each(function(){
   1522 			jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]
   1523 				.apply( jQuery(this), args );
   1524 		});
   1525 },
   1526 slideDown: function(speed,callback){
   1527 	return this.animate({height: "show"}, speed, callback);
   1528 },
   1529 slideUp: function(speed,callback){
   1530 	return this.animate({height: "hide"}, speed, callback);
   1531 },
   1532 slideToggle: function(speed, callback){
   1533 	return this.each(function(){
   1534 		var state = jQuery(this).is(":hidden") ? "show" : "hide";
   1535 		jQuery(this).animate({height: state}, speed, callback);
   1536 	});
   1537 },
   1538 fadeIn: function(speed, callback){
   1539 	return this.animate({opacity: "show"}, speed, callback);
   1540 },
   1541 fadeOut: function(speed, callback){
   1542 	return this.animate({opacity: "hide"}, speed, callback);
   1543 },
   1544 fadeTo: function(speed,to,callback){
   1545 	return this.animate({opacity: to}, speed, callback);
   1546 },
   1547 animate: function( prop, speed, easing, callback ) {
   1548 	return this.queue(function(){
   1549 	
   1550 		this.curAnim = jQuery.extend({}, prop);
   1551 		var opt = jQuery.speed(speed, easing, callback);
   1552 		
   1553 		for ( var p in prop ) {
   1554 			var e = new jQuery.fx( this, opt, p );
   1555 			if ( prop[p].constructor == Number )
   1556 				e.custom( e.cur(), prop[p] );
   1557 			else
   1558 				e[ prop[p] ]( prop );
   1559 		}
   1560 		
   1561 	});
   1562 },
   1563 queue: function(type,fn){
   1564 	if ( !fn ) {
   1565 		fn = type;
   1566 		type = "fx";
   1567 	}
   1568 
   1569 	return this.each(function(){
   1570 		if ( !this.queue )
   1571 			this.queue = {};
   1572 
   1573 		if ( !this.queue[type] )
   1574 			this.queue[type] = [];
   1575 
   1576 		this.queue[type].push( fn );
   1577 	
   1578 		if ( this.queue[type].length == 1 )
   1579 			fn.apply(this);
   1580 	});
   1581 }
   1582 
   1583 });
   1584 
   1585 jQuery.extend({
   1586 
   1587 speed: function(speed, easing, fn) {
   1588 	var opt = speed && speed.constructor == Object ? speed : {
   1589 		complete: fn || !fn && easing || 
   1590 			jQuery.isFunction( speed ) && speed,
   1591 		duration: speed,
   1592 		easing: fn && easing || easing && easing.constructor != Function && easing
   1593 	};
   1594 
   1595 	opt.duration = (opt.duration && opt.duration.constructor == Number ? 
   1596 		opt.duration : 
   1597 		{ slow: 600, fast: 200 }[opt.duration]) || 400;
   1598 
   1599 	// Queueing
   1600 	opt.old = opt.complete;
   1601 	opt.complete = function(){
   1602 		jQuery.dequeue(this, "fx");
   1603 		if ( jQuery.isFunction( opt.old ) )
   1604 			opt.old.apply( this );
   1605 	};
   1606 
   1607 	return opt;
   1608 },
   1609 
   1610 easing: {},
   1611 
   1612 queue: {},
   1613 
   1614 dequeue: function(elem,type){
   1615 	type = type || "fx";
   1616 
   1617 	if ( elem.queue && elem.queue[type] ) {
   1618 		// Remove self
   1619 		elem.queue[type].shift();
   1620 
   1621 		// Get next function
   1622 		var f = elem.queue[type][0];
   1623 	
   1624 		if ( f ) f.apply( elem );
   1625 	}
   1626 },
   1627 
   1628 /*
   1629  * I originally wrote fx() as a clone of moo.fx and in the process
   1630  * of making it small in size the code became illegible to sane
   1631  * people. You've been warned.
   1632  */
   1633 
   1634 fx: function( elem, options, prop ){
   1635 
   1636 	var z = this;
   1637 
   1638 	// The styles
   1639 	var y = elem.style;
   1640 	
   1641 	// Store display property
   1642 	var oldDisplay = jQuery.css(elem, "display");
   1643 
   1644 	// Set display property to block for animation
   1645 	y.display = "block";
   1646 
   1647 	// Make sure that nothing sneaks out
   1648 	y.overflow = "hidden";
   1649 
   1650 	// Simple function for setting a style value
   1651 	z.a = function(){
   1652 		if ( options.step )
   1653 			options.step.apply( elem, [ z.now ] );
   1654 
   1655 		if ( prop == "opacity" )
   1656 			jQuery.attr(y, "opacity", z.now); // Let attr handle opacity
   1657 		else if ( parseInt(z.now) ) // My hate for IE will never die
   1658 			y[prop] = parseInt(z.now) + "px";
   1659 	};
   1660 
   1661 	// Figure out the maximum number to run to
   1662 	z.max = function(){
   1663 		return parseFloat( jQuery.css(elem,prop) );
   1664 	};
   1665 
   1666 	// Get the current size
   1667 	z.cur = function(){
   1668 		var r = parseFloat( jQuery.curCSS(elem, prop) );
   1669 		return r && r > -10000 ? r : z.max();
   1670 	};
   1671 
   1672 	// Start an animation from one number to another
   1673 	z.custom = function(from,to){
   1674 		z.startTime = (new Date()).getTime();
   1675 		z.now = from;
   1676 		z.a();
   1677 
   1678 		z.timer = setInterval(function(){
   1679 			z.step(from, to);
   1680 		}, 13);
   1681 	};
   1682 
   1683 	// Simple 'show' function
   1684 	z.show = function(){
   1685 		if ( !elem.orig ) elem.orig = {};
   1686 
   1687 		// Remember where we started, so that we can go back to it later
   1688 		elem.orig[prop] = this.cur();
   1689 
   1690 		options.show = true;
   1691 
   1692 		// Begin the animation
   1693 		z.custom(0, elem.orig[prop]);
   1694 
   1695 		// Stupid IE, look what you made me do
   1696 		if ( prop != "opacity" )
   1697 			y[prop] = "1px";
   1698 	};
   1699 
   1700 	// Simple 'hide' function
   1701 	z.hide = function(){
   1702 		if ( !elem.orig ) elem.orig = {};
   1703 
   1704 		// Remember where we started, so that we can go back to it later
   1705 		elem.orig[prop] = this.cur();
   1706 
   1707 		options.hide = true;
   1708 
   1709 		// Begin the animation
   1710 		z.custom(elem.orig[prop], 0);
   1711 	};
   1712 	
   1713 	//Simple 'toggle' function
   1714 	z.toggle = function() {
   1715 		if ( !elem.orig ) elem.orig = {};
   1716 
   1717 		// Remember where we started, so that we can go back to it later
   1718 		elem.orig[prop] = this.cur();
   1719 
   1720 		if(oldDisplay == "none")  {
   1721 			options.show = true;
   1722 			
   1723 			// Stupid IE, look what you made me do
   1724 			if ( prop != "opacity" )
   1725 				y[prop] = "1px";
   1726 
   1727 			// Begin the animation
   1728 			z.custom(0, elem.orig[prop]);	
   1729 		} else {
   1730 			options.hide = true;
   1731 
   1732 			// Begin the animation
   1733 			z.custom(elem.orig[prop], 0);
   1734 		}		
   1735 	};
   1736 
   1737 	// Each step of an animation
   1738 	z.step = function(firstNum, lastNum){
   1739 		var t = (new Date()).getTime();
   1740 
   1741 		if (t > options.duration + z.startTime) {
   1742 			// Stop the timer
   1743 			clearInterval(z.timer);
   1744 			z.timer = null;
   1745 
   1746 			z.now = lastNum;
   1747 			z.a();
   1748 
   1749 			if (elem.curAnim) elem.curAnim[ prop ] = true;
   1750 
   1751 			var done = true;
   1752 			for ( var i in elem.curAnim )
   1753 				if ( elem.curAnim[i] !== true )
   1754 					done = false;
   1755 
   1756 			if ( done ) {
   1757 				// Reset the overflow
   1758 				y.overflow = "";
   1759 				
   1760 				// Reset the display
   1761 				y.display = oldDisplay;
   1762 				if (jQuery.css(elem, "display") == "none")
   1763 					y.display = "block";
   1764 
   1765 				// Hide the element if the "hide" operation was done
   1766 				if ( options.hide ) 
   1767 					y.display = "none";
   1768 
   1769 				// Reset the properties, if the item has been hidden or shown
   1770 				if ( options.hide || options.show )
   1771 					for ( var p in elem.curAnim )
   1772 						if (p == "opacity")
   1773 							jQuery.attr(y, p, elem.orig[p]);
   1774 						else
   1775 							y[p] = "";
   1776 			}
   1777 
   1778 			// If a callback was provided, execute it
   1779 			if ( done && jQuery.isFunction( options.complete ) )
   1780 				// Execute the complete function
   1781 				options.complete.apply( elem );
   1782 		} else {
   1783 			var n = t - this.startTime;
   1784 			// Figure out where in the animation we are and set the number
   1785 			var p = n / options.duration;
   1786 			
   1787 			// If the easing function exists, then use it 
   1788 			z.now = options.easing && jQuery.easing[options.easing] ?
   1789 				jQuery.easing[options.easing](p, n,  firstNum, (lastNum-firstNum), options.duration) :
   1790 				// else use default linear easing
   1791 				((-Math.cos(p*Math.PI)/2) + 0.5) * (lastNum-firstNum) + firstNum;
   1792 
   1793 			// Perform the next step of the animation
   1794 			z.a();
   1795 		}
   1796 	};
   1797 
   1798 }
   1799 });
   1800 jQuery.fn.extend({
   1801 loadIfModified: function( url, params, callback ) {
   1802 	this.load( url, params, callback, 1 );
   1803 },
   1804 load: function( url, params, callback, ifModified ) {
   1805 	if ( jQuery.isFunction( url ) )
   1806 		return this.bind("load", url);
   1807 
   1808 	callback = callback || function(){};
   1809 
   1810 	// Default to a GET request
   1811 	var type = "GET";
   1812 
   1813 	// If the second parameter was provided
   1814 	if ( params )
   1815 		// If it's a function
   1816 		if ( jQuery.isFunction( params.constructor ) ) {
   1817 			// We assume that it's the callback
   1818 			callback = params;
   1819 			params = null;
   1820 
   1821 		// Otherwise, build a param string
   1822 		} else {
   1823 			params = jQuery.param( params );
   1824 			type = "POST";
   1825 		}
   1826 
   1827 	var self = this;
   1828 
   1829 	// Request the remote document
   1830 	jQuery.ajax({
   1831 		url: url,
   1832 		type: type,
   1833 		data: params,
   1834 		ifModified: ifModified,
   1835 		complete: function(res, status){
   1836 			if ( status == "success" || !ifModified && status == "notmodified" )
   1837 				// Inject the HTML into all the matched elements
   1838 				self.attr("innerHTML", res.responseText)
   1839 				  // Execute all the scripts inside of the newly-injected HTML
   1840 				  .evalScripts()
   1841 				  // Execute callback
   1842 				  .each( callback, [res.responseText, status, res] );
   1843 			else
   1844 				callback.apply( self, [res.responseText, status, res] );
   1845 		}
   1846 	});
   1847 	return this;
   1848 },
   1849 serialize: function() {
   1850 	return jQuery.param( this );
   1851 },
   1852 evalScripts: function() {
   1853 	return this.find("script").each(function(){
   1854 		if ( this.src )
   1855 			jQuery.getScript( this.src );
   1856 		else
   1857 			jQuery.globalEval( this.text || this.textContent || this.innerHTML || "" );
   1858 	}).end();
   1859 }
   1860 
   1861 });
   1862 
   1863 // If IE is used, create a wrapper for the XMLHttpRequest object
   1864 if ( jQuery.browser.msie && typeof XMLHttpRequest == "undefined" )
   1865 XMLHttpRequest = function(){
   1866 	return new ActiveXObject("Microsoft.XMLHTTP");
   1867 };
   1868 
   1869 // Attach a bunch of functions for handling common AJAX events
   1870 
   1871 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
   1872 jQuery.fn[o] = function(f){
   1873 	return this.bind(o, f);
   1874 };
   1875 });
   1876 
   1877 jQuery.extend({
   1878 get: function( url, data, callback, type, ifModified ) {
   1879 	// shift arguments if data argument was ommited
   1880 	if ( jQuery.isFunction( data ) ) {
   1881 		callback = data;
   1882 		data = null;
   1883 	}
   1884 	
   1885 	return jQuery.ajax({
   1886 		url: url,
   1887 		data: data,
   1888 		success: callback,
   1889 		dataType: type,
   1890 		ifModified: ifModified
   1891 	});
   1892 },
   1893 getIfModified: function( url, data, callback, type ) {
   1894 	return jQuery.get(url, data, callback, type, 1);
   1895 },
   1896 getScript: function( url, callback ) {
   1897 	return jQuery.get(url, null, callback, "script");
   1898 },
   1899 getJSON: function( url, data, callback ) {
   1900 	return jQuery.get(url, data, callback, "json");
   1901 },
   1902 post: function( url, data, callback, type ) {
   1903 	return jQuery.ajax({
   1904 		type: "POST",
   1905 		url: url,
   1906 		data: data,
   1907 		success: callback,
   1908 		dataType: type
   1909 	});
   1910 },
   1911 
   1912 // timeout (ms)
   1913 //timeout: 0,
   1914 ajaxTimeout: function( timeout ) {
   1915 	jQuery.ajaxSettings.timeout = timeout;
   1916 },
   1917 ajaxSetup: function( settings ) {
   1918 	jQuery.extend( jQuery.ajaxSettings, settings );
   1919 },
   1920 
   1921 ajaxSettings: {
   1922 	global: true,
   1923 	type: "GET",
   1924 	timeout: 0,
   1925 	contentType: "application/x-www-form-urlencoded",
   1926 	processData: true,
   1927 	async: true,
   1928 	data: null
   1929 },
   1930 
   1931 // Last-Modified header cache for next request
   1932 lastModified: {},
   1933 ajax: function( s ) {
   1934 	// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
   1935 	s = jQuery.extend({}, jQuery.ajaxSettings, s);
   1936 
   1937 	// if data available
   1938 	if ( s.data ) {
   1939 		// convert data if not already a string
   1940 		if (s.processData && typeof s.data != "string")
   1941    			s.data = jQuery.param(s.data);
   1942 		// append data to url for get requests
   1943 		if( s.type.toLowerCase() == "get" )
   1944 			// "?" + data or "&" + data (in case there are already params)
   1945 			s.url += ((s.url.indexOf("?") > -1) ? "&" : "?") + s.data;
   1946 	}
   1947 
   1948 	// Watch for a new set of requests
   1949 	if ( s.global && ! jQuery.active++ )
   1950 		jQuery.event.trigger( "ajaxStart" );
   1951 
   1952 	var requestDone = false;
   1953 
   1954 	// Create the request object
   1955 	var xml = new XMLHttpRequest();
   1956 
   1957 	// Open the socket
   1958 	xml.open(s.type, s.url, s.async);
   1959 
   1960 	// Set the correct header, if data is being sent
   1961 	if ( s.data )
   1962 		xml.setRequestHeader("Content-Type", s.contentType);
   1963 
   1964 	// Set the If-Modified-Since header, if ifModified mode.
   1965 	if ( s.ifModified )
   1966 		xml.setRequestHeader("If-Modified-Since",
   1967 			jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
   1968 
   1969 	// Set header so the called script knows that it's an XMLHttpRequest
   1970 	xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
   1971 
   1972 	// Make sure the browser sends the right content length
   1973 	if ( xml.overrideMimeType )
   1974 		xml.setRequestHeader("Connection", "close");
   1975 		
   1976 	// Allow custom headers/mimetypes
   1977 	if( s.beforeSend )
   1978 		s.beforeSend(xml);
   1979 		
   1980 	if ( s.global )
   1981 	    jQuery.event.trigger("ajaxSend", [xml, s]);
   1982 
   1983 	// Wait for a response to come back
   1984 	var onreadystatechange = function(isTimeout){
   1985 		// The transfer is complete and the data is available, or the request timed out
   1986 		if ( xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
   1987 			requestDone = true;
   1988 			var status;
   1989 			try {
   1990 				status = jQuery.httpSuccess( xml ) && isTimeout != "timeout" ?
   1991 					s.ifModified && jQuery.httpNotModified( xml, s.url ) ? "notmodified" : "success" : "error";
   1992 				// Make sure that the request was successful or notmodified
   1993 				if ( status != "error" ) {
   1994 					// Cache Last-Modified header, if ifModified mode.
   1995 					var modRes;
   1996 					try {
   1997 						modRes = xml.getResponseHeader("Last-Modified");
   1998 					} catch(e) {} // swallow exception thrown by FF if header is not available
   1999 
   2000 					if ( s.ifModified && modRes )
   2001 						jQuery.lastModified[s.url] = modRes;
   2002 
   2003 					// process the data (runs the xml through httpData regardless of callback)
   2004 					var data = jQuery.httpData( xml, s.dataType );
   2005 
   2006 					// If a local callback was specified, fire it and pass it the data
   2007 					if ( s.success )
   2008 						s.success( data, status );
   2009 
   2010 					// Fire the global callback
   2011 					if( s.global )
   2012 						jQuery.event.trigger( "ajaxSuccess", [xml, s] );
   2013 				} else
   2014 					jQuery.handleError(s, xml, status);
   2015 			} catch(e) {
   2016 				status = "error";
   2017 				jQuery.handleError(s, xml, status, e);
   2018 			}
   2019 
   2020 			// The request was completed
   2021 			if( s.global )
   2022 				jQuery.event.trigger( "ajaxComplete", [xml, s] );
   2023 
   2024 			// Handle the global AJAX counter
   2025 			if ( s.global && ! --jQuery.active )
   2026 				jQuery.event.trigger( "ajaxStop" );
   2027 
   2028 			// Process result
   2029 			if ( s.complete )
   2030 				s.complete(xml, status);
   2031 
   2032 			// Stop memory leaks
   2033 			xml.onreadystatechange = function(){};
   2034 			xml = null;
   2035 		}
   2036 	};
   2037 	xml.onreadystatechange = onreadystatechange;
   2038 
   2039 	// Timeout checker
   2040 	if ( s.timeout > 0 )
   2041 		setTimeout(function(){
   2042 			// Check to see if the request is still happening
   2043 			if ( xml ) {
   2044 				// Cancel the request
   2045 				xml.abort();
   2046 
   2047 				if( !requestDone )
   2048 					onreadystatechange( "timeout" );
   2049 			}
   2050 		}, s.timeout);
   2051 		
   2052 	// save non-leaking reference 
   2053 	var xml2 = xml;
   2054 
   2055 	// Send the data
   2056 	try {
   2057 		xml2.send(s.data);
   2058 	} catch(e) {
   2059 		jQuery.handleError(s, xml, null, e);
   2060 	}
   2061 	
   2062 	// firefox 1.5 doesn't fire statechange for sync requests
   2063 	if ( !s.async )
   2064 		onreadystatechange();
   2065 	
   2066 	// return XMLHttpRequest to allow aborting the request etc.
   2067 	return xml2;
   2068 },
   2069 
   2070 handleError: function( s, xml, status, e ) {
   2071 	// If a local callback was specified, fire it
   2072 	if ( s.error ) s.error( xml, status, e );
   2073 
   2074 	// Fire the global callback
   2075 	if ( s.global )
   2076 		jQuery.event.trigger( "ajaxError", [xml, s, e] );
   2077 },
   2078 
   2079 // Counter for holding the number of active queries
   2080 active: 0,
   2081 
   2082 // Determines if an XMLHttpRequest was successful or not
   2083 httpSuccess: function( r ) {
   2084 	try {
   2085 		return !r.status && location.protocol == "file:" ||
   2086 			( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
   2087 			jQuery.browser.safari && r.status == undefined;
   2088 	} catch(e){}
   2089 	return false;
   2090 },
   2091 
   2092 // Determines if an XMLHttpRequest returns NotModified
   2093 httpNotModified: function( xml, url ) {
   2094 	try {
   2095 		var xmlRes = xml.getResponseHeader("Last-Modified");
   2096 
   2097 		// Firefox always returns 200. check Last-Modified date
   2098 		return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
   2099 			jQuery.browser.safari && xml.status == undefined;
   2100 	} catch(e){}
   2101 	return false;
   2102 },
   2103 
   2104 /* Get the data out of an XMLHttpRequest.
   2105  * Return parsed XML if content-type header is "xml" and type is "xml" or omitted,
   2106  * otherwise return plain text.
   2107  * (String) data - The type of data that you're expecting back,
   2108  * (e.g. "xml", "html", "script")
   2109  */
   2110 httpData: function( r, type ) {
   2111 	var ct = r.getResponseHeader("content-type");
   2112 	var data = !type && ct && ct.indexOf("xml") >= 0;
   2113 	data = type == "xml" || data ? r.responseXML : r.responseText;
   2114 
   2115 	// If the type is "script", eval it in global context
   2116 	if ( type == "script" )
   2117 		jQuery.globalEval( data );
   2118 
   2119 	// Get the JavaScript object, if JSON is used.
   2120 	if ( type == "json" )
   2121 		eval( "data = " + data );
   2122 
   2123 	// evaluate scripts within html
   2124 	if ( type == "html" )
   2125 		jQuery("<div>").html(data).evalScripts();
   2126 
   2127 	return data;
   2128 },
   2129 
   2130 // Serialize an array of form elements or a set of
   2131 // key/values into a query string
   2132 param: function( a ) {
   2133 	var s = [];
   2134 
   2135 	// If an array was passed in, assume that it is an array
   2136 	// of form elements
   2137 	if ( a.constructor == Array || a.jquery )
   2138 		// Serialize the form elements
   2139 		jQuery.each( a, function(){
   2140 			s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
   2141 		});
   2142 
   2143 	// Otherwise, assume that it's an object of key/value pairs
   2144 	else
   2145 		// Serialize the key/values
   2146 		for ( var j in a )
   2147 			// If the value is an array then the key names need to be repeated
   2148 			if ( a[j].constructor == Array )
   2149 				jQuery.each( a[j], function(){
   2150 					s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
   2151 				});
   2152 			else
   2153 				s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
   2154 
   2155 	// Return the resulting serialization
   2156 	return s.join("&");
   2157 },
   2158 
   2159 // evalulates a script in global context
   2160 // not reliable for safari
   2161 globalEval: function( data ) {
   2162 	if ( window.execScript )
   2163 		window.execScript( data );
   2164 	else if ( jQuery.browser.safari )
   2165 		// safari doesn't provide a synchronous global eval
   2166 		window.setTimeout( data, 0 );
   2167 	else
   2168 		eval.call( window, data );
   2169 }
   2170 
   2171 });
   2172 }