PageRenderTime 279ms CodeModel.GetById 22ms app.highlight 211ms RepoModel.GetById 0ms app.codeStats 2ms

/scalate-website/src/scripts/jquery.js

http://github.com/scalate/scalate
JavaScript | 8981 lines | 6304 code | 1570 blank | 1107 comment | 1827 complexity | 12840be281cca027968c56e19ebdf6ec MD5 | raw file
   1/*!
   2 * jQuery JavaScript Library v1.6.2
   3 * http://jquery.com/
   4 *
   5 * Copyright 2011, John Resig
   6 * Dual licensed under the MIT or GPL Version 2 licenses.
   7 * http://jquery.org/license
   8 *
   9 * Includes Sizzle.js
  10 * http://sizzlejs.com/
  11 * Copyright 2011, The Dojo Foundation
  12 * Released under the MIT, BSD, and GPL Licenses.
  13 *
  14 * Date: Thu Jun 30 14:16:56 2011 -0400
  15 */
  16(function( window, undefined ) {
  17
  18// Use the correct document accordingly with window argument (sandbox)
  19var document = window.document,
  20	navigator = window.navigator,
  21	location = window.location;
  22var jQuery = (function() {
  23
  24// Define a local copy of jQuery
  25var jQuery = function( selector, context ) {
  26		// The jQuery object is actually just the init constructor 'enhanced'
  27		return new jQuery.fn.init( selector, context, rootjQuery );
  28	},
  29
  30	// Map over jQuery in case of overwrite
  31	_jQuery = window.jQuery,
  32
  33	// Map over the $ in case of overwrite
  34	_$ = window.$,
  35
  36	// A central reference to the root jQuery(document)
  37	rootjQuery,
  38
  39	// A simple way to check for HTML strings or ID strings
  40	// (both of which we optimize for)
  41	quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
  42
  43	// Check if a string has a non-whitespace character in it
  44	rnotwhite = /\S/,
  45
  46	// Used for trimming whitespace
  47	trimLeft = /^\s+/,
  48	trimRight = /\s+$/,
  49
  50	// Check for digits
  51	rdigit = /\d/,
  52
  53	// Match a standalone tag
  54	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
  55
  56	// JSON RegExp
  57	rvalidchars = /^[\],:{}\s]*$/,
  58	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
  59	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
  60	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
  61
  62	// Useragent RegExp
  63	rwebkit = /(webkit)[ \/]([\w.]+)/,
  64	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
  65	rmsie = /(msie) ([\w.]+)/,
  66	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
  67
  68	// Matches dashed string for camelizing
  69	rdashAlpha = /-([a-z])/ig,
  70
  71	// Used by jQuery.camelCase as callback to replace()
  72	fcamelCase = function( all, letter ) {
  73		return letter.toUpperCase();
  74	},
  75
  76	// Keep a UserAgent string for use with jQuery.browser
  77	userAgent = navigator.userAgent,
  78
  79	// For matching the engine and version of the browser
  80	browserMatch,
  81
  82	// The deferred used on DOM ready
  83	readyList,
  84
  85	// The ready event handler
  86	DOMContentLoaded,
  87
  88	// Save a reference to some core methods
  89	toString = Object.prototype.toString,
  90	hasOwn = Object.prototype.hasOwnProperty,
  91	push = Array.prototype.push,
  92	slice = Array.prototype.slice,
  93	trim = String.prototype.trim,
  94	indexOf = Array.prototype.indexOf,
  95
  96	// [[Class]] -> type pairs
  97	class2type = {};
  98
  99jQuery.fn = jQuery.prototype = {
 100	constructor: jQuery,
 101	init: function( selector, context, rootjQuery ) {
 102		var match, elem, ret, doc;
 103
 104		// Handle $(""), $(null), or $(undefined)
 105		if ( !selector ) {
 106			return this;
 107		}
 108
 109		// Handle $(DOMElement)
 110		if ( selector.nodeType ) {
 111			this.context = this[0] = selector;
 112			this.length = 1;
 113			return this;
 114		}
 115
 116		// The body element only exists once, optimize finding it
 117		if ( selector === "body" && !context && document.body ) {
 118			this.context = document;
 119			this[0] = document.body;
 120			this.selector = selector;
 121			this.length = 1;
 122			return this;
 123		}
 124
 125		// Handle HTML strings
 126		if ( typeof selector === "string" ) {
 127			// Are we dealing with HTML string or an ID?
 128			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
 129				// Assume that strings that start and end with <> are HTML and skip the regex check
 130				match = [ null, selector, null ];
 131
 132			} else {
 133				match = quickExpr.exec( selector );
 134			}
 135
 136			// Verify a match, and that no context was specified for #id
 137			if ( match && (match[1] || !context) ) {
 138
 139				// HANDLE: $(html) -> $(array)
 140				if ( match[1] ) {
 141					context = context instanceof jQuery ? context[0] : context;
 142					doc = (context ? context.ownerDocument || context : document);
 143
 144					// If a single string is passed in and it's a single tag
 145					// just do a createElement and skip the rest
 146					ret = rsingleTag.exec( selector );
 147
 148					if ( ret ) {
 149						if ( jQuery.isPlainObject( context ) ) {
 150							selector = [ document.createElement( ret[1] ) ];
 151							jQuery.fn.attr.call( selector, context, true );
 152
 153						} else {
 154							selector = [ doc.createElement( ret[1] ) ];
 155						}
 156
 157					} else {
 158						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
 159						selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
 160					}
 161
 162					return jQuery.merge( this, selector );
 163
 164				// HANDLE: $("#id")
 165				} else {
 166					elem = document.getElementById( match[2] );
 167
 168					// Check parentNode to catch when Blackberry 4.6 returns
 169					// nodes that are no longer in the document #6963
 170					if ( elem && elem.parentNode ) {
 171						// Handle the case where IE and Opera return items
 172						// by name instead of ID
 173						if ( elem.id !== match[2] ) {
 174							return rootjQuery.find( selector );
 175						}
 176
 177						// Otherwise, we inject the element directly into the jQuery object
 178						this.length = 1;
 179						this[0] = elem;
 180					}
 181
 182					this.context = document;
 183					this.selector = selector;
 184					return this;
 185				}
 186
 187			// HANDLE: $(expr, $(...))
 188			} else if ( !context || context.jquery ) {
 189				return (context || rootjQuery).find( selector );
 190
 191			// HANDLE: $(expr, context)
 192			// (which is just equivalent to: $(context).find(expr)
 193			} else {
 194				return this.constructor( context ).find( selector );
 195			}
 196
 197		// HANDLE: $(function)
 198		// Shortcut for document ready
 199		} else if ( jQuery.isFunction( selector ) ) {
 200			return rootjQuery.ready( selector );
 201		}
 202
 203		if (selector.selector !== undefined) {
 204			this.selector = selector.selector;
 205			this.context = selector.context;
 206		}
 207
 208		return jQuery.makeArray( selector, this );
 209	},
 210
 211	// Start with an empty selector
 212	selector: "",
 213
 214	// The current version of jQuery being used
 215	jquery: "1.6.2",
 216
 217	// The default length of a jQuery object is 0
 218	length: 0,
 219
 220	// The number of elements contained in the matched element set
 221	size: function() {
 222		return this.length;
 223	},
 224
 225	toArray: function() {
 226		return slice.call( this, 0 );
 227	},
 228
 229	// Get the Nth element in the matched element set OR
 230	// Get the whole matched element set as a clean array
 231	get: function( num ) {
 232		return num == null ?
 233
 234			// Return a 'clean' array
 235			this.toArray() :
 236
 237			// Return just the object
 238			( num < 0 ? this[ this.length + num ] : this[ num ] );
 239	},
 240
 241	// Take an array of elements and push it onto the stack
 242	// (returning the new matched element set)
 243	pushStack: function( elems, name, selector ) {
 244		// Build a new jQuery matched element set
 245		var ret = this.constructor();
 246
 247		if ( jQuery.isArray( elems ) ) {
 248			push.apply( ret, elems );
 249
 250		} else {
 251			jQuery.merge( ret, elems );
 252		}
 253
 254		// Add the old object onto the stack (as a reference)
 255		ret.prevObject = this;
 256
 257		ret.context = this.context;
 258
 259		if ( name === "find" ) {
 260			ret.selector = this.selector + (this.selector ? " " : "") + selector;
 261		} else if ( name ) {
 262			ret.selector = this.selector + "." + name + "(" + selector + ")";
 263		}
 264
 265		// Return the newly-formed element set
 266		return ret;
 267	},
 268
 269	// Execute a callback for every element in the matched set.
 270	// (You can seed the arguments with an array of args, but this is
 271	// only used internally.)
 272	each: function( callback, args ) {
 273		return jQuery.each( this, callback, args );
 274	},
 275
 276	ready: function( fn ) {
 277		// Attach the listeners
 278		jQuery.bindReady();
 279
 280		// Add the callback
 281		readyList.done( fn );
 282
 283		return this;
 284	},
 285
 286	eq: function( i ) {
 287		return i === -1 ?
 288			this.slice( i ) :
 289			this.slice( i, +i + 1 );
 290	},
 291
 292	first: function() {
 293		return this.eq( 0 );
 294	},
 295
 296	last: function() {
 297		return this.eq( -1 );
 298	},
 299
 300	slice: function() {
 301		return this.pushStack( slice.apply( this, arguments ),
 302			"slice", slice.call(arguments).join(",") );
 303	},
 304
 305	map: function( callback ) {
 306		return this.pushStack( jQuery.map(this, function( elem, i ) {
 307			return callback.call( elem, i, elem );
 308		}));
 309	},
 310
 311	end: function() {
 312		return this.prevObject || this.constructor(null);
 313	},
 314
 315	// For internal use only.
 316	// Behaves like an Array's method, not like a jQuery method.
 317	push: push,
 318	sort: [].sort,
 319	splice: [].splice
 320};
 321
 322// Give the init function the jQuery prototype for later instantiation
 323jQuery.fn.init.prototype = jQuery.fn;
 324
 325jQuery.extend = jQuery.fn.extend = function() {
 326	var options, name, src, copy, copyIsArray, clone,
 327		target = arguments[0] || {},
 328		i = 1,
 329		length = arguments.length,
 330		deep = false;
 331
 332	// Handle a deep copy situation
 333	if ( typeof target === "boolean" ) {
 334		deep = target;
 335		target = arguments[1] || {};
 336		// skip the boolean and the target
 337		i = 2;
 338	}
 339
 340	// Handle case when target is a string or something (possible in deep copy)
 341	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
 342		target = {};
 343	}
 344
 345	// extend jQuery itself if only one argument is passed
 346	if ( length === i ) {
 347		target = this;
 348		--i;
 349	}
 350
 351	for ( ; i < length; i++ ) {
 352		// Only deal with non-null/undefined values
 353		if ( (options = arguments[ i ]) != null ) {
 354			// Extend the base object
 355			for ( name in options ) {
 356				src = target[ name ];
 357				copy = options[ name ];
 358
 359				// Prevent never-ending loop
 360				if ( target === copy ) {
 361					continue;
 362				}
 363
 364				// Recurse if we're merging plain objects or arrays
 365				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
 366					if ( copyIsArray ) {
 367						copyIsArray = false;
 368						clone = src && jQuery.isArray(src) ? src : [];
 369
 370					} else {
 371						clone = src && jQuery.isPlainObject(src) ? src : {};
 372					}
 373
 374					// Never move original objects, clone them
 375					target[ name ] = jQuery.extend( deep, clone, copy );
 376
 377				// Don't bring in undefined values
 378				} else if ( copy !== undefined ) {
 379					target[ name ] = copy;
 380				}
 381			}
 382		}
 383	}
 384
 385	// Return the modified object
 386	return target;
 387};
 388
 389jQuery.extend({
 390	noConflict: function( deep ) {
 391		if ( window.$ === jQuery ) {
 392			window.$ = _$;
 393		}
 394
 395		if ( deep && window.jQuery === jQuery ) {
 396			window.jQuery = _jQuery;
 397		}
 398
 399		return jQuery;
 400	},
 401
 402	// Is the DOM ready to be used? Set to true once it occurs.
 403	isReady: false,
 404
 405	// A counter to track how many items to wait for before
 406	// the ready event fires. See #6781
 407	readyWait: 1,
 408
 409	// Hold (or release) the ready event
 410	holdReady: function( hold ) {
 411		if ( hold ) {
 412			jQuery.readyWait++;
 413		} else {
 414			jQuery.ready( true );
 415		}
 416	},
 417
 418	// Handle when the DOM is ready
 419	ready: function( wait ) {
 420		// Either a released hold or an DOMready/load event and not yet ready
 421		if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
 422			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
 423			if ( !document.body ) {
 424				return setTimeout( jQuery.ready, 1 );
 425			}
 426
 427			// Remember that the DOM is ready
 428			jQuery.isReady = true;
 429
 430			// If a normal DOM Ready event fired, decrement, and wait if need be
 431			if ( wait !== true && --jQuery.readyWait > 0 ) {
 432				return;
 433			}
 434
 435			// If there are functions bound, to execute
 436			readyList.resolveWith( document, [ jQuery ] );
 437
 438			// Trigger any bound ready events
 439			if ( jQuery.fn.trigger ) {
 440				jQuery( document ).trigger( "ready" ).unbind( "ready" );
 441			}
 442		}
 443	},
 444
 445	bindReady: function() {
 446		if ( readyList ) {
 447			return;
 448		}
 449
 450		readyList = jQuery._Deferred();
 451
 452		// Catch cases where $(document).ready() is called after the
 453		// browser event has already occurred.
 454		if ( document.readyState === "complete" ) {
 455			// Handle it asynchronously to allow scripts the opportunity to delay ready
 456			return setTimeout( jQuery.ready, 1 );
 457		}
 458
 459		// Mozilla, Opera and webkit nightlies currently support this event
 460		if ( document.addEventListener ) {
 461			// Use the handy event callback
 462			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
 463
 464			// A fallback to window.onload, that will always work
 465			window.addEventListener( "load", jQuery.ready, false );
 466
 467		// If IE event model is used
 468		} else if ( document.attachEvent ) {
 469			// ensure firing before onload,
 470			// maybe late but safe also for iframes
 471			document.attachEvent( "onreadystatechange", DOMContentLoaded );
 472
 473			// A fallback to window.onload, that will always work
 474			window.attachEvent( "onload", jQuery.ready );
 475
 476			// If IE and not a frame
 477			// continually check to see if the document is ready
 478			var toplevel = false;
 479
 480			try {
 481				toplevel = window.frameElement == null;
 482			} catch(e) {}
 483
 484			if ( document.documentElement.doScroll && toplevel ) {
 485				doScrollCheck();
 486			}
 487		}
 488	},
 489
 490	// See test/unit/core.js for details concerning isFunction.
 491	// Since version 1.3, DOM methods and functions like alert
 492	// aren't supported. They return false on IE (#2968).
 493	isFunction: function( obj ) {
 494		return jQuery.type(obj) === "function";
 495	},
 496
 497	isArray: Array.isArray || function( obj ) {
 498		return jQuery.type(obj) === "array";
 499	},
 500
 501	// A crude way of determining if an object is a window
 502	isWindow: function( obj ) {
 503		return obj && typeof obj === "object" && "setInterval" in obj;
 504	},
 505
 506	isNaN: function( obj ) {
 507		return obj == null || !rdigit.test( obj ) || isNaN( obj );
 508	},
 509
 510	type: function( obj ) {
 511		return obj == null ?
 512			String( obj ) :
 513			class2type[ toString.call(obj) ] || "object";
 514	},
 515
 516	isPlainObject: function( obj ) {
 517		// Must be an Object.
 518		// Because of IE, we also have to check the presence of the constructor property.
 519		// Make sure that DOM nodes and window objects don't pass through, as well
 520		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
 521			return false;
 522		}
 523
 524		// Not own constructor property must be Object
 525		if ( obj.constructor &&
 526			!hasOwn.call(obj, "constructor") &&
 527			!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
 528			return false;
 529		}
 530
 531		// Own properties are enumerated firstly, so to speed up,
 532		// if last one is own, then all properties are own.
 533
 534		var key;
 535		for ( key in obj ) {}
 536
 537		return key === undefined || hasOwn.call( obj, key );
 538	},
 539
 540	isEmptyObject: function( obj ) {
 541		for ( var name in obj ) {
 542			return false;
 543		}
 544		return true;
 545	},
 546
 547	error: function( msg ) {
 548		throw msg;
 549	},
 550
 551	parseJSON: function( data ) {
 552		if ( typeof data !== "string" || !data ) {
 553			return null;
 554		}
 555
 556		// Make sure leading/trailing whitespace is removed (IE can't handle it)
 557		data = jQuery.trim( data );
 558
 559		// Attempt to parse using the native JSON parser first
 560		if ( window.JSON && window.JSON.parse ) {
 561			return window.JSON.parse( data );
 562		}
 563
 564		// Make sure the incoming data is actual JSON
 565		// Logic borrowed from http://json.org/json2.js
 566		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
 567			.replace( rvalidtokens, "]" )
 568			.replace( rvalidbraces, "")) ) {
 569
 570			return (new Function( "return " + data ))();
 571
 572		}
 573		jQuery.error( "Invalid JSON: " + data );
 574	},
 575
 576	// Cross-browser xml parsing
 577	// (xml & tmp used internally)
 578	parseXML: function( data , xml , tmp ) {
 579
 580		if ( window.DOMParser ) { // Standard
 581			tmp = new DOMParser();
 582			xml = tmp.parseFromString( data , "text/xml" );
 583		} else { // IE
 584			xml = new ActiveXObject( "Microsoft.XMLDOM" );
 585			xml.async = "false";
 586			xml.loadXML( data );
 587		}
 588
 589		tmp = xml.documentElement;
 590
 591		if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
 592			jQuery.error( "Invalid XML: " + data );
 593		}
 594
 595		return xml;
 596	},
 597
 598	noop: function() {},
 599
 600	// Evaluates a script in a global context
 601	// Workarounds based on findings by Jim Driscoll
 602	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
 603	globalEval: function( data ) {
 604		if ( data && rnotwhite.test( data ) ) {
 605			// We use execScript on Internet Explorer
 606			// We use an anonymous function so that context is window
 607			// rather than jQuery in Firefox
 608			( window.execScript || function( data ) {
 609				window[ "eval" ].call( window, data );
 610			} )( data );
 611		}
 612	},
 613
 614	// Converts a dashed string to camelCased string;
 615	// Used by both the css and data modules
 616	camelCase: function( string ) {
 617		return string.replace( rdashAlpha, fcamelCase );
 618	},
 619
 620	nodeName: function( elem, name ) {
 621		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
 622	},
 623
 624	// args is for internal usage only
 625	each: function( object, callback, args ) {
 626		var name, i = 0,
 627			length = object.length,
 628			isObj = length === undefined || jQuery.isFunction( object );
 629
 630		if ( args ) {
 631			if ( isObj ) {
 632				for ( name in object ) {
 633					if ( callback.apply( object[ name ], args ) === false ) {
 634						break;
 635					}
 636				}
 637			} else {
 638				for ( ; i < length; ) {
 639					if ( callback.apply( object[ i++ ], args ) === false ) {
 640						break;
 641					}
 642				}
 643			}
 644
 645		// A special, fast, case for the most common use of each
 646		} else {
 647			if ( isObj ) {
 648				for ( name in object ) {
 649					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
 650						break;
 651					}
 652				}
 653			} else {
 654				for ( ; i < length; ) {
 655					if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
 656						break;
 657					}
 658				}
 659			}
 660		}
 661
 662		return object;
 663	},
 664
 665	// Use native String.trim function wherever possible
 666	trim: trim ?
 667		function( text ) {
 668			return text == null ?
 669				"" :
 670				trim.call( text );
 671		} :
 672
 673		// Otherwise use our own trimming functionality
 674		function( text ) {
 675			return text == null ?
 676				"" :
 677				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
 678		},
 679
 680	// results is for internal usage only
 681	makeArray: function( array, results ) {
 682		var ret = results || [];
 683
 684		if ( array != null ) {
 685			// The window, strings (and functions) also have 'length'
 686			// The extra typeof function check is to prevent crashes
 687			// in Safari 2 (See: #3039)
 688			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
 689			var type = jQuery.type( array );
 690
 691			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
 692				push.call( ret, array );
 693			} else {
 694				jQuery.merge( ret, array );
 695			}
 696		}
 697
 698		return ret;
 699	},
 700
 701	inArray: function( elem, array ) {
 702
 703		if ( indexOf ) {
 704			return indexOf.call( array, elem );
 705		}
 706
 707		for ( var i = 0, length = array.length; i < length; i++ ) {
 708			if ( array[ i ] === elem ) {
 709				return i;
 710			}
 711		}
 712
 713		return -1;
 714	},
 715
 716	merge: function( first, second ) {
 717		var i = first.length,
 718			j = 0;
 719
 720		if ( typeof second.length === "number" ) {
 721			for ( var l = second.length; j < l; j++ ) {
 722				first[ i++ ] = second[ j ];
 723			}
 724
 725		} else {
 726			while ( second[j] !== undefined ) {
 727				first[ i++ ] = second[ j++ ];
 728			}
 729		}
 730
 731		first.length = i;
 732
 733		return first;
 734	},
 735
 736	grep: function( elems, callback, inv ) {
 737		var ret = [], retVal;
 738		inv = !!inv;
 739
 740		// Go through the array, only saving the items
 741		// that pass the validator function
 742		for ( var i = 0, length = elems.length; i < length; i++ ) {
 743			retVal = !!callback( elems[ i ], i );
 744			if ( inv !== retVal ) {
 745				ret.push( elems[ i ] );
 746			}
 747		}
 748
 749		return ret;
 750	},
 751
 752	// arg is for internal usage only
 753	map: function( elems, callback, arg ) {
 754		var value, key, ret = [],
 755			i = 0,
 756			length = elems.length,
 757			// jquery objects are treated as arrays
 758			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
 759
 760		// Go through the array, translating each of the items to their
 761		if ( isArray ) {
 762			for ( ; i < length; i++ ) {
 763				value = callback( elems[ i ], i, arg );
 764
 765				if ( value != null ) {
 766					ret[ ret.length ] = value;
 767				}
 768			}
 769
 770		// Go through every key on the object,
 771		} else {
 772			for ( key in elems ) {
 773				value = callback( elems[ key ], key, arg );
 774
 775				if ( value != null ) {
 776					ret[ ret.length ] = value;
 777				}
 778			}
 779		}
 780
 781		// Flatten any nested arrays
 782		return ret.concat.apply( [], ret );
 783	},
 784
 785	// A global GUID counter for objects
 786	guid: 1,
 787
 788	// Bind a function to a context, optionally partially applying any
 789	// arguments.
 790	proxy: function( fn, context ) {
 791		if ( typeof context === "string" ) {
 792			var tmp = fn[ context ];
 793			context = fn;
 794			fn = tmp;
 795		}
 796
 797		// Quick check to determine if target is callable, in the spec
 798		// this throws a TypeError, but we will just return undefined.
 799		if ( !jQuery.isFunction( fn ) ) {
 800			return undefined;
 801		}
 802
 803		// Simulated bind
 804		var args = slice.call( arguments, 2 ),
 805			proxy = function() {
 806				return fn.apply( context, args.concat( slice.call( arguments ) ) );
 807			};
 808
 809		// Set the guid of unique handler to the same of original handler, so it can be removed
 810		proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
 811
 812		return proxy;
 813	},
 814
 815	// Mutifunctional method to get and set values to a collection
 816	// The value/s can optionally be executed if it's a function
 817	access: function( elems, key, value, exec, fn, pass ) {
 818		var length = elems.length;
 819
 820		// Setting many attributes
 821		if ( typeof key === "object" ) {
 822			for ( var k in key ) {
 823				jQuery.access( elems, k, key[k], exec, fn, value );
 824			}
 825			return elems;
 826		}
 827
 828		// Setting one attribute
 829		if ( value !== undefined ) {
 830			// Optionally, function values get executed if exec is true
 831			exec = !pass && exec && jQuery.isFunction(value);
 832
 833			for ( var i = 0; i < length; i++ ) {
 834				fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
 835			}
 836
 837			return elems;
 838		}
 839
 840		// Getting an attribute
 841		return length ? fn( elems[0], key ) : undefined;
 842	},
 843
 844	now: function() {
 845		return (new Date()).getTime();
 846	},
 847
 848	// Use of jQuery.browser is frowned upon.
 849	// More details: http://docs.jquery.com/Utilities/jQuery.browser
 850	uaMatch: function( ua ) {
 851		ua = ua.toLowerCase();
 852
 853		var match = rwebkit.exec( ua ) ||
 854			ropera.exec( ua ) ||
 855			rmsie.exec( ua ) ||
 856			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
 857			[];
 858
 859		return { browser: match[1] || "", version: match[2] || "0" };
 860	},
 861
 862	sub: function() {
 863		function jQuerySub( selector, context ) {
 864			return new jQuerySub.fn.init( selector, context );
 865		}
 866		jQuery.extend( true, jQuerySub, this );
 867		jQuerySub.superclass = this;
 868		jQuerySub.fn = jQuerySub.prototype = this();
 869		jQuerySub.fn.constructor = jQuerySub;
 870		jQuerySub.sub = this.sub;
 871		jQuerySub.fn.init = function init( selector, context ) {
 872			if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
 873				context = jQuerySub( context );
 874			}
 875
 876			return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
 877		};
 878		jQuerySub.fn.init.prototype = jQuerySub.fn;
 879		var rootjQuerySub = jQuerySub(document);
 880		return jQuerySub;
 881	},
 882
 883	browser: {}
 884});
 885
 886// Populate the class2type map
 887jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
 888	class2type[ "[object " + name + "]" ] = name.toLowerCase();
 889});
 890
 891browserMatch = jQuery.uaMatch( userAgent );
 892if ( browserMatch.browser ) {
 893	jQuery.browser[ browserMatch.browser ] = true;
 894	jQuery.browser.version = browserMatch.version;
 895}
 896
 897// Deprecated, use jQuery.browser.webkit instead
 898if ( jQuery.browser.webkit ) {
 899	jQuery.browser.safari = true;
 900}
 901
 902// IE doesn't match non-breaking spaces with \s
 903if ( rnotwhite.test( "\xA0" ) ) {
 904	trimLeft = /^[\s\xA0]+/;
 905	trimRight = /[\s\xA0]+$/;
 906}
 907
 908// All jQuery objects should point back to these
 909rootjQuery = jQuery(document);
 910
 911// Cleanup functions for the document ready method
 912if ( document.addEventListener ) {
 913	DOMContentLoaded = function() {
 914		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
 915		jQuery.ready();
 916	};
 917
 918} else if ( document.attachEvent ) {
 919	DOMContentLoaded = function() {
 920		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
 921		if ( document.readyState === "complete" ) {
 922			document.detachEvent( "onreadystatechange", DOMContentLoaded );
 923			jQuery.ready();
 924		}
 925	};
 926}
 927
 928// The DOM ready check for Internet Explorer
 929function doScrollCheck() {
 930	if ( jQuery.isReady ) {
 931		return;
 932	}
 933
 934	try {
 935		// If IE is used, use the trick by Diego Perini
 936		// http://javascript.nwbox.com/IEContentLoaded/
 937		document.documentElement.doScroll("left");
 938	} catch(e) {
 939		setTimeout( doScrollCheck, 1 );
 940		return;
 941	}
 942
 943	// and execute any waiting functions
 944	jQuery.ready();
 945}
 946
 947return jQuery;
 948
 949})();
 950
 951
 952var // Promise methods
 953	promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
 954	// Static reference to slice
 955	sliceDeferred = [].slice;
 956
 957jQuery.extend({
 958	// Create a simple deferred (one callbacks list)
 959	_Deferred: function() {
 960		var // callbacks list
 961			callbacks = [],
 962			// stored [ context , args ]
 963			fired,
 964			// to avoid firing when already doing so
 965			firing,
 966			// flag to know if the deferred has been cancelled
 967			cancelled,
 968			// the deferred itself
 969			deferred  = {
 970
 971				// done( f1, f2, ...)
 972				done: function() {
 973					if ( !cancelled ) {
 974						var args = arguments,
 975							i,
 976							length,
 977							elem,
 978							type,
 979							_fired;
 980						if ( fired ) {
 981							_fired = fired;
 982							fired = 0;
 983						}
 984						for ( i = 0, length = args.length; i < length; i++ ) {
 985							elem = args[ i ];
 986							type = jQuery.type( elem );
 987							if ( type === "array" ) {
 988								deferred.done.apply( deferred, elem );
 989							} else if ( type === "function" ) {
 990								callbacks.push( elem );
 991							}
 992						}
 993						if ( _fired ) {
 994							deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
 995						}
 996					}
 997					return this;
 998				},
 999
1000				// resolve with given context and args
1001				resolveWith: function( context, args ) {
1002					if ( !cancelled && !fired && !firing ) {
1003						// make sure args are available (#8421)
1004						args = args || [];
1005						firing = 1;
1006						try {
1007							while( callbacks[ 0 ] ) {
1008								callbacks.shift().apply( context, args );
1009							}
1010						}
1011						finally {
1012							fired = [ context, args ];
1013							firing = 0;
1014						}
1015					}
1016					return this;
1017				},
1018
1019				// resolve with this as context and given arguments
1020				resolve: function() {
1021					deferred.resolveWith( this, arguments );
1022					return this;
1023				},
1024
1025				// Has this deferred been resolved?
1026				isResolved: function() {
1027					return !!( firing || fired );
1028				},
1029
1030				// Cancel
1031				cancel: function() {
1032					cancelled = 1;
1033					callbacks = [];
1034					return this;
1035				}
1036			};
1037
1038		return deferred;
1039	},
1040
1041	// Full fledged deferred (two callbacks list)
1042	Deferred: function( func ) {
1043		var deferred = jQuery._Deferred(),
1044			failDeferred = jQuery._Deferred(),
1045			promise;
1046		// Add errorDeferred methods, then and promise
1047		jQuery.extend( deferred, {
1048			then: function( doneCallbacks, failCallbacks ) {
1049				deferred.done( doneCallbacks ).fail( failCallbacks );
1050				return this;
1051			},
1052			always: function() {
1053				return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1054			},
1055			fail: failDeferred.done,
1056			rejectWith: failDeferred.resolveWith,
1057			reject: failDeferred.resolve,
1058			isRejected: failDeferred.isResolved,
1059			pipe: function( fnDone, fnFail ) {
1060				return jQuery.Deferred(function( newDefer ) {
1061					jQuery.each( {
1062						done: [ fnDone, "resolve" ],
1063						fail: [ fnFail, "reject" ]
1064					}, function( handler, data ) {
1065						var fn = data[ 0 ],
1066							action = data[ 1 ],
1067							returned;
1068						if ( jQuery.isFunction( fn ) ) {
1069							deferred[ handler ](function() {
1070								returned = fn.apply( this, arguments );
1071								if ( returned && jQuery.isFunction( returned.promise ) ) {
1072									returned.promise().then( newDefer.resolve, newDefer.reject );
1073								} else {
1074									newDefer[ action ]( returned );
1075								}
1076							});
1077						} else {
1078							deferred[ handler ]( newDefer[ action ] );
1079						}
1080					});
1081				}).promise();
1082			},
1083			// Get a promise for this deferred
1084			// If obj is provided, the promise aspect is added to the object
1085			promise: function( obj ) {
1086				if ( obj == null ) {
1087					if ( promise ) {
1088						return promise;
1089					}
1090					promise = obj = {};
1091				}
1092				var i = promiseMethods.length;
1093				while( i-- ) {
1094					obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1095				}
1096				return obj;
1097			}
1098		});
1099		// Make sure only one callback list will be used
1100		deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1101		// Unexpose cancel
1102		delete deferred.cancel;
1103		// Call given func if any
1104		if ( func ) {
1105			func.call( deferred, deferred );
1106		}
1107		return deferred;
1108	},
1109
1110	// Deferred helper
1111	when: function( firstParam ) {
1112		var args = arguments,
1113			i = 0,
1114			length = args.length,
1115			count = length,
1116			deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1117				firstParam :
1118				jQuery.Deferred();
1119		function resolveFunc( i ) {
1120			return function( value ) {
1121				args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1122				if ( !( --count ) ) {
1123					// Strange bug in FF4:
1124					// Values changed onto the arguments object sometimes end up as undefined values
1125					// outside the $.when method. Cloning the object into a fresh array solves the issue
1126					deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1127				}
1128			};
1129		}
1130		if ( length > 1 ) {
1131			for( ; i < length; i++ ) {
1132				if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1133					args[ i ].promise().then( resolveFunc(i), deferred.reject );
1134				} else {
1135					--count;
1136				}
1137			}
1138			if ( !count ) {
1139				deferred.resolveWith( deferred, args );
1140			}
1141		} else if ( deferred !== firstParam ) {
1142			deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1143		}
1144		return deferred.promise();
1145	}
1146});
1147
1148
1149
1150jQuery.support = (function() {
1151
1152	var div = document.createElement( "div" ),
1153		documentElement = document.documentElement,
1154		all,
1155		a,
1156		select,
1157		opt,
1158		input,
1159		marginDiv,
1160		support,
1161		fragment,
1162		body,
1163		testElementParent,
1164		testElement,
1165		testElementStyle,
1166		tds,
1167		events,
1168		eventName,
1169		i,
1170		isSupported;
1171
1172	// Preliminary tests
1173	div.setAttribute("className", "t");
1174	div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1175
1176	all = div.getElementsByTagName( "*" );
1177	a = div.getElementsByTagName( "a" )[ 0 ];
1178
1179	// Can't get basic test support
1180	if ( !all || !all.length || !a ) {
1181		return {};
1182	}
1183
1184	// First batch of supports tests
1185	select = document.createElement( "select" );
1186	opt = select.appendChild( document.createElement("option") );
1187	input = div.getElementsByTagName( "input" )[ 0 ];
1188
1189	support = {
1190		// IE strips leading whitespace when .innerHTML is used
1191		leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1192
1193		// Make sure that tbody elements aren't automatically inserted
1194		// IE will insert them into empty tables
1195		tbody: !div.getElementsByTagName( "tbody" ).length,
1196
1197		// Make sure that link elements get serialized correctly by innerHTML
1198		// This requires a wrapper element in IE
1199		htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1200
1201		// Get the style information from getAttribute
1202		// (IE uses .cssText instead)
1203		style: /top/.test( a.getAttribute("style") ),
1204
1205		// Make sure that URLs aren't manipulated
1206		// (IE normalizes it by default)
1207		hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1208
1209		// Make sure that element opacity exists
1210		// (IE uses filter instead)
1211		// Use a regex to work around a WebKit issue. See #5145
1212		opacity: /^0.55$/.test( a.style.opacity ),
1213
1214		// Verify style float existence
1215		// (IE uses styleFloat instead of cssFloat)
1216		cssFloat: !!a.style.cssFloat,
1217
1218		// Make sure that if no value is specified for a checkbox
1219		// that it defaults to "on".
1220		// (WebKit defaults to "" instead)
1221		checkOn: ( input.value === "on" ),
1222
1223		// Make sure that a selected-by-default option has a working selected property.
1224		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1225		optSelected: opt.selected,
1226
1227		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1228		getSetAttribute: div.className !== "t",
1229
1230		// Will be defined later
1231		submitBubbles: true,
1232		changeBubbles: true,
1233		focusinBubbles: false,
1234		deleteExpando: true,
1235		noCloneEvent: true,
1236		inlineBlockNeedsLayout: false,
1237		shrinkWrapBlocks: false,
1238		reliableMarginRight: true
1239	};
1240
1241	// Make sure checked status is properly cloned
1242	input.checked = true;
1243	support.noCloneChecked = input.cloneNode( true ).checked;
1244
1245	// Make sure that the options inside disabled selects aren't marked as disabled
1246	// (WebKit marks them as disabled)
1247	select.disabled = true;
1248	support.optDisabled = !opt.disabled;
1249
1250	// Test to see if it's possible to delete an expando from an element
1251	// Fails in Internet Explorer
1252	try {
1253		delete div.test;
1254	} catch( e ) {
1255		support.deleteExpando = false;
1256	}
1257
1258	if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1259		div.attachEvent( "onclick", function() {
1260			// Cloning a node shouldn't copy over any
1261			// bound event handlers (IE does this)
1262			support.noCloneEvent = false;
1263		});
1264		div.cloneNode( true ).fireEvent( "onclick" );
1265	}
1266
1267	// Check if a radio maintains it's value
1268	// after being appended to the DOM
1269	input = document.createElement("input");
1270	input.value = "t";
1271	input.setAttribute("type", "radio");
1272	support.radioValue = input.value === "t";
1273
1274	input.setAttribute("checked", "checked");
1275	div.appendChild( input );
1276	fragment = document.createDocumentFragment();
1277	fragment.appendChild( div.firstChild );
1278
1279	// WebKit doesn't clone checked state correctly in fragments
1280	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1281
1282	div.innerHTML = "";
1283
1284	// Figure out if the W3C box model works as expected
1285	div.style.width = div.style.paddingLeft = "1px";
1286
1287	body = document.getElementsByTagName( "body" )[ 0 ];
1288	// We use our own, invisible, body unless the body is already present
1289	// in which case we use a div (#9239)
1290	testElement = document.createElement( body ? "div" : "body" );
1291	testElementStyle = {
1292		visibility: "hidden",
1293		width: 0,
1294		height: 0,
1295		border: 0,
1296		margin: 0
1297	};
1298	if ( body ) {
1299		jQuery.extend( testElementStyle, {
1300			position: "absolute",
1301			left: -1000,
1302			top: -1000
1303		});
1304	}
1305	for ( i in testElementStyle ) {
1306		testElement.style[ i ] = testElementStyle[ i ];
1307	}
1308	testElement.appendChild( div );
1309	testElementParent = body || documentElement;
1310	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1311
1312	// Check if a disconnected checkbox will retain its checked
1313	// value of true after appended to the DOM (IE6/7)
1314	support.appendChecked = input.checked;
1315
1316	support.boxModel = div.offsetWidth === 2;
1317
1318	if ( "zoom" in div.style ) {
1319		// Check if natively block-level elements act like inline-block
1320		// elements when setting their display to 'inline' and giving
1321		// them layout
1322		// (IE < 8 does this)
1323		div.style.display = "inline";
1324		div.style.zoom = 1;
1325		support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1326
1327		// Check if elements with layout shrink-wrap their children
1328		// (IE 6 does this)
1329		div.style.display = "";
1330		div.innerHTML = "<div style='width:4px;'></div>";
1331		support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1332	}
1333
1334	div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1335	tds = div.getElementsByTagName( "td" );
1336
1337	// Check if table cells still have offsetWidth/Height when they are set
1338	// to display:none and there are still other visible table cells in a
1339	// table row; if so, offsetWidth/Height are not reliable for use when
1340	// determining if an element has been hidden directly using
1341	// display:none (it is still safe to use offsets if a parent element is
1342	// hidden; don safety goggles and see bug #4512 for more information).
1343	// (only IE 8 fails this test)
1344	isSupported = ( tds[ 0 ].offsetHeight === 0 );
1345
1346	tds[ 0 ].style.display = "";
1347	tds[ 1 ].style.display = "none";
1348
1349	// Check if empty table cells still have offsetWidth/Height
1350	// (IE < 8 fail this test)
1351	support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1352	div.innerHTML = "";
1353
1354	// Check if div with explicit width and no margin-right incorrectly
1355	// gets computed margin-right based on width of container. For more
1356	// info see bug #3333
1357	// Fails in WebKit before Feb 2011 nightlies
1358	// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1359	if ( document.defaultView && document.defaultView.getComputedStyle ) {
1360		marginDiv = document.createElement( "div" );
1361		marginDiv.style.width = "0";
1362		marginDiv.style.marginRight = "0";
1363		div.appendChild( marginDiv );
1364		support.reliableMarginRight =
1365			( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1366	}
1367
1368	// Remove the body element we added
1369	testElement.innerHTML = "";
1370	testElementParent.removeChild( testElement );
1371
1372	// Technique from Juriy Zaytsev
1373	// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1374	// We only care about the case where non-standard event systems
1375	// are used, namely in IE. Short-circuiting here helps us to
1376	// avoid an eval call (in setAttribute) which can cause CSP
1377	// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1378	if ( div.attachEvent ) {
1379		for( i in {
1380			submit: 1,
1381			change: 1,
1382			focusin: 1
1383		} ) {
1384			eventName = "on" + i;
1385			isSupported = ( eventName in div );
1386			if ( !isSupported ) {
1387				div.setAttribute( eventName, "return;" );
1388				isSupported = ( typeof div[ eventName ] === "function" );
1389			}
1390			support[ i + "Bubbles" ] = isSupported;
1391		}
1392	}
1393
1394	// Null connected elements to avoid leaks in IE
1395	testElement = fragment = select = opt = body = marginDiv = div = input = null;
1396
1397	return support;
1398})();
1399
1400// Keep track of boxModel
1401jQuery.boxModel = jQuery.support.boxModel;
1402
1403
1404
1405
1406var rbrace = /^(?:\{.*\}|\[.*\])$/,
1407	rmultiDash = /([a-z])([A-Z])/g;
1408
1409jQuery.extend({
1410	cache: {},
1411
1412	// Please use with caution
1413	uuid: 0,
1414
1415	// Unique for each copy of jQuery on the page
1416	// Non-digits removed to match rinlinejQuery
1417	expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1418
1419	// The following elements throw uncatchable exceptions if you
1420	// attempt to add expando properties to them.
1421	noData: {
1422		"embed": true,
1423		// Ban all objects except for Flash (which handle expandos)
1424		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1425		"applet": true
1426	},
1427
1428	hasData: function( elem ) {
1429		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1430
1431		return !!elem && !isEmptyDataObject( elem );
1432	},
1433
1434	data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1435		if ( !jQuery.acceptData( elem ) ) {
1436			return;
1437		}
1438
1439		var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
1440
1441			// We have to handle DOM nodes and JS objects differently because IE6-7
1442			// can't GC object references properly across the DOM-JS boundary
1443			isNode = elem.nodeType,
1444
1445			// Only DOM nodes need the global jQuery cache; JS object data is
1446			// attached directly to the object so GC can occur automatically
1447			cache = isNode ? jQuery.cache : elem,
1448
1449			// Only defining an ID for JS objects if its cache already exists allows
1450			// the code to shortcut on the same path as a DOM node with no cache
1451			id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1452
1453		// Avoid doing any more work than we need to when trying to get data on an
1454		// object that has no data at all
1455		if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
1456			return;
1457		}
1458
1459		if ( !id ) {
1460			// Only DOM nodes need a new unique ID for each element since their data
1461			// ends up in the global cache
1462			if ( isNode ) {
1463				elem[ jQuery.expando ] = id = ++jQuery.uuid;
1464			} else {
1465				id = jQuery.expando;
1466			}
1467		}
1468
1469		if ( !cache[ id ] ) {
1470			cache[ id ] = {};
1471
1472			// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1473			// metadata on plain JS objects when the object is serialized using
1474			// JSON.stringify
1475			if ( !isNode ) {
1476				cache[ id ].toJSON = jQuery.noop;
1477			}
1478		}
1479
1480		// An object can be passed to jQuery.data instead of a key/value pair; this gets
1481		// shallow copied over onto the existing cache
1482		if ( typeof name === "object" || typeof name === "function" ) {
1483			if ( pvt ) {
1484				cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1485			} else {
1486				cache[ id ] = jQuery.extend(cache[ id ], name);
1487			}
1488		}
1489
1490		thisCache = cache[ id ];
1491
1492		// Internal jQuery data is stored in a separate object inside the object's data
1493		// cache in order to avoid key collisions between internal data and user-defined
1494		// data
1495		if ( pvt ) {
1496			if ( !thisCache[ internalKey ] ) {
1497				thisCache[ internalKey ] = {};
1498			}
1499
1500			thisCache = thisCache[ internalKey ];
1501		}
1502
1503		if ( data !== undefined ) {
1504			thisCache[ jQuery.camelCase( name ) ] = data;
1505		}
1506
1507		// TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1508		// not attempt to inspect the internal events object using jQuery.data, as this
1509		// internal data object is undocumented and subject to change.
1510		if ( name === "events" && !thisCache[name] ) {
1511			return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1512		}
1513
1514		return getByName ? 
1515			// Check for both converted-to-camel and non-converted data property names
1516			thisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] :
1517			thisCache;
1518	},
1519
1520	removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1521		if ( !jQuery.acceptData( elem ) ) {
1522			return;
1523		}
1524
1525		var internalKey = jQuery.expando, isNode = elem.nodeType,
1526
1527			// See jQuery.data for more information
1528			cache = isNode ? jQuery.cache : elem,
1529
1530			// See jQuery.data for more information
1531			id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1532
1533		// If there is already no cache entry for this object, there is no
1534		// purpose in continuing
1535		if ( !cache[ id ] ) {
1536			return;
1537		}
1538
1539		if ( name ) {
1540			var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1541
1542			if ( thisCache ) {
1543				delete thisCache[ name ];
1544
1545				// If there is no data left in the cache, we want to continue
1546				// and let the cache object itself get destroyed
1547				if ( !isEmptyDataObject(thisCache) ) {
1548					return;
1549				}
1550			}
1551		}
1552
1553		// See jQuery.data for more information
1554		if ( pvt ) {
1555			delete cache[ id ][ internalKey ];
1556
1557			// Don't destroy the parent cache unless the internal data object
1558			// had been the only thing left in it
1559			if ( !isEmptyDataObject(cache[ id ]) ) {
1560				return;
1561			}
1562		}
1563
1564		var internalCache = cache[ id ][ internalKey ];
1565
1566		// Browsers that fail expando deletion also refuse to delete expandos on
1567		// the window, but it will allow it on all other JS objects; other browsers
1568		// don't care
1569		if ( jQuery.support.deleteExpando || cache != window ) {
1570			delete cache[ id ];
1571		} else {
1572			cache[ id ] = null;
1573		}
1574
1575		// We destroyed the entire user cache at once because it's faster than
1576		// iterating through each key, but we need to continue to persist internal
1577		// data if it existed
1578		if ( internalCache ) {
1579			cache[ id ] = {};
1580			// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1581			// metadata on plain JS objects when the object is serialized using
1582			// JSON.stringify
1583			if ( !isNode ) {
1584				cache[ id ].toJSON = jQuery.noop;
1585			}
1586
1587			cache[ id ][ internalKey ] = internalCache;
1588
1589		// Otherwise, we need to eliminate the expando on the node to avoid
1590		// false lookups in the cache for entries that no longer exist
1591		} else if ( isNode ) {
1592			// IE does not allow us to delete expando properties from nodes,
1593			// nor does it have a removeAttribute function on Document nodes;
1594			// we must handle all of these cases
1595			if ( jQuery.support.deleteExpando ) {
1596				delete elem[ jQuery.expando ];
1597			} else if ( elem.removeAttribute ) {
1598				elem.removeAttribute( jQuery.expando );
1599			} else {
1600				elem[ jQuery.expando ] = null;
1601			}
1602		}
1603	},
1604
1605	// For internal use only.
1606	_data: function( elem, name, data ) {
1607		return jQuery.data( elem, name, data, true );
1608	},
1609
1610	// A method for determining if a DOM node can handle the data expando
1611	acceptData: function( elem ) {
1612		if ( elem.nodeName ) {
1613			var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1614
1615			if ( match ) {
1616				return !(match === true || elem.getAttribute("classid") !== match);
1617			}
1618		}
1619
1620		return true;
1621	}
1622});
1623
1624jQuery.fn.extend({
1625	data: function( key, value ) {
1626		var data = null;
1627
1628		if ( typeof key === "undefined" ) {
1629			if ( this.length ) {
1630				data = jQuery.data( this[0] );
1631
1632				if ( this[0].nodeType === 1 ) {
1633			    var attr = this[0].attributes, name;
1634					for ( var i = 0, l = attr.length; i < l; i++ ) {
1635						name = attr[i].name;
1636
1637						if ( name.indexOf( "data-" ) === 0 ) {
1638							name = jQuery.camelCase( name.substring(5) );
1639
1640							dataAttr( this[0], name, data[ name ] );
1641						}
1642					}
1643				}
1644			}
1645
1646			return data;
1647
1648		} else if ( typeof key === "object" ) {
1649			return this.each(function() {
1650				jQuery.data( this, key );
1651			});
1652		}
1653
1654		var parts = key.split(".");
1655		parts[1] = parts[1] ? "." + parts[1] : "";
1656
1657		if ( value === undefined ) {
1658			data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1659
1660			// Try to fetch any internally stored data first
1661			if ( data === undefined && this.length ) {
1662				data = jQuery.data( this[0], key );
1663				data = dataAttr( this[0], key, data );
1664			}
1665
1666			return data === undefined && parts[1] ?
1667				this.data( parts[0] ) :
1668				data;
1669
1670		} else {
1671			return this.each(function() {
1672				var $this = jQuery( this ),
1673					args = [ parts[0], value ];
1674
1675				$this.triggerHandler( "setData" + parts[1] + "!", args );
1676				jQuery.data( this, key, value );
1677				$this.triggerHandler( "changeData" + parts[1] + "!", args );
1678			});
1679		}
1680	},
1681
1682	removeData: function( key ) {
1683		return this.each(function() {
1684			jQuery.removeData( this, key );
1685		});
1686	}
1687});
1688
1689function dataAttr( elem, key, data ) {
1690	// If nothing was found internally, try to fetch any
1691	// data from the HTML5 data-* attribute
1692	if ( data === undefined && elem.nodeType === 1 ) {
1693		var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1694
1695		data = elem.getAttribute( name );
1696
1697		if ( typeof data === "string" ) {
1698			try {
1699				data = data === "true" ? true :
1700				data === "false" ? false :
1701				data === "null" ? null :
1702				!jQuery.isNaN( data ) ? parseFloat( data ) :
1703					rbrace.test( data ) ? jQuery.parseJSON( data ) :
1704					data;
1705			} catch( e ) {}
1706
1707			// Make sure we set the data so it isn't changed later
1708			jQuery.data( elem, key, data );
1709
1710		} else {
1711			data = undefined;
1712		}
1713	}
1714
1715	return data;
1716}
1717
1718// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1719// property to be considered empty objects; this property always exists in
1720// order to make sure JSON.stringify does not expose internal metadata
1721function isEmptyDataObject( obj ) {
1722	for ( var name in obj ) {
1723		if ( name !== "toJSON" ) {
1724			return false;
1725		}
1726	}
1727
1728	return true;
1729}
1730
1731
1732
1733
1734function handleQueueMarkDefer( elem, type, src ) {
1735	var deferDataKey = type + "defer",
1736		queueDataKey = type + "queue",
1737		markDataKey = type + "mark",
1738		defer = jQuery.data( elem, deferDataKey, undefined, true );
1739	if ( defer &&
1740		( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1741		( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1742		// Give room for hard-coded callbacks to fire first
1743		// and eventually mark/queue something else on the element
1744		setTimeout( function() {
1745			if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1746				!jQuery.data( elem, markDataKey, undefined, true ) ) {
1747				jQuery.removeData( elem, deferDataKey, true );
1748				defer.resolve();
1749			}
1750		}, 0 );
1751	}
1752}
1753
1754jQuery.extend({
1755
1756	_mark: function( elem, type ) {
1757		if ( elem ) {
1758			type = (type || "fx") + "mark";
1759			jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1760		}
1761	},
1762
1763	_unmark: function( force, elem, type ) {
1764		if ( force !== true ) {
1765			type = elem;
1766			elem = force;
1767			force = false;
1768		}
1769		if ( elem ) {
1770			type = type || "fx";
1771			var key = type + "mark",
1772				count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1773			if ( count ) {
1774				jQuery.data( elem, key, count, true );
1775			} else {
1776				jQuery.removeData( elem, key, true );
1777				handleQueueMarkDefer( elem, type, "mark" );
1778			}
1779		}
1780	},
1781
1782	queue: function( elem, type, data ) {
1783		if ( elem ) {
1784			type = (type || "fx") + "queue";
1785			var q = jQuery.data( elem, type, undefined, true );
1786			// Speed up dequeue by getting out quickly if this is just a lookup
1787			if ( data ) {
1788				if ( !q || jQuery.isArray(data) ) {
1789					q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1790				} else {
1791					q.push( data );
1792				}
1793			}
1794			return q || [];
1795		}
1796	},
1797
1798	dequeue: function( elem, type ) {
1799		type = type || "fx";
1800
1801		var queue = jQuery.queue( elem, type ),
1802			fn = queue.shift(),
1803			defer;
1804
1805		// If the fx queue is dequeued, always remove the progress sentinel
1806		if ( fn === "inprogress" ) {
1807			fn = queue.shift();
1808		}
1809
1810		if ( fn ) {
1811			// Add a progress sentinel to prevent the fx queue from being
1812			// automatically dequeued
1813			if ( type === "fx" ) {
1814				queue.unshift("inprogress");
1815			}
1816
1817			fn.call(elem, function() {
1818				jQuery.dequeue(elem, type);
1819			});
1820		}
1821
1822		if ( !queue.length ) {
1823			jQuery.removeData( elem, type + "queue", true );
1824			handleQueueMarkDefer( elem, type, "queue" );
1825		}
1826	}
1827});
1828
1829jQuery.fn.extend({
1830	queue: function( type, data ) {
1831		if ( typeof type !== "string" ) {
1832			data = type;
1833			type = "fx";
1834		}
1835
1836		if ( data === undefined ) {
1837			return jQuery.queue( this[0], type );
1838		}
1839		return this.each(function() {
1840			var queue = jQuery.queue( this, type, data );
1841
1842			if ( type === "fx" && queue[0] !== "inprogress" ) {
1843				jQuery.dequeue( this, type );
1844			}
1845		});
1846	},
1847	dequeue: function( type ) {
1848		return this.each(function() {
1849			jQuery.dequeue( this, type );
1850		});
1851	},
1852	// Based off of the plugin by Clint Helfers, with permission.
1853	// http://blindsignals.com/index.php/2009/07/jquery-delay/
1854	delay: function( time, type ) {
1855		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1856		type = type || "fx";
1857
1858		return this.queue( type, function() {
1859			var elem = this;
1860			setTimeout(function() {
1861				jQuery.dequeue( elem, type );
1862			}, time );
1863		});
1864	},
1865	clearQueue: function( type ) {
1866		return this.queue( type || "fx", [] );
1867	},
1868	// Get a promise resolved when queues of a certain type
1869	// are emptied (fx is the type by default)
1870	promise: function( type, object ) {
1871		if ( typeof type !== "string" ) {
1872			object = type;
1873			type = undefined;
1874		}
1875		type = type || "fx";
1876		var defer = jQuery.Deferred(),
1877			elements = this,
1878			i = elements.length,
1879			count = 1,
1880			deferDataKey = type + "defer",
1881			queueDataKey = type + "queue",
1882			markDataKey = type + "mark",
1883			tmp;
1884		function resolve() {
1885			if ( !( --count ) ) {
1886				defer.resolveWith( elements, [ elements ] );
1887			}
1888		}
1889		while( i-- ) {
1890			if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1891					( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1892						jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1893					jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1894				count++;
1895				tmp.done( resolve );
1896			}
1897		}
1898		resolve();
1899		return defer.promise();
1900	}
1901});
1902
1903
1904
1905
1906var rclass = /[\n\t\r]/g,
1907	rspace = /\s+/,
1908	rreturn = /\r/g,
1909	rtype = /^(?:button|input)$/i,
1910	rfocusable = /^(?:button|input|object|select|textarea)$/i,
1911	rclickable = /^a(?:rea)?$/i,
1912	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1913	rinvalidChar = /\:|^on/,
1914	formHook, boolHook;
1915
1916jQuery.fn.extend({
1917	attr: function( name, value ) {
1918		return jQuery.access( this, name, value, true, jQuery.attr );
1919	},
1920
1921	removeAttr: function( name ) {
1922		return this.each(function() {
1923			jQuery.removeAttr( this, name );
1924		});
1925	},
1926	
1927	prop: function( name, value ) {
1928		return jQuery.access( this, name, value, true, jQuery.prop );
1929	},
1930	
1931	removeProp: function( name ) {
1932		name = jQuery.propFix[ name ] || name;
1933		return this.each(function() {
1934			// try/catch handles cases where IE balks (such as removing a property on window)
1935			try {
1936				this[ name ] = undefined;
1937				delete this[ name ];
1938			} catch( e ) {}
1939		});
1940	},
1941
1942	addClass: function( value ) {
1943		var classNames, i, l, elem,
1944			setClass, c, cl;
1945
1946		if ( jQuery.isFunction( value ) ) {
1947			return this.each(function( j ) {
1948				jQuery( this ).addClass( value.call(this, j, this.className) );
1949			});
1950		}
1951
1952		if ( value && typeof value === "string" ) {
1953			classNames = value.split( rspace );
1954
1955			for ( i = 0, l = this.length; i < l; i++ ) {
1956				elem = this[ i ];
1957
1958				if ( elem.nodeType === 1 ) {
1959					if ( !elem.className && classNames.length === 1 ) {
1960						elem.className = value;
1961
1962					} else {
1963						setClass = " " + elem.className + " ";
1964
1965						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
1966							if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
1967								setClass += classNames[ c ] + " ";
1968							}
1969						}
1970						elem.className = jQuery.trim( setClass );
1971					}
1972				}
1973			}
1974		}
1975
1976		return this;
1977	},
1978
1979	removeClass: function( value ) {
1980		var classNames, i, l, elem, className, c, cl;
1981
1982		if ( jQuery.isFunction( value ) ) {
1983			return this.each(function( j ) {
1984				jQuery( this ).removeClass( value.call(this, j, this.className) );
1985			});
1986		}
1987
1988		if ( (value && typeof value === "string") || value === undefined ) {
1989			classNames = (value || "").split( rspace );
1990
1991			for ( i = 0, l = this.length; i < l; i++ ) {
1992				elem = this[ i ];
1993
1994				if ( elem.nodeType === 1 && elem.className ) {
1995					if ( value ) {
1996						className = (" " + elem.className + " ").replace( rclass, " " );
1997						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
1998							className = className.replace(" " + classNames[ c ] + " ", " ");
1999						}
2000						elem.className = jQuery.trim( className );
2001
2002					} else {
2003						elem.className = "";
2004					}
2005				}
2006			}
2007		}
2008
2009		return this;
2010	},
2011
2012	toggleClass: function( value, stateVal ) {
2013		var type = typeof value,
2014			isBool = typeof stateVal === "boolean";
2015
2016		if ( jQuery.isFunction( value ) ) {
2017			return this.each(function( i ) {
2018				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2019			});
2020		}
2021
2022		return this.each(function() {
2023			if ( type === "string" ) {
2024				// toggle individual class names
2025				var className,
2026					i = 0,
2027					self = jQuery( this ),
2028					state = stateVal,
2029					classNames = value.split( rspace );
2030
2031				while ( (className = classNames[ i++ ]) ) {
2032					// check each className given, space seperated list
2033					state = isBool ? state : !self.hasClass( className );
2034					self[ state ? "addClass" : "removeClass" ]( className );
2035				}
2036
2037			} else if ( type === "undefined" || type === "boolean" ) {
2038				if ( this.className ) {
2039					// store className if set
2040					jQuery._data( this, "__className__", this.className );
2041				}
2042
2043				// toggle whole className
2044				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2045			}
2046		});
2047	},
2048
2049	hasClass: function( selector ) {
2050		var className = " " + selector + " ";
2051		for ( var i = 0, l = this.length; i < l; i++ ) {
2052			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2053				return true;
2054			}
2055		}
2056
2057		return false;
2058	},
2059
2060	val: function( value ) {
2061		var hooks, ret,
2062			elem = this[0];
2063		
2064		if ( !arguments.length ) {
2065			if ( elem ) {
2066				hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2067
2068				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2069					return ret;
2070				}
2071
2072				ret = elem.value;
2073
2074				return typeof ret === "string" ? 
2075					// handle most common string cases
2076					ret.replace(rreturn, "") : 
2077					// handle cases where value is null/undef or number
2078					ret == null ? "" : ret;
2079			}
2080
2081			return undefined;
2082		}
2083
2084		var isFunction = jQuery.isFunction( value );
2085
2086		return this.each(function( i ) {
2087			var self = jQuery(this), val;
2088
2089			if ( this.nodeType !== 1 ) {
2090				return;
2091			}
2092
2093			if ( isFunction ) {
2094				val = value.call( this, i, self.val() );
2095			} else {
2096				val = value;
2097			}
2098
2099			// Treat null/undefined as ""; convert numbers to string
2100			if ( val == null ) {
2101				val = "";
2102			} else if ( typeof val === "number" ) {
2103				val += "";
2104			} else if ( jQuery.isArray( val ) ) {
2105				val = jQuery.map(val, function ( value ) {
2106					return value == null ? "" : value + "";
2107				});
2108			}
2109
2110			hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2111
2112			// If set returns undefined, fall back to normal setting
2113			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2114				this.value = val;
2115			}
2116		});
2117	}
2118});
2119
2120jQuery.extend({
2121	valHooks: {
2122		option: {
2123			get: function( elem ) {
2124				// attributes.value is undefined in Blackberry 4.7 but
2125				// uses .value. See #6932
2126				var val = elem.attributes.value;
2127				return !val || val.specified ? elem.value : elem.text;
2128			}
2129		},
2130		select: {
2131			get: function( elem ) {
2132				var value,
2133					index = elem.selectedIndex,
2134					values = [],
2135					options = elem.options,
2136					one = elem.type === "select-one";
2137
2138				// Nothing was selected
2139				if ( index < 0 ) {
2140					return null;
2141				}
2142
2143				// Loop through all the selected options
2144				for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2145					var option = options[ i ];
2146
2147					// Don't return options that are disabled or in a disabled optgroup
2148					if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2149							(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2150
2151						// Get the specific value for the option
2152						value = jQuery( option ).val();
2153
2154						// We don't need an array for one selects
2155						if ( one ) {
2156							return value;
2157						}
2158
2159						// Multi-Selects return an array
2160						values.push( value );
2161					}
2162				}
2163
2164				// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2165				if ( one && !values.length && options.length ) {
2166					return jQuery( options[ index ] ).val();
2167				}
2168
2169				return values;
2170			},
2171
2172			set: function( elem, value ) {
2173				var values = jQuery.makeArray( value );
2174
2175				jQuery(elem).find("option").each(function() {
2176					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2177				});
2178
2179				if ( !values.length ) {
2180					elem.selectedIndex = -1;
2181				}
2182				return values;
2183			}
2184		}
2185	},
2186
2187	attrFn: {
2188		val: true,
2189		css: true,
2190		html: true,
2191		text: true,
2192		data: true,
2193		width: true,
2194		height: true,
2195		offset: true
2196	},
2197	
2198	attrFix: {
2199		// Always normalize to ensure hook usage
2200		tabindex: "tabIndex"
2201	},
2202	
2203	attr: function( elem, name, value, pass ) {
2204		var nType = elem.nodeType;
2205		
2206		// don't get/set attributes on text, comment and attribute nodes
2207		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2208			return undefined;
2209		}
2210
2211		if ( pass && name in jQuery.attrFn ) {
2212			return jQuery( elem )[ name ]( value );
2213		}
2214
2215		// Fallback to prop when attributes are not supported
2216		if ( !("getAttribute" in elem) ) {
2217			return jQuery.prop( elem, name, value );
2218		}
2219
2220		var ret, hooks,
2221			notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2222
2223		// Normalize the name if needed
2224		if ( notxml ) {
2225			name = jQuery.attrFix[ name ] || name;
2226
2227			hooks = jQuery.attrHooks[ name ];
2228
2229			if ( !hooks ) {
2230				// Use boolHook for boolean attributes
2231				if ( rboolean.test( name ) ) {
2232
2233					hooks = boolHook;
2234
2235				// Use formHook for forms and if the name contains certain characters
2236				} else if ( formHook && name !== "className" &&
2237					(jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
2238
2239					hooks = formHook;
2240				}
2241			}
2242		}
2243
2244		if ( value !== undefined ) {
2245
2246			if ( value === null ) {
2247				jQuery.removeAttr( elem, name );
2248				return undefined;
2249
2250			} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2251				return ret;
2252
2253			} else {
2254				elem.setAttribute( name, "" + value );
2255				return value;
2256			}
2257
2258		} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2259			return ret;
2260
2261		} else {
2262
2263			ret = elem.getAttribute( name );
2264
2265			// Non-existent attributes return null, we normalize to undefined
2266			return ret === null ?
2267				undefined :
2268				ret;
2269		}
2270	},
2271
2272	removeAttr: function( elem, name ) {
2273		var propName;
2274		if ( elem.nodeType === 1 ) {
2275			name = jQuery.attrFix[ name ] || name;
2276		
2277			if ( jQuery.support.getSetAttribute ) {
2278				// Use removeAttribute in browsers that support it
2279				elem.removeAttribute( name );
2280			} else {
2281				jQuery.attr( elem, name, "" );
2282				elem.removeAttributeNode( elem.getAttributeNode( name ) );
2283			}
2284
2285			// Set corresponding property to false for boolean attributes
2286			if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2287				elem[ propName ] = false;
2288			}
2289		}
2290	},
2291
2292	attrHooks: {
2293		type: {
2294			set: function( elem, value ) {
2295				// We can't allow the type property to be changed (since it causes problems in IE)
2296				if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2297					jQuery.error( "type property can't be changed" );
2298				} else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2299					// Setting the type on a radio button after the value resets the value in IE6-9
2300					// Reset value to it's default in case type is set after value
2301					// This is for element creation
2302					var val = elem.value;
2303					elem.setAttribute( "type", value );
2304					if ( val ) {
2305						elem.value = val;
2306					}
2307					return value;
2308				}
2309			}
2310		},
2311		tabIndex: {
2312			get: function( elem ) {
2313				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2314				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2315				var attributeNode = elem.getAttributeNode("tabIndex");
2316
2317				return attributeNode && attributeNode.specified ?
2318					parseInt( attributeNode.value, 10 ) :
2319					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2320						0 :
2321						undefined;
2322			}
2323		},
2324		// Use the value property for back compat
2325		// Use the formHook for button elements in IE6/7 (#1954)
2326		value: {
2327			get: function( elem, name ) {
2328				if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2329					return formHook.get( elem, name );
2330				}
2331				return name in elem ?
2332					elem.value :
2333					null;
2334			},
2335			set: function( elem, value, name ) {
2336				if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2337					return formHook.set( elem, value, name );
2338				}
2339				// Does not return so that setAttribute is also used
2340				elem.value = value;
2341			}
2342		}
2343	},
2344
2345	propFix: {
2346		tabindex: "tabIndex",
2347		readonly: "readOnly",
2348		"for": "htmlFor",
2349		"class": "className",
2350		maxlength: "maxLength",
2351		cellspacing: "cellSpacing",
2352		cellpadding: "cellPadding",
2353		rowspan: "rowSpan",
2354		colspan: "colSpan",
2355		usemap: "useMap",
2356		frameborder: "frameBorder",
2357		contenteditable: "contentEditable"
2358	},
2359	
2360	prop: function( elem, name, value ) {
2361		var nType = elem.nodeType;
2362
2363		// don't get/set properties on text, comment and attribute nodes
2364		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2365			return undefined;
2366		}
2367
2368		var ret, hooks,
2369			notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2370
2371		if ( notxml ) {
2372			// Fix name and attach hooks
2373			name = jQuery.propFix[ name ] || name;
2374			hooks = jQuery.propHooks[ name ];
2375		}
2376
2377		if ( value !== undefined ) {
2378			if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2379				return ret;
2380
2381			} else {
2382				return (elem[ name ] = value);
2383			}
2384
2385		} else {
2386			if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2387				return ret;
2388
2389			} else {
2390				return elem[ name ];
2391			}
2392		}
2393	},
2394	
2395	propHooks: {}
2396});
2397
2398// Hook for boolean attributes
2399boolHook = {
2400	get: function( elem, name ) {
2401		// Align boolean attributes with corresponding properties
2402		return jQuery.prop( elem, name ) ?
2403			name.toLowerCase() :
2404			undefined;
2405	},
2406	set: function( elem, value, name ) {
2407		var propName;
2408		if ( value === false ) {
2409			// Remove boolean attributes when set to false
2410			jQuery.removeAttr( elem, name );
2411		} else {
2412			// value is true since we know at this point it's type boolean and not false
2413			// Set boolean attributes to the same name and set the DOM property
2414			propName = jQuery.propFix[ name ] || name;
2415			if ( propName in elem ) {
2416				// Only set the IDL specifically if it already exists on the element
2417				elem[ propName ] = true;
2418			}
2419
2420			elem.setAttribute( name, name.toLowerCase() );
2421		}
2422		return name;
2423	}
2424};
2425
2426// IE6/7 do not support getting/setting some attributes with get/setAttribute
2427if ( !jQuery.support.getSetAttribute ) {
2428
2429	// propFix is more comprehensive and contains all fixes
2430	jQuery.attrFix = jQuery.propFix;
2431	
2432	// Use this for any attribute on a form in IE6/7
2433	formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = {
2434		get: function( elem, name ) {
2435			var ret;
2436			ret = elem.getAttributeNode( name );
2437			// Return undefined if nodeValue is empty string
2438			return ret && ret.nodeValue !== "" ?
2439				ret.nodeValue :
2440				undefined;
2441		},
2442		set: function( elem, value, name ) {
2443			// Check form objects in IE (multiple bugs related)
2444			// Only use nodeValue if the attribute node exists on the form
2445			var ret = elem.getAttributeNode( name );
2446			if ( ret ) {
2447				ret.nodeValue = value;
2448				return value;
2449			}
2450		}
2451	};
2452
2453	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
2454	// This is for removals
2455	jQuery.each([ "width", "height" ], function( i, name ) {
2456		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2457			set: function( elem, value ) {
2458				if ( value === "" ) {
2459					elem.setAttribute( name, "auto" );
2460					return value;
2461				}
2462			}
2463		});
2464	});
2465}
2466
2467
2468// Some attributes require a special call on IE
2469if ( !jQuery.support.hrefNormalized ) {
2470	jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2471		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2472			get: function( elem ) {
2473				var ret = elem.getAttribute( name, 2 );
2474				return ret === null ? undefined : ret;
2475			}
2476		});
2477	});
2478}
2479
2480if ( !jQuery.support.style ) {
2481	jQuery.attrHooks.style = {
2482		get: function( elem ) {
2483			// Return undefined in the case of empty string
2484			// Normalize to lowercase since IE uppercases css property names
2485			return elem.style.cssText.toLowerCase() || undefined;
2486		},
2487		set: function( elem, value ) {
2488			return (elem.style.cssText = "" + value);
2489		}
2490	};
2491}
2492
2493// Safari mis-reports the default selected property of an option
2494// Accessing the parent's selectedIndex property fixes it
2495if ( !jQuery.support.optSelected ) {
2496	jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2497		get: function( elem ) {
2498			var parent = elem.parentNode;
2499
2500			if ( parent ) {
2501				parent.selectedIndex;
2502
2503				// Make sure that it also works with optgroups, see #5701
2504				if ( parent.parentNode ) {
2505					parent.parentNode.selectedIndex;
2506				}
2507			}
2508		}
2509	});
2510}
2511
2512// Radios and checkboxes getter/setter
2513if ( !jQuery.support.checkOn ) {
2514	jQuery.each([ "radio", "checkbox" ], function() {
2515		jQuery.valHooks[ this ] = {
2516			get: function( elem ) {
2517				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2518				return elem.getAttribute("value") === null ? "on" : elem.value;
2519			}
2520		};
2521	});
2522}
2523jQuery.each([ "radio", "checkbox" ], function() {
2524	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2525		set: function( elem, value ) {
2526			if ( jQuery.isArray( value ) ) {
2527				return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2528			}
2529		}
2530	});
2531});
2532
2533
2534
2535
2536var rnamespaces = /\.(.*)$/,
2537	rformElems = /^(?:textarea|input|select)$/i,
2538	rperiod = /\./g,
2539	rspaces = / /g,
2540	rescape = /[^\w\s.|`]/g,
2541	fcleanup = function( nm ) {
2542		return nm.replace(rescape, "\\$&");
2543	};
2544
2545/*
2546 * A number of helper functions used for managing events.
2547 * Many of the ideas behind this code originated from
2548 * Dean Edwards' addEvent library.
2549 */
2550jQuery.event = {
2551
2552	// Bind an event to an element
2553	// Original by Dean Edwards
2554	add: function( elem, types, handler, data ) {
2555		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2556			return;
2557		}
2558
2559		if ( handler === false ) {
2560			handler = returnFalse;
2561		} else if ( !handler ) {
2562			// Fixes bug #7229. Fix recommended by jdalton
2563			return;
2564		}
2565
2566		var handleObjIn, handleObj;
2567
2568		if ( handler.handler ) {
2569			handleObjIn = handler;
2570			handler = handleObjIn.handler;
2571		}
2572
2573		// Make sure that the function being executed has a unique ID
2574		if ( !handler.guid ) {
2575			handler.guid = jQuery.guid++;
2576		}
2577
2578		// Init the element's event structure
2579		var elemData = jQuery._data( elem );
2580
2581		// If no elemData is found then we must be trying to bind to one of the
2582		// banned noData elements
2583		if ( !elemData ) {
2584			return;
2585		}
2586
2587		var events = elemData.events,
2588			eventHandle = elemData.handle;
2589
2590		if ( !events ) {
2591			elemData.events = events = {};
2592		}
2593
2594		if ( !eventHandle ) {
2595			elemData.handle = eventHandle = function( e ) {
2596				// Discard the second event of a jQuery.event.trigger() and
2597				// when an event is called after a page has unloaded
2598				return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2599					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2600					undefined;
2601			};
2602		}
2603
2604		// Add elem as a property of the handle function
2605		// This is to prevent a memory leak with non-native events in IE.
2606		eventHandle.elem = elem;
2607
2608		// Handle multiple events separated by a space
2609		// jQuery(...).bind("mouseover mouseout", fn);
2610		types = types.split(" ");
2611
2612		var type, i = 0, namespaces;
2613
2614		while ( (type = types[ i++ ]) ) {
2615			handleObj = handleObjIn ?
2616				jQuery.extend({}, handleObjIn) :
2617				{ handler: handler, data: data };
2618
2619			// Namespaced event handlers
2620			if ( type.indexOf(".") > -1 ) {
2621				namespaces = type.split(".");
2622				type = namespaces.shift();
2623				handleObj.namespace = namespaces.slice(0).sort().join(".");
2624
2625			} else {
2626				namespaces = [];
2627				handleObj.namespace = "";
2628			}
2629
2630			handleObj.type = type;
2631			if ( !handleObj.guid ) {
2632				handleObj.guid = handler.guid;
2633			}
2634
2635			// Get the current list of functions bound to this event
2636			var handlers = events[ type ],
2637				special = jQuery.event.special[ type ] || {};
2638
2639			// Init the event handler queue
2640			if ( !handlers ) {
2641				handlers = events[ type ] = [];
2642
2643				// Check for a special event handler
2644				// Only use addEventListener/attachEvent if the special
2645				// events handler returns false
2646				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2647					// Bind the global event handler to the element
2648					if ( elem.addEventListener ) {
2649						elem.addEventListener( type, eventHandle, false );
2650
2651					} else if ( elem.attachEvent ) {
2652						elem.attachEvent( "on" + type, eventHandle );
2653					}
2654				}
2655			}
2656
2657			if ( special.add ) {
2658				special.add.call( elem, handleObj );
2659
2660				if ( !handleObj.handler.guid ) {
2661					handleObj.handler.guid = handler.guid;
2662				}
2663			}
2664
2665			// Add the function to the element's handler list
2666			handlers.push( handleObj );
2667
2668			// Keep track of which events have been used, for event optimization
2669			jQuery.event.global[ type ] = true;
2670		}
2671
2672		// Nullify elem to prevent memory leaks in IE
2673		elem = null;
2674	},
2675
2676	global: {},
2677
2678	// Detach an event or set of events from an element
2679	remove: function( elem, types, handler, pos ) {
2680		// don't do events on text and comment nodes
2681		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2682			return;
2683		}
2684
2685		if ( handler === false ) {
2686			handler = returnFalse;
2687		}
2688
2689		var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2690			elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2691			events = elemData && elemData.events;
2692
2693		if ( !elemData || !events ) {
2694			return;
2695		}
2696
2697		// types is actually an event object here
2698		if ( types && types.type ) {
2699			handler = types.handler;
2700			types = types.type;
2701		}
2702
2703		// Unbind all events for the element
2704		if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2705			types = types || "";
2706
2707			for ( type in events ) {
2708				jQuery.event.remove( elem, type + types );
2709			}
2710
2711			return;
2712		}
2713
2714		// Handle multiple events separated by a space
2715		// jQuery(...).unbind("mouseover mouseout", fn);
2716		types = types.split(" ");
2717
2718		while ( (type = types[ i++ ]) ) {
2719			origType = type;
2720			handleObj = null;
2721			all = type.indexOf(".") < 0;
2722			namespaces = [];
2723
2724			if ( !all ) {
2725				// Namespaced event handlers
2726				namespaces = type.split(".");
2727				type = namespaces.shift();
2728
2729				namespace = new RegExp("(^|\\.)" +
2730					jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2731			}
2732
2733			eventType = events[ type ];
2734
2735			if ( !eventType ) {
2736				continue;
2737			}
2738
2739			if ( !handler ) {
2740				for ( j = 0; j < eventType.length; j++ ) {
2741					handleObj = eventType[ j ];
2742
2743					if ( all || namespace.test( handleObj.namespace ) ) {
2744						jQuery.event.remove( elem, origType, handleObj.handler, j );
2745						eventType.splice( j--, 1 );
2746					}
2747				}
2748
2749				continue;
2750			}
2751
2752			special = jQuery.event.special[ type ] || {};
2753
2754			for ( j = pos || 0; j < eventType.length; j++ ) {
2755				handleObj = eventType[ j ];
2756
2757				if ( handler.guid === handleObj.guid ) {
2758					// remove the given handler for the given type
2759					if ( all || namespace.test( handleObj.namespace ) ) {
2760						if ( pos == null ) {
2761							eventType.splice( j--, 1 );
2762						}
2763
2764						if ( special.remove ) {
2765							special.remove.call( elem, handleObj );
2766						}
2767					}
2768
2769					if ( pos != null ) {
2770						break;
2771					}
2772				}
2773			}
2774
2775			// remove generic event handler if no more handlers exist
2776			if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2777				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2778					jQuery.removeEvent( elem, type, elemData.handle );
2779				}
2780
2781				ret = null;
2782				delete events[ type ];
2783			}
2784		}
2785
2786		// Remove the expando if it's no longer used
2787		if ( jQuery.isEmptyObject( events ) ) {
2788			var handle = elemData.handle;
2789			if ( handle ) {
2790				handle.elem = null;
2791			}
2792
2793			delete elemData.events;
2794			delete elemData.handle;
2795
2796			if ( jQuery.isEmptyObject( elemData ) ) {
2797				jQuery.removeData( elem, undefined, true );
2798			}
2799		}
2800	},
2801	
2802	// Events that are safe to short-circuit if no handlers are attached.
2803	// Native DOM events should not be added, they may have inline handlers.
2804	customEvent: {
2805		"getData": true,
2806		"setData": true,
2807		"changeData": true
2808	},
2809
2810	trigger: function( event, data, elem, onlyHandlers ) {
2811		// Event object or event type
2812		var type = event.type || event,
2813			namespaces = [],
2814			exclusive;
2815
2816		if ( type.indexOf("!") >= 0 ) {
2817			// Exclusive events trigger only for the exact event (no namespaces)
2818			type = type.slice(0, -1);
2819			exclusive = true;
2820		}
2821
2822		if ( type.indexOf(".") >= 0 ) {
2823			// Namespaced trigger; create a regexp to match event type in handle()
2824			namespaces = type.split(".");
2825			type = namespaces.shift();
2826			namespaces.sort();
2827		}
2828
2829		if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2830			// No jQuery handlers for this event type, and it can't have inline handlers
2831			return;
2832		}
2833
2834		// Caller can pass in an Event, Object, or just an event type string
2835		event = typeof event === "object" ?
2836			// jQuery.Event object
2837			event[ jQuery.expando ] ? event :
2838			// Object literal
2839			new jQuery.Event( type, event ) :
2840			// Just the event type (string)
2841			new jQuery.Event( type );
2842
2843		event.type = type;
2844		event.exclusive = exclusive;
2845		event.namespace = namespaces.join(".");
2846		event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2847		
2848		// triggerHandler() and global events don't bubble or run the default action
2849		if ( onlyHandlers || !elem ) {
2850			event.preventDefault();
2851			event.stopPropagation();
2852		}
2853
2854		// Handle a global trigger
2855		if ( !elem ) {
2856			// TODO: Stop taunting the data cache; remove global events and always attach to document
2857			jQuery.each( jQuery.cache, function() {
2858				// internalKey variable is just used to make it easier to find
2859				// and potentially change this stuff later; currently it just
2860				// points to jQuery.expando
2861				var internalKey = jQuery.expando,
2862					internalCache = this[ internalKey ];
2863				if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2864					jQuery.event.trigger( event, data, internalCache.handle.elem );
2865				}
2866			});
2867			return;
2868		}
2869
2870		// Don't do events on text and comment nodes
2871		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2872			return;
2873		}
2874
2875		// Clean up the event in case it is being reused
2876		event.result = undefined;
2877		event.target = elem;
2878
2879		// Clone any incoming data and prepend the event, creating the handler arg list
2880		data = data != null ? jQuery.makeArray( data ) : [];
2881		data.unshift( event );
2882
2883		var cur = elem,
2884			// IE doesn't like method names with a colon (#3533, #8272)
2885			ontype = type.indexOf(":") < 0 ? "on" + type : "";
2886
2887		// Fire event on the current element, then bubble up the DOM tree
2888		do {
2889			var handle = jQuery._data( cur, "handle" );
2890
2891			event.currentTarget = cur;
2892			if ( handle ) {
2893				handle.apply( cur, data );
2894			}
2895
2896			// Trigger an inline bound script
2897			if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2898				event.result = false;
2899				event.preventDefault();
2900			}
2901
2902			// Bubble up to document, then to window
2903			cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2904		} while ( cur && !event.isPropagationStopped() );
2905
2906		// If nobody prevented the default action, do it now
2907		if ( !event.isDefaultPrevented() ) {
2908			var old,
2909				special = jQuery.event.special[ type ] || {};
2910
2911			if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2912				!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2913
2914				// Call a native DOM method on the target with the same name name as the event.
2915				// Can't use an .isFunction)() check here because IE6/7 fails that test.
2916				// IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2917				try {
2918					if ( ontype && elem[ type ] ) {
2919						// Don't re-trigger an onFOO event when we call its FOO() method
2920						old = elem[ ontype ];
2921
2922						if ( old ) {
2923							elem[ ontype ] = null;
2924						}
2925
2926						jQuery.event.triggered = type;
2927						elem[ type ]();
2928					}
2929				} catch ( ieError ) {}
2930
2931				if ( old ) {
2932					elem[ ontype ] = old;
2933				}
2934
2935				jQuery.event.triggered = undefined;
2936			}
2937		}
2938		
2939		return event.result;
2940	},
2941
2942	handle: function( event ) {
2943		event = jQuery.event.fix( event || window.event );
2944		// Snapshot the handlers list since a called handler may add/remove events.
2945		var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2946			run_all = !event.exclusive && !event.namespace,
2947			args = Array.prototype.slice.call( arguments, 0 );
2948
2949		// Use the fix-ed Event rather than the (read-only) native event
2950		args[0] = event;
2951		event.currentTarget = this;
2952
2953		for ( var j = 0, l = handlers.length; j < l; j++ ) {
2954			var handleObj = handlers[ j ];
2955
2956			// Triggered event must 1) be non-exclusive and have no namespace, or
2957			// 2) have namespace(s) a subset or equal to those in the bound event.
2958			if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2959				// Pass in a reference to the handler function itself
2960				// So that we can later remove it
2961				event.handler = handleObj.handler;
2962				event.data = handleObj.data;
2963				event.handleObj = handleObj;
2964
2965				var ret = handleObj.handler.apply( this, args );
2966
2967				if ( ret !== undefined ) {
2968					event.result = ret;
2969					if ( ret === false ) {
2970						event.preventDefault();
2971						event.stopPropagation();
2972					}
2973				}
2974
2975				if ( event.isImmediatePropagationStopped() ) {
2976					break;
2977				}
2978			}
2979		}
2980		return event.result;
2981	},
2982
2983	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2984
2985	fix: function( event ) {
2986		if ( event[ jQuery.expando ] ) {
2987			return event;
2988		}
2989
2990		// store a copy of the original event object
2991		// and "clone" to set read-only properties
2992		var originalEvent = event;
2993		event = jQuery.Event( originalEvent );
2994
2995		for ( var i = this.props.length, prop; i; ) {
2996			prop = this.props[ --i ];
2997			event[ prop ] = originalEvent[ prop ];
2998		}
2999
3000		// Fix target property, if necessary
3001		if ( !event.target ) {
3002			// Fixes #1925 where srcElement might not be defined either
3003			event.target = event.srcElement || document;
3004		}
3005
3006		// check if target is a textnode (safari)
3007		if ( event.target.nodeType === 3 ) {
3008			event.target = event.target.parentNode;
3009		}
3010
3011		// Add relatedTarget, if necessary
3012		if ( !event.relatedTarget && event.fromElement ) {
3013			event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
3014		}
3015
3016		// Calculate pageX/Y if missing and clientX/Y available
3017		if ( event.pageX == null && event.clientX != null ) {
3018			var eventDocument = event.target.ownerDocument || document,
3019				doc = eventDocument.documentElement,
3020				body = eventDocument.body;
3021
3022			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
3023			event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
3024		}
3025
3026		// Add which for key events
3027		if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
3028			event.which = event.charCode != null ? event.charCode : event.keyCode;
3029		}
3030
3031		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
3032		if ( !event.metaKey && event.ctrlKey ) {
3033			event.metaKey = event.ctrlKey;
3034		}
3035
3036		// Add which for click: 1 === left; 2 === middle; 3 === right
3037		// Note: button is not normalized, so don't use it
3038		if ( !event.which && event.button !== undefined ) {
3039			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3040		}
3041
3042		return event;
3043	},
3044
3045	// Deprecated, use jQuery.guid instead
3046	guid: 1E8,
3047
3048	// Deprecated, use jQuery.proxy instead
3049	proxy: jQuery.proxy,
3050
3051	special: {
3052		ready: {
3053			// Make sure the ready event is setup
3054			setup: jQuery.bindReady,
3055			teardown: jQuery.noop
3056		},
3057
3058		live: {
3059			add: function( handleObj ) {
3060				jQuery.event.add( this,
3061					liveConvert( handleObj.origType, handleObj.selector ),
3062					jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3063			},
3064
3065			remove: function( handleObj ) {
3066				jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3067			}
3068		},
3069
3070		beforeunload: {
3071			setup: function( data, namespaces, eventHandle ) {
3072				// We only want to do this special case on windows
3073				if ( jQuery.isWindow( this ) ) {
3074					this.onbeforeunload = eventHandle;
3075				}
3076			},
3077
3078			teardown: function( namespaces, eventHandle ) {
3079				if ( this.onbeforeunload === eventHandle ) {
3080					this.onbeforeunload = null;
3081				}
3082			}
3083		}
3084	}
3085};
3086
3087jQuery.removeEvent = document.removeEventListener ?
3088	function( elem, type, handle ) {
3089		if ( elem.removeEventListener ) {
3090			elem.removeEventListener( type, handle, false );
3091		}
3092	} :
3093	function( elem, type, handle ) {
3094		if ( elem.detachEvent ) {
3095			elem.detachEvent( "on" + type, handle );
3096		}
3097	};
3098
3099jQuery.Event = function( src, props ) {
3100	// Allow instantiation without the 'new' keyword
3101	if ( !this.preventDefault ) {
3102		return new jQuery.Event( src, props );
3103	}
3104
3105	// Event object
3106	if ( src && src.type ) {
3107		this.originalEvent = src;
3108		this.type = src.type;
3109
3110		// Events bubbling up the document may have been marked as prevented
3111		// by a handler lower down the tree; reflect the correct value.
3112		this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3113			src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3114
3115	// Event type
3116	} else {
3117		this.type = src;
3118	}
3119
3120	// Put explicitly provided properties onto the event object
3121	if ( props ) {
3122		jQuery.extend( this, props );
3123	}
3124
3125	// timeStamp is buggy for some events on Firefox(#3843)
3126	// So we won't rely on the native value
3127	this.timeStamp = jQuery.now();
3128
3129	// Mark it as fixed
3130	this[ jQuery.expando ] = true;
3131};
3132
3133function returnFalse() {
3134	return false;
3135}
3136function returnTrue() {
3137	return true;
3138}
3139
3140// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3141// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3142jQuery.Event.prototype = {
3143	preventDefault: function() {
3144		this.isDefaultPrevented = returnTrue;
3145
3146		var e = this.originalEvent;
3147		if ( !e ) {
3148			return;
3149		}
3150
3151		// if preventDefault exists run it on the original event
3152		if ( e.preventDefault ) {
3153			e.preventDefault();
3154
3155		// otherwise set the returnValue property of the original event to false (IE)
3156		} else {
3157			e.returnValue = false;
3158		}
3159	},
3160	stopPropagation: function() {
3161		this.isPropagationStopped = returnTrue;
3162
3163		var e = this.originalEvent;
3164		if ( !e ) {
3165			return;
3166		}
3167		// if stopPropagation exists run it on the original event
3168		if ( e.stopPropagation ) {
3169			e.stopPropagation();
3170		}
3171		// otherwise set the cancelBubble property of the original event to true (IE)
3172		e.cancelBubble = true;
3173	},
3174	stopImmediatePropagation: function() {
3175		this.isImmediatePropagationStopped = returnTrue;
3176		this.stopPropagation();
3177	},
3178	isDefaultPrevented: returnFalse,
3179	isPropagationStopped: returnFalse,
3180	isImmediatePropagationStopped: returnFalse
3181};
3182
3183// Checks if an event happened on an element within another element
3184// Used in jQuery.event.special.mouseenter and mouseleave handlers
3185var withinElement = function( event ) {
3186
3187	// Check if mouse(over|out) are still within the same parent element
3188	var related = event.relatedTarget,
3189		inside = false,
3190		eventType = event.type;
3191
3192	event.type = event.data;
3193
3194	if ( related !== this ) {
3195
3196		if ( related ) {
3197			inside = jQuery.contains( this, related );
3198		}
3199
3200		if ( !inside ) {
3201
3202			jQuery.event.handle.apply( this, arguments );
3203
3204			event.type = eventType;
3205		}
3206	}
3207},
3208
3209// In case of event delegation, we only need to rename the event.type,
3210// liveHandler will take care of the rest.
3211delegate = function( event ) {
3212	event.type = event.data;
3213	jQuery.event.handle.apply( this, arguments );
3214};
3215
3216// Create mouseenter and mouseleave events
3217jQuery.each({
3218	mouseenter: "mouseover",
3219	mouseleave: "mouseout"
3220}, function( orig, fix ) {
3221	jQuery.event.special[ orig ] = {
3222		setup: function( data ) {
3223			jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3224		},
3225		teardown: function( data ) {
3226			jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3227		}
3228	};
3229});
3230
3231// submit delegation
3232if ( !jQuery.support.submitBubbles ) {
3233
3234	jQuery.event.special.submit = {
3235		setup: function( data, namespaces ) {
3236			if ( !jQuery.nodeName( this, "form" ) ) {
3237				jQuery.event.add(this, "click.specialSubmit", function( e ) {
3238					var elem = e.target,
3239						type = elem.type;
3240
3241					if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3242						trigger( "submit", this, arguments );
3243					}
3244				});
3245
3246				jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3247					var elem = e.target,
3248						type = elem.type;
3249
3250					if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3251						trigger( "submit", this, arguments );
3252					}
3253				});
3254
3255			} else {
3256				return false;
3257			}
3258		},
3259
3260		teardown: function( namespaces ) {
3261			jQuery.event.remove( this, ".specialSubmit" );
3262		}
3263	};
3264
3265}
3266
3267// change delegation, happens here so we have bind.
3268if ( !jQuery.support.changeBubbles ) {
3269
3270	var changeFilters,
3271
3272	getVal = function( elem ) {
3273		var type = elem.type, val = elem.value;
3274
3275		if ( type === "radio" || type === "checkbox" ) {
3276			val = elem.checked;
3277
3278		} else if ( type === "select-multiple" ) {
3279			val = elem.selectedIndex > -1 ?
3280				jQuery.map( elem.options, function( elem ) {
3281					return elem.selected;
3282				}).join("-") :
3283				"";
3284
3285		} else if ( jQuery.nodeName( elem, "select" ) ) {
3286			val = elem.selectedIndex;
3287		}
3288
3289		return val;
3290	},
3291
3292	testChange = function testChange( e ) {
3293		var elem = e.target, data, val;
3294
3295		if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3296			return;
3297		}
3298
3299		data = jQuery._data( elem, "_change_data" );
3300		val = getVal(elem);
3301
3302		// the current data will be also retrieved by beforeactivate
3303		if ( e.type !== "focusout" || elem.type !== "radio" ) {
3304			jQuery._data( elem, "_change_data", val );
3305		}
3306
3307		if ( data === undefined || val === data ) {
3308			return;
3309		}
3310
3311		if ( data != null || val ) {
3312			e.type = "change";
3313			e.liveFired = undefined;
3314			jQuery.event.trigger( e, arguments[1], elem );
3315		}
3316	};
3317
3318	jQuery.event.special.change = {
3319		filters: {
3320			focusout: testChange,
3321
3322			beforedeactivate: testChange,
3323
3324			click: function( e ) {
3325				var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3326
3327				if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3328					testChange.call( this, e );
3329				}
3330			},
3331
3332			// Change has to be called before submit
3333			// Keydown will be called before keypress, which is used in submit-event delegation
3334			keydown: function( e ) {
3335				var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3336
3337				if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3338					(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3339					type === "select-multiple" ) {
3340					testChange.call( this, e );
3341				}
3342			},
3343
3344			// Beforeactivate happens also before the previous element is blurred
3345			// with this event you can't trigger a change event, but you can store
3346			// information
3347			beforeactivate: function( e ) {
3348				var elem = e.target;
3349				jQuery._data( elem, "_change_data", getVal(elem) );
3350			}
3351		},
3352
3353		setup: function( data, namespaces ) {
3354			if ( this.type === "file" ) {
3355				return false;
3356			}
3357
3358			for ( var type in changeFilters ) {
3359				jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3360			}
3361
3362			return rformElems.test( this.nodeName );
3363		},
3364
3365		teardown: function( namespaces ) {
3366			jQuery.event.remove( this, ".specialChange" );
3367
3368			return rformElems.test( this.nodeName );
3369		}
3370	};
3371
3372	changeFilters = jQuery.event.special.change.filters;
3373
3374	// Handle when the input is .focus()'d
3375	changeFilters.focus = changeFilters.beforeactivate;
3376}
3377
3378function trigger( type, elem, args ) {
3379	// Piggyback on a donor event to simulate a different one.
3380	// Fake originalEvent to avoid donor's stopPropagation, but if the
3381	// simulated event prevents default then we do the same on the donor.
3382	// Don't pass args or remember liveFired; they apply to the donor event.
3383	var event = jQuery.extend( {}, args[ 0 ] );
3384	event.type = type;
3385	event.originalEvent = {};
3386	event.liveFired = undefined;
3387	jQuery.event.handle.call( elem, event );
3388	if ( event.isDefaultPrevented() ) {
3389		args[ 0 ].preventDefault();
3390	}
3391}
3392
3393// Create "bubbling" focus and blur events
3394if ( !jQuery.support.focusinBubbles ) {
3395	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3396
3397		// Attach a single capturing handler while someone wants focusin/focusout
3398		var attaches = 0;
3399
3400		jQuery.event.special[ fix ] = {
3401			setup: function() {
3402				if ( attaches++ === 0 ) {
3403					document.addEventListener( orig, handler, true );
3404				}
3405			},
3406			teardown: function() {
3407				if ( --attaches === 0 ) {
3408					document.removeEventListener( orig, handler, true );
3409				}
3410			}
3411		};
3412
3413		function handler( donor ) {
3414			// Donor event is always a native one; fix it and switch its type.
3415			// Let focusin/out handler cancel the donor focus/blur event.
3416			var e = jQuery.event.fix( donor );
3417			e.type = fix;
3418			e.originalEvent = {};
3419			jQuery.event.trigger( e, null, e.target );
3420			if ( e.isDefaultPrevented() ) {
3421				donor.preventDefault();
3422			}
3423		}
3424	});
3425}
3426
3427jQuery.each(["bind", "one"], function( i, name ) {
3428	jQuery.fn[ name ] = function( type, data, fn ) {
3429		var handler;
3430
3431		// Handle object literals
3432		if ( typeof type === "object" ) {
3433			for ( var key in type ) {
3434				this[ name ](key, data, type[key], fn);
3435			}
3436			return this;
3437		}
3438
3439		if ( arguments.length === 2 || data === false ) {
3440			fn = data;
3441			data = undefined;
3442		}
3443
3444		if ( name === "one" ) {
3445			handler = function( event ) {
3446				jQuery( this ).unbind( event, handler );
3447				return fn.apply( this, arguments );
3448			};
3449			handler.guid = fn.guid || jQuery.guid++;
3450		} else {
3451			handler = fn;
3452		}
3453
3454		if ( type === "unload" && name !== "one" ) {
3455			this.one( type, data, fn );
3456
3457		} else {
3458			for ( var i = 0, l = this.length; i < l; i++ ) {
3459				jQuery.event.add( this[i], type, handler, data );
3460			}
3461		}
3462
3463		return this;
3464	};
3465});
3466
3467jQuery.fn.extend({
3468	unbind: function( type, fn ) {
3469		// Handle object literals
3470		if ( typeof type === "object" && !type.preventDefault ) {
3471			for ( var key in type ) {
3472				this.unbind(key, type[key]);
3473			}
3474
3475		} else {
3476			for ( var i = 0, l = this.length; i < l; i++ ) {
3477				jQuery.event.remove( this[i], type, fn );
3478			}
3479		}
3480
3481		return this;
3482	},
3483
3484	delegate: function( selector, types, data, fn ) {
3485		return this.live( types, data, fn, selector );
3486	},
3487
3488	undelegate: function( selector, types, fn ) {
3489		if ( arguments.length === 0 ) {
3490			return this.unbind( "live" );
3491
3492		} else {
3493			return this.die( types, null, fn, selector );
3494		}
3495	},
3496
3497	trigger: function( type, data ) {
3498		return this.each(function() {
3499			jQuery.event.trigger( type, data, this );
3500		});
3501	},
3502
3503	triggerHandler: function( type, data ) {
3504		if ( this[0] ) {
3505			return jQuery.event.trigger( type, data, this[0], true );
3506		}
3507	},
3508
3509	toggle: function( fn ) {
3510		// Save reference to arguments for access in closure
3511		var args = arguments,
3512			guid = fn.guid || jQuery.guid++,
3513			i = 0,
3514			toggler = function( event ) {
3515				// Figure out which function to execute
3516				var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3517				jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3518
3519				// Make sure that clicks stop
3520				event.preventDefault();
3521
3522				// and execute the function
3523				return args[ lastToggle ].apply( this, arguments ) || false;
3524			};
3525
3526		// link all the functions, so any of them can unbind this click handler
3527		toggler.guid = guid;
3528		while ( i < args.length ) {
3529			args[ i++ ].guid = guid;
3530		}
3531
3532		return this.click( toggler );
3533	},
3534
3535	hover: function( fnOver, fnOut ) {
3536		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3537	}
3538});
3539
3540var liveMap = {
3541	focus: "focusin",
3542	blur: "focusout",
3543	mouseenter: "mouseover",
3544	mouseleave: "mouseout"
3545};
3546
3547jQuery.each(["live", "die"], function( i, name ) {
3548	jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3549		var type, i = 0, match, namespaces, preType,
3550			selector = origSelector || this.selector,
3551			context = origSelector ? this : jQuery( this.context );
3552
3553		if ( typeof types === "object" && !types.preventDefault ) {
3554			for ( var key in types ) {
3555				context[ name ]( key, data, types[key], selector );
3556			}
3557
3558			return this;
3559		}
3560
3561		if ( name === "die" && !types &&
3562					origSelector && origSelector.charAt(0) === "." ) {
3563
3564			context.unbind( origSelector );
3565
3566			return this;
3567		}
3568
3569		if ( data === false || jQuery.isFunction( data ) ) {
3570			fn = data || returnFalse;
3571			data = undefined;
3572		}
3573
3574		types = (types || "").split(" ");
3575
3576		while ( (type = types[ i++ ]) != null ) {
3577			match = rnamespaces.exec( type );
3578			namespaces = "";
3579
3580			if ( match )  {
3581				namespaces = match[0];
3582				type = type.replace( rnamespaces, "" );
3583			}
3584
3585			if ( type === "hover" ) {
3586				types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3587				continue;
3588			}
3589
3590			preType = type;
3591
3592			if ( liveMap[ type ] ) {
3593				types.push( liveMap[ type ] + namespaces );
3594				type = type + namespaces;
3595
3596			} else {
3597				type = (liveMap[ type ] || type) + namespaces;
3598			}
3599
3600			if ( name === "live" ) {
3601				// bind live handler
3602				for ( var j = 0, l = context.length; j < l; j++ ) {
3603					jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3604						{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3605				}
3606
3607			} else {
3608				// unbind live handler
3609				context.unbind( "live." + liveConvert( type, selector ), fn );
3610			}
3611		}
3612
3613		return this;
3614	};
3615});
3616
3617function liveHandler( event ) {
3618	var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3619		elems = [],
3620		selectors = [],
3621		events = jQuery._data( this, "events" );
3622
3623	// Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3624	if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3625		return;
3626	}
3627
3628	if ( event.namespace ) {
3629		namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3630	}
3631
3632	event.liveFired = this;
3633
3634	var live = events.live.slice(0);
3635
3636	for ( j = 0; j < live.length; j++ ) {
3637		handleObj = live[j];
3638
3639		if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3640			selectors.push( handleObj.selector );
3641
3642		} else {
3643			live.splice( j--, 1 );
3644		}
3645	}
3646
3647	match = jQuery( event.target ).closest( selectors, event.currentTarget );
3648
3649	for ( i = 0, l = match.length; i < l; i++ ) {
3650		close = match[i];
3651
3652		for ( j = 0; j < live.length; j++ ) {
3653			handleObj = live[j];
3654
3655			if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3656				elem = close.elem;
3657				related = null;
3658
3659				// Those two events require additional checking
3660				if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3661					event.type = handleObj.preType;
3662					related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3663
3664					// Make sure not to accidentally match a child element with the same selector
3665					if ( related && jQuery.contains( elem, related ) ) {
3666						related = elem;
3667					}
3668				}
3669
3670				if ( !related || related !== elem ) {
3671					elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3672				}
3673			}
3674		}
3675	}
3676
3677	for ( i = 0, l = elems.length; i < l; i++ ) {
3678		match = elems[i];
3679
3680		if ( maxLevel && match.level > maxLevel ) {
3681			break;
3682		}
3683
3684		event.currentTarget = match.elem;
3685		event.data = match.handleObj.data;
3686		event.handleObj = match.handleObj;
3687
3688		ret = match.handleObj.origHandler.apply( match.elem, arguments );
3689
3690		if ( ret === false || event.isPropagationStopped() ) {
3691			maxLevel = match.level;
3692
3693			if ( ret === false ) {
3694				stop = false;
3695			}
3696			if ( event.isImmediatePropagationStopped() ) {
3697				break;
3698			}
3699		}
3700	}
3701
3702	return stop;
3703}
3704
3705function liveConvert( type, selector ) {
3706	return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3707}
3708
3709jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3710	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3711	"change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3712
3713	// Handle event binding
3714	jQuery.fn[ name ] = function( data, fn ) {
3715		if ( fn == null ) {
3716			fn = data;
3717			data = null;
3718		}
3719
3720		return arguments.length > 0 ?
3721			this.bind( name, data, fn ) :
3722			this.trigger( name );
3723	};
3724
3725	if ( jQuery.attrFn ) {
3726		jQuery.attrFn[ name ] = true;
3727	}
3728});
3729
3730
3731
3732/*!
3733 * Sizzle CSS Selector Engine
3734 *  Copyright 2011, The Dojo Foundation
3735 *  Released under the MIT, BSD, and GPL Licenses.
3736 *  More information: http://sizzlejs.com/
3737 */
3738(function(){
3739
3740var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3741	done = 0,
3742	toString = Object.prototype.toString,
3743	hasDuplicate = false,
3744	baseHasDuplicate = true,
3745	rBackslash = /\\/g,
3746	rNonWord = /\W/;
3747
3748// Here we check if the JavaScript engine is using some sort of
3749// optimization where it does not always call our comparision
3750// function. If that is the case, discard the hasDuplicate value.
3751//   Thus far that includes Google Chrome.
3752[0, 0].sort(function() {
3753	baseHasDuplicate = false;
3754	return 0;
3755});
3756
3757var Sizzle = function( selector, context, results, seed ) {
3758	results = results || [];
3759	context = context || document;
3760
3761	var origContext = context;
3762
3763	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3764		return [];
3765	}
3766	
3767	if ( !selector || typeof selector !== "string" ) {
3768		return results;
3769	}
3770
3771	var m, set, checkSet, extra, ret, cur, pop, i,
3772		prune = true,
3773		contextXML = Sizzle.isXML( context ),
3774		parts = [],
3775		soFar = selector;
3776	
3777	// Reset the position of the chunker regexp (start from head)
3778	do {
3779		chunker.exec( "" );
3780		m = chunker.exec( soFar );
3781
3782		if ( m ) {
3783			soFar = m[3];
3784		
3785			parts.push( m[1] );
3786		
3787			if ( m[2] ) {
3788				extra = m[3];
3789				break;
3790			}
3791		}
3792	} while ( m );
3793
3794	if ( parts.length > 1 && origPOS.exec( selector ) ) {
3795
3796		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3797			set = posProcess( parts[0] + parts[1], context );
3798
3799		} else {
3800			set = Expr.relative[ parts[0] ] ?
3801				[ context ] :
3802				Sizzle( parts.shift(), context );
3803
3804			while ( parts.length ) {
3805				selector = parts.shift();
3806
3807				if ( Expr.relative[ selector ] ) {
3808					selector += parts.shift();
3809				}
3810				
3811				set = posProcess( selector, set );
3812			}
3813		}
3814
3815	} else {
3816		// Take a shortcut and set the context if the root selector is an ID
3817		// (but not if it'll be faster if the inner selector is an ID)
3818		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3819				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3820
3821			ret = Sizzle.find( parts.shift(), context, contextXML );
3822			context = ret.expr ?
3823				Sizzle.filter( ret.expr, ret.set )[0] :
3824				ret.set[0];
3825		}
3826
3827		if ( context ) {
3828			ret = seed ?
3829				{ expr: parts.pop(), set: makeArray(seed) } :
3830				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3831
3832			set = ret.expr ?
3833				Sizzle.filter( ret.expr, ret.set ) :
3834				ret.set;
3835
3836			if ( parts.length > 0 ) {
3837				checkSet = makeArray( set );
3838
3839			} else {
3840				prune = false;
3841			}
3842
3843			while ( parts.length ) {
3844				cur = parts.pop();
3845				pop = cur;
3846
3847				if ( !Expr.relative[ cur ] ) {
3848					cur = "";
3849				} else {
3850					pop = parts.pop();
3851				}
3852
3853				if ( pop == null ) {
3854					pop = context;
3855				}
3856
3857				Expr.relative[ cur ]( checkSet, pop, contextXML );
3858			}
3859
3860		} else {
3861			checkSet = parts = [];
3862		}
3863	}
3864
3865	if ( !checkSet ) {
3866		checkSet = set;
3867	}
3868
3869	if ( !checkSet ) {
3870		Sizzle.error( cur || selector );
3871	}
3872
3873	if ( toString.call(checkSet) === "[object Array]" ) {
3874		if ( !prune ) {
3875			results.push.apply( results, checkSet );
3876
3877		} else if ( context && context.nodeType === 1 ) {
3878			for ( i = 0; checkSet[i] != null; i++ ) {
3879				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3880					results.push( set[i] );
3881				}
3882			}
3883
3884		} else {
3885			for ( i = 0; checkSet[i] != null; i++ ) {
3886				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3887					results.push( set[i] );
3888				}
3889			}
3890		}
3891
3892	} else {
3893		makeArray( checkSet, results );
3894	}
3895
3896	if ( extra ) {
3897		Sizzle( extra, origContext, results, seed );
3898		Sizzle.uniqueSort( results );
3899	}
3900
3901	return results;
3902};
3903
3904Sizzle.uniqueSort = function( results ) {
3905	if ( sortOrder ) {
3906		hasDuplicate = baseHasDuplicate;
3907		results.sort( sortOrder );
3908
3909		if ( hasDuplicate ) {
3910			for ( var i = 1; i < results.length; i++ ) {
3911				if ( results[i] === results[ i - 1 ] ) {
3912					results.splice( i--, 1 );
3913				}
3914			}
3915		}
3916	}
3917
3918	return results;
3919};
3920
3921Sizzle.matches = function( expr, set ) {
3922	return Sizzle( expr, null, null, set );
3923};
3924
3925Sizzle.matchesSelector = function( node, expr ) {
3926	return Sizzle( expr, null, null, [node] ).length > 0;
3927};
3928
3929Sizzle.find = function( expr, context, isXML ) {
3930	var set;
3931
3932	if ( !expr ) {
3933		return [];
3934	}
3935
3936	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3937		var match,
3938			type = Expr.order[i];
3939		
3940		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3941			var left = match[1];
3942			match.splice( 1, 1 );
3943
3944			if ( left.substr( left.length - 1 ) !== "\\" ) {
3945				match[1] = (match[1] || "").replace( rBackslash, "" );
3946				set = Expr.find[ type ]( match, context, isXML );
3947
3948				if ( set != null ) {
3949					expr = expr.replace( Expr.match[ type ], "" );
3950					break;
3951				}
3952			}
3953		}
3954	}
3955
3956	if ( !set ) {
3957		set = typeof context.getElementsByTagName !== "undefined" ?
3958			context.getElementsByTagName( "*" ) :
3959			[];
3960	}
3961
3962	return { set: set, expr: expr };
3963};
3964
3965Sizzle.filter = function( expr, set, inplace, not ) {
3966	var match, anyFound,
3967		old = expr,
3968		result = [],
3969		curLoop = set,
3970		isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3971
3972	while ( expr && set.length ) {
3973		for ( var type in Expr.filter ) {
3974			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3975				var found, item,
3976					filter = Expr.filter[ type ],
3977					left = match[1];
3978
3979				anyFound = false;
3980
3981				match.splice(1,1);
3982
3983				if ( left.substr( left.length - 1 ) === "\\" ) {
3984					continue;
3985				}
3986
3987				if ( curLoop === result ) {
3988					result = [];
3989				}
3990
3991				if ( Expr.preFilter[ type ] ) {
3992					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3993
3994					if ( !match ) {
3995						anyFound = found = true;
3996
3997					} else if ( match === true ) {
3998						continue;
3999					}
4000				}
4001
4002				if ( match ) {
4003					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4004						if ( item ) {
4005							found = filter( item, match, i, curLoop );
4006							var pass = not ^ !!found;
4007
4008							if ( inplace && found != null ) {
4009								if ( pass ) {
4010									anyFound = true;
4011
4012								} else {
4013									curLoop[i] = false;
4014								}
4015
4016							} else if ( pass ) {
4017								result.push( item );
4018								anyFound = true;
4019							}
4020						}
4021					}
4022				}
4023
4024				if ( found !== undefined ) {
4025					if ( !inplace ) {
4026						curLoop = result;
4027					}
4028
4029					expr = expr.replace( Expr.match[ type ], "" );
4030
4031					if ( !anyFound ) {
4032						return [];
4033					}
4034
4035					break;
4036				}
4037			}
4038		}
4039
4040		// Improper expression
4041		if ( expr === old ) {
4042			if ( anyFound == null ) {
4043				Sizzle.error( expr );
4044
4045			} else {
4046				break;
4047			}
4048		}
4049
4050		old = expr;
4051	}
4052
4053	return curLoop;
4054};
4055
4056Sizzle.error = function( msg ) {
4057	throw "Syntax error, unrecognized expression: " + msg;
4058};
4059
4060var Expr = Sizzle.selectors = {
4061	order: [ "ID", "NAME", "TAG" ],
4062
4063	match: {
4064		ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4065		CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4066		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4067		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4068		TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4069		CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4070		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4071		PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4072	},
4073
4074	leftMatch: {},
4075
4076	attrMap: {
4077		"class": "className",
4078		"for": "htmlFor"
4079	},
4080
4081	attrHandle: {
4082		href: function( elem ) {
4083			return elem.getAttribute( "href" );
4084		},
4085		type: function( elem ) {
4086			return elem.getAttribute( "type" );
4087		}
4088	},
4089
4090	relative: {
4091		"+": function(checkSet, part){
4092			var isPartStr = typeof part === "string",
4093				isTag = isPartStr && !rNonWord.test( part ),
4094				isPartStrNotTag = isPartStr && !isTag;
4095
4096			if ( isTag ) {
4097				part = part.toLowerCase();
4098			}
4099
4100			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4101				if ( (elem = checkSet[i]) ) {
4102					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4103
4104					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4105						elem || false :
4106						elem === part;
4107				}
4108			}
4109
4110			if ( isPartStrNotTag ) {
4111				Sizzle.filter( part, checkSet, true );
4112			}
4113		},
4114
4115		">": function( checkSet, part ) {
4116			var elem,
4117				isPartStr = typeof part === "string",
4118				i = 0,
4119				l = checkSet.length;
4120
4121			if ( isPartStr && !rNonWord.test( part ) ) {
4122				part = part.toLowerCase();
4123
4124				for ( ; i < l; i++ ) {
4125					elem = checkSet[i];
4126
4127					if ( elem ) {
4128						var parent = elem.parentNode;
4129						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4130					}
4131				}
4132
4133			} else {
4134				for ( ; i < l; i++ ) {
4135					elem = checkSet[i];
4136
4137					if ( elem ) {
4138						checkSet[i] = isPartStr ?
4139							elem.parentNode :
4140							elem.parentNode === part;
4141					}
4142				}
4143
4144				if ( isPartStr ) {
4145					Sizzle.filter( part, checkSet, true );
4146				}
4147			}
4148		},
4149
4150		"": function(checkSet, part, isXML){
4151			var nodeCheck,
4152				doneName = done++,
4153				checkFn = dirCheck;
4154
4155			if ( typeof part === "string" && !rNonWord.test( part ) ) {
4156				part = part.toLowerCase();
4157				nodeCheck = part;
4158				checkFn = dirNodeCheck;
4159			}
4160
4161			checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4162		},
4163
4164		"~": function( checkSet, part, isXML ) {
4165			var nodeCheck,
4166				doneName = done++,
4167				checkFn = dirCheck;
4168
4169			if ( typeof part === "string" && !rNonWord.test( part ) ) {
4170				part = part.toLowerCase();
4171				nodeCheck = part;
4172				checkFn = dirNodeCheck;
4173			}
4174
4175			checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4176		}
4177	},
4178
4179	find: {
4180		ID: function( match, context, isXML ) {
4181			if ( typeof context.getElementById !== "undefined" && !isXML ) {
4182				var m = context.getElementById(match[1]);
4183				// Check parentNode to catch when Blackberry 4.6 returns
4184				// nodes that are no longer in the document #6963
4185				return m && m.parentNode ? [m] : [];
4186			}
4187		},
4188
4189		NAME: function( match, context ) {
4190			if ( typeof context.getElementsByName !== "undefined" ) {
4191				var ret = [],
4192					results = context.getElementsByName( match[1] );
4193
4194				for ( var i = 0, l = results.length; i < l; i++ ) {
4195					if ( results[i].getAttribute("name") === match[1] ) {
4196						ret.push( results[i] );
4197					}
4198				}
4199
4200				return ret.length === 0 ? null : ret;
4201			}
4202		},
4203
4204		TAG: function( match, context ) {
4205			if ( typeof context.getElementsByTagName !== "undefined" ) {
4206				return context.getElementsByTagName( match[1] );
4207			}
4208		}
4209	},
4210	preFilter: {
4211		CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4212			match = " " + match[1].replace( rBackslash, "" ) + " ";
4213
4214			if ( isXML ) {
4215				return match;
4216			}
4217
4218			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4219				if ( elem ) {
4220					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4221						if ( !inplace ) {
4222							result.push( elem );
4223						}
4224
4225					} else if ( inplace ) {
4226						curLoop[i] = false;
4227					}
4228				}
4229			}
4230
4231			return false;
4232		},
4233
4234		ID: function( match ) {
4235			return match[1].replace( rBackslash, "" );
4236		},
4237
4238		TAG: function( match, curLoop ) {
4239			return match[1].replace( rBackslash, "" ).toLowerCase();
4240		},
4241
4242		CHILD: function( match ) {
4243			if ( match[1] === "nth" ) {
4244				if ( !match[2] ) {
4245					Sizzle.error( match[0] );
4246				}
4247
4248				match[2] = match[2].replace(/^\+|\s*/g, '');
4249
4250				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4251				var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4252					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4253					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4254
4255				// calculate the numbers (first)n+(last) including if they are negative
4256				match[2] = (test[1] + (test[2] || 1)) - 0;
4257				match[3] = test[3] - 0;
4258			}
4259			else if ( match[2] ) {
4260				Sizzle.error( match[0] );
4261			}
4262
4263			// TODO: Move to normal caching system
4264			match[0] = done++;
4265
4266			return match;
4267		},
4268
4269		ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4270			var name = match[1] = match[1].replace( rBackslash, "" );
4271			
4272			if ( !isXML && Expr.attrMap[name] ) {
4273				match[1] = Expr.attrMap[name];
4274			}
4275
4276			// Handle if an un-quoted value was used
4277			match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4278
4279			if ( match[2] === "~=" ) {
4280				match[4] = " " + match[4] + " ";
4281			}
4282
4283			return match;
4284		},
4285
4286		PSEUDO: function( match, curLoop, inplace, result, not ) {
4287			if ( match[1] === "not" ) {
4288				// If we're dealing with a complex expression, or a simple one
4289				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4290					match[3] = Sizzle(match[3], null, null, curLoop);
4291
4292				} else {
4293					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4294
4295					if ( !inplace ) {
4296						result.push.apply( result, ret );
4297					}
4298
4299					return false;
4300				}
4301
4302			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4303				return true;
4304			}
4305			
4306			return match;
4307		},
4308
4309		POS: function( match ) {
4310			match.unshift( true );
4311
4312			return match;
4313		}
4314	},
4315	
4316	filters: {
4317		enabled: function( elem ) {
4318			return elem.disabled === false && elem.type !== "hidden";
4319		},
4320
4321		disabled: function( elem ) {
4322			return elem.disabled === true;
4323		},
4324
4325		checked: function( elem ) {
4326			return elem.checked === true;
4327		},
4328		
4329		selected: function( elem ) {
4330			// Accessing this property makes selected-by-default
4331			// options in Safari work properly
4332			if ( elem.parentNode ) {
4333				elem.parentNode.selectedIndex;
4334			}
4335			
4336			return elem.selected === true;
4337		},
4338
4339		parent: function( elem ) {
4340			return !!elem.firstChild;
4341		},
4342
4343		empty: function( elem ) {
4344			return !elem.firstChild;
4345		},
4346
4347		has: function( elem, i, match ) {
4348			return !!Sizzle( match[3], elem ).length;
4349		},
4350
4351		header: function( elem ) {
4352			return (/h\d/i).test( elem.nodeName );
4353		},
4354
4355		text: function( elem ) {
4356			var attr = elem.getAttribute( "type" ), type = elem.type;
4357			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 
4358			// use getAttribute instead to test this case
4359			return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4360		},
4361
4362		radio: function( elem ) {
4363			return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4364		},
4365
4366		checkbox: function( elem ) {
4367			return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4368		},
4369
4370		file: function( elem ) {
4371			return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4372		},
4373
4374		password: function( elem ) {
4375			return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4376		},
4377
4378		submit: function( elem ) {
4379			var name = elem.nodeName.toLowerCase();
4380			return (name === "input" || name === "button") && "submit" === elem.type;
4381		},
4382
4383		image: function( elem ) {
4384			return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4385		},
4386
4387		reset: function( elem ) {
4388			var name = elem.nodeName.toLowerCase();
4389			return (name === "input" || name === "button") && "reset" === elem.type;
4390		},
4391
4392		button: function( elem ) {
4393			var name = elem.nodeName.toLowerCase();
4394			return name === "input" && "button" === elem.type || name === "button";
4395		},
4396
4397		input: function( elem ) {
4398			return (/input|select|textarea|button/i).test( elem.nodeName );
4399		},
4400
4401		focus: function( elem ) {
4402			return elem === elem.ownerDocument.activeElement;
4403		}
4404	},
4405	setFilters: {
4406		first: function( elem, i ) {
4407			return i === 0;
4408		},
4409
4410		last: function( elem, i, match, array ) {
4411			return i === array.length - 1;
4412		},
4413
4414		even: function( elem, i ) {
4415			return i % 2 === 0;
4416		},
4417
4418		odd: function( elem, i ) {
4419			return i % 2 === 1;
4420		},
4421
4422		lt: function( elem, i, match ) {
4423			return i < match[3] - 0;
4424		},
4425
4426		gt: function( elem, i, match ) {
4427			return i > match[3] - 0;
4428		},
4429
4430		nth: function( elem, i, match ) {
4431			return match[3] - 0 === i;
4432		},
4433
4434		eq: function( elem, i, match ) {
4435			return match[3] - 0 === i;
4436		}
4437	},
4438	filter: {
4439		PSEUDO: function( elem, match, i, array ) {
4440			var name = match[1],
4441				filter = Expr.filters[ name ];
4442
4443			if ( filter ) {
4444				return filter( elem, i, match, array );
4445
4446			} else if ( name === "contains" ) {
4447				return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4448
4449			} else if ( name === "not" ) {
4450				var not = match[3];
4451
4452				for ( var j = 0, l = not.length; j < l; j++ ) {
4453					if ( not[j] === elem ) {
4454						return false;
4455					}
4456				}
4457
4458				return true;
4459
4460			} else {
4461				Sizzle.error( name );
4462			}
4463		},
4464
4465		CHILD: function( elem, match ) {
4466			var type = match[1],
4467				node = elem;
4468
4469			switch ( type ) {
4470				case "only":
4471				case "first":
4472					while ( (node = node.previousSibling) )	 {
4473						if ( node.nodeType === 1 ) { 
4474							return false; 
4475						}
4476					}
4477
4478					if ( type === "first" ) { 
4479						return true; 
4480					}
4481
4482					node = elem;
4483
4484				case "last":
4485					while ( (node = node.nextSibling) )	 {
4486						if ( node.nodeType === 1 ) { 
4487							return false; 
4488						}
4489					}
4490
4491					return true;
4492
4493				case "nth":
4494					var first = match[2],
4495						last = match[3];
4496
4497					if ( first === 1 && last === 0 ) {
4498						return true;
4499					}
4500					
4501					var doneName = match[0],
4502						parent = elem.parentNode;
4503	
4504					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4505						var count = 0;
4506						
4507						for ( node = parent.firstChild; node; node = node.nextSibling ) {
4508							if ( node.nodeType === 1 ) {
4509								node.nodeIndex = ++count;
4510							}
4511						} 
4512
4513						parent.sizcache = doneName;
4514					}
4515					
4516					var diff = elem.nodeIndex - last;
4517
4518					if ( first === 0 ) {
4519						return diff === 0;
4520
4521					} else {
4522						return ( diff % first === 0 && diff / first >= 0 );
4523					}
4524			}
4525		},
4526
4527		ID: function( elem, match ) {
4528			return elem.nodeType === 1 && elem.getAttribute("id") === match;
4529		},
4530
4531		TAG: function( elem, match ) {
4532			return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
4533		},
4534		
4535		CLASS: function( elem, match ) {
4536			return (" " + (elem.className || elem.getAttribute("class")) + " ")
4537				.indexOf( match ) > -1;
4538		},
4539
4540		ATTR: function( elem, match ) {
4541			var name = match[1],
4542				result = Expr.attrHandle[ name ] ?
4543					Expr.attrHandle[ name ]( elem ) :
4544					elem[ name ] != null ?
4545						elem[ name ] :
4546						elem.getAttribute( name ),
4547				value = result + "",
4548				type = match[2],
4549				check = match[4];
4550
4551			return result == null ?
4552				type === "!=" :
4553				type === "=" ?
4554				value === check :
4555				type === "*=" ?
4556				value.indexOf(check) >= 0 :
4557				type === "~=" ?
4558				(" " + value + " ").indexOf(check) >= 0 :
4559				!check ?
4560				value && result !== false :
4561				type === "!=" ?
4562				value !== check :
4563				type === "^=" ?
4564				value.indexOf(check) === 0 :
4565				type === "$=" ?
4566				value.substr(value.length - check.length) === check :
4567				type === "|=" ?
4568				value === check || value.substr(0, check.length + 1) === check + "-" :
4569				false;
4570		},
4571
4572		POS: function( elem, match, i, array ) {
4573			var name = match[2],
4574				filter = Expr.setFilters[ name ];
4575
4576			if ( filter ) {
4577				return filter( elem, i, match, array );
4578			}
4579		}
4580	}
4581};
4582
4583var origPOS = Expr.match.POS,
4584	fescape = function(all, num){
4585		return "\\" + (num - 0 + 1);
4586	};
4587
4588for ( var type in Expr.match ) {
4589	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4590	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4591}
4592
4593var makeArray = function( array, results ) {
4594	array = Array.prototype.slice.call( array, 0 );
4595
4596	if ( results ) {
4597		results.push.apply( results, array );
4598		return results;
4599	}
4600	
4601	return array;
4602};
4603
4604// Perform a simple check to determine if the browser is capable of
4605// converting a NodeList to an array using builtin methods.
4606// Also verifies that the returned array holds DOM nodes
4607// (which is not the case in the Blackberry browser)
4608try {
4609	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4610
4611// Provide a fallback method if it does not work
4612} catch( e ) {
4613	makeArray = function( array, results ) {
4614		var i = 0,
4615			ret = results || [];
4616
4617		if ( toString.call(array) === "[object Array]" ) {
4618			Array.prototype.push.apply( ret, array );
4619
4620		} else {
4621			if ( typeof array.length === "number" ) {
4622				for ( var l = array.length; i < l; i++ ) {
4623					ret.push( array[i] );
4624				}
4625
4626			} else {
4627				for ( ; array[i]; i++ ) {
4628					ret.push( array[i] );
4629				}
4630			}
4631		}
4632
4633		return ret;
4634	};
4635}
4636
4637var sortOrder, siblingCheck;
4638
4639if ( document.documentElement.compareDocumentPosition ) {
4640	sortOrder = function( a, b ) {
4641		if ( a === b ) {
4642			hasDuplicate = true;
4643			return 0;
4644		}
4645
4646		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4647			return a.compareDocumentPosition ? -1 : 1;
4648		}
4649
4650		return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4651	};
4652
4653} else {
4654	sortOrder = function( a, b ) {
4655		// The nodes are identical, we can exit early
4656		if ( a === b ) {
4657			hasDuplicate = true;
4658			return 0;
4659
4660		// Fallback to using sourceIndex (in IE) if it's available on both nodes
4661		} else if ( a.sourceIndex && b.sourceIndex ) {
4662			return a.sourceIndex - b.sourceIndex;
4663		}
4664
4665		var al, bl,
4666			ap = [],
4667			bp = [],
4668			aup = a.parentNode,
4669			bup = b.parentNode,
4670			cur = aup;
4671
4672		// If the nodes are siblings (or identical) we can do a quick check
4673		if ( aup === bup ) {
4674			return siblingCheck( a, b );
4675
4676		// If no parents were found then the nodes are disconnected
4677		} else if ( !aup ) {
4678			return -1;
4679
4680		} else if ( !bup ) {
4681			return 1;
4682		}
4683
4684		// Otherwise they're somewhere else in the tree so we need
4685		// to build up a full list of the parentNodes for comparison
4686		while ( cur ) {
4687			ap.unshift( cur );
4688			cur = cur.parentNode;
4689		}
4690
4691		cur = bup;
4692
4693		while ( cur ) {
4694			bp.unshift( cur );
4695			cur = cur.parentNode;
4696		}
4697
4698		al = ap.length;
4699		bl = bp.length;
4700
4701		// Start walking down the tree looking for a discrepancy
4702		for ( var i = 0; i < al && i < bl; i++ ) {
4703			if ( ap[i] !== bp[i] ) {
4704				return siblingCheck( ap[i], bp[i] );
4705			}
4706		}
4707
4708		// We ended someplace up the tree so do a sibling check
4709		return i === al ?
4710			siblingCheck( a, bp[i], -1 ) :
4711			siblingCheck( ap[i], b, 1 );
4712	};
4713
4714	siblingCheck = function( a, b, ret ) {
4715		if ( a === b ) {
4716			return ret;
4717		}
4718
4719		var cur = a.nextSibling;
4720
4721		while ( cur ) {
4722			if ( cur === b ) {
4723				return -1;
4724			}
4725
4726			cur = cur.nextSibling;
4727		}
4728
4729		return 1;
4730	};
4731}
4732
4733// Utility function for retreiving the text value of an array of DOM nodes
4734Sizzle.getText = function( elems ) {
4735	var ret = "", elem;
4736
4737	for ( var i = 0; elems[i]; i++ ) {
4738		elem = elems[i];
4739
4740		// Get the text from text nodes and CDATA nodes
4741		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4742			ret += elem.nodeValue;
4743
4744		// Traverse everything else, except comment nodes
4745		} else if ( elem.nodeType !== 8 ) {
4746			ret += Sizzle.getText( elem.childNodes );
4747		}
4748	}
4749
4750	return ret;
4751};
4752
4753// Check to see if the browser returns elements by name when
4754// querying by getElementById (and provide a workaround)
4755(function(){
4756	// We're going to inject a fake input element with a specified name
4757	var form = document.createElement("div"),
4758		id = "script" + (new Date()).getTime(),
4759		root = document.documentElement;
4760
4761	form.innerHTML = "<a name='" + id + "'/>";
4762
4763	// Inject it into the root element, check its status, and remove it quickly
4764	root.insertBefore( form, root.firstChild );
4765
4766	// The workaround has to do additional checks after a getElementById
4767	// Which slows things down for other browsers (hence the branching)
4768	if ( document.getElementById( id ) ) {
4769		Expr.find.ID = function( match, context, isXML ) {
4770			if ( typeof context.getElementById !== "undefined" && !isXML ) {
4771				var m = context.getElementById(match[1]);
4772
4773				return m ?
4774					m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4775						[m] :
4776						undefined :
4777					[];
4778			}
4779		};
4780
4781		Expr.filter.ID = function( elem, match ) {
4782			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4783
4784			return elem.nodeType === 1 && node && node.nodeValue === match;
4785		};
4786	}
4787
4788	root.removeChild( form );
4789
4790	// release memory in IE
4791	root = form = null;
4792})();
4793
4794(function(){
4795	// Check to see if the browser returns only elements
4796	// when doing getElementsByTagName("*")
4797
4798	// Create a fake element
4799	var div = document.createElement("div");
4800	div.appendChild( document.createComment("") );
4801
4802	// Make sure no comments are found
4803	if ( div.getElementsByTagName("*").length > 0 ) {
4804		Expr.find.TAG = function( match, context ) {
4805			var results = context.getElementsByTagName( match[1] );
4806
4807			// Filter out possible comments
4808			if ( match[1] === "*" ) {
4809				var tmp = [];
4810
4811				for ( var i = 0; results[i]; i++ ) {
4812					if ( results[i].nodeType === 1 ) {
4813						tmp.push( results[i] );
4814					}
4815				}
4816
4817				results = tmp;
4818			}
4819
4820			return results;
4821		};
4822	}
4823
4824	// Check to see if an attribute returns normalized href attributes
4825	div.innerHTML = "<a href='#'></a>";
4826
4827	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4828			div.firstChild.getAttribute("href") !== "#" ) {
4829
4830		Expr.attrHandle.href = function( elem ) {
4831			return elem.getAttribute( "href", 2 );
4832		};
4833	}
4834
4835	// release memory in IE
4836	div = null;
4837})();
4838
4839if ( document.querySelectorAll ) {
4840	(function(){
4841		var oldSizzle = Sizzle,
4842			div = document.createElement("div"),
4843			id = "__sizzle__";
4844
4845		div.innerHTML = "<p class='TEST'></p>";
4846
4847		// Safari can't handle uppercase or unicode characters when
4848		// in quirks mode.
4849		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4850			return;
4851		}
4852	
4853		Sizzle = function( query, context, extra, seed ) {
4854			context = context || document;
4855
4856			// Only use querySelectorAll on non-XML documents
4857			// (ID selectors don't work in non-HTML documents)
4858			if ( !seed && !Sizzle.isXML(context) ) {
4859				// See if we find a selector to speed up
4860				var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4861				
4862				if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4863					// Speed-up: Sizzle("TAG")
4864					if ( match[1] ) {
4865						return makeArray( context.getElementsByTagName( query ), extra );
4866					
4867					// Speed-up: Sizzle(".CLASS")
4868					} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4869						return makeArray( context.getElementsByClassName( match[2] ), extra );
4870					}
4871				}
4872				
4873				if ( context.nodeType === 9 ) {
4874					// Speed-up: Sizzle("body")
4875					// The body element only exists once, optimize finding it
4876					if ( query === "body" && context.body ) {
4877						return makeArray( [ context.body ], extra );
4878						
4879					// Speed-up: Sizzle("#ID")
4880					} else if ( match && match[3] ) {
4881						var elem = context.getElementById( match[3] );
4882
4883						// Check parentNode to catch when Blackberry 4.6 returns
4884						// nodes that are no longer in the document #6963
4885						if ( elem && elem.parentNode ) {
4886							// Handle the case where IE and Opera return items
4887							// by name instead of ID
4888							if ( elem.id === match[3] ) {
4889								return makeArray( [ elem ], extra );
4890							}
4891							
4892						} else {
4893							return makeArray( [], extra );
4894						}
4895					}
4896					
4897					try {
4898						return makeArray( context.querySelectorAll(query), extra );
4899					} catch(qsaError) {}
4900
4901				// qSA works strangely on Element-rooted queries
4902				// We can work around this by specifying an extra ID on the root
4903				// and working up from there (Thanks to Andrew Dupont for the technique)
4904				// IE 8 doesn't work on object elements
4905				} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4906					var oldContext = context,
4907						old = context.getAttribute( "id" ),
4908						nid = old || id,
4909						hasParent = context.parentNode,
4910						relativeHierarchySelector = /^\s*[+~]/.test( query );
4911
4912					if ( !old ) {
4913						context.setAttribute( "id", nid );
4914					} else {
4915						nid = nid.replace( /'/g, "\\$&" );
4916					}
4917					if ( relativeHierarchySelector && hasParent ) {
4918						context = context.parentNode;
4919					}
4920
4921					try {
4922						if ( !relativeHierarchySelector || hasParent ) {
4923							return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4924						}
4925
4926					} catch(pseudoError) {
4927					} finally {
4928						if ( !old ) {
4929							oldContext.removeAttribute( "id" );
4930						}
4931					}
4932				}
4933			}
4934		
4935			return oldSizzle(query, context, extra, seed);
4936		};
4937
4938		for ( var prop in oldSizzle ) {
4939			Sizzle[ prop ] = oldSizzle[ prop ];
4940		}
4941
4942		// release memory in IE
4943		div = null;
4944	})();
4945}
4946
4947(function(){
4948	var html = document.documentElement,
4949		matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
4950
4951	if ( matches ) {
4952		// Check to see if it's possible to do matchesSelector
4953		// on a disconnected node (IE 9 fails this)
4954		var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
4955			pseudoWorks = false;
4956
4957		try {
4958			// This should fail with an exception
4959			// Gecko does not error, returns false instead
4960			matches.call( document.documentElement, "[test!='']:sizzle" );
4961	
4962		} catch( pseudoError ) {
4963			pseudoWorks = true;
4964		}
4965
4966		Sizzle.matchesSelector = function( node, expr ) {
4967			// Make sure that attribute selectors are quoted
4968			expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4969
4970			if ( !Sizzle.isXML( node ) ) {
4971				try { 
4972					if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4973						var ret = matches.call( node, expr );
4974
4975						// IE 9's matchesSelector returns false on disconnected nodes
4976						if ( ret || !disconnectedMatch ||
4977								// As well, disconnected nodes are said to be in a document
4978								// fragment in IE 9, so check for that
4979								node.document && node.document.nodeType !== 11 ) {
4980							return ret;
4981						}
4982					}
4983				} catch(e) {}
4984			}
4985
4986			return Sizzle(expr, null, null, [node]).length > 0;
4987		};
4988	}
4989})();
4990
4991(function(){
4992	var div = document.createElement("div");
4993
4994	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4995
4996	// Opera can't find a second classname (in 9.6)
4997	// Also, make sure that getElementsByClassName actually exists
4998	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4999		return;
5000	}
5001
5002	// Safari caches class attributes, doesn't catch changes (in 3.2)
5003	div.lastChild.className = "e";
5004
5005	if ( div.getElementsByClassName("e").length === 1 ) {
5006		return;
5007	}
5008	
5009	Expr.order.splice(1, 0, "CLASS");
5010	Expr.find.CLASS = function( match, context, isXML ) {
5011		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5012			return context.getElementsByClassName(match[1]);
5013		}
5014	};
5015
5016	// release memory in IE
5017	div = null;
5018})();
5019
5020function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5021	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5022		var elem = checkSet[i];
5023
5024		if ( elem ) {
5025			var match = false;
5026
5027			elem = elem[dir];
5028
5029			while ( elem ) {
5030				if ( elem.sizcache === doneName ) {
5031					match = checkSet[elem.sizset];
5032					break;
5033				}
5034
5035				if ( elem.nodeType === 1 && !isXML ){
5036					elem.sizcache = doneName;
5037					elem.sizset = i;
5038				}
5039
5040				if ( elem.nodeName.toLowerCase() === cur ) {
5041					match = elem;
5042					break;
5043				}
5044
5045				elem = elem[dir];
5046			}
5047
5048			checkSet[i] = match;
5049		}
5050	}
5051}
5052
5053function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5054	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5055		var elem = checkSet[i];
5056
5057		if ( elem ) {
5058			var match = false;
5059			
5060			elem = elem[dir];
5061
5062			while ( elem ) {
5063				if ( elem.sizcache === doneName ) {
5064					match = checkSet[elem.sizset];
5065					break;
5066				}
5067
5068				if ( elem.nodeType === 1 ) {
5069					if ( !isXML ) {
5070						elem.sizcache = doneName;
5071						elem.sizset = i;
5072					}
5073
5074					if ( typeof cur !== "string" ) {
5075						if ( elem === cur ) {
5076							match = true;
5077							break;
5078						}
5079
5080					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5081						match = elem;
5082						break;
5083					}
5084				}
5085
5086				elem = elem[dir];
5087			}
5088
5089			checkSet[i] = match;
5090		}
5091	}
5092}
5093
5094if ( document.documentElement.contains ) {
5095	Sizzle.contains = function( a, b ) {
5096		return a !== b && (a.contains ? a.contains(b) : true);
5097	};
5098
5099} else if ( document.documentElement.compareDocumentPosition ) {
5100	Sizzle.contains = function( a, b ) {
5101		return !!(a.compareDocumentPosition(b) & 16);
5102	};
5103
5104} else {
5105	Sizzle.contains = function() {
5106		return false;
5107	};
5108}
5109
5110Sizzle.isXML = function( elem ) {
5111	// documentElement is verified for cases where it doesn't yet exist
5112	// (such as loading iframes in IE - #4833) 
5113	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5114
5115	return documentElement ? documentElement.nodeName !== "HTML" : false;
5116};
5117
5118var posProcess = function( selector, context ) {
5119	var match,
5120		tmpSet = [],
5121		later = "",
5122		root = context.nodeType ? [context] : context;
5123
5124	// Position selectors must be done after the filter
5125	// And so must :not(positional) so we move all PSEUDOs to the end
5126	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5127		later += match[0];
5128		selector = selector.replace( Expr.match.PSEUDO, "" );
5129	}
5130
5131	selector = Expr.relative[selector] ? selector + "*" : selector;
5132
5133	for ( var i = 0, l = root.length; i < l; i++ ) {
5134		Sizzle( selector, root[i], tmpSet );
5135	}
5136
5137	return Sizzle.filter( later, tmpSet );
5138};
5139
5140// EXPOSE
5141jQuery.find = Sizzle;
5142jQuery.expr = Sizzle.selectors;
5143jQuery.expr[":"] = jQuery.expr.filters;
5144jQuery.unique = Sizzle.uniqueSort;
5145jQuery.text = Sizzle.getText;
5146jQuery.isXMLDoc = Sizzle.isXML;
5147jQuery.contains = Sizzle.contains;
5148
5149
5150})();
5151
5152
5153var runtil = /Until$/,
5154	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5155	// Note: This RegExp should be improved, or likely pulled from Sizzle
5156	rmultiselector = /,/,
5157	isSimple = /^.[^:#\[\.,]*$/,
5158	slice = Array.prototype.slice,
5159	POS = jQuery.expr.match.POS,
5160	// methods guaranteed to produce a unique set when starting from a unique set
5161	guaranteedUnique = {
5162		children: true,
5163		contents: true,
5164		next: true,
5165		prev: true
5166	};
5167
5168jQuery.fn.extend({
5169	find: function( selector ) {
5170		var self = this,
5171			i, l;
5172
5173		if ( typeof selector !== "string" ) {
5174			return jQuery( selector ).filter(function() {
5175				for ( i = 0, l = self.length; i < l; i++ ) {
5176					if ( jQuery.contains( self[ i ], this ) ) {
5177						return true;
5178					}
5179				}
5180			});
5181		}
5182
5183		var ret = this.pushStack( "", "find", selector ),
5184			length, n, r;
5185
5186		for ( i = 0, l = this.length; i < l; i++ ) {
5187			length = ret.length;
5188			jQuery.find( selector, this[i], ret );
5189
5190			if ( i > 0 ) {
5191				// Make sure that the results are unique
5192				for ( n = length; n < ret.length; n++ ) {
5193					for ( r = 0; r < length; r++ ) {
5194						if ( ret[r] === ret[n] ) {
5195							ret.splice(n--, 1);
5196							break;
5197						}
5198					}
5199				}
5200			}
5201		}
5202
5203		return ret;
5204	},
5205
5206	has: function( target ) {
5207		var targets = jQuery( target );
5208		return this.filter(function() {
5209			for ( var i = 0, l = targets.length; i < l; i++ ) {
5210				if ( jQuery.contains( this, targets[i] ) ) {
5211					return true;
5212				}
5213			}
5214		});
5215	},
5216
5217	not: function( selector ) {
5218		return this.pushStack( winnow(this, selector, false), "not", selector);
5219	},
5220
5221	filter: function( selector ) {
5222		return this.pushStack( winnow(this, selector, true), "filter", selector );
5223	},
5224
5225	is: function( selector ) {
5226		return !!selector && ( typeof selector === "string" ?
5227			jQuery.filter( selector, this ).length > 0 :
5228			this.filter( selector ).length > 0 );
5229	},
5230
5231	closest: function( selectors, context ) {
5232		var ret = [], i, l, cur = this[0];
5233		
5234		// Array
5235		if ( jQuery.isArray( selectors ) ) {
5236			var match, selector,
5237				matches = {},
5238				level = 1;
5239
5240			if ( cur && selectors.length ) {
5241				for ( i = 0, l = selectors.length; i < l; i++ ) {
5242					selector = selectors[i];
5243
5244					if ( !matches[ selector ] ) {
5245						matches[ selector ] = POS.test( selector ) ?
5246							jQuery( selector, context || this.context ) :
5247							selector;
5248					}
5249				}
5250
5251				while ( cur && cur.ownerDocument && cur !== context ) {
5252					for ( selector in matches ) {
5253						match = matches[ selector ];
5254
5255						if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5256							ret.push({ selector: selector, elem: cur, level: level });
5257						}
5258					}
5259
5260					cur = cur.parentNode;
5261					level++;
5262				}
5263			}
5264
5265			return ret;
5266		}
5267
5268		// String
5269		var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5270				jQuery( selectors, context || this.context ) :
5271				0;
5272
5273		for ( i = 0, l = this.length; i < l; i++ ) {
5274			cur = this[i];
5275
5276			while ( cur ) {
5277				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5278					ret.push( cur );
5279					break;
5280
5281				} else {
5282					cur = cur.parentNode;
5283					if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5284						break;
5285					}
5286				}
5287			}
5288		}
5289
5290		ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5291
5292		return this.pushStack( ret, "closest", selectors );
5293	},
5294
5295	// Determine the position of an element within
5296	// the matched set of elements
5297	index: function( elem ) {
5298		if ( !elem || typeof elem === "string" ) {
5299			return jQuery.inArray( this[0],
5300				// If it receives a string, the selector is used
5301				// If it receives nothing, the siblings are used
5302				elem ? jQuery( elem ) : this.parent().children() );
5303		}
5304		// Locate the position of the desired element
5305		return jQuery.inArray(
5306			// If it receives a jQuery object, the first element is used
5307			elem.jquery ? elem[0] : elem, this );
5308	},
5309
5310	add: function( selector, context ) {
5311		var set = typeof selector === "string" ?
5312				jQuery( selector, context ) :
5313				jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5314			all = jQuery.merge( this.get(), set );
5315
5316		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5317			all :
5318			jQuery.unique( all ) );
5319	},
5320
5321	andSelf: function() {
5322		return this.add( this.prevObject );
5323	}
5324});
5325
5326// A painfully simple check to see if an element is disconnected
5327// from a document (should be improved, where feasible).
5328function isDisconnected( node ) {
5329	return !node || !node.parentNode || node.parentNode.nodeType === 11;
5330}
5331
5332jQuery.each({
5333	parent: function( elem ) {
5334		var parent = elem.parentNode;
5335		return parent && parent.nodeType !== 11 ? parent : null;
5336	},
5337	parents: function( elem ) {
5338		return jQuery.dir( elem, "parentNode" );
5339	},
5340	parentsUntil: function( elem, i, until ) {
5341		return jQuery.dir( elem, "parentNode", until );
5342	},
5343	next: function( elem ) {
5344		return jQuery.nth( elem, 2, "nextSibling" );
5345	},
5346	prev: function( elem ) {
5347		return jQuery.nth( elem, 2, "previousSibling" );
5348	},
5349	nextAll: function( elem ) {
5350		return jQuery.dir( elem, "nextSibling" );
5351	},
5352	prevAll: function( elem ) {
5353		return jQuery.dir( elem, "previousSibling" );
5354	},
5355	nextUntil: function( elem, i, until ) {
5356		return jQuery.dir( elem, "nextSibling", until );
5357	},
5358	prevUntil: function( elem, i, until ) {
5359		return jQuery.dir( elem, "previousSibling", until );
5360	},
5361	siblings: function( elem ) {
5362		return jQuery.sibling( elem.parentNode.firstChild, elem );
5363	},
5364	children: function( elem ) {
5365		return jQuery.sibling( elem.firstChild );
5366	},
5367	contents: function( elem ) {
5368		return jQuery.nodeName( elem, "iframe" ) ?
5369			elem.contentDocument || elem.contentWindow.document :
5370			jQuery.makeArray( elem.childNodes );
5371	}
5372}, function( name, fn ) {
5373	jQuery.fn[ name ] = function( until, selector ) {
5374		var ret = jQuery.map( this, fn, until ),
5375			// The variable 'args' was introduced in
5376			// https://github.com/jquery/jquery/commit/52a0238
5377			// to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5378			// http://code.google.com/p/v8/issues/detail?id=1050
5379			args = slice.call(arguments);
5380
5381		if ( !runtil.test( name ) ) {
5382			selector = until;
5383		}
5384
5385		if ( selector && typeof selector === "string" ) {
5386			ret = jQuery.filter( selector, ret );
5387		}
5388
5389		ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5390
5391		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5392			ret = ret.reverse();
5393		}
5394
5395		return this.pushStack( ret, name, args.join(",") );
5396	};
5397});
5398
5399jQuery.extend({
5400	filter: function( expr, elems, not ) {
5401		if ( not ) {
5402			expr = ":not(" + expr + ")";
5403		}
5404
5405		return elems.length === 1 ?
5406			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5407			jQuery.find.matches(expr, elems);
5408	},
5409
5410	dir: function( elem, dir, until ) {
5411		var matched = [],
5412			cur = elem[ dir ];
5413
5414		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5415			if ( cur.nodeType === 1 ) {
5416				matched.push( cur );
5417			}
5418			cur = cur[dir];
5419		}
5420		return matched;
5421	},
5422
5423	nth: function( cur, result, dir, elem ) {
5424		result = result || 1;
5425		var num = 0;
5426
5427		for ( ; cur; cur = cur[dir] ) {
5428			if ( cur.nodeType === 1 && ++num === result ) {
5429				break;
5430			}
5431		}
5432
5433		return cur;
5434	},
5435
5436	sibling: function( n, elem ) {
5437		var r = [];
5438
5439		for ( ; n; n = n.nextSibling ) {
5440			if ( n.nodeType === 1 && n !== elem ) {
5441				r.push( n );
5442			}
5443		}
5444
5445		return r;
5446	}
5447});
5448
5449// Implement the identical functionality for filter and not
5450function winnow( elements, qualifier, keep ) {
5451
5452	// Can't pass null or undefined to indexOf in Firefox 4
5453	// Set to 0 to skip string check
5454	qualifier = qualifier || 0;
5455
5456	if ( jQuery.isFunction( qualifier ) ) {
5457		return jQuery.grep(elements, function( elem, i ) {
5458			var retVal = !!qualifier.call( elem, i, elem );
5459			return retVal === keep;
5460		});
5461
5462	} else if ( qualifier.nodeType ) {
5463		return jQuery.grep(elements, function( elem, i ) {
5464			return (elem === qualifier) === keep;
5465		});
5466
5467	} else if ( typeof qualifier === "string" ) {
5468		var filtered = jQuery.grep(elements, function( elem ) {
5469			return elem.nodeType === 1;
5470		});
5471
5472		if ( isSimple.test( qualifier ) ) {
5473			return jQuery.filter(qualifier, filtered, !keep);
5474		} else {
5475			qualifier = jQuery.filter( qualifier, filtered );
5476		}
5477	}
5478
5479	return jQuery.grep(elements, function( elem, i ) {
5480		return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5481	});
5482}
5483
5484
5485
5486
5487var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5488	rleadingWhitespace = /^\s+/,
5489	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5490	rtagName = /<([\w:]+)/,
5491	rtbody = /<tbody/i,
5492	rhtml = /<|&#?\w+;/,
5493	rnocache = /<(?:script|object|embed|option|style)/i,
5494	// checked="checked" or checked
5495	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5496	rscriptType = /\/(java|ecma)script/i,
5497	rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5498	wrapMap = {
5499		option: [ 1, "<select multiple='multiple'>", "</select>" ],
5500		legend: [ 1, "<fieldset>", "</fieldset>" ],
5501		thead: [ 1, "<table>", "</table>" ],
5502		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5503		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5504		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5505		area: [ 1, "<map>", "</map>" ],
5506		_default: [ 0, "", "" ]
5507	};
5508
5509wrapMap.optgroup = wrapMap.option;
5510wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5511wrapMap.th = wrapMap.td;
5512
5513// IE can't serialize <link> and <script> tags normally
5514if ( !jQuery.support.htmlSerialize ) {
5515	wrapMap._default = [ 1, "div<div>", "</div>" ];
5516}
5517
5518jQuery.fn.extend({
5519	text: function( text ) {
5520		if ( jQuery.isFunction(text) ) {
5521			return this.each(function(i) {
5522				var self = jQuery( this );
5523
5524				self.text( text.call(this, i, self.text()) );
5525			});
5526		}
5527
5528		if ( typeof text !== "object" && text !== undefined ) {
5529			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5530		}
5531
5532		return jQuery.text( this );
5533	},
5534
5535	wrapAll: function( html ) {
5536		if ( jQuery.isFunction( html ) ) {
5537			return this.each(function(i) {
5538				jQuery(this).wrapAll( html.call(this, i) );
5539			});
5540		}
5541
5542		if ( this[0] ) {
5543			// The elements to wrap the target around
5544			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5545
5546			if ( this[0].parentNode ) {
5547				wrap.insertBefore( this[0] );
5548			}
5549
5550			wrap.map(function() {
5551				var elem = this;
5552
5553				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5554					elem = elem.firstChild;
5555				}
5556
5557				return elem;
5558			}).append( this );
5559		}
5560
5561		return this;
5562	},
5563
5564	wrapInner: function( html ) {
5565		if ( jQuery.isFunction( html ) ) {
5566			return this.each(function(i) {
5567				jQuery(this).wrapInner( html.call(this, i) );
5568			});
5569		}
5570
5571		return this.each(function() {
5572			var self = jQuery( this ),
5573				contents = self.contents();
5574
5575			if ( contents.length ) {
5576				contents.wrapAll( html );
5577
5578			} else {
5579				self.append( html );
5580			}
5581		});
5582	},
5583
5584	wrap: function( html ) {
5585		return this.each(function() {
5586			jQuery( this ).wrapAll( html );
5587		});
5588	},
5589
5590	unwrap: function() {
5591		return this.parent().each(function() {
5592			if ( !jQuery.nodeName( this, "body" ) ) {
5593				jQuery( this ).replaceWith( this.childNodes );
5594			}
5595		}).end();
5596	},
5597
5598	append: function() {
5599		return this.domManip(arguments, true, function( elem ) {
5600			if ( this.nodeType === 1 ) {
5601				this.appendChild( elem );
5602			}
5603		});
5604	},
5605
5606	prepend: function() {
5607		return this.domManip(arguments, true, function( elem ) {
5608			if ( this.nodeType === 1 ) {
5609				this.insertBefore( elem, this.firstChild );
5610			}
5611		});
5612	},
5613
5614	before: function() {
5615		if ( this[0] && this[0].parentNode ) {
5616			return this.domManip(arguments, false, function( elem ) {
5617				this.parentNode.insertBefore( elem, this );
5618			});
5619		} else if ( arguments.length ) {
5620			var set = jQuery(arguments[0]);
5621			set.push.apply( set, this.toArray() );
5622			return this.pushStack( set, "before", arguments );
5623		}
5624	},
5625
5626	after: function() {
5627		if ( this[0] && this[0].parentNode ) {
5628			return this.domManip(arguments, false, function( elem ) {
5629				this.parentNode.insertBefore( elem, this.nextSibling );
5630			});
5631		} else if ( arguments.length ) {
5632			var set = this.pushStack( this, "after", arguments );
5633			set.push.apply( set, jQuery(arguments[0]).toArray() );
5634			return set;
5635		}
5636	},
5637
5638	// keepData is for internal use only--do not document
5639	remove: function( selector, keepData ) {
5640		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5641			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5642				if ( !keepData && elem.nodeType === 1 ) {
5643					jQuery.cleanData( elem.getElementsByTagName("*") );
5644					jQuery.cleanData( [ elem ] );
5645				}
5646
5647				if ( elem.parentNode ) {
5648					elem.parentNode.removeChild( elem );
5649				}
5650			}
5651		}
5652
5653		return this;
5654	},
5655
5656	empty: function() {
5657		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5658			// Remove element nodes and prevent memory leaks
5659			if ( elem.nodeType === 1 ) {
5660				jQuery.cleanData( elem.getElementsByTagName("*") );
5661			}
5662
5663			// Remove any remaining nodes
5664			while ( elem.firstChild ) {
5665				elem.removeChild( elem.firstChild );
5666			}
5667		}
5668
5669		return this;
5670	},
5671
5672	clone: function( dataAndEvents, deepDataAndEvents ) {
5673		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5674		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5675
5676		return this.map( function () {
5677			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5678		});
5679	},
5680
5681	html: function( value ) {
5682		if ( value === undefined ) {
5683			return this[0] && this[0].nodeType === 1 ?
5684				this[0].innerHTML.replace(rinlinejQuery, "") :
5685				null;
5686
5687		// See if we can take a shortcut and just use innerHTML
5688		} else if ( typeof value === "string" && !rnocache.test( value ) &&
5689			(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5690			!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5691
5692			value = value.replace(rxhtmlTag, "<$1></$2>");
5693
5694			try {
5695				for ( var i = 0, l = this.length; i < l; i++ ) {
5696					// Remove element nodes and prevent memory leaks
5697					if ( this[i].nodeType === 1 ) {
5698						jQuery.cleanData( this[i].getElementsByTagName("*") );
5699						this[i].innerHTML = value;
5700					}
5701				}
5702
5703			// If using innerHTML throws an exception, use the fallback method
5704			} catch(e) {
5705				this.empty().append( value );
5706			}
5707
5708		} else if ( jQuery.isFunction( value ) ) {
5709			this.each(function(i){
5710				var self = jQuery( this );
5711
5712				self.html( value.call(this, i, self.html()) );
5713			});
5714
5715		} else {
5716			this.empty().append( value );
5717		}
5718
5719		return this;
5720	},
5721
5722	replaceWith: function( value ) {
5723		if ( this[0] && this[0].parentNode ) {
5724			// Make sure that the elements are removed from the DOM before they are inserted
5725			// this can help fix replacing a parent with child elements
5726			if ( jQuery.isFunction( value ) ) {
5727				return this.each(function(i) {
5728					var self = jQuery(this), old = self.html();
5729					self.replaceWith( value.call( this, i, old ) );
5730				});
5731			}
5732
5733			if ( typeof value !== "string" ) {
5734				value = jQuery( value ).detach();
5735			}
5736
5737			return this.each(function() {
5738				var next = this.nextSibling,
5739					parent = this.parentNode;
5740
5741				jQuery( this ).remove();
5742
5743				if ( next ) {
5744					jQuery(next).before( value );
5745				} else {
5746					jQuery(parent).append( value );
5747				}
5748			});
5749		} else {
5750			return this.length ?
5751				this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5752				this;
5753		}
5754	},
5755
5756	detach: function( selector ) {
5757		return this.remove( selector, true );
5758	},
5759
5760	domManip: function( args, table, callback ) {
5761		var results, first, fragment, parent,
5762			value = args[0],
5763			scripts = [];
5764
5765		// We can't cloneNode fragments that contain checked, in WebKit
5766		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5767			return this.each(function() {
5768				jQuery(this).domManip( args, table, callback, true );
5769			});
5770		}
5771
5772		if ( jQuery.isFunction(value) ) {
5773			return this.each(function(i) {
5774				var self = jQuery(this);
5775				args[0] = value.call(this, i, table ? self.html() : undefined);
5776				self.domManip( args, table, callback );
5777			});
5778		}
5779
5780		if ( this[0] ) {
5781			parent = value && value.parentNode;
5782
5783			// If we're in a fragment, just use that instead of building a new one
5784			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5785				results = { fragment: parent };
5786
5787			} else {
5788				results = jQuery.buildFragment( args, this, scripts );
5789			}
5790
5791			fragment = results.fragment;
5792
5793			if ( fragment.childNodes.length === 1 ) {
5794				first = fragment = fragment.firstChild;
5795			} else {
5796				first = fragment.firstChild;
5797			}
5798
5799			if ( first ) {
5800				table = table && jQuery.nodeName( first, "tr" );
5801
5802				for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5803					callback.call(
5804						table ?
5805							root(this[i], first) :
5806							this[i],
5807						// Make sure that we do not leak memory by inadvertently discarding
5808						// the original fragment (which might have attached data) instead of
5809						// using it; in addition, use the original fragment object for the last
5810						// item instead of first because it can end up being emptied incorrectly
5811						// in certain situations (Bug #8070).
5812						// Fragments from the fragment cache must always be cloned and never used
5813						// in place.
5814						results.cacheable || (l > 1 && i < lastIndex) ?
5815							jQuery.clone( fragment, true, true ) :
5816							fragment
5817					);
5818				}
5819			}
5820
5821			if ( scripts.length ) {
5822				jQuery.each( scripts, evalScript );
5823			}
5824		}
5825
5826		return this;
5827	}
5828});
5829
5830function root( elem, cur ) {
5831	return jQuery.nodeName(elem, "table") ?
5832		(elem.getElementsByTagName("tbody")[0] ||
5833		elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5834		elem;
5835}
5836
5837function cloneCopyEvent( src, dest ) {
5838
5839	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5840		return;
5841	}
5842
5843	var internalKey = jQuery.expando,
5844		oldData = jQuery.data( src ),
5845		curData = jQuery.data( dest, oldData );
5846
5847	// Switch to use the internal data object, if it exists, for the next
5848	// stage of data copying
5849	if ( (oldData = oldData[ internalKey ]) ) {
5850		var events = oldData.events;
5851				curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5852
5853		if ( events ) {
5854			delete curData.handle;
5855			curData.events = {};
5856
5857			for ( var type in events ) {
5858				for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5859					jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
5860				}
5861			}
5862		}
5863	}
5864}
5865
5866function cloneFixAttributes( src, dest ) {
5867	var nodeName;
5868
5869	// We do not need to do anything for non-Elements
5870	if ( dest.nodeType !== 1 ) {
5871		return;
5872	}
5873
5874	// clearAttributes removes the attributes, which we don't want,
5875	// but also removes the attachEvent events, which we *do* want
5876	if ( dest.clearAttributes ) {
5877		dest.clearAttributes();
5878	}
5879
5880	// mergeAttributes, in contrast, only merges back on the
5881	// original attributes, not the events
5882	if ( dest.mergeAttributes ) {
5883		dest.mergeAttributes( src );
5884	}
5885
5886	nodeName = dest.nodeName.toLowerCase();
5887
5888	// IE6-8 fail to clone children inside object elements that use
5889	// the proprietary classid attribute value (rather than the type
5890	// attribute) to identify the type of content to display
5891	if ( nodeName === "object" ) {
5892		dest.outerHTML = src.outerHTML;
5893
5894	} else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5895		// IE6-8 fails to persist the checked state of a cloned checkbox
5896		// or radio button. Worse, IE6-7 fail to give the cloned element
5897		// a checked appearance if the defaultChecked value isn't also set
5898		if ( src.checked ) {
5899			dest.defaultChecked = dest.checked = src.checked;
5900		}
5901
5902		// IE6-7 get confused and end up setting the value of a cloned
5903		// checkbox/radio button to an empty string instead of "on"
5904		if ( dest.value !== src.value ) {
5905			dest.value = src.value;
5906		}
5907
5908	// IE6-8 fails to return the selected option to the default selected
5909	// state when cloning options
5910	} else if ( nodeName === "option" ) {
5911		dest.selected = src.defaultSelected;
5912
5913	// IE6-8 fails to set the defaultValue to the correct value when
5914	// cloning other types of input fields
5915	} else if ( nodeName === "input" || nodeName === "textarea" ) {
5916		dest.defaultValue = src.defaultValue;
5917	}
5918
5919	// Event data gets referenced instead of copied if the expando
5920	// gets copied too
5921	dest.removeAttribute( jQuery.expando );
5922}
5923
5924jQuery.buildFragment = function( args, nodes, scripts ) {
5925	var fragment, cacheable, cacheresults, doc;
5926
5927  // nodes may contain either an explicit document object,
5928  // a jQuery collection or context object.
5929  // If nodes[0] contains a valid object to assign to doc
5930  if ( nodes && nodes[0]