PageRenderTime 181ms CodeModel.GetById 24ms app.highlight 137ms RepoModel.GetById 1ms app.codeStats 1ms

/ShowMeTheBestReply/web-app/js/jquery/jquery-1.3.2.js

http://showmethebestreply.googlecode.com/
JavaScript | 2472 lines | 1956 code | 314 blank | 202 comment | 387 complexity | 7b7ece4224616a0eb48bf16057e15e77 MD5 | raw file
   1/*!
   2 * jQuery JavaScript Library v1.3.2
   3 * http://jquery.com/
   4 *
   5 * Copyright (c) 2009 John Resig
   6 * Dual licensed under the MIT and GPL licenses.
   7 * http://docs.jquery.com/License
   8 *
   9 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
  10 * Revision: 6246
  11 */
  12(function(){
  13
  14var 
  15	// Will speed up references to window, and allows munging its name.
  16	window = this,
  17	// Will speed up references to undefined, and allows munging its name.
  18	undefined,
  19	// Map over jQuery in case of overwrite
  20	_jQuery = window.jQuery,
  21	// Map over the $ in case of overwrite
  22	_$ = window.$,
  23
  24	jQuery = window.jQuery = window.$ = function( selector, context ) {
  25		// The jQuery object is actually just the init constructor 'enhanced'
  26		return new jQuery.fn.init( selector, context );
  27	},
  28
  29	// A simple way to check for HTML strings or ID strings
  30	// (both of which we optimize for)
  31	quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
  32	// Is it a simple selector
  33	isSimple = /^.[^:#\[\.,]*$/;
  34
  35jQuery.fn = jQuery.prototype = {
  36	init: function( selector, context ) {
  37		// Make sure that a selection was provided
  38		selector = selector || document;
  39
  40		// Handle $(DOMElement)
  41		if ( selector.nodeType ) {
  42			this[0] = selector;
  43			this.length = 1;
  44			this.context = selector;
  45			return this;
  46		}
  47		// Handle HTML strings
  48		if ( typeof selector === "string" ) {
  49			// Are we dealing with HTML string or an ID?
  50			var match = quickExpr.exec( selector );
  51
  52			// Verify a match, and that no context was specified for #id
  53			if ( match && (match[1] || !context) ) {
  54
  55				// HANDLE: $(html) -> $(array)
  56				if ( match[1] )
  57					selector = jQuery.clean( [ match[1] ], context );
  58
  59				// HANDLE: $("#id")
  60				else {
  61					var elem = document.getElementById( match[3] );
  62
  63					// Handle the case where IE and Opera return items
  64					// by name instead of ID
  65					if ( elem && elem.id != match[3] )
  66						return jQuery().find( selector );
  67
  68					// Otherwise, we inject the element directly into the jQuery object
  69					var ret = jQuery( elem || [] );
  70					ret.context = document;
  71					ret.selector = selector;
  72					return ret;
  73				}
  74
  75			// HANDLE: $(expr, [context])
  76			// (which is just equivalent to: $(content).find(expr)
  77			} else
  78				return jQuery( context ).find( selector );
  79
  80		// HANDLE: $(function)
  81		// Shortcut for document ready
  82		} else if ( jQuery.isFunction( selector ) )
  83			return jQuery( document ).ready( selector );
  84
  85		// Make sure that old selector state is passed along
  86		if ( selector.selector && selector.context ) {
  87			this.selector = selector.selector;
  88			this.context = selector.context;
  89		}
  90
  91		return this.setArray(jQuery.isArray( selector ) ?
  92			selector :
  93			jQuery.makeArray(selector));
  94	},
  95
  96	// Start with an empty selector
  97	selector: "",
  98
  99	// The current version of jQuery being used
 100	jquery: "1.3.2",
 101
 102	// The number of elements contained in the matched element set
 103	size: function() {
 104		return this.length;
 105	},
 106
 107	// Get the Nth element in the matched element set OR
 108	// Get the whole matched element set as a clean array
 109	get: function( num ) {
 110		return num === undefined ?
 111
 112			// Return a 'clean' array
 113			Array.prototype.slice.call( this ) :
 114
 115			// Return just the object
 116			this[ num ];
 117	},
 118
 119	// Take an array of elements and push it onto the stack
 120	// (returning the new matched element set)
 121	pushStack: function( elems, name, selector ) {
 122		// Build a new jQuery matched element set
 123		var ret = jQuery( elems );
 124
 125		// Add the old object onto the stack (as a reference)
 126		ret.prevObject = this;
 127
 128		ret.context = this.context;
 129
 130		if ( name === "find" )
 131			ret.selector = this.selector + (this.selector ? " " : "") + selector;
 132		else if ( name )
 133			ret.selector = this.selector + "." + name + "(" + selector + ")";
 134
 135		// Return the newly-formed element set
 136		return ret;
 137	},
 138
 139	// Force the current matched set of elements to become
 140	// the specified array of elements (destroying the stack in the process)
 141	// You should use pushStack() in order to do this, but maintain the stack
 142	setArray: function( elems ) {
 143		// Resetting the length to 0, then using the native Array push
 144		// is a super-fast way to populate an object with array-like properties
 145		this.length = 0;
 146		Array.prototype.push.apply( this, elems );
 147
 148		return this;
 149	},
 150
 151	// Execute a callback for every element in the matched set.
 152	// (You can seed the arguments with an array of args, but this is
 153	// only used internally.)
 154	each: function( callback, args ) {
 155		return jQuery.each( this, callback, args );
 156	},
 157
 158	// Determine the position of an element within
 159	// the matched set of elements
 160	index: function( elem ) {
 161		// Locate the position of the desired element
 162		return jQuery.inArray(
 163			// If it receives a jQuery object, the first element is used
 164			elem && elem.jquery ? elem[0] : elem
 165		, this );
 166	},
 167
 168	attr: function( name, value, type ) {
 169		var options = name;
 170
 171		// Look for the case where we're accessing a style value
 172		if ( typeof name === "string" )
 173			if ( value === undefined )
 174				return this[0] && jQuery[ type || "attr" ]( this[0], name );
 175
 176			else {
 177				options = {};
 178				options[ name ] = value;
 179			}
 180
 181		// Check to see if we're setting style values
 182		return this.each(function(i){
 183			// Set all the styles
 184			for ( name in options )
 185				jQuery.attr(
 186					type ?
 187						this.style :
 188						this,
 189					name, jQuery.prop( this, options[ name ], type, i, name )
 190				);
 191		});
 192	},
 193
 194	css: function( key, value ) {
 195		// ignore negative width and height values
 196		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
 197			value = undefined;
 198		return this.attr( key, value, "curCSS" );
 199	},
 200
 201	text: function( text ) {
 202		if ( typeof text !== "object" && text != null )
 203			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
 204
 205		var ret = "";
 206
 207		jQuery.each( text || this, function(){
 208			jQuery.each( this.childNodes, function(){
 209				if ( this.nodeType != 8 )
 210					ret += this.nodeType != 1 ?
 211						this.nodeValue :
 212						jQuery.fn.text( [ this ] );
 213			});
 214		});
 215
 216		return ret;
 217	},
 218
 219	wrapAll: function( html ) {
 220		if ( this[0] ) {
 221			// The elements to wrap the target around
 222			var wrap = jQuery( html, this[0].ownerDocument ).clone();
 223
 224			if ( this[0].parentNode )
 225				wrap.insertBefore( this[0] );
 226
 227			wrap.map(function(){
 228				var elem = this;
 229
 230				while ( elem.firstChild )
 231					elem = elem.firstChild;
 232
 233				return elem;
 234			}).append(this);
 235		}
 236
 237		return this;
 238	},
 239
 240	wrapInner: function( html ) {
 241		return this.each(function(){
 242			jQuery( this ).contents().wrapAll( html );
 243		});
 244	},
 245
 246	wrap: function( html ) {
 247		return this.each(function(){
 248			jQuery( this ).wrapAll( html );
 249		});
 250	},
 251
 252	append: function() {
 253		return this.domManip(arguments, true, function(elem){
 254			if (this.nodeType == 1)
 255				this.appendChild( elem );
 256		});
 257	},
 258
 259	prepend: function() {
 260		return this.domManip(arguments, true, function(elem){
 261			if (this.nodeType == 1)
 262				this.insertBefore( elem, this.firstChild );
 263		});
 264	},
 265
 266	before: function() {
 267		return this.domManip(arguments, false, function(elem){
 268			this.parentNode.insertBefore( elem, this );
 269		});
 270	},
 271
 272	after: function() {
 273		return this.domManip(arguments, false, function(elem){
 274			this.parentNode.insertBefore( elem, this.nextSibling );
 275		});
 276	},
 277
 278	end: function() {
 279		return this.prevObject || jQuery( [] );
 280	},
 281
 282	// For internal use only.
 283	// Behaves like an Array's method, not like a jQuery method.
 284	push: [].push,
 285	sort: [].sort,
 286	splice: [].splice,
 287
 288	find: function( selector ) {
 289		if ( this.length === 1 ) {
 290			var ret = this.pushStack( [], "find", selector );
 291			ret.length = 0;
 292			jQuery.find( selector, this[0], ret );
 293			return ret;
 294		} else {
 295			return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
 296				return jQuery.find( selector, elem );
 297			})), "find", selector );
 298		}
 299	},
 300
 301	clone: function( events ) {
 302		// Do the clone
 303		var ret = this.map(function(){
 304			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
 305				// IE copies events bound via attachEvent when
 306				// using cloneNode. Calling detachEvent on the
 307				// clone will also remove the events from the orignal
 308				// In order to get around this, we use innerHTML.
 309				// Unfortunately, this means some modifications to
 310				// attributes in IE that are actually only stored
 311				// as properties will not be copied (such as the
 312				// the name attribute on an input).
 313				var html = this.outerHTML;
 314				if ( !html ) {
 315					var div = this.ownerDocument.createElement("div");
 316					div.appendChild( this.cloneNode(true) );
 317					html = div.innerHTML;
 318				}
 319
 320				return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
 321			} else
 322				return this.cloneNode(true);
 323		});
 324
 325		// Copy the events from the original to the clone
 326		if ( events === true ) {
 327			var orig = this.find("*").andSelf(), i = 0;
 328
 329			ret.find("*").andSelf().each(function(){
 330				if ( this.nodeName !== orig[i].nodeName )
 331					return;
 332
 333				var events = jQuery.data( orig[i], "events" );
 334
 335				for ( var type in events ) {
 336					for ( var handler in events[ type ] ) {
 337						jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
 338					}
 339				}
 340
 341				i++;
 342			});
 343		}
 344
 345		// Return the cloned set
 346		return ret;
 347	},
 348
 349	filter: function( selector ) {
 350		return this.pushStack(
 351			jQuery.isFunction( selector ) &&
 352			jQuery.grep(this, function(elem, i){
 353				return selector.call( elem, i );
 354			}) ||
 355
 356			jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
 357				return elem.nodeType === 1;
 358			}) ), "filter", selector );
 359	},
 360
 361	closest: function( selector ) {
 362		var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
 363			closer = 0;
 364
 365		return this.map(function(){
 366			var cur = this;
 367			while ( cur && cur.ownerDocument ) {
 368				if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
 369					jQuery.data(cur, "closest", closer);
 370					return cur;
 371				}
 372				cur = cur.parentNode;
 373				closer++;
 374			}
 375		});
 376	},
 377
 378	not: function( selector ) {
 379		if ( typeof selector === "string" )
 380			// test special case where just one selector is passed in
 381			if ( isSimple.test( selector ) )
 382				return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
 383			else
 384				selector = jQuery.multiFilter( selector, this );
 385
 386		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
 387		return this.filter(function() {
 388			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
 389		});
 390	},
 391
 392	add: function( selector ) {
 393		return this.pushStack( jQuery.unique( jQuery.merge(
 394			this.get(),
 395			typeof selector === "string" ?
 396				jQuery( selector ) :
 397				jQuery.makeArray( selector )
 398		)));
 399	},
 400
 401	is: function( selector ) {
 402		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
 403	},
 404
 405	hasClass: function( selector ) {
 406		return !!selector && this.is( "." + selector );
 407	},
 408
 409	val: function( value ) {
 410		if ( value === undefined ) {			
 411			var elem = this[0];
 412
 413			if ( elem ) {
 414				if( jQuery.nodeName( elem, 'option' ) )
 415					return (elem.attributes.value || {}).specified ? elem.value : elem.text;
 416				
 417				// We need to handle select boxes special
 418				if ( jQuery.nodeName( elem, "select" ) ) {
 419					var index = elem.selectedIndex,
 420						values = [],
 421						options = elem.options,
 422						one = elem.type == "select-one";
 423
 424					// Nothing was selected
 425					if ( index < 0 )
 426						return null;
 427
 428					// Loop through all the selected options
 429					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
 430						var option = options[ i ];
 431
 432						if ( option.selected ) {
 433							// Get the specifc value for the option
 434							value = jQuery(option).val();
 435
 436							// We don't need an array for one selects
 437							if ( one )
 438								return value;
 439
 440							// Multi-Selects return an array
 441							values.push( value );
 442						}
 443					}
 444
 445					return values;				
 446				}
 447
 448				// Everything else, we just grab the value
 449				return (elem.value || "").replace(/\r/g, "");
 450
 451			}
 452
 453			return undefined;
 454		}
 455
 456		if ( typeof value === "number" )
 457			value += '';
 458
 459		return this.each(function(){
 460			if ( this.nodeType != 1 )
 461				return;
 462
 463			if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
 464				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
 465					jQuery.inArray(this.name, value) >= 0);
 466
 467			else if ( jQuery.nodeName( this, "select" ) ) {
 468				var values = jQuery.makeArray(value);
 469
 470				jQuery( "option", this ).each(function(){
 471					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
 472						jQuery.inArray( this.text, values ) >= 0);
 473				});
 474
 475				if ( !values.length )
 476					this.selectedIndex = -1;
 477
 478			} else
 479				this.value = value;
 480		});
 481	},
 482
 483	html: function( value ) {
 484		return value === undefined ?
 485			(this[0] ?
 486				this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
 487				null) :
 488			this.empty().append( value );
 489	},
 490
 491	replaceWith: function( value ) {
 492		return this.after( value ).remove();
 493	},
 494
 495	eq: function( i ) {
 496		return this.slice( i, +i + 1 );
 497	},
 498
 499	slice: function() {
 500		return this.pushStack( Array.prototype.slice.apply( this, arguments ),
 501			"slice", Array.prototype.slice.call(arguments).join(",") );
 502	},
 503
 504	map: function( callback ) {
 505		return this.pushStack( jQuery.map(this, function(elem, i){
 506			return callback.call( elem, i, elem );
 507		}));
 508	},
 509
 510	andSelf: function() {
 511		return this.add( this.prevObject );
 512	},
 513
 514	domManip: function( args, table, callback ) {
 515		if ( this[0] ) {
 516			var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
 517				scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
 518				first = fragment.firstChild;
 519
 520			if ( first )
 521				for ( var i = 0, l = this.length; i < l; i++ )
 522					callback.call( root(this[i], first), this.length > 1 || i > 0 ?
 523							fragment.cloneNode(true) : fragment );
 524		
 525			if ( scripts )
 526				jQuery.each( scripts, evalScript );
 527		}
 528
 529		return this;
 530		
 531		function root( elem, cur ) {
 532			return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
 533				(elem.getElementsByTagName("tbody")[0] ||
 534				elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
 535				elem;
 536		}
 537	}
 538};
 539
 540// Give the init function the jQuery prototype for later instantiation
 541jQuery.fn.init.prototype = jQuery.fn;
 542
 543function evalScript( i, elem ) {
 544	if ( elem.src )
 545		jQuery.ajax({
 546			url: elem.src,
 547			async: false,
 548			dataType: "script"
 549		});
 550
 551	else
 552		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
 553
 554	if ( elem.parentNode )
 555		elem.parentNode.removeChild( elem );
 556}
 557
 558function now(){
 559	return +new Date;
 560}
 561
 562jQuery.extend = jQuery.fn.extend = function() {
 563	// copy reference to target object
 564	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
 565
 566	// Handle a deep copy situation
 567	if ( typeof target === "boolean" ) {
 568		deep = target;
 569		target = arguments[1] || {};
 570		// skip the boolean and the target
 571		i = 2;
 572	}
 573
 574	// Handle case when target is a string or something (possible in deep copy)
 575	if ( typeof target !== "object" && !jQuery.isFunction(target) )
 576		target = {};
 577
 578	// extend jQuery itself if only one argument is passed
 579	if ( length == i ) {
 580		target = this;
 581		--i;
 582	}
 583
 584	for ( ; i < length; i++ )
 585		// Only deal with non-null/undefined values
 586		if ( (options = arguments[ i ]) != null )
 587			// Extend the base object
 588			for ( var name in options ) {
 589				var src = target[ name ], copy = options[ name ];
 590
 591				// Prevent never-ending loop
 592				if ( target === copy )
 593					continue;
 594
 595				// Recurse if we're merging object values
 596				if ( deep && copy && typeof copy === "object" && !copy.nodeType )
 597					target[ name ] = jQuery.extend( deep, 
 598						// Never move original objects, clone them
 599						src || ( copy.length != null ? [ ] : { } )
 600					, copy );
 601
 602				// Don't bring in undefined values
 603				else if ( copy !== undefined )
 604					target[ name ] = copy;
 605
 606			}
 607
 608	// Return the modified object
 609	return target;
 610};
 611
 612// exclude the following css properties to add px
 613var	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
 614	// cache defaultView
 615	defaultView = document.defaultView || {},
 616	toString = Object.prototype.toString;
 617
 618jQuery.extend({
 619	noConflict: function( deep ) {
 620		window.$ = _$;
 621
 622		if ( deep )
 623			window.jQuery = _jQuery;
 624
 625		return jQuery;
 626	},
 627
 628	// See test/unit/core.js for details concerning isFunction.
 629	// Since version 1.3, DOM methods and functions like alert
 630	// aren't supported. They return false on IE (#2968).
 631	isFunction: function( obj ) {
 632		return toString.call(obj) === "[object Function]";
 633	},
 634
 635	isArray: function( obj ) {
 636		return toString.call(obj) === "[object Array]";
 637	},
 638
 639	// check if an element is in a (or is an) XML document
 640	isXMLDoc: function( elem ) {
 641		return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
 642			!!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
 643	},
 644
 645	// Evalulates a script in a global context
 646	globalEval: function( data ) {
 647		if ( data && /\S/.test(data) ) {
 648			// Inspired by code by Andrea Giammarchi
 649			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
 650			var head = document.getElementsByTagName("head")[0] || document.documentElement,
 651				script = document.createElement("script");
 652
 653			script.type = "text/javascript";
 654			if ( jQuery.support.scriptEval )
 655				script.appendChild( document.createTextNode( data ) );
 656			else
 657				script.text = data;
 658
 659			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
 660			// This arises when a base node is used (#2709).
 661			head.insertBefore( script, head.firstChild );
 662			head.removeChild( script );
 663		}
 664	},
 665
 666	nodeName: function( elem, name ) {
 667		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
 668	},
 669
 670	// args is for internal usage only
 671	each: function( object, callback, args ) {
 672		var name, i = 0, length = object.length;
 673
 674		if ( args ) {
 675			if ( length === undefined ) {
 676				for ( name in object )
 677					if ( callback.apply( object[ name ], args ) === false )
 678						break;
 679			} else
 680				for ( ; i < length; )
 681					if ( callback.apply( object[ i++ ], args ) === false )
 682						break;
 683
 684		// A special, fast, case for the most common use of each
 685		} else {
 686			if ( length === undefined ) {
 687				for ( name in object )
 688					if ( callback.call( object[ name ], name, object[ name ] ) === false )
 689						break;
 690			} else
 691				for ( var value = object[0];
 692					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
 693		}
 694
 695		return object;
 696	},
 697
 698	prop: function( elem, value, type, i, name ) {
 699		// Handle executable functions
 700		if ( jQuery.isFunction( value ) )
 701			value = value.call( elem, i );
 702
 703		// Handle passing in a number to a CSS property
 704		return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
 705			value + "px" :
 706			value;
 707	},
 708
 709	className: {
 710		// internal only, use addClass("class")
 711		add: function( elem, classNames ) {
 712			jQuery.each((classNames || "").split(/\s+/), function(i, className){
 713				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
 714					elem.className += (elem.className ? " " : "") + className;
 715			});
 716		},
 717
 718		// internal only, use removeClass("class")
 719		remove: function( elem, classNames ) {
 720			if (elem.nodeType == 1)
 721				elem.className = classNames !== undefined ?
 722					jQuery.grep(elem.className.split(/\s+/), function(className){
 723						return !jQuery.className.has( classNames, className );
 724					}).join(" ") :
 725					"";
 726		},
 727
 728		// internal only, use hasClass("class")
 729		has: function( elem, className ) {
 730			return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
 731		}
 732	},
 733
 734	// A method for quickly swapping in/out CSS properties to get correct calculations
 735	swap: function( elem, options, callback ) {
 736		var old = {};
 737		// Remember the old values, and insert the new ones
 738		for ( var name in options ) {
 739			old[ name ] = elem.style[ name ];
 740			elem.style[ name ] = options[ name ];
 741		}
 742
 743		callback.call( elem );
 744
 745		// Revert the old values
 746		for ( var name in options )
 747			elem.style[ name ] = old[ name ];
 748	},
 749
 750	css: function( elem, name, force, extra ) {
 751		if ( name == "width" || name == "height" ) {
 752			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
 753
 754			function getWH() {
 755				val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
 756
 757				if ( extra === "border" )
 758					return;
 759
 760				jQuery.each( which, function() {
 761					if ( !extra )
 762						val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
 763					if ( extra === "margin" )
 764						val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
 765					else
 766						val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
 767				});
 768			}
 769
 770			if ( elem.offsetWidth !== 0 )
 771				getWH();
 772			else
 773				jQuery.swap( elem, props, getWH );
 774
 775			return Math.max(0, Math.round(val));
 776		}
 777
 778		return jQuery.curCSS( elem, name, force );
 779	},
 780
 781	curCSS: function( elem, name, force ) {
 782		var ret, style = elem.style;
 783
 784		// We need to handle opacity special in IE
 785		if ( name == "opacity" && !jQuery.support.opacity ) {
 786			ret = jQuery.attr( style, "opacity" );
 787
 788			return ret == "" ?
 789				"1" :
 790				ret;
 791		}
 792
 793		// Make sure we're using the right name for getting the float value
 794		if ( name.match( /float/i ) )
 795			name = styleFloat;
 796
 797		if ( !force && style && style[ name ] )
 798			ret = style[ name ];
 799
 800		else if ( defaultView.getComputedStyle ) {
 801
 802			// Only "float" is needed here
 803			if ( name.match( /float/i ) )
 804				name = "float";
 805
 806			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
 807
 808			var computedStyle = defaultView.getComputedStyle( elem, null );
 809
 810			if ( computedStyle )
 811				ret = computedStyle.getPropertyValue( name );
 812
 813			// We should always get a number back from opacity
 814			if ( name == "opacity" && ret == "" )
 815				ret = "1";
 816
 817		} else if ( elem.currentStyle ) {
 818			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
 819				return letter.toUpperCase();
 820			});
 821
 822			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
 823
 824			// From the awesome hack by Dean Edwards
 825			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
 826
 827			// If we're not dealing with a regular pixel number
 828			// but a number that has a weird ending, we need to convert it to pixels
 829			if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
 830				// Remember the original values
 831				var left = style.left, rsLeft = elem.runtimeStyle.left;
 832
 833				// Put in the new values to get a computed value out
 834				elem.runtimeStyle.left = elem.currentStyle.left;
 835				style.left = ret || 0;
 836				ret = style.pixelLeft + "px";
 837
 838				// Revert the changed values
 839				style.left = left;
 840				elem.runtimeStyle.left = rsLeft;
 841			}
 842		}
 843
 844		return ret;
 845	},
 846
 847	clean: function( elems, context, fragment ) {
 848		context = context || document;
 849
 850		// !context.createElement fails in IE with an error but returns typeof 'object'
 851		if ( typeof context.createElement === "undefined" )
 852			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
 853
 854		// If a single string is passed in and it's a single tag
 855		// just do a createElement and skip the rest
 856		if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
 857			var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
 858			if ( match )
 859				return [ context.createElement( match[1] ) ];
 860		}
 861
 862		var ret = [], scripts = [], div = context.createElement("div");
 863
 864		jQuery.each(elems, function(i, elem){
 865			if ( typeof elem === "number" )
 866				elem += '';
 867
 868			if ( !elem )
 869				return;
 870
 871			// Convert html string into DOM nodes
 872			if ( typeof elem === "string" ) {
 873				// Fix "XHTML"-style tags in all browsers
 874				elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
 875					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
 876						all :
 877						front + "></" + tag + ">";
 878				});
 879
 880				// Trim whitespace, otherwise indexOf won't work as expected
 881				var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
 882
 883				var wrap =
 884					// option or optgroup
 885					!tags.indexOf("<opt") &&
 886					[ 1, "<select multiple='multiple'>", "</select>" ] ||
 887
 888					!tags.indexOf("<leg") &&
 889					[ 1, "<fieldset>", "</fieldset>" ] ||
 890
 891					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
 892					[ 1, "<table>", "</table>" ] ||
 893
 894					!tags.indexOf("<tr") &&
 895					[ 2, "<table><tbody>", "</tbody></table>" ] ||
 896
 897				 	// <thead> matched above
 898					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
 899					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
 900
 901					!tags.indexOf("<col") &&
 902					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
 903
 904					// IE can't serialize <link> and <script> tags normally
 905					!jQuery.support.htmlSerialize &&
 906					[ 1, "div<div>", "</div>" ] ||
 907
 908					[ 0, "", "" ];
 909
 910				// Go to html and back, then peel off extra wrappers
 911				div.innerHTML = wrap[1] + elem + wrap[2];
 912
 913				// Move to the right depth
 914				while ( wrap[0]-- )
 915					div = div.lastChild;
 916
 917				// Remove IE's autoinserted <tbody> from table fragments
 918				if ( !jQuery.support.tbody ) {
 919
 920					// String was a <table>, *may* have spurious <tbody>
 921					var hasBody = /<tbody/i.test(elem),
 922						tbody = !tags.indexOf("<table") && !hasBody ?
 923							div.firstChild && div.firstChild.childNodes :
 924
 925						// String was a bare <thead> or <tfoot>
 926						wrap[1] == "<table>" && !hasBody ?
 927							div.childNodes :
 928							[];
 929
 930					for ( var j = tbody.length - 1; j >= 0 ; --j )
 931						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
 932							tbody[ j ].parentNode.removeChild( tbody[ j ] );
 933
 934					}
 935
 936				// IE completely kills leading whitespace when innerHTML is used
 937				if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
 938					div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
 939				
 940				elem = jQuery.makeArray( div.childNodes );
 941			}
 942
 943			if ( elem.nodeType )
 944				ret.push( elem );
 945			else
 946				ret = jQuery.merge( ret, elem );
 947
 948		});
 949
 950		if ( fragment ) {
 951			for ( var i = 0; ret[i]; i++ ) {
 952				if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
 953					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
 954				} else {
 955					if ( ret[i].nodeType === 1 )
 956						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
 957					fragment.appendChild( ret[i] );
 958				}
 959			}
 960			
 961			return scripts;
 962		}
 963
 964		return ret;
 965	},
 966
 967	attr: function( elem, name, value ) {
 968		// don't set attributes on text and comment nodes
 969		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
 970			return undefined;
 971
 972		var notxml = !jQuery.isXMLDoc( elem ),
 973			// Whether we are setting (or getting)
 974			set = value !== undefined;
 975
 976		// Try to normalize/fix the name
 977		name = notxml && jQuery.props[ name ] || name;
 978
 979		// Only do all the following if this is a node (faster for style)
 980		// IE elem.getAttribute passes even for style
 981		if ( elem.tagName ) {
 982
 983			// These attributes require special treatment
 984			var special = /href|src|style/.test( name );
 985
 986			// Safari mis-reports the default selected property of a hidden option
 987			// Accessing the parent's selectedIndex property fixes it
 988			if ( name == "selected" && elem.parentNode )
 989				elem.parentNode.selectedIndex;
 990
 991			// If applicable, access the attribute via the DOM 0 way
 992			if ( name in elem && notxml && !special ) {
 993				if ( set ){
 994					// We can't allow the type property to be changed (since it causes problems in IE)
 995					if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
 996						throw "type property can't be changed";
 997
 998					elem[ name ] = value;
 999				}
1000
1001				// browsers index elements by id/name on forms, give priority to attributes.
1002				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1003					return elem.getAttributeNode( name ).nodeValue;
1004
1005				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1006				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1007				if ( name == "tabIndex" ) {
1008					var attributeNode = elem.getAttributeNode( "tabIndex" );
1009					return attributeNode && attributeNode.specified
1010						? attributeNode.value
1011						: elem.nodeName.match(/(button|input|object|select|textarea)/i)
1012							? 0
1013							: elem.nodeName.match(/^(a|area)$/i) && elem.href
1014								? 0
1015								: undefined;
1016				}
1017
1018				return elem[ name ];
1019			}
1020
1021			if ( !jQuery.support.style && notxml &&  name == "style" )
1022				return jQuery.attr( elem.style, "cssText", value );
1023
1024			if ( set )
1025				// convert the value to a string (all browsers do this but IE) see #1070
1026				elem.setAttribute( name, "" + value );
1027
1028			var attr = !jQuery.support.hrefNormalized && notxml && special
1029					// Some attributes require a special call on IE
1030					? elem.getAttribute( name, 2 )
1031					: elem.getAttribute( name );
1032
1033			// Non-existent attributes return null, we normalize to undefined
1034			return attr === null ? undefined : attr;
1035		}
1036
1037		// elem is actually elem.style ... set the style
1038
1039		// IE uses filters for opacity
1040		if ( !jQuery.support.opacity && name == "opacity" ) {
1041			if ( set ) {
1042				// IE has trouble with opacity if it does not have layout
1043				// Force it by setting the zoom level
1044				elem.zoom = 1;
1045
1046				// Set the alpha filter to set the opacity
1047				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1048					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1049			}
1050
1051			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1052				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1053				"";
1054		}
1055
1056		name = name.replace(/-([a-z])/ig, function(all, letter){
1057			return letter.toUpperCase();
1058		});
1059
1060		if ( set )
1061			elem[ name ] = value;
1062
1063		return elem[ name ];
1064	},
1065
1066	trim: function( text ) {
1067		return (text || "").replace( /^\s+|\s+$/g, "" );
1068	},
1069
1070	makeArray: function( array ) {
1071		var ret = [];
1072
1073		if( array != null ){
1074			var i = array.length;
1075			// The window, strings (and functions) also have 'length'
1076			if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
1077				ret[0] = array;
1078			else
1079				while( i )
1080					ret[--i] = array[i];
1081		}
1082
1083		return ret;
1084	},
1085
1086	inArray: function( elem, array ) {
1087		for ( var i = 0, length = array.length; i < length; i++ )
1088		// Use === because on IE, window == document
1089			if ( array[ i ] === elem )
1090				return i;
1091
1092		return -1;
1093	},
1094
1095	merge: function( first, second ) {
1096		// We have to loop this way because IE & Opera overwrite the length
1097		// expando of getElementsByTagName
1098		var i = 0, elem, pos = first.length;
1099		// Also, we need to make sure that the correct elements are being returned
1100		// (IE returns comment nodes in a '*' query)
1101		if ( !jQuery.support.getAll ) {
1102			while ( (elem = second[ i++ ]) != null )
1103				if ( elem.nodeType != 8 )
1104					first[ pos++ ] = elem;
1105
1106		} else
1107			while ( (elem = second[ i++ ]) != null )
1108				first[ pos++ ] = elem;
1109
1110		return first;
1111	},
1112
1113	unique: function( array ) {
1114		var ret = [], done = {};
1115
1116		try {
1117
1118			for ( var i = 0, length = array.length; i < length; i++ ) {
1119				var id = jQuery.data( array[ i ] );
1120
1121				if ( !done[ id ] ) {
1122					done[ id ] = true;
1123					ret.push( array[ i ] );
1124				}
1125			}
1126
1127		} catch( e ) {
1128			ret = array;
1129		}
1130
1131		return ret;
1132	},
1133
1134	grep: function( elems, callback, inv ) {
1135		var ret = [];
1136
1137		// Go through the array, only saving the items
1138		// that pass the validator function
1139		for ( var i = 0, length = elems.length; i < length; i++ )
1140			if ( !inv != !callback( elems[ i ], i ) )
1141				ret.push( elems[ i ] );
1142
1143		return ret;
1144	},
1145
1146	map: function( elems, callback ) {
1147		var ret = [];
1148
1149		// Go through the array, translating each of the items to their
1150		// new value (or values).
1151		for ( var i = 0, length = elems.length; i < length; i++ ) {
1152			var value = callback( elems[ i ], i );
1153
1154			if ( value != null )
1155				ret[ ret.length ] = value;
1156		}
1157
1158		return ret.concat.apply( [], ret );
1159	}
1160});
1161
1162// Use of jQuery.browser is deprecated.
1163// It's included for backwards compatibility and plugins,
1164// although they should work to migrate away.
1165
1166var userAgent = navigator.userAgent.toLowerCase();
1167
1168// Figure out what browser is being used
1169jQuery.browser = {
1170	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1171	safari: /webkit/.test( userAgent ),
1172	opera: /opera/.test( userAgent ),
1173	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1174	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1175};
1176
1177jQuery.each({
1178	parent: function(elem){return elem.parentNode;},
1179	parents: function(elem){return jQuery.dir(elem,"parentNode");},
1180	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1181	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1182	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1183	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1184	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1185	children: function(elem){return jQuery.sibling(elem.firstChild);},
1186	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1187}, function(name, fn){
1188	jQuery.fn[ name ] = function( selector ) {
1189		var ret = jQuery.map( this, fn );
1190
1191		if ( selector && typeof selector == "string" )
1192			ret = jQuery.multiFilter( selector, ret );
1193
1194		return this.pushStack( jQuery.unique( ret ), name, selector );
1195	};
1196});
1197
1198jQuery.each({
1199	appendTo: "append",
1200	prependTo: "prepend",
1201	insertBefore: "before",
1202	insertAfter: "after",
1203	replaceAll: "replaceWith"
1204}, function(name, original){
1205	jQuery.fn[ name ] = function( selector ) {
1206		var ret = [], insert = jQuery( selector );
1207
1208		for ( var i = 0, l = insert.length; i < l; i++ ) {
1209			var elems = (i > 0 ? this.clone(true) : this).get();
1210			jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
1211			ret = ret.concat( elems );
1212		}
1213
1214		return this.pushStack( ret, name, selector );
1215	};
1216});
1217
1218jQuery.each({
1219	removeAttr: function( name ) {
1220		jQuery.attr( this, name, "" );
1221		if (this.nodeType == 1)
1222			this.removeAttribute( name );
1223	},
1224
1225	addClass: function( classNames ) {
1226		jQuery.className.add( this, classNames );
1227	},
1228
1229	removeClass: function( classNames ) {
1230		jQuery.className.remove( this, classNames );
1231	},
1232
1233	toggleClass: function( classNames, state ) {
1234		if( typeof state !== "boolean" )
1235			state = !jQuery.className.has( this, classNames );
1236		jQuery.className[ state ? "add" : "remove" ]( this, classNames );
1237	},
1238
1239	remove: function( selector ) {
1240		if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
1241			// Prevent memory leaks
1242			jQuery( "*", this ).add([this]).each(function(){
1243				jQuery.event.remove(this);
1244				jQuery.removeData(this);
1245			});
1246			if (this.parentNode)
1247				this.parentNode.removeChild( this );
1248		}
1249	},
1250
1251	empty: function() {
1252		// Remove element nodes and prevent memory leaks
1253		jQuery(this).children().remove();
1254
1255		// Remove any remaining nodes
1256		while ( this.firstChild )
1257			this.removeChild( this.firstChild );
1258	}
1259}, function(name, fn){
1260	jQuery.fn[ name ] = function(){
1261		return this.each( fn, arguments );
1262	};
1263});
1264
1265// Helper function used by the dimensions and offset modules
1266function num(elem, prop) {
1267	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1268}
1269var expando = "jQuery" + now(), uuid = 0, windowData = {};
1270
1271jQuery.extend({
1272	cache: {},
1273
1274	data: function( elem, name, data ) {
1275		elem = elem == window ?
1276			windowData :
1277			elem;
1278
1279		var id = elem[ expando ];
1280
1281		// Compute a unique ID for the element
1282		if ( !id )
1283			id = elem[ expando ] = ++uuid;
1284
1285		// Only generate the data cache if we're
1286		// trying to access or manipulate it
1287		if ( name && !jQuery.cache[ id ] )
1288			jQuery.cache[ id ] = {};
1289
1290		// Prevent overriding the named cache with undefined values
1291		if ( data !== undefined )
1292			jQuery.cache[ id ][ name ] = data;
1293
1294		// Return the named cache data, or the ID for the element
1295		return name ?
1296			jQuery.cache[ id ][ name ] :
1297			id;
1298	},
1299
1300	removeData: function( elem, name ) {
1301		elem = elem == window ?
1302			windowData :
1303			elem;
1304
1305		var id = elem[ expando ];
1306
1307		// If we want to remove a specific section of the element's data
1308		if ( name ) {
1309			if ( jQuery.cache[ id ] ) {
1310				// Remove the section of cache data
1311				delete jQuery.cache[ id ][ name ];
1312
1313				// If we've removed all the data, remove the element's cache
1314				name = "";
1315
1316				for ( name in jQuery.cache[ id ] )
1317					break;
1318
1319				if ( !name )
1320					jQuery.removeData( elem );
1321			}
1322
1323		// Otherwise, we want to remove all of the element's data
1324		} else {
1325			// Clean up the element expando
1326			try {
1327				delete elem[ expando ];
1328			} catch(e){
1329				// IE has trouble directly removing the expando
1330				// but it's ok with using removeAttribute
1331				if ( elem.removeAttribute )
1332					elem.removeAttribute( expando );
1333			}
1334
1335			// Completely remove the data cache
1336			delete jQuery.cache[ id ];
1337		}
1338	},
1339	queue: function( elem, type, data ) {
1340		if ( elem ){
1341	
1342			type = (type || "fx") + "queue";
1343	
1344			var q = jQuery.data( elem, type );
1345	
1346			if ( !q || jQuery.isArray(data) )
1347				q = jQuery.data( elem, type, jQuery.makeArray(data) );
1348			else if( data )
1349				q.push( data );
1350	
1351		}
1352		return q;
1353	},
1354
1355	dequeue: function( elem, type ){
1356		var queue = jQuery.queue( elem, type ),
1357			fn = queue.shift();
1358		
1359		if( !type || type === "fx" )
1360			fn = queue[0];
1361			
1362		if( fn !== undefined )
1363			fn.call(elem);
1364	}
1365});
1366
1367jQuery.fn.extend({
1368	data: function( key, value ){
1369		var parts = key.split(".");
1370		parts[1] = parts[1] ? "." + parts[1] : "";
1371
1372		if ( value === undefined ) {
1373			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1374
1375			if ( data === undefined && this.length )
1376				data = jQuery.data( this[0], key );
1377
1378			return data === undefined && parts[1] ?
1379				this.data( parts[0] ) :
1380				data;
1381		} else
1382			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1383				jQuery.data( this, key, value );
1384			});
1385	},
1386
1387	removeData: function( key ){
1388		return this.each(function(){
1389			jQuery.removeData( this, key );
1390		});
1391	},
1392	queue: function(type, data){
1393		if ( typeof type !== "string" ) {
1394			data = type;
1395			type = "fx";
1396		}
1397
1398		if ( data === undefined )
1399			return jQuery.queue( this[0], type );
1400
1401		return this.each(function(){
1402			var queue = jQuery.queue( this, type, data );
1403			
1404			 if( type == "fx" && queue.length == 1 )
1405				queue[0].call(this);
1406		});
1407	},
1408	dequeue: function(type){
1409		return this.each(function(){
1410			jQuery.dequeue( this, type );
1411		});
1412	}
1413});/*!
1414 * Sizzle CSS Selector Engine - v0.9.3
1415 *  Copyright 2009, The Dojo Foundation
1416 *  Released under the MIT, BSD, and GPL Licenses.
1417 *  More information: http://sizzlejs.com/
1418 */
1419(function(){
1420
1421var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
1422	done = 0,
1423	toString = Object.prototype.toString;
1424
1425var Sizzle = function(selector, context, results, seed) {
1426	results = results || [];
1427	context = context || document;
1428
1429	if ( context.nodeType !== 1 && context.nodeType !== 9 )
1430		return [];
1431	
1432	if ( !selector || typeof selector !== "string" ) {
1433		return results;
1434	}
1435
1436	var parts = [], m, set, checkSet, check, mode, extra, prune = true;
1437	
1438	// Reset the position of the chunker regexp (start from head)
1439	chunker.lastIndex = 0;
1440	
1441	while ( (m = chunker.exec(selector)) !== null ) {
1442		parts.push( m[1] );
1443		
1444		if ( m[2] ) {
1445			extra = RegExp.rightContext;
1446			break;
1447		}
1448	}
1449
1450	if ( parts.length > 1 && origPOS.exec( selector ) ) {
1451		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
1452			set = posProcess( parts[0] + parts[1], context );
1453		} else {
1454			set = Expr.relative[ parts[0] ] ?
1455				[ context ] :
1456				Sizzle( parts.shift(), context );
1457
1458			while ( parts.length ) {
1459				selector = parts.shift();
1460
1461				if ( Expr.relative[ selector ] )
1462					selector += parts.shift();
1463
1464				set = posProcess( selector, set );
1465			}
1466		}
1467	} else {
1468		var ret = seed ?
1469			{ expr: parts.pop(), set: makeArray(seed) } :
1470			Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
1471		set = Sizzle.filter( ret.expr, ret.set );
1472
1473		if ( parts.length > 0 ) {
1474			checkSet = makeArray(set);
1475		} else {
1476			prune = false;
1477		}
1478
1479		while ( parts.length ) {
1480			var cur = parts.pop(), pop = cur;
1481
1482			if ( !Expr.relative[ cur ] ) {
1483				cur = "";
1484			} else {
1485				pop = parts.pop();
1486			}
1487
1488			if ( pop == null ) {
1489				pop = context;
1490			}
1491
1492			Expr.relative[ cur ]( checkSet, pop, isXML(context) );
1493		}
1494	}
1495
1496	if ( !checkSet ) {
1497		checkSet = set;
1498	}
1499
1500	if ( !checkSet ) {
1501		throw "Syntax error, unrecognized expression: " + (cur || selector);
1502	}
1503
1504	if ( toString.call(checkSet) === "[object Array]" ) {
1505		if ( !prune ) {
1506			results.push.apply( results, checkSet );
1507		} else if ( context.nodeType === 1 ) {
1508			for ( var i = 0; checkSet[i] != null; i++ ) {
1509				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
1510					results.push( set[i] );
1511				}
1512			}
1513		} else {
1514			for ( var i = 0; checkSet[i] != null; i++ ) {
1515				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
1516					results.push( set[i] );
1517				}
1518			}
1519		}
1520	} else {
1521		makeArray( checkSet, results );
1522	}
1523
1524	if ( extra ) {
1525		Sizzle( extra, context, results, seed );
1526
1527		if ( sortOrder ) {
1528			hasDuplicate = false;
1529			results.sort(sortOrder);
1530
1531			if ( hasDuplicate ) {
1532				for ( var i = 1; i < results.length; i++ ) {
1533					if ( results[i] === results[i-1] ) {
1534						results.splice(i--, 1);
1535					}
1536				}
1537			}
1538		}
1539	}
1540
1541	return results;
1542};
1543
1544Sizzle.matches = function(expr, set){
1545	return Sizzle(expr, null, null, set);
1546};
1547
1548Sizzle.find = function(expr, context, isXML){
1549	var set, match;
1550
1551	if ( !expr ) {
1552		return [];
1553	}
1554
1555	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
1556		var type = Expr.order[i], match;
1557		
1558		if ( (match = Expr.match[ type ].exec( expr )) ) {
1559			var left = RegExp.leftContext;
1560
1561			if ( left.substr( left.length - 1 ) !== "\\" ) {
1562				match[1] = (match[1] || "").replace(/\\/g, "");
1563				set = Expr.find[ type ]( match, context, isXML );
1564				if ( set != null ) {
1565					expr = expr.replace( Expr.match[ type ], "" );
1566					break;
1567				}
1568			}
1569		}
1570	}
1571
1572	if ( !set ) {
1573		set = context.getElementsByTagName("*");
1574	}
1575
1576	return {set: set, expr: expr};
1577};
1578
1579Sizzle.filter = function(expr, set, inplace, not){
1580	var old = expr, result = [], curLoop = set, match, anyFound,
1581		isXMLFilter = set && set[0] && isXML(set[0]);
1582
1583	while ( expr && set.length ) {
1584		for ( var type in Expr.filter ) {
1585			if ( (match = Expr.match[ type ].exec( expr )) != null ) {
1586				var filter = Expr.filter[ type ], found, item;
1587				anyFound = false;
1588
1589				if ( curLoop == result ) {
1590					result = [];
1591				}
1592
1593				if ( Expr.preFilter[ type ] ) {
1594					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
1595
1596					if ( !match ) {
1597						anyFound = found = true;
1598					} else if ( match === true ) {
1599						continue;
1600					}
1601				}
1602
1603				if ( match ) {
1604					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
1605						if ( item ) {
1606							found = filter( item, match, i, curLoop );
1607							var pass = not ^ !!found;
1608
1609							if ( inplace && found != null ) {
1610								if ( pass ) {
1611									anyFound = true;
1612								} else {
1613									curLoop[i] = false;
1614								}
1615							} else if ( pass ) {
1616								result.push( item );
1617								anyFound = true;
1618							}
1619						}
1620					}
1621				}
1622
1623				if ( found !== undefined ) {
1624					if ( !inplace ) {
1625						curLoop = result;
1626					}
1627
1628					expr = expr.replace( Expr.match[ type ], "" );
1629
1630					if ( !anyFound ) {
1631						return [];
1632					}
1633
1634					break;
1635				}
1636			}
1637		}
1638
1639		// Improper expression
1640		if ( expr == old ) {
1641			if ( anyFound == null ) {
1642				throw "Syntax error, unrecognized expression: " + expr;
1643			} else {
1644				break;
1645			}
1646		}
1647
1648		old = expr;
1649	}
1650
1651	return curLoop;
1652};
1653
1654var Expr = Sizzle.selectors = {
1655	order: [ "ID", "NAME", "TAG" ],
1656	match: {
1657		ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1658		CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1659		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
1660		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
1661		TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
1662		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
1663		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
1664		PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
1665	},
1666	attrMap: {
1667		"class": "className",
1668		"for": "htmlFor"
1669	},
1670	attrHandle: {
1671		href: function(elem){
1672			return elem.getAttribute("href");
1673		}
1674	},
1675	relative: {
1676		"+": function(checkSet, part, isXML){
1677			var isPartStr = typeof part === "string",
1678				isTag = isPartStr && !/\W/.test(part),
1679				isPartStrNotTag = isPartStr && !isTag;
1680
1681			if ( isTag && !isXML ) {
1682				part = part.toUpperCase();
1683			}
1684
1685			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
1686				if ( (elem = checkSet[i]) ) {
1687					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
1688
1689					checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
1690						elem || false :
1691						elem === part;
1692				}
1693			}
1694
1695			if ( isPartStrNotTag ) {
1696				Sizzle.filter( part, checkSet, true );
1697			}
1698		},
1699		">": function(checkSet, part, isXML){
1700			var isPartStr = typeof part === "string";
1701
1702			if ( isPartStr && !/\W/.test(part) ) {
1703				part = isXML ? part : part.toUpperCase();
1704
1705				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1706					var elem = checkSet[i];
1707					if ( elem ) {
1708						var parent = elem.parentNode;
1709						checkSet[i] = parent.nodeName === part ? parent : false;
1710					}
1711				}
1712			} else {
1713				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1714					var elem = checkSet[i];
1715					if ( elem ) {
1716						checkSet[i] = isPartStr ?
1717							elem.parentNode :
1718							elem.parentNode === part;
1719					}
1720				}
1721
1722				if ( isPartStr ) {
1723					Sizzle.filter( part, checkSet, true );
1724				}
1725			}
1726		},
1727		"": function(checkSet, part, isXML){
1728			var doneName = done++, checkFn = dirCheck;
1729
1730			if ( !part.match(/\W/) ) {
1731				var nodeCheck = part = isXML ? part : part.toUpperCase();
1732				checkFn = dirNodeCheck;
1733			}
1734
1735			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1736		},
1737		"~": function(checkSet, part, isXML){
1738			var doneName = done++, checkFn = dirCheck;
1739
1740			if ( typeof part === "string" && !part.match(/\W/) ) {
1741				var nodeCheck = part = isXML ? part : part.toUpperCase();
1742				checkFn = dirNodeCheck;
1743			}
1744
1745			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
1746		}
1747	},
1748	find: {
1749		ID: function(match, context, isXML){
1750			if ( typeof context.getElementById !== "undefined" && !isXML ) {
1751				var m = context.getElementById(match[1]);
1752				return m ? [m] : [];
1753			}
1754		},
1755		NAME: function(match, context, isXML){
1756			if ( typeof context.getElementsByName !== "undefined" ) {
1757				var ret = [], results = context.getElementsByName(match[1]);
1758
1759				for ( var i = 0, l = results.length; i < l; i++ ) {
1760					if ( results[i].getAttribute("name") === match[1] ) {
1761						ret.push( results[i] );
1762					}
1763				}
1764
1765				return ret.length === 0 ? null : ret;
1766			}
1767		},
1768		TAG: function(match, context){
1769			return context.getElementsByTagName(match[1]);
1770		}
1771	},
1772	preFilter: {
1773		CLASS: function(match, curLoop, inplace, result, not, isXML){
1774			match = " " + match[1].replace(/\\/g, "") + " ";
1775
1776			if ( isXML ) {
1777				return match;
1778			}
1779
1780			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
1781				if ( elem ) {
1782					if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
1783						if ( !inplace )
1784							result.push( elem );
1785					} else if ( inplace ) {
1786						curLoop[i] = false;
1787					}
1788				}
1789			}
1790
1791			return false;
1792		},
1793		ID: function(match){
1794			return match[1].replace(/\\/g, "");
1795		},
1796		TAG: function(match, curLoop){
1797			for ( var i = 0; curLoop[i] === false; i++ ){}
1798			return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
1799		},
1800		CHILD: function(match){
1801			if ( match[1] == "nth" ) {
1802				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1803				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1804					match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
1805					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
1806
1807				// calculate the numbers (first)n+(last) including if they are negative
1808				match[2] = (test[1] + (test[2] || 1)) - 0;
1809				match[3] = test[3] - 0;
1810			}
1811
1812			// TODO: Move to normal caching system
1813			match[0] = done++;
1814
1815			return match;
1816		},
1817		ATTR: function(match, curLoop, inplace, result, not, isXML){
1818			var name = match[1].replace(/\\/g, "");
1819			
1820			if ( !isXML && Expr.attrMap[name] ) {
1821				match[1] = Expr.attrMap[name];
1822			}
1823
1824			if ( match[2] === "~=" ) {
1825				match[4] = " " + match[4] + " ";
1826			}
1827
1828			return match;
1829		},
1830		PSEUDO: function(match, curLoop, inplace, result, not){
1831			if ( match[1] === "not" ) {
1832				// If we're dealing with a complex expression, or a simple one
1833				if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
1834					match[3] = Sizzle(match[3], null, null, curLoop);
1835				} else {
1836					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
1837					if ( !inplace ) {
1838						result.push.apply( result, ret );
1839					}
1840					return false;
1841				}
1842			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
1843				return true;
1844			}
1845			
1846			return match;
1847		},
1848		POS: function(match){
1849			match.unshift( true );
1850			return match;
1851		}
1852	},
1853	filters: {
1854		enabled: function(elem){
1855			return elem.disabled === false && elem.type !== "hidden";
1856		},
1857		disabled: function(elem){
1858			return elem.disabled === true;
1859		},
1860		checked: function(elem){
1861			return elem.checked === true;
1862		},
1863		selected: function(elem){
1864			// Accessing this property makes selected-by-default
1865			// options in Safari work properly
1866			elem.parentNode.selectedIndex;
1867			return elem.selected === true;
1868		},
1869		parent: function(elem){
1870			return !!elem.firstChild;
1871		},
1872		empty: function(elem){
1873			return !elem.firstChild;
1874		},
1875		has: function(elem, i, match){
1876			return !!Sizzle( match[3], elem ).length;
1877		},
1878		header: function(elem){
1879			return /h\d/i.test( elem.nodeName );
1880		},
1881		text: function(elem){
1882			return "text" === elem.type;
1883		},
1884		radio: function(elem){
1885			return "radio" === elem.type;
1886		},
1887		checkbox: function(elem){
1888			return "checkbox" === elem.type;
1889		},
1890		file: function(elem){
1891			return "file" === elem.type;
1892		},
1893		password: function(elem){
1894			return "password" === elem.type;
1895		},
1896		submit: function(elem){
1897			return "submit" === elem.type;
1898		},
1899		image: function(elem){
1900			return "image" === elem.type;
1901		},
1902		reset: function(elem){
1903			return "reset" === elem.type;
1904		},
1905		button: function(elem){
1906			return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
1907		},
1908		input: function(elem){
1909			return /input|select|textarea|button/i.test(elem.nodeName);
1910		}
1911	},
1912	setFilters: {
1913		first: function(elem, i){
1914			return i === 0;
1915		},
1916		last: function(elem, i, match, array){
1917			return i === array.length - 1;
1918		},
1919		even: function(elem, i){
1920			return i % 2 === 0;
1921		},
1922		odd: function(elem, i){
1923			return i % 2 === 1;
1924		},
1925		lt: function(elem, i, match){
1926			return i < match[3] - 0;
1927		},
1928		gt: function(elem, i, match){
1929			return i > match[3] - 0;
1930		},
1931		nth: function(elem, i, match){
1932			return match[3] - 0 == i;
1933		},
1934		eq: function(elem, i, match){
1935			return match[3] - 0 == i;
1936		}
1937	},
1938	filter: {
1939		PSEUDO: function(elem, match, i, array){
1940			var name = match[1], filter = Expr.filters[ name ];
1941
1942			if ( filter ) {
1943				return filter( elem, i, match, array );
1944			} else if ( name === "contains" ) {
1945				return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
1946			} else if ( name === "not" ) {
1947				var not = match[3];
1948
1949				for ( var i = 0, l = not.length; i < l; i++ ) {
1950					if ( not[i] === elem ) {
1951						return false;
1952					}
1953				}
1954
1955				return true;
1956			}
1957		},
1958		CHILD: function(elem, match){
1959			var type = match[1], node = elem;
1960			switch (type) {
1961				case 'only':
1962				case 'first':
1963					while (node = node.previousSibling)  {
1964						if ( node.nodeType === 1 ) return false;
1965					}
1966					if ( type == 'first') return true;
1967					node = elem;
1968				case 'last':
1969					while (node = node.nextSibling)  {
1970						if ( node.nodeType === 1 ) return false;
1971					}
1972					return true;
1973				case 'nth':
1974					var first = match[2], last = match[3];
1975
1976					if ( first == 1 && last == 0 ) {
1977						return true;
1978					}
1979					
1980					var doneName = match[0],
1981						parent = elem.parentNode;
1982	
1983					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
1984						var count = 0;
1985						for ( node = parent.firstChild; node; node = node.nextSibling ) {
1986							if ( node.nodeType === 1 ) {
1987								node.nodeIndex = ++count;
1988							}
1989						} 
1990						parent.sizcache = doneName;
1991					}
1992					
1993					var diff = elem.nodeIndex - last;
1994					if ( first == 0 ) {
1995						return diff == 0;
1996					} else {
1997						return ( diff % first == 0 && diff / first >= 0 );
1998					}
1999			}
2000		},
2001		ID: function(elem, match){
2002			return elem.nodeType === 1 && elem.getAttribute("id") === match;
2003		},
2004		TAG: function(elem, match){
2005			return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
2006		},
2007		CLASS: function(elem, match){
2008			return (" " + (elem.className || elem.getAttribute("class")) + " ")
2009				.indexOf( match ) > -1;
2010		},
2011		ATTR: function(elem, match){
2012			var name = match[1],
2013				result = Expr.attrHandle[ name ] ?
2014					Expr.attrHandle[ name ]( elem ) :
2015					elem[ name ] != null ?
2016						elem[ name ] :
2017						elem.getAttribute( name ),
2018				value = result + "",
2019				type = match[2],
2020				check = match[4];
2021
2022			return result == null ?
2023				type === "!=" :
2024				type === "=" ?
2025				value === check :
2026				type === "*=" ?
2027				value.indexOf(check) >= 0 :
2028				type === "~=" ?
2029				(" " + value + " ").indexOf(check) >= 0 :
2030				!check ?
2031				value && result !== false :
2032				type === "!=" ?
2033				value != check :
2034				type === "^=" ?
2035				value.indexOf(check) === 0 :
2036				type === "$=" ?
2037				value.substr(value.length - check.length) === check :
2038				type === "|=" ?
2039				value === check || value.substr(0, check.length + 1) === check + "-" :
2040				false;
2041		},
2042		POS: function(elem, match, i, array){
2043			var name = match[2], filter = Expr.setFilters[ name ];
2044
2045			if ( filter ) {
2046				return filter( elem, i, match, array );
2047			}
2048		}
2049	}
2050};
2051
2052var origPOS = Expr.match.POS;
2053
2054for ( var type in Expr.match ) {
2055	Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
2056}
2057
2058var makeArray = function(array, results) {
2059	array = Array.prototype.slice.call( array );
2060
2061	if ( results ) {
2062		results.push.apply( results, array );
2063		return results;
2064	}
2065	
2066	return array;
2067};
2068
2069// Perform a simple check to determine if the browser is capable of
2070// converting a NodeList to an array using builtin methods.
2071try {
2072	Array.prototype.slice.call( document.documentElement.childNodes );
2073
2074// Provide a fallback method if it does not work
2075} catch(e){
2076	makeArray = function(array, results) {
2077		var ret = results || [];
2078
2079		if ( toString.call(array) === "[object Array]" ) {
2080			Array.prototype.push.apply( ret, array );
2081		} else {
2082			if ( typeof array.length === "number" ) {
2083				for ( var i = 0, l = array.length; i < l; i++ ) {
2084					ret.push( array[i] );
2085				}
2086			} else {
2087				for ( var i = 0; array[i]; i++ ) {
2088					ret.push( array[i] );
2089				}
2090			}
2091		}
2092
2093		return ret;
2094	};
2095}
2096
2097var sortOrder;
2098
2099if ( document.documentElement.compareDocumentPosition ) {
2100	sortOrder = function( a, b ) {
2101		var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
2102		if ( ret === 0 ) {
2103			hasDuplicate = true;
2104		}
2105		return ret;
2106	};
2107} else if ( "sourceIndex" in document.documentElement ) {
2108	sortOrder = function( a, b ) {
2109		var ret = a.sourceIndex - b.sourceIndex;
2110		if ( ret === 0 ) {
2111			hasDuplicate = true;
2112		}
2113		return ret;
2114	};
2115} else if ( document.createRange ) {
2116	sortOrder = function( a, b ) {
2117		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
2118		aRange.selectNode(a);
2119		aRange.collapse(true);
2120		bRange.selectNode(b);
2121		bRange.collapse(true);
2122		var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
2123		if ( ret === 0 ) {
2124			hasDuplicate = true;
2125		}
2126		return ret;
2127	};
2128}
2129
2130// Check to see if the browser returns elements by name when
2131// querying by getElementById (and provide a workaround)
2132(function(){
2133	// We're going to inject a fake input element with a specified name
2134	var form = document.createElement("form"),
2135		id = "script" + (new Date).getTime();
2136	form.innerHTML = "<input name='" + id + "'/>";
2137
2138	// Inject it into the root element, check its status, and remove it quickly
2139	var root = document.documentElement;
2140	root.insertBefore( form, root.firstChild );
2141
2142	// The workaround has to do additional checks after a getElementById
2143	// Which slows things down for other browsers (hence the branching)
2144	if ( !!document.getElementById( id ) ) {
2145		Expr.find.ID = function(match, context, isXML){
2146			if ( typeof context.getElementById !== "undefined" && !isXML ) {
2147				var m = context.getElementById(match[1]);
2148				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
2149			}
2150		};
2151
2152		Expr.filter.ID = function(elem, match){
2153			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
2154			return elem.nodeType === 1 && node && node.nodeValue === match;
2155		};
2156	}
2157
2158	root.removeChild( form );
2159})();
2160
2161(function(){
2162	// Check to see if the browser returns only elements
2163	// when doing getElementsByTagName("*")
2164
2165	// Create a fake element
2166	var div = document.createElement("div");
2167	div.appendChild( document.createComment("") );
2168
2169	// Make sure no comments are found
2170	if ( div.getElementsByTagName("*").length > 0 ) {
2171		Expr.find.TAG = function(match, context){
2172			var results = context.getElementsByTagName(match[1]);
2173
2174			// Filter out possible comments
2175			if ( match[1] === "*" ) {
2176				var tmp = [];
2177
2178				for ( var i = 0; results[i]; i++ ) {
2179					if ( results[i].nodeType === 1 ) {
2180						tmp.push( results[i] );
2181					}
2182				}
2183
2184				results = tmp;
2185			}
2186
2187			return results;
2188		};
2189	}
2190
2191	// Check to see if an attribute returns normalized href attributes
2192	div.innerHTML = "<a href='#'></a>";
2193	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
2194			div.firstChild.getAttribute("href") !== "#" ) {
2195		Expr.attrHandle.href = function(elem){
2196			return elem.getAttribute("href", 2);
2197		};
2198	}
2199})();
2200
2201if ( document.querySelectorAll ) (function(){
2202	var oldSizzle = Sizzle, div = document.createElement("div");
2203	div.innerHTML = "<p class='TEST'></p>";
2204
2205	// Safari can't handle uppercase or unicode characters when
2206	// in quirks mode.
2207	if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
2208		return;
2209	}
2210	
2211	Sizzle = function(query, context, extra, seed){
2212		context = context || document;
2213
2214		// Only use querySelectorAll on non-XML documents
2215		// (ID selectors don't work in non-HTML documents)
2216		if ( !seed && context.nodeType === 9 && !isXML(context) ) {
2217			try {
2218				return makeArray( context.querySelectorAll(query), extra );
2219			} catch(e){}
2220		}
2221		
2222		return oldSizzle(query, context, extra, seed);
2223	};
2224
2225	Sizzle.find = oldSizzle.find;
2226	Sizzle.filter = oldSizzle.filter;
2227	Sizzle.selectors = oldSizzle.selectors;
2228	Sizzle.matches = oldSizzle.matches;
2229})();
2230
2231if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
2232	var div = document.createElement("div");
2233	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
2234
2235	// Opera can't find a second classname (in 9.6)
2236	if ( div.getElementsByClassName("e").length === 0 )
2237		return;
2238
2239	// Safari caches class attributes, doesn't catch changes (in 3.2)
2240	div.lastChild.className = "e";
2241
2242	if ( div.getElementsByClassName("e").length === 1 )
2243		return;
2244
2245	Expr.order.splice(1, 0, "CLASS");
2246	Expr.find.CLASS = function(match, context, isXML) {
2247		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
2248			return context.getElementsByClassName(match[1]);
2249		}
2250	};
2251})();
2252
2253function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2254	var sibDir = dir == "previousSibling" && !isXML;
2255	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2256		var elem = checkSet[i];
2257		if ( elem ) {
2258			if ( sibDir && elem.nodeType === 1 ){
2259				elem.sizcache = doneName;
2260				elem.sizset = i;
2261			}
2262			elem = elem[dir];
2263			var match = false;
2264
2265			while ( elem ) {
2266				if ( elem.sizcache === doneName ) {
2267					match = checkSet[elem.sizset];
2268					break;
2269				}
2270
2271				if ( elem.nodeType === 1 && !isXML ){
2272					elem.sizcache = doneName;
2273					elem.sizset = i;
2274				}
2275
2276				if ( elem.nodeName === cur ) {
2277					match = elem;
2278					break;
2279				}
2280
2281				elem = elem[dir];
2282			}
2283
2284			checkSet[i] = match;
2285		}
2286	}
2287}
2288
2289function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2290	var sibDir = dir == "previousSibling" && !isXML;
2291	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2292		var elem = checkSet[i];
2293		if ( elem ) {
2294			if ( sibDir && elem.nodeType === 1 ) {
2295				elem.sizcache = doneName;
2296				elem.sizset = i;
2297			}
2298			elem = elem[dir];
2299			var match = false;
2300
2301			while ( elem ) {
2302				if ( elem.sizcache === doneName ) {
2303					match = checkSet[elem.sizset];
2304					break;
2305				}
2306
2307				if ( elem.nodeType === 1 ) {
2308					if ( !isXML ) {
2309						elem.sizcache = doneName;
2310						elem.sizset = i;
2311					}
2312					if ( typeof cur !== "string" ) {
2313						if ( elem === cur ) {
2314							match = true;
2315							break;
2316						}
2317
2318					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
2319						match = elem;
2320						break;
2321					}
2322				}
2323
2324				elem = elem[dir];
2325			}
2326
2327			checkSet[i] = match;
2328		}
2329	}
2330}
2331
2332var contains = document.compareDocumentPosition ?  function(a, b){
2333	return a.compareDocumentPosition(b) & 16;
2334} : function(a, b){
2335	return a !== b && (a.contains ? a.contains(b) : true);
2336};
2337
2338var isXML = function(elem){
2339	return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
2340		!!elem.ownerDocument && isXML( elem.ownerDocument );
2341};
2342
2343var posProcess = function(selector, context){
2344	var tmpSet = [], later = "", match,
2345		root = context.nodeType ? [context] : context;
2346
2347	// Position selectors must be done after the filter
2348	// And so must :not(positional) so we move all PSEUDOs to the end
2349	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
2350		later += match[0];
2351		selector = selector.replace( Expr.match.PSEUDO, "" );
2352	}
2353
2354	selector = Expr.relative[selector] ? selector + "*" : selector;
2355
2356	for ( var i = 0, l = root.length; i < l; i++ ) {
2357		Sizzle( selector, root[i], tmpSet );
2358	}
2359
2360	return Sizzle.filter( later, tmpSet );
2361};
2362
2363// EXPOSE
2364jQuery.find = Sizzle;
2365jQuery.filter = Sizzle.filter;
2366jQuery.expr = Sizzle.selectors;
2367jQuery.expr[":"] = jQuery.expr.filters;
2368
2369Sizzle.selectors.filters.hidden = function(elem){
2370	return elem.offsetWidth === 0 || elem.offsetHeight === 0;
2371};
2372
2373Sizzle.selectors.filters.visible = function(elem){
2374	return elem.offsetWidth > 0 || elem.offsetHeight > 0;
2375};
2376
2377Sizzle.selectors.filters.animated = function(elem){
2378	return jQuery.grep(jQuery.timers, function(fn){
2379		return elem === fn.elem;
2380	}).length;
2381};
2382
2383jQuery.multiFilter = function( expr, elems, not ) {
2384	if ( not ) {
2385		expr = ":not(" + expr + ")";
2386	}
2387
2388	return Sizzle.matches(expr, elems);
2389};
2390
2391jQuery.dir = function( elem, dir ){
2392	var matched = [], cur = elem[dir];
2393	while ( cur && cur != document ) {
2394		if ( cur.nodeType == 1 )
2395			matched.push( cur );
2396		cur = cur[dir];
2397	}
2398	return matched;
2399};
2400
2401jQuery.nth = function(cur, result, dir, elem){
2402	result = result || 1;
2403	var num = 0;
2404
2405	for ( ; cur; cur = cur[dir] )
2406		if ( cur.nodeType == 1 && ++num == result )
2407			break;
2408
2409	return cur;
2410};
2411
2412jQuery.sibling = function(n, elem){
2413	var r = [];
2414
2415	for ( ; n; n = n.nextSibling ) {
2416		if ( n.nodeType == 1 && n != elem )
2417			r.push( n );
2418	}
2419
2420	return r;
2421};
2422
2423return;
2424
2425window.Sizzle = Sizzle;
2426
2427})();
2428/*
2429 * A number of helper functions used for managing events.
2430 * Many of the ideas behind this code originated from
2431 * Dean Edwards' addEvent library.
2432 */
2433jQuery.event = {
2434
2435	// Bind an event to an element
2436	// Original by Dean Edwards
2437	add: function(elem, types, handler, data) {
2438		if ( elem.nodeType == 3 || elem.nodeType == 8 )
2439			return;
2440
2441		// For whatever reason, IE has trouble passing the window object
2442		// around, causing it to be cloned in the process
2443		if ( elem.setInterval && elem != window )
2444			elem = window;
2445
2446		// Make sure that the function being executed has a unique ID
2447		if ( !handler.guid )
2448			handler.guid = this.guid++;
2449
2450		// if data is passed, bind to handler
2451		if ( data !== undefined ) {
2452			// Create temporary function pointer to original handler
2453			var fn = handler;
2454
2455			// Create unique handler function, wrapped around original handler
2456			handler = this.proxy( fn );
2457
2458			// Store data in unique handler
2459			handler.data = data;
2460		}
2461
2462		// Init the element's event structure
2463		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
2464			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
2465				// Handle the second event of a trigger and when
2466				// an event is called after a page has unloaded
2467				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
2468					jQuery.event.handle.apply(arguments.callee.elem, arguments) :
2469					undefined;
2470			});
2471		// Add elem as a property of the handle function
2472		// This is to prevent a me