PageSourceSearch

https://www.ohtabooks.com/mt5-static/jquery/jquery.js

js ohtabooks.com collected 2026-09-24 09:32:47 UTC 236,202 bytes, 8,981 lines download raw bytes

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>
1174<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] ) {
5931    doc = nodes[0].ownerDocument || nodes[0];
5932  }
5933
5934  // Ensure that an attr object doesn't incorrectly stand in as a document object
5935	// Chrome and Firefox seem to allow this to occur and will throw exception
5936	// Fixes #8950
5937	if ( !doc.createDocumentFragment ) {
5938		doc = document;
5939	}
5940
5941	// Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5942	// Cloning options loses the selected state, so don't cache them
5943	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5944	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5945	if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5946		args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5947
5948		cacheable = true;
5949
5950		cacheresults = jQuery.fragments[ args[0] ];
5951		if ( cacheresults && cacheresults !== 1 ) {
5952			fragment = cacheresults;
5953		}
5954	}
5955
5956	if ( !fragment ) {
5957		fragment = doc.createDocumentFragment();
5958		jQuery.clean( args, doc, fragment, scripts );
5959	}
5960
5961	if ( cacheable ) {
5962		jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5963	}
5964
5965	return { fragment: fragment, cacheable: cacheable };
5966};
5967
5968jQuery.fragments = {};
5969
5970jQuery.each({
5971	appendTo: "append",
5972	prependTo: "prepend",
5973	insertBefore: "before",
5974	insertAfter: "after",
5975	replaceAll: "replaceWith"
5976}, function( name, original ) {
5977	jQuery.fn[ name ] = function( selector ) {
5978		var ret = [],
5979			insert = jQuery( selector ),
5980			parent = this.length === 1 && this[0].parentNode;
5981
5982		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5983			insert[ original ]( this[0] );
5984			return this;
5985
5986		} else {
5987			for ( var i = 0, l = insert.length; i < l; i++ ) {
5988				var elems = (i > 0 ? this.clone(true) : this).get();
5989				jQuery( insert[i] )[ original ]( elems );
5990				ret = ret.concat( elems );
5991			}
5992
5993			return this.pushStack( ret, name, insert.selector );
5994		}
5995	};
5996});
5997
5998function getAll( elem ) {
5999	if ( "getElementsByTagName" in elem ) {
6000		return elem.getElementsByTagName( "*" );
6001
6002	} else if ( "querySelectorAll" in elem ) {
6003		return elem.querySelectorAll( "*" );
6004
6005	} else {
6006		return [];
6007	}
6008}
6009
6010// Used in clean, fixes the defaultChecked property
6011function fixDefaultChecked( elem ) {
6012	if ( elem.type === "checkbox" || elem.type === "radio" ) {
6013		elem.defaultChecked = elem.checked;
6014	}
6015}
6016// Finds all inputs and passes them to fixDefaultChecked
6017function findInputs( elem ) {
6018	if ( jQuery.nodeName( elem, "input" ) ) {
6019		fixDefaultChecked( elem );
6020	} else if ( "getElementsByTagName" in elem ) {
6021		jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6022	}
6023}
6024
6025jQuery.extend({
6026	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6027		var clone = elem.cloneNode(true),
6028				srcElements,
6029				destElements,
6030				i;
6031
6032		if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6033				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6034			// IE copies events bound via attachEvent when using cloneNode.
6035			// Calling detachEvent on the clone will also remove the events
6036			// from the original. In order to get around this, we use some
6037			// proprietary methods to clear the events. Thanks to MooTools
6038			// guys for this hotness.
6039
6040			cloneFixAttributes( elem, clone );
6041
6042			// Using Sizzle here is crazy slow, so we use getElementsByTagName
6043			// instead
6044			srcElements = getAll( elem );
6045			destElements = getAll( clone );
6046
6047			// Weird iteration because IE will replace the length property
6048			// with an element if you are cloning the body and one of the
6049			// elements on the page has a name or id of "length"
6050			for ( i = 0; srcElements[i]; ++i ) {
6051				cloneFixAttributes( srcElements[i], destElements[i] );
6052			}
6053		}
6054
6055		// Copy the events from the original to the clone
6056		if ( dataAndEvents ) {
6057			cloneCopyEvent( elem, clone );
6058
6059			if ( deepDataAndEvents ) {
6060				srcElements = getAll( elem );
6061				destElements = getAll( clone );
6062
6063				for ( i = 0; srcElements[i]; ++i ) {
6064					cloneCopyEvent( srcElements[i], destElements[i] );
6065				}
6066			}
6067		}
6068
6069		srcElements = destElements = null;
6070
6071		// Return the cloned set
6072		return clone;
6073	},
6074
6075	clean: function( elems, context, fragment, scripts ) {
6076		var checkScriptType;
6077
6078		context = context || document;
6079
6080		// !context.createElement fails in IE with an error but returns typeof 'object'
6081		if ( typeof context.createElement === "undefined" ) {
6082			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6083		}
6084
6085		var ret = [], j;
6086
6087		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6088			if ( typeof elem === "number" ) {
6089				elem += "";
6090			}
6091
6092			if ( !elem ) {
6093				continue;
6094			}
6095
6096			// Convert html string into DOM nodes
6097			if ( typeof elem === "string" ) {
6098				if ( !rhtml.test( elem ) ) {
6099					elem = context.createTextNode( elem );
6100				} else {
6101					// Fix "XHTML"-style tags in all browsers
6102					elem = elem.replace(rxhtmlTag, "<$1></$2>");
6103
6104					// Trim whitespace, otherwise indexOf won't work as expected
6105					var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6106						wrap = wrapMap[ tag ] || wrapMap._default,
6107						depth = wrap[0],
6108						div = context.createElement("div");
6109
6110					// Go to html and back, then peel off extra wrappers
6111					div.innerHTML = wrap[1] + elem + wrap[2];
6112
6113					// Move to the right depth
6114					while ( depth-- ) {
6115						div = div.lastChild;
6116					}
6117
6118					// Remove IE's autoinserted <tbody> from table fragments
6119					if ( !jQuery.support.tbody ) {
6120
6121						// String was a <table>, *may* have spurious <tbody>
6122						var hasBody = rtbody.test(elem),
6123							tbody = tag === "table" && !hasBody ?
6124								div.firstChild && div.firstChild.childNodes :
6125
6126								// String was a bare <thead> or <tfoot>
6127								wrap[1] === "<table>" && !hasBody ?
6128									div.childNodes :
6129									[];
6130
6131						for ( j = tbody.length - 1; j >= 0 ; --j ) {
6132							if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6133								tbody[ j ].parentNode.removeChild( tbody[ j ] );
6134							}
6135						}
6136					}
6137
6138					// IE completely kills leading whitespace when innerHTML is used
6139					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6140						div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6141					}
6142
6143					elem = div.childNodes;
6144				}
6145			}
6146
6147			// Resets defaultChecked for any radios and checkboxes
6148			// about to be appended to the DOM in IE 6/7 (#8060)
6149			var len;
6150			if ( !jQuery.support.appendChecked ) {
6151				if ( elem[0] && typeof (len = elem.length) === "number" ) {
6152					for ( j = 0; j < len; j++ ) {
6153						findInputs( elem[j] );
6154					}
6155				} else {
6156					findInputs( elem );
6157				}
6158			}
6159
6160			if ( elem.nodeType ) {
6161				ret.push( elem );
6162			} else {
6163				ret = jQuery.merge( ret, elem );
6164			}
6165		}
6166
6167		if ( fragment ) {
6168			checkScriptType = function( elem ) {
6169				return !elem.type || rscriptType.test( elem.type );
6170			};
6171			for ( i = 0; ret[i]; i++ ) {
6172				if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6173					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6174
6175				} else {
6176					if ( ret[i].nodeType === 1 ) {
6177						var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6178
6179						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6180					}
6181					fragment.appendChild( ret[i] );
6182				}
6183			}
6184		}
6185
6186		return ret;
6187	},
6188
6189	cleanData: function( elems ) {
6190		var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6191			deleteExpando = jQuery.support.deleteExpando;
6192
6193		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6194			if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6195				continue;
6196			}
6197
6198			id = elem[ jQuery.expando ];
6199
6200			if ( id ) {
6201				data = cache[ id ] && cache[ id ][ internalKey ];
6202
6203				if ( data && data.events ) {
6204					for ( var type in data.events ) {
6205						if ( special[ type ] ) {
6206							jQuery.event.remove( elem, type );
6207
6208						// This is a shortcut to avoid jQuery.event.remove's overhead
6209						} else {
6210							jQuery.removeEvent( elem, type, data.handle );
6211						}
6212					}
6213
6214					// Null the DOM reference to avoid IE6/7/8 leak (#7054)
6215					if ( data.handle ) {
6216						data.handle.elem = null;
6217					}
6218				}
6219
6220				if ( deleteExpando ) {
6221					delete elem[ jQuery.expando ];
6222
6223				} else if ( elem.removeAttribute ) {
6224					elem.removeAttribute( jQuery.expando );
6225				}
6226
6227				delete cache[ id ];
6228			}
6229		}
6230	}
6231});
6232
6233function evalScript( i, elem ) {
6234	if ( elem.src ) {
6235		jQuery.ajax({
6236			url: elem.src,
6237			async: false,
6238			dataType: "script"
6239		});
6240	} else {
6241		jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6242	}
6243
6244	if ( elem.parentNode ) {
6245		elem.parentNode.removeChild( elem );
6246	}
6247}
6248
6249
6250
6251var ralpha = /alpha\([^)]*\)/i,
6252	ropacity = /opacity=([^)]*)/,
6253	// fixed for IE9, see #8346
6254	rupper = /([A-Z]|^ms)/g,
6255	rnumpx = /^-?\d+(?:px)?$/i,
6256	rnum = /^-?\d/,
6257	rrelNum = /^[+\-]=/,
6258	rrelNumFilter = /[^+\-\.\de]+/g,
6259
6260	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6261	cssWidth = [ "Left", "Right" ],
6262	cssHeight = [ "Top", "Bottom" ],
6263	curCSS,
6264
6265	getComputedStyle,
6266	currentStyle;
6267
6268jQuery.fn.css = function( name, value ) {
6269	// Setting 'undefined' is a no-op
6270	if ( arguments.length === 2 && value === undefined ) {
6271		return this;
6272	}
6273
6274	return jQuery.access( this, name, value, true, function( elem, name, value ) {
6275		return value !== undefined ?
6276			jQuery.style( elem, name, value ) :
6277			jQuery.css( elem, name );
6278	});
6279};
6280
6281jQuery.extend({
6282	// Add in style property hooks for overriding the default
6283	// behavior of getting and setting a style property
6284	cssHooks: {
6285		opacity: {
6286			get: function( elem, computed ) {
6287				if ( computed ) {
6288					// We should always get a number back from opacity
6289					var ret = curCSS( elem, "opacity", "opacity" );
6290					return ret === "" ? "1" : ret;
6291
6292				} else {
6293					return elem.style.opacity;
6294				}
6295			}
6296		}
6297	},
6298
6299	// Exclude the following css properties to add px
6300	cssNumber: {
6301		"fillOpacity": true,
6302		"fontWeight": true,
6303		"lineHeight": true,
6304		"opacity": true,
6305		"orphans": true,
6306		"widows": true,
6307		"zIndex": true,
6308		"zoom": true
6309	},
6310
6311	// Add in properties whose names you wish to fix before
6312	// setting or getting the value
6313	cssProps: {
6314		// normalize float css property
6315		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6316	},
6317
6318	// Get and set the style property on a DOM Node
6319	style: function( elem, name, value, extra ) {
6320		// Don't set styles on text and comment nodes
6321		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6322			return;
6323		}
6324
6325		// Make sure that we're working with the right name
6326		var ret, type, origName = jQuery.camelCase( name ),
6327			style = elem.style, hooks = jQuery.cssHooks[ origName ];
6328
6329		name = jQuery.cssProps[ origName ] || origName;
6330
6331		// Check if we're setting a value
6332		if ( value !== undefined ) {
6333			type = typeof value;
6334
6335			// Make sure that NaN and null values aren't set. See: #7116
6336			if ( type === "number" && isNaN( value ) || value == null ) {
6337				return;
6338			}
6339
6340			// convert relative number strings (+= or -=) to relative numbers. #7345
6341			if ( type === "string" && rrelNum.test( value ) ) {
6342				value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6343				// Fixes bug #9237
6344				type = "number";
6345			}
6346
6347			// If a number was passed in, add 'px' to the (except for certain CSS properties)
6348			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6349				value += "px";
6350			}
6351
6352			// If a hook was provided, use that value, otherwise just set the specified value
6353			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6354				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6355				// Fixes bug #5509
6356				try {
6357					style[ name ] = value;
6358				} catch(e) {}
6359			}
6360
6361		} else {
6362			// If a hook was provided get the non-computed value from there
6363			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6364				return ret;
6365			}
6366
6367			// Otherwise just get the value from the style object
6368			return style[ name ];
6369		}
6370	},
6371
6372	css: function( elem, name, extra ) {
6373		var ret, hooks;
6374
6375		// Make sure that we're working with the right name
6376		name = jQuery.camelCase( name );
6377		hooks = jQuery.cssHooks[ name ];
6378		name = jQuery.cssProps[ name ] || name;
6379
6380		// cssFloat needs a special treatment
6381		if ( name === "cssFloat" ) {
6382			name = "float";
6383		}
6384
6385		// If a hook was provided get the computed value from there
6386		if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6387			return ret;
6388
6389		// Otherwise, if a way to get the computed value exists, use that
6390		} else if ( curCSS ) {
6391			return curCSS( elem, name );
6392		}
6393	},
6394
6395	// A method for quickly swapping in/out CSS properties to get correct calculations
6396	swap: function( elem, options, callback ) {
6397		var old = {};
6398
6399		// Remember the old values, and insert the new ones
6400		for ( var name in options ) {
6401			old[ name ] = elem.style[ name ];
6402			elem.style[ name ] = options[ name ];
6403		}
6404
6405		callback.call( elem );
6406
6407		// Revert the old values
6408		for ( name in options ) {
6409			elem.style[ name ] = old[ name ];
6410		}
6411	}
6412});
6413
6414// DEPRECATED, Use jQuery.css() instead
6415jQuery.curCSS = jQuery.css;
6416
6417jQuery.each(["height", "width"], function( i, name ) {
6418	jQuery.cssHooks[ name ] = {
6419		get: function( elem, computed, extra ) {
6420			var val;
6421
6422			if ( computed ) {
6423				if ( elem.offsetWidth !== 0 ) {
6424					return getWH( elem, name, extra );
6425				} else {
6426					jQuery.swap( elem, cssShow, function() {
6427						val = getWH( elem, name, extra );
6428					});
6429				}
6430
6431				return val;
6432			}
6433		},
6434
6435		set: function( elem, value ) {
6436			if ( rnumpx.test( value ) ) {
6437				// ignore negative width and height values #1599
6438				value = parseFloat( value );
6439
6440				if ( value >= 0 ) {
6441					return value + "px";
6442				}
6443
6444			} else {
6445				return value;
6446			}
6447		}
6448	};
6449});
6450
6451if ( !jQuery.support.opacity ) {
6452	jQuery.cssHooks.opacity = {
6453		get: function( elem, computed ) {
6454			// IE uses filters for opacity
6455			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6456				( parseFloat( RegExp.$1 ) / 100 ) + "" :
6457				computed ? "1" : "";
6458		},
6459
6460		set: function( elem, value ) {
6461			var style = elem.style,
6462				currentStyle = elem.currentStyle;
6463
6464			// IE has trouble with opacity if it does not have layout
6465			// Force it by setting the zoom level
6466			style.zoom = 1;
6467
6468			// Set the alpha filter to set the opacity
6469			var opacity = jQuery.isNaN( value ) ?
6470				"" :
6471				"alpha(opacity=" + value * 100 + ")",
6472				filter = currentStyle && currentStyle.filter || style.filter || "";
6473
6474			style.filter = ralpha.test( filter ) ?
6475				filter.replace( ralpha, opacity ) :
6476				filter + " " + opacity;
6477		}
6478	};
6479}
6480
6481jQuery(function() {
6482	// This hook cannot be added until DOM ready because the support test
6483	// for it is not run until after DOM ready
6484	if ( !jQuery.support.reliableMarginRight ) {
6485		jQuery.cssHooks.marginRight = {
6486			get: function( elem, computed ) {
6487				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6488				// Work around by temporarily setting element display to inline-block
6489				var ret;
6490				jQuery.swap( elem, { "display": "inline-block" }, function() {
6491					if ( computed ) {
6492						ret = curCSS( elem, "margin-right", "marginRight" );
6493					} else {
6494						ret = elem.style.marginRight;
6495					}
6496				});
6497				return ret;
6498			}
6499		};
6500	}
6501});
6502
6503if ( document.defaultView && document.defaultView.getComputedStyle ) {
6504	getComputedStyle = function( elem, name ) {
6505		var ret, defaultView, computedStyle;
6506
6507		name = name.replace( rupper, "-$1" ).toLowerCase();
6508
6509		if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6510			return undefined;
6511		}
6512
6513		if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6514			ret = computedStyle.getPropertyValue( name );
6515			if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6516				ret = jQuery.style( elem, name );
6517			}
6518		}
6519
6520		return ret;
6521	};
6522}
6523
6524if ( document.documentElement.currentStyle ) {
6525	currentStyle = function( elem, name ) {
6526		var left,
6527			ret = elem.currentStyle && elem.currentStyle[ name ],
6528			rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
6529			style = elem.style;
6530
6531		// From the awesome hack by Dean Edwards
6532		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6533
6534		// If we're not dealing with a regular pixel number
6535		// but a number that has a weird ending, we need to convert it to pixels
6536		if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6537			// Remember the original values
6538			left = style.left;
6539
6540			// Put in the new values to get a computed value out
6541			if ( rsLeft ) {
6542				elem.runtimeStyle.left = elem.currentStyle.left;
6543			}
6544			style.left = name === "fontSize" ? "1em" : (ret || 0);
6545			ret = style.pixelLeft + "px";
6546
6547			// Revert the changed values
6548			style.left = left;
6549			if ( rsLeft ) {
6550				elem.runtimeStyle.left = rsLeft;
6551			}
6552		}
6553
6554		return ret === "" ? "auto" : ret;
6555	};
6556}
6557
6558curCSS = getComputedStyle || currentStyle;
6559
6560function getWH( elem, name, extra ) {
6561
6562	// Start with offset property
6563	var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6564		which = name === "width" ? cssWidth : cssHeight;
6565
6566	if ( val > 0 ) {
6567		if ( extra !== "border" ) {
6568			jQuery.each( which, function() {
6569				if ( !extra ) {
6570					val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6571				}
6572				if ( extra === "margin" ) {
6573					val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6574				} else {
6575					val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6576				}
6577			});
6578		}
6579
6580		return val + "px";
6581	}
6582
6583	// Fall back to computed then uncomputed css if necessary
6584	val = curCSS( elem, name, name );
6585	if ( val < 0 || val == null ) {
6586		val = elem.style[ name ] || 0;
6587	}
6588	// Normalize "", auto, and prepare for extra
6589	val = parseFloat( val ) || 0;
6590
6591	// Add padding, border, margin
6592	if ( extra ) {
6593		jQuery.each( which, function() {
6594			val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6595			if ( extra !== "padding" ) {
6596				val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6597			}
6598			if ( extra === "margin" ) {
6599				val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6600			}
6601		});
6602	}
6603
6604	return val + "px";
6605}
6606
6607if ( jQuery.expr && jQuery.expr.filters ) {
6608	jQuery.expr.filters.hidden = function( elem ) {
6609		var width = elem.offsetWidth,
6610			height = elem.offsetHeight;
6611
6612		return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "dis
6612play" )) === "none");
6613	};
6614
6615	jQuery.expr.filters.visible = function( elem ) {
6616		return !jQuery.expr.filters.hidden( elem );
6617	};
6618}
6619
6620
6621
6622
6623var r20 = /%20/g,
6624	rbracket = /\[\]$/,
6625	rCRLF = /\r?\n/g,
6626	rhash = /#.*$/,
6627	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6628	rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6629	// #7653, #8125, #8152: local protocol detection
6630	rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
6631	rnoContent = /^(?:GET|HEAD)$/,
6632	rprotocol = /^\/\//,
6633	rquery = /\?/,
6634	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6635	rselectTextarea = /^(?:select|textarea)/i,
6636	rspacesAjax = /\s+/,
6637	rts = /([?&])_=[^&]*/,
6638	rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6639
6640	// Keep a copy of the old load method
6641	_load = jQuery.fn.load,
6642
6643	/* Prefilters
6644	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6645	 * 2) These are called:
6646	 *    - BEFORE asking for a transport
6647	 *    - AFTER param serialization (s.data is a string if s.processData is true)
6648	 * 3) key is the dataType
6649	 * 4) the catchall symbol "*" can be used
6650	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6651	 */
6652	prefilters = {},
6653
6654	/* Transports bindings
6655	 * 1) key is the dataType
6656	 * 2) the catchall symbol "*" can be used
6657	 * 3) selection will start with transport dataType and THEN go to "*" if needed
6658	 */
6659	transports = {},
6660
6661	// Document location
6662	ajaxLocation,
6663
6664	// Document location segments
6665	ajaxLocParts;
6666
6667// #8138, IE may throw an exception when accessing
6668// a field from window.location if document.domain has been set
6669try {
6670	ajaxLocation = location.href;
6671} catch( e ) {
6672	// Use the href attribute of an A element
6673	// since IE will modify it given document.location
6674	ajaxLocation = document.createElement( "a" );
6675	ajaxLocation.href = "";
6676	ajaxLocation = ajaxLocation.href;
6677}
6678
6679// Segment location into parts
6680ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6681
6682// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6683function addToPrefiltersOrTransports( structure ) {
6684
6685	// dataTypeExpression is optional and defaults to "*"
6686	return function( dataTypeExpression, func ) {
6687
6688		if ( typeof dataTypeExpression !== "string" ) {
6689			func = dataTypeExpression;
6690			dataTypeExpression = "*";
6691		}
6692
6693		if ( jQuery.isFunction( func ) ) {
6694			var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6695				i = 0,
6696				length = dataTypes.length,
6697				dataType,
6698				list,
6699				placeBefore;
6700
6701			// For each dataType in the dataTypeExpression
6702			for(; i < length; i++ ) {
6703				dataType = dataTypes[ i ];
6704				// We control if we're asked to add before
6705				// any existing element
6706				placeBefore = /^\+/.test( dataType );
6707				if ( placeBefore ) {
6708					dataType = dataType.substr( 1 ) || "*";
6709				}
6710				list = structure[ dataType ] = structure[ dataType ] || [];
6711				// then we add to the structure accordingly
6712				list[ placeBefore ? "unshift" : "push" ]( func );
6713			}
6714		}
6715	};
6716}
6717
6718// Base inspection function for prefilters and transports
6719function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6720		dataType /* internal */, inspected /* internal */ ) {
6721
6722	dataType = dataType || options.dataTypes[ 0 ];
6723	inspected = inspected || {};
6724
6725	inspected[ dataType ] = true;
6726
6727	var list = structure[ dataType ],
6728		i = 0,
6729		length = list ? list.length : 0,
6730		executeOnly = ( structure === prefilters ),
6731		selection;
6732
6733	for(; i < length && ( executeOnly || !selection ); i++ ) {
6734		selection = list[ i ]( options, originalOptions, jqXHR );
6735		// If we got redirected to another dataType
6736		// we try there if executing only and not done already
6737		if ( typeof selection === "string" ) {
6738			if ( !executeOnly || inspected[ selection ] ) {
6739				selection = undefined;
6740			} else {
6741				options.dataTypes.unshift( selection );
6742				selection = inspectPrefiltersOrTransports(
6743						structure, options, originalOptions, jqXHR, selection, inspected );
6744			}
6745		}
6746	}
6747	// If we're only executing or nothing was selected
6748	// we try the catchall dataType if not done already
6749	if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6750		selection = inspectPrefiltersOrTransports(
6751				structure, options, originalOptions, jqXHR, "*", inspected );
6752	}
6753	// unnecessary when only executing (prefilters)
6754	// but it'll be ignored by the caller in that case
6755	return selection;
6756}
6757
6758jQuery.fn.extend({
6759	load: function( url, params, callback ) {
6760		if ( typeof url !== "string" && _load ) {
6761			return _load.apply( this, arguments );
6762
6763		// Don't do a request if no elements are being requested
6764		} else if ( !this.length ) {
6765			return this;
6766		}
6767
6768		var off = url.indexOf( " " );
6769		if ( off >= 0 ) {
6770			var selector = url.slice( off, url.length );
6771			url = url.slice( 0, off );
6772		}
6773
6774		// Default to a GET request
6775		var type = "GET";
6776
6777		// If the second parameter was provided
6778		if ( params ) {
6779			// If it's a function
6780			if ( jQuery.isFunction( params ) ) {
6781				// We assume that it's the callback
6782				callback = params;
6783				params = undefined;
6784
6785			// Otherwise, build a param string
6786			} else if ( typeof params === "object" ) {
6787				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
6788				type = "POST";
6789			}
6790		}
6791
6792		var self = this;
6793
6794		// Request the remote document
6795		jQuery.ajax({
6796			url: url,
6797			type: type,
6798			dataType: "html",
6799			data: params,
6800			// Complete callback (responseText is used internally)
6801			complete: function( jqXHR, status, responseText ) {
6802				// Store the response as specified by the jqXHR object
6803				responseText = jqXHR.responseText;
6804				// If successful, inject the HTML into all the matched elements
6805				if ( jqXHR.isResolved() ) {
6806					// #4825: Get the actual response in case
6807					// a dataFilter is present in ajaxSettings
6808					jqXHR.done(function( r ) {
6809						responseText = r;
6810					});
6811					// See if a selector was specified
6812					self.html( selector ?
6813						// Create a dummy div to hold the results
6814						jQuery("<div>")
6815							// inject the contents of the document in, removing the scripts
6816							// to avoid any 'Permission Denied' errors in IE
6817							.append(responseText.replace(rscript, ""))
6818
6819							// Locate the specified elements
6820							.find(selector) :
6821
6822						// If not, just inject the full result
6823						responseText );
6824				}
6825
6826				if ( callback ) {
6827					self.each( callback, [ responseText, status, jqXHR ] );
6828				}
6829			}
6830		});
6831
6832		return this;
6833	},
6834
6835	serialize: function() {
6836		return jQuery.param( this.serializeArray() );
6837	},
6838
6839	serializeArray: function() {
6840		return this.map(function(){
6841			return this.elements ? jQuery.makeArray( this.elements ) : this;
6842		})
6843		.filter(function(){
6844			return this.name && !this.disabled &&
6845				( this.checked || rselectTextarea.test( this.nodeName ) ||
6846					rinput.test( this.type ) );
6847		})
6848		.map(function( i, elem ){
6849			var val = jQuery( this ).val();
6850
6851			return val == null ?
6852				null :
6853				jQuery.isArray( val ) ?
6854					jQuery.map( val, function( val, i ){
6855						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6856					}) :
6857					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6858		}).get();
6859	}
6860});
6861
6862// Attach a bunch of functions for handling common AJAX events
6863jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6864	jQuery.fn[ o ] = function( f ){
6865		return this.bind( o, f );
6866	};
6867});
6868
6869jQuery.each( [ "get", "post" ], function( i, method ) {
6870	jQuery[ method ] = function( url, data, callback, type ) {
6871		// shift arguments if data argument was omitted
6872		if ( jQuery.isFunction( data ) ) {
6873			type = type || callback;
6874			callback = data;
6875			data = undefined;
6876		}
6877
6878		return jQuery.ajax({
6879			type: method,
6880			url: url,
6881			data: data,
6882			success: callback,
6883			dataType: type
6884		});
6885	};
6886});
6887
6888jQuery.extend({
6889
6890	getScript: function( url, callback ) {
6891		return jQuery.get( url, undefined, callback, "script" );
6892	},
6893
6894	getJSON: function( url, data, callback ) {
6895		return jQuery.get( url, data, callback, "json" );
6896	},
6897
6898	// Creates a full fledged settings object into target
6899	// with both ajaxSettings and settings fields.
6900	// If target is omitted, writes into ajaxSettings.
6901	ajaxSetup: function ( target, settings ) {
6902		if ( !settings ) {
6903			// Only one parameter, we extend ajaxSettings
6904			settings = target;
6905			target = jQuery.extend( true, jQuery.ajaxSettings, settings );
6906		} else {
6907			// target was provided, we extend into it
6908			jQuery.extend( true, target, jQuery.ajaxSettings, settings );
6909		}
6910		// Flatten fields we don't want deep extended
6911		for( var field in { context: 1, url: 1 } ) {
6912			if ( field in settings ) {
6913				target[ field ] = settings[ field ];
6914			} else if( field in jQuery.ajaxSettings ) {
6915				target[ field ] = jQuery.ajaxSettings[ field ];
6916			}
6917		}
6918		return target;
6919	},
6920
6921	ajaxSettings: {
6922		url: ajaxLocation,
6923		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
6924		global: true,
6925		type: "GET",
6926		contentType: "application/x-www-form-urlencoded",
6927		processData: true,
6928		async: true,
6929		/*
6930		timeout: 0,
6931		data: null,
6932		dataType: null,
6933		username: null,
6934		password: null,
6935		cache: null,
6936		traditional: false,
6937		headers: {},
6938		*/
6939
6940		accepts: {
6941			xml: "application/xml, text/xml",
6942			html: "text/html",
6943			text: "text/plain",
6944			json: "application/json, text/javascript",
6945			"*": "*/*"
6946		},
6947
6948		contents: {
6949			xml: /xml/,
6950			html: /html/,
6951			json: /json/
6952		},
6953
6954		responseFields: {
6955			xml: "responseXML",
6956			text: "responseText"
6957		},
6958
6959		// List of data converters
6960		// 1) key format is "source_type destination_type" (a single space in-between)
6961		// 2) the catchall symbol "*" can be used for source_type
6962		converters: {
6963
6964			// Convert anything to text
6965			"* text": window.String,
6966
6967			// Text to html (true = no transformation)
6968			"text html": true,
6969
6970			// Evaluate text as a json expression
6971			"text json": jQuery.parseJSON,
6972
6973			// Parse text as xml
6974			"text xml": jQuery.parseXML
6975		}
6976	},
6977
6978	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
6979	ajaxTransport: addToPrefiltersOrTransports( transports ),
6980
6981	// Main method
6982	ajax: function( url, options ) {
6983
6984		// If url is an object, simulate pre-1.5 signature
6985		if ( typeof url === "object" ) {
6986			options = url;
6987			url = undefined;
6988		}
6989
6990		// Force options to be an object
6991		options = options || {};
6992
6993		var // Create the final options object
6994			s = jQuery.ajaxSetup( {}, options ),
6995			// Callbacks context
6996			callbackContext = s.context || s,
6997			// Context for global events
6998			// It's the callbackContext if one was provided in the options
6999			// and if it's a DOM node or a jQuery collection
7000			globalEventContext = callbackContext !== s &&
7001				( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7002						jQuery( callbackContext ) : jQuery.event,
7003			// Deferreds
7004			deferred = jQuery.Deferred(),
7005			completeDeferred = jQuery._Deferred(),
7006			// Status-dependent callbacks
7007			statusCode = s.statusCode || {},
7008			// ifModified key
7009			ifModifiedKey,
7010			// Headers (they are sent all at once)
7011			requestHeaders = {},
7012			requestHeadersNames = {},
7013			// Response headers
7014			responseHeadersString,
7015			responseHeaders,
7016			// transport
7017			transport,
7018			// timeout handle
7019			timeoutTimer,
7020			// Cross-domain detection vars
7021			parts,
7022			// The jqXHR state
7023			state = 0,
7024			// To know if global events are to be dispatched
7025			fireGlobals,
7026			// Loop variable
7027			i,
7028			// Fake xhr
7029			jqXHR = {
7030
7031				readyState: 0,
7032
7033				// Caches the header
7034				setRequestHeader: function( name, value ) {
7035					if ( !state ) {
7036						var lname = name.toLowerCase();
7037						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7038						requestHeaders[ name ] = value;
7039					}
7040					return this;
7041				},
7042
7043				// Raw string
7044				getAllResponseHeaders: function() {
7045					return state === 2 ? responseHeadersString : null;
7046				},
7047
7048				// Builds headers hashtable if needed
7049				getResponseHeader: function( key ) {
7050					var match;
7051					if ( state === 2 ) {
7052						if ( !responseHeaders ) {
7053							responseHeaders = {};
7054							while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7055								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7056							}
7057						}
7058						match = responseHeaders[ key.toLowerCase() ];
7059					}
7060					return match === undefined ? null : match;
7061				},
7062
7063				// Overrides response content-type header
7064				overrideMimeType: function( type ) {
7065					if ( !state ) {
7066						s.mimeType = type;
7067					}
7068					return this;
7069				},
7070
7071				// Cancel the request
7072				abort: function( statusText ) {
7073					statusText = statusText || "abort";
7074					if ( transport ) {
7075						transport.abort( statusText );
7076					}
7077					done( 0, statusText );
7078					return this;
7079				}
7080			};
7081
7082		// Callback for when everything is done
7083		// It is defined here because jslint complains if it is declared
7084		// at the end of the function (which would be more logical and readable)
7085		function done( status, statusText, responses, headers ) {
7086
7087			// Called once
7088			if ( state === 2 ) {
7089				return;
7090			}
7091
7092			// State is "done" now
7093			state = 2;
7094
7095			// Clear timeout if it exists
7096			if ( timeoutTimer ) {
7097				clearTimeout( timeoutTimer );
7098			}
7099
7100			// Dereference transport for early garbage collection
7101			// (no matter how long the jqXHR object will be used)
7102			transport = undefined;
7103
7104			// Cache response headers
7105			responseHeadersString = headers || "";
7106
7107			// Set readyState
7108			jqXHR.readyState = status ? 4 : 0;
7109
7110			var isSuccess,
7111				success,
7112				error,
7113				response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7114				lastModified,
7115				etag;
7116
7117			// If successful, handle type chaining
7118			if ( status >= 200 && status < 300 || status === 304 ) {
7119
7120				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7121				if ( s.ifModified ) {
7122
7123					if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7124						jQuery.lastModified[ ifModifiedKey ] = lastModified;
7125					}
7126					if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7127						jQuery.etag[ ifModifiedKey ] = etag;
7128					}
7129				}
7130
7131				// If not modified
7132				if ( status === 304 ) {
7133
7134					statusText = "notmodified";
7135					isSuccess = true;
7136
7137				// If we have data
7138				} else {
7139
7140					try {
7141						success = ajaxConvert( s, response );
7142						statusText = "success";
7143						isSuccess = true;
7144					} catch(e) {
7145						// We have a parsererror
7146						statusText = "parsererror";
7147						error = e;
7148					}
7149				}
7150			} else {
7151				// We extract error from statusText
7152				// then normalize statusText and status for non-aborts
7153				error = statusText;
7154				if( !statusText || status ) {
7155					statusText = "error";
7156					if ( status < 0 ) {
7157						status = 0;
7158					}
7159				}
7160			}
7161
7162			// Set data for the fake xhr object
7163			jqXHR.status = status;
7164			jqXHR.statusText = statusText;
7165
7166			// Success/Error
7167			if ( isSuccess ) {
7168				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7169			} else {
7170				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7171			}
7172
7173			// Status-dependent callbacks
7174			jqXHR.statusCode( statusCode );
7175			statusCode = undefined;
7176
7177			if ( fireGlobals ) {
7178				globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7179						[ jqXHR, s, isSuccess ? success : error ] );
7180			}
7181
7182			// Complete
7183			completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7184
7185			if ( fireGlobals ) {
7186				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
7187				// Handle the global AJAX counter
7188				if ( !( --jQuery.active ) ) {
7189					jQuery.event.trigger( "ajaxStop" );
7190				}
7191			}
7192		}
7193
7194		// Attach deferreds
7195		deferred.promise( jqXHR );
7196		jqXHR.success = jqXHR.done;
7197		jqXHR.error = jqXHR.fail;
7198		jqXHR.complete = completeDeferred.done;
7199
7200		// Status-dependent callbacks
7201		jqXHR.statusCode = function( map ) {
7202			if ( map ) {
7203				var tmp;
7204				if ( state < 2 ) {
7205					for( tmp in map ) {
7206						statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7207					}
7208				} else {
7209					tmp = map[ jqXHR.status ];
7210					jqXHR.then( tmp, tmp );
7211				}
7212			}
7213			return this;
7214		};
7215
7216		// Remove hash character (#7531: and string promotion)
7217		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7218		// We also use the url parameter if available
7219		s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7220
7221		// Extract dataTypes list
7222		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7223
7224		// Determine if a cross-domain request is in order
7225		if ( s.crossDomain == null ) {
7226			parts = rurl.exec( s.url.toLowerCase() );
7227			s.crossDomain = !!( parts &&
7228				( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7229					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7230						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7231			);
7232		}
7233
7234		// Convert data if not already a string
7235		if ( s.data && s.processData && typeof s.data !== "string" ) {
7236			s.data = jQuery.param( s.data, s.traditional );
7237		}
7238
7239		// Apply prefilters
7240		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7241
7242		// If request was aborted inside a prefiler, stop there
7243		if ( state === 2 ) {
7244			return false;
7245		}
7246
7247		// We can fire global events as of now if asked to
7248		fireGlobals = s.global;
7249
7250		// Uppercase the type
7251		s.type = s.type.toUpperCase();
7252
7253		// Determine if request has content
7254		s.hasContent = !rnoContent.test( s.type );
7255
7256		// Watch for a new set of requests
7257		if ( fireGlobals && jQuery.active++ === 0 ) {
7258			jQuery.event.trigger( "ajaxStart" );
7259		}
7260
7261		// More options handling for requests with no content
7262		if ( !s.hasContent ) {
7263
7264			// If data is available, append data to url
7265			if ( s.data ) {
7266				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7267			}
7268
7269			// Get ifModifiedKey before adding the anti-cache parameter
7270			ifModifiedKey = s.url;
7271
7272			// Add anti-cache in url if needed
7273			if ( s.cache === false ) {
7274
7275				var ts = jQuery.now(),
7276					// try replacing _= if it is there
7277					ret = s.url.replace( rts, "$1_=" + ts );
7278
7279				// if nothing was replaced, add timestamp to the end
7280				s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7281			}
7282		}
7283
7284		// Set the correct header, if data is being sent
7285		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7286			jqXHR.setRequestHeader( "Content-Type", s.contentType );
7287		}
7288
7289		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7290		if ( s.ifModified ) {
7291			ifModifiedKey = ifModifiedKey || s.url;
7292			if ( jQuery.lastModified[ ifModifiedKey ] ) {
7293				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7294			}
7295			if ( jQuery.etag[ ifModifiedKey ] ) {
7296				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7297			}
7298		}
7299
7300		// Set the Accepts header for the server, depending on the dataType
7301		jqXHR.setRequestHeader(
7302			"Accept",
7303			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7304				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
7305				s.accepts[ "*" ]
7306		);
7307
7308		// Check for headers option
7309		for ( i in s.headers ) {
7310			jqXHR.setRequestHeader( i, s.headers[ i ] );
7311		}
7312
7313		// Allow custom headers/mimetypes and early abort
7314		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7315				// Abort if not done already
7316				jqXHR.abort();
7317				return false;
7318
7319		}
7320
7321		// Install callbacks on deferreds
7322		for ( i in { success: 1, error: 1, complete: 1 } ) {
7323			jqXHR[ i ]( s[ i ] );
7324		}
7325
7326		// Get transport
7327		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7328
7329		// If no transport, we auto-abort
7330		if ( !transport ) {
7331			done( -1, "No Transport" );
7332		} else {
7333			jqXHR.readyState = 1;
7334			// Send global event
7335			if ( fireGlobals ) {
7336				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7337			}
7338			// Timeout
7339			if ( s.async && s.timeout > 0 ) {
7340				timeoutTimer = setTimeout( function(){
7341					jqXHR.abort( "timeout" );
7342				}, s.timeout );
7343			}
7344
7345			try {
7346				state = 1;
7347				transport.send( requestHeaders, done );
7348			} catch (e) {
7349				// Propagate exception as error if not done
7350				if ( status < 2 ) {
7351					done( -1, e );
7352				// Simply rethrow otherwise
7353				} else {
7354					jQuery.error( e );
7355				}
7356			}
7357		}
7358
7359		return jqXHR;
7360	},
7361
7362	// Serialize an array of form elements or a set of
7363	// key/values into a query string
7364	param: function( a, traditional ) {
7365		var s = [],
7366			add = function( key, value ) {
7367				// If value is a function, invoke it and return its value
7368				value = jQuery.isFunction( value ) ? value() : value;
7369				s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7370			};
7371
7372		// Set traditional to true for jQuery <= 1.3.2 behavior.
7373		if ( traditional === undefined ) {
7374			traditional = jQuery.ajaxSettings.traditional;
7375		}
7376
7377		// If an array was passed in, assume that it is an array of form elements.
7378		if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7379			// Serialize the form elements
7380			jQuery.each( a, function() {
7381				add( this.name, this.value );
7382			});
7383
7384		} else {
7385			// If traditional, encode the "old" way (the way 1.3.2 or older
7386			// did it), otherwise encode params recursively.
7387			for ( var prefix in a ) {
7388				buildParams( prefix, a[ prefix ], traditional, add );
7389			}
7390		}
7391
7392		// Return the resulting serialization
7393		return s.join( "&" ).replace( r20, "+" );
7394	}
7395});
7396
7397function buildParams( prefix, obj, traditional, add ) {
7398	if ( jQuery.isArray( obj ) ) {
7399		// Serialize array item.
7400		jQuery.each( obj, function( i, v ) {
7401			if ( traditional || rbracket.test( prefix ) ) {
7402				// Treat each array item as a scalar.
7403				add( prefix, v );
7404
7405			} else {
7406				// If array item is non-scalar (array or object), encode its
7407				// numeric index to resolve deserialization ambiguity issues.
7408				// Note that rack (as of 1.0.0) can't currently deserialize
7409				// nested arrays properly, and attempting to do so may cause
7410				// a server error. Possible fixes are to modify rack's
7411				// deserialization algorithm or to provide an option or flag
7412				// to force array serialization to be shallow.
7413				buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7414			}
7415		});
7416
7417	} else if ( !traditional && obj != null && typeof obj === "object" ) {
7418		// Serialize object item.
7419		for ( var name in obj ) {
7420			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7421		}
7422
7423	} else {
7424		// Serialize scalar item.
7425		add( prefix, obj );
7426	}
7427}
7428
7429// This is still on the jQuery object... for now
7430// Want to move this to jQuery.ajax some day
7431jQuery.extend({
7432
7433	// Counter for holding the number of active queries
7434	active: 0,
7435
7436	// Last-Modified header cache for next request
7437	lastModified: {},
7438	etag: {}
7439
7440}
7440);
7441
7442/* Handles responses to an ajax request:
7443 * - sets all responseXXX fields accordingly
7444 * - finds the right dataType (mediates between content-type and expected dataType)
7445 * - returns the corresponding response
7446 */
7447function ajaxHandleResponses( s, jqXHR, responses ) {
7448
7449	var contents = s.contents,
7450		dataTypes = s.dataTypes,
7451		responseFields = s.responseFields,
7452		ct,
7453		type,
7454		finalDataType,
7455		firstDataType;
7456
7457	// Fill responseXXX fields
7458	for( type in responseFields ) {
7459		if ( type in responses ) {
7460			jqXHR[ responseFields[type] ] = responses[ type ];
7461		}
7462	}
7463
7464	// Remove auto dataType and get content-type in the process
7465	while( dataTypes[ 0 ] === "*" ) {
7466		dataTypes.shift();
7467		if ( ct === undefined ) {
7468			ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7469		}
7470	}
7471
7472	// Check if we're dealing with a known content-type
7473	if ( ct ) {
7474		for ( type in contents ) {
7475			if ( contents[ type ] && contents[ type ].test( ct ) ) {
7476				dataTypes.unshift( type );
7477				break;
7478			}
7479		}
7480	}
7481
7482	// Check to see if we have a response for the expected dataType
7483	if ( dataTypes[ 0 ] in responses ) {
7484		finalDataType = dataTypes[ 0 ];
7485	} else {
7486		// Try convertible dataTypes
7487		for ( type in responses ) {
7488			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7489				finalDataType = type;
7490				break;
7491			}
7492			if ( !firstDataType ) {
7493				firstDataType = type;
7494			}
7495		}
7496		// Or just use first one
7497		finalDataType = finalDataType || firstDataType;
7498	}
7499
7500	// If we found a dataType
7501	// We add the dataType to the list if needed
7502	// and return the corresponding response
7503	if ( finalDataType ) {
7504		if ( finalDataType !== dataTypes[ 0 ] ) {
7505			dataTypes.unshift( finalDataType );
7506		}
7507		return responses[ finalDataType ];
7508	}
7509}
7510
7511// Chain conversions given the request and the original response
7512function ajaxConvert( s, response ) {
7513
7514	// Apply the dataFilter if provided
7515	if ( s.dataFilter ) {
7516		response = s.dataFilter( response, s.dataType );
7517	}
7518
7519	var dataTypes = s.dataTypes,
7520		converters = {},
7521		i,
7522		key,
7523		length = dataTypes.length,
7524		tmp,
7525		// Current and previous dataTypes
7526		current = dataTypes[ 0 ],
7527		prev,
7528		// Conversion expression
7529		conversion,
7530		// Conversion function
7531		conv,
7532		// Conversion functions (transitive conversion)
7533		conv1,
7534		conv2;
7535
7536	// For each dataType in the chain
7537	for( i = 1; i < length; i++ ) {
7538
7539		// Create converters map
7540		// with lowercased keys
7541		if ( i === 1 ) {
7542			for( key in s.converters ) {
7543				if( typeof key === "string" ) {
7544					converters[ key.toLowerCase() ] = s.converters[ key ];
7545				}
7546			}
7547		}
7548
7549		// Get the dataTypes
7550		prev = current;
7551		current = dataTypes[ i ];
7552
7553		// If current is auto dataType, update it to prev
7554		if( current === "*" ) {
7555			current = prev;
7556		// If no auto and dataTypes are actually different
7557		} else if ( prev !== "*" && prev !== current ) {
7558
7559			// Get the converter
7560			conversion = prev + " " + current;
7561			conv = converters[ conversion ] || converters[ "* " + current ];
7562
7563			// If there is no direct converter, search transitively
7564			if ( !conv ) {
7565				conv2 = undefined;
7566				for( conv1 in converters ) {
7567					tmp = conv1.split( " " );
7568					if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7569						conv2 = converters[ tmp[1] + " " + current ];
7570						if ( conv2 ) {
7571							conv1 = converters[ conv1 ];
7572							if ( conv1 === true ) {
7573								conv = conv2;
7574							} else if ( conv2 === true ) {
7575								conv = conv1;
7576							}
7577							break;
7578						}
7579					}
7580				}
7581			}
7582			// If we found no converter, dispatch an error
7583			if ( !( conv || conv2 ) ) {
7584				jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7585			}
7586			// If found converter is not an equivalence
7587			if ( conv !== true ) {
7588				// Convert with 1 or 2 converters accordingly
7589				response = conv ? conv( response ) : conv2( conv1(response) );
7590			}
7591		}
7592	}
7593	return response;
7594}
7595
7596
7597
7598
7599var jsc = jQuery.now(),
7600	jsre = /(\=)\?(&|$)|\?\?/i;
7601
7602// Default jsonp settings
7603jQuery.ajaxSetup({
7604	jsonp: "callback",
7605	jsonpCallback: function() {
7606		return jQuery.expando + "_" + ( jsc++ );
7607	}
7608});
7609
7610// Detect, normalize options and install callbacks for jsonp requests
7611jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7612
7613	var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7614		( typeof s.data === "string" );
7615
7616	if ( s.dataTypes[ 0 ] === "jsonp" ||
7617		s.jsonp !== false && ( jsre.test( s.url ) ||
7618				inspectData && jsre.test( s.data ) ) ) {
7619
7620		var responseContainer,
7621			jsonpCallback = s.jsonpCallback =
7622				jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7623			previous = window[ jsonpCallback ],
7624			url = s.url,
7625			data = s.data,
7626			replace = "$1" + jsonpCallback + "$2";
7627
7628		if ( s.jsonp !== false ) {
7629			url = url.replace( jsre, replace );
7630			if ( s.url === url ) {
7631				if ( inspectData ) {
7632					data = data.replace( jsre, replace );
7633				}
7634				if ( s.data === data ) {
7635					// Add callback manually
7636					url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7637				}
7638			}
7639		}
7640
7641		s.url = url;
7642		s.data = data;
7643
7644		// Install callback
7645		window[ jsonpCallback ] = function( response ) {
7646			responseContainer = [ response ];
7647		};
7648
7649		// Clean-up function
7650		jqXHR.always(function() {
7651			// Set callback back to previous value
7652			window[ jsonpCallback ] = previous;
7653			// Call if it was a function and we have a response
7654			if ( responseContainer && jQuery.isFunction( previous ) ) {
7655				window[ jsonpCallback ]( responseContainer[ 0 ] );
7656			}
7657		});
7658
7659		// Use data converter to retrieve json after script execution
7660		s.converters["script json"] = function() {
7661			if ( !responseContainer ) {
7662				jQuery.error( jsonpCallback + " was not called" );
7663			}
7664			return responseContainer[ 0 ];
7665		};
7666
7667		// force json dataType
7668		s.dataTypes[ 0 ] = "json";
7669
7670		// Delegate to script
7671		return "script";
7672	}
7673});
7674
7675
7676
7677
7678// Install script dataType
7679jQuery.ajaxSetup({
7680	accepts: {
7681		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7682	},
7683	contents: {
7684		script: /javascript|ecmascript/
7685	},
7686	converters: {
7687		"text script": function( text ) {
7688			jQuery.globalEval( text );
7689			return text;
7690		}
7691	}
7692});
7693
7694// Handle cache's special case and global
7695jQuery.ajaxPrefilter( "script", function( s ) {
7696	if ( s.cache === undefined ) {
7697		s.cache = false;
7698	}
7699	if ( s.crossDomain ) {
7700		s.type = "GET";
7701		s.global = false;
7702	}
7703});
7704
7705// Bind script tag hack transport
7706jQuery.ajaxTransport( "script", function(s) {
7707
7708	// This transport only deals with cross domain requests
7709	if ( s.crossDomain ) {
7710
7711		var script,
7712			head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7713
7714		return {
7715
7716			send: function( _, callback ) {
7717
7718				script = document.createElement( "script" );
7719
7720				script.async = "async";
7721
7722				if ( s.scriptCharset ) {
7723					script.charset = s.scriptCharset;
7724				}
7725
7726				script.src = s.url;
7727
7728				// Attach handlers for all browsers
7729				script.onload = script.onreadystatechange = function( _, isAbort ) {
7730
7731					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7732
7733						// Handle memory leak in IE
7734						script.onload = script.onreadystatechange = null;
7735
7736						// Remove the script
7737						if ( head && script.parentNode ) {
7738							head.removeChild( script );
7739						}
7740
7741						// Dereference the script
7742						script = undefined;
7743
7744						// Callback if not abort
7745						if ( !isAbort ) {
7746							callback( 200, "success" );
7747						}
7748					}
7749				};
7750				// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
7751				// This arises when a base node is used (#2709 and #4378).
7752				head.insertBefore( script, head.firstChild );
7753			},
7754
7755			abort: function() {
7756				if ( script ) {
7757					script.onload( 0, 1 );
7758				}
7759			}
7760		};
7761	}
7762});
7763
7764
7765
7766
7767var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7768	xhrOnUnloadAbort = window.ActiveXObject ? function() {
7769		// Abort all pending requests
7770		for ( var key in xhrCallbacks ) {
7771			xhrCallbacks[ key ]( 0, 1 );
7772		}
7773	} : false,
7774	xhrId = 0,
7775	xhrCallbacks;
7776
7777// Functions to create xhrs
7778function createStandardXHR() {
7779	try {
7780		return new window.XMLHttpRequest();
7781	} catch( e ) {}
7782}
7783
7784function createActiveXHR() {
7785	try {
7786		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7787	} catch( e ) {}
7788}
7789
7790// Create the request object
7791// (This is still attached to ajaxSettings for backward compatibility)
7792jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7793	/* Microsoft failed to properly
7794	 * implement the XMLHttpRequest in IE7 (can't request local files),
7795	 * so we use the ActiveXObject when it is available
7796	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7797	 * we need a fallback.
7798	 */
7799	function() {
7800		return !this.isLocal && createStandardXHR() || createActiveXHR();
7801	} :
7802	// For all other browsers, use the standard XMLHttpRequest object
7803	createStandardXHR;
7804
7805// Determine support properties
7806(function( xhr ) {
7807	jQuery.extend( jQuery.support, {
7808		ajax: !!xhr,
7809		cors: !!xhr && ( "withCredentials" in xhr )
7810	});
7811})( jQuery.ajaxSettings.xhr() );
7812
7813// Create transport if the browser can provide an xhr
7814if ( jQuery.support.ajax ) {
7815
7816	jQuery.ajaxTransport(function( s ) {
7817		// Cross domain only allowed if supported through XMLHttpRequest
7818		if ( !s.crossDomain || jQuery.support.cors ) {
7819
7820			var callback;
7821
7822			return {
7823				send: function( headers, complete ) {
7824
7825					// Get a new xhr
7826					var xhr = s.xhr(),
7827						handle,
7828						i;
7829
7830					// Open the socket
7831					// Passing null username, generates a login popup on Opera (#2865)
7832					if ( s.username ) {
7833						xhr.open( s.type, s.url, s.async, s.username, s.password );
7834					} else {
7835						xhr.open( s.type, s.url, s.async );
7836					}
7837
7838					// Apply custom fields if provided
7839					if ( s.xhrFields ) {
7840						for ( i in s.xhrFields ) {
7841							xhr[ i ] = s.xhrFields[ i ];
7842						}
7843					}
7844
7845					// Override mime type if needed
7846					if ( s.mimeType && xhr.overrideMimeType ) {
7847						xhr.overrideMimeType( s.mimeType );
7848					}
7849
7850					// X-Requested-With header
7851					// For cross-domain requests, seeing as conditions for a preflight are
7852					// akin to a jigsaw puzzle, we simply never set it to be sure.
7853					// (it can always be set on a per-request basis or even using ajaxSetup)
7854					// For same-domain requests, won't change header if already provided.
7855					if ( !s.crossDomain && !headers["X-Requested-With"] ) {
7856						headers[ "X-Requested-With" ] = "XMLHttpRequest";
7857					}
7858
7859					// Need an extra try/catch for cross domain requests in Firefox 3
7860					try {
7861						for ( i in headers ) {
7862							xhr.setRequestHeader( i, headers[ i ] );
7863						}
7864					} catch( _ ) {}
7865
7866					// Do send the request
7867					// This may raise an exception which is actually
7868					// handled in jQuery.ajax (so no try/catch here)
7869					xhr.send( ( s.hasContent && s.data ) || null );
7870
7871					// Listener
7872					callback = function( _, isAbort ) {
7873
7874						var status,
7875							statusText,
7876							responseHeaders,
7877							responses,
7878							xml;
7879
7880						// Firefox throws exceptions when accessing properties
7881						// of an xhr when a network error occured
7882						// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
7883						try {
7884
7885							// Was never called and is aborted or complete
7886							if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7887
7888								// Only called once
7889								callback = undefined;
7890
7891								// Do not keep as active anymore
7892								if ( handle ) {
7893									xhr.onreadystatechange = jQuery.noop;
7894									if ( xhrOnUnloadAbort ) {
7895										delete xhrCallbacks[ handle ];
7896									}
7897								}
7898
7899								// If it's an abort
7900								if ( isAbort ) {
7901									// Abort it manually if needed
7902									if ( xhr.readyState !== 4 ) {
7903										xhr.abort();
7904									}
7905								} else {
7906									status = xhr.status;
7907									responseHeaders = xhr.getAllResponseHeaders();
7908									responses = {};
7909									xml = xhr.responseXML;
7910
7911									// Construct response list
7912									if ( xml && xml.documentElement /* #4958 */ ) {
7913										responses.xml = xml;
7914									}
7915									responses.text = xhr.responseText;
7916
7917									// Firefox throws an exception when accessing
7918									// statusText for faulty cross-domain requests
7919									try {
7920										statusText = xhr.statusText;
7921									} catch( e ) {
7922										// We normalize with Webkit giving an empty statusText
7923										statusText = "";
7924									}
7925
7926									// Filter status for non standard behaviors
7927
7928									// If the request is local and we have data: assume a success
7929									// (success with no data won't get notified, that's the best we
7930									// can do given current implementations)
7931									if ( !status && s.isLocal && !s.crossDomain ) {
7932										status = responses.text ? 200 : 404;
7933									// IE - #1450: sometimes returns 1223 when it should be 204
7934									} else if ( status === 1223 ) {
7935										status = 204;
7936									}
7937								}
7938							}
7939						} catch( firefoxAccessException ) {
7940							if ( !isAbort ) {
7941								complete( -1, firefoxAccessException );
7942							}
7943						}
7944
7945						// Call complete if needed
7946						if ( responses ) {
7947							complete( status, statusText, responses, responseHeaders );
7948						}
7949					};
7950
7951					// if we're in sync mode or it's in cache
7952					// and has been retrieved directly (IE6 & IE7)
7953					// we need to manually fire the callback
7954					if ( !s.async || xhr.readyState === 4 ) {
7955						callback();
7956					} else {
7957						handle = ++xhrId;
7958						if ( xhrOnUnloadAbort ) {
7959							// Create the active xhrs callbacks list if needed
7960							// and attach the unload handler
7961							if ( !xhrCallbacks ) {
7962								xhrCallbacks = {};
7963								jQuery( window ).unload( xhrOnUnloadAbort );
7964							}
7965							// Add to list of active xhrs callbacks
7966							xhrCallbacks[ handle ] = callback;
7967						}
7968						xhr.onreadystatechange = callback;
7969					}
7970				},
7971
7972				abort: function() {
7973					if ( callback ) {
7974						callback(0,1);
7975					}
7976				}
7977			};
7978		}
7979	});
7980}
7981
7982
7983
7984
7985var elemdisplay = {},
7986	iframe, iframeDoc,
7987	rfxtypes = /^(?:toggle|show|hide)$/,
7988	rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
7989	timerId,
7990	fxAttrs = [
7991		// height animations
7992		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
7993		// width animations
7994		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
7995		// opacity animations
7996		[ "opacity" ]
7997	],
7998	fxNow,
7999	requestAnimationFrame = window.webkitRequestAnimationFrame ||
8000		window.mozRequestAnimationFrame ||
8001		window.oRequestAnimationFrame;
8002
8003jQuery.fn.extend({
8004	show: function( speed, easing, callback ) {
8005		var elem, display;
8006
8007		if ( speed || speed === 0 ) {
8008			return this.animate( genFx("show", 3), speed, easing, callback);
8009
8010		} else {
8011			for ( var i = 0, j = this.length; i < j; i++ ) {
8012				elem = this[i];
8013
8014				if ( elem.style ) {
8015					display = elem.style.display;
8016
8017					// Reset the inline display of this element to learn if it is
8018					// being hidden by cascaded rules or not
8019					if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8020						display = elem.style.display = "";
8021					}
8022
8023					// Set elements which have been overridden with display: none
8024					// in a stylesheet to whatever the default browser style is
8025					// for such an element
8026					if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
8027						jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
8028					}
8029				}
8030			}
8031
8032			// Set the display of most of the elements in a second loop
8033			// to avoid the constant reflow
8034			for ( i = 0; i < j; i++ ) {
8035				elem = this[i];
8036
8037				if ( elem.style ) {
8038					display = elem.style.display;
8039
8040					if ( display === "" || display === "none" ) {
8041						elem.style.display = jQuery._data(elem, "olddisplay") || "";
8042					}
8043				}
8044			}
8045
8046			return this;
8047		}
8048	},
8049
8050	hide: function( speed, easing, callback ) {
8051		if ( speed || speed === 0 ) {
8052			return this.animate( genFx("hide", 3), speed, easing, callback);
8053
8054		} else {
8055			for ( var i = 0, j = this.length; i < j; i++ ) {
8056				if ( this[i].style ) {
8057					var display = jQuery.css( this[i], "display" );
8058
8059					if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8060						jQuery._data( this[i], "olddisplay", display );
8061					}
8062				}
8063			}
8064
8065			// Set the display of the elements in a second loop
8066			// to avoid the constant reflow
8067			for ( i = 0; i < j; i++ ) {
8068				if ( this[i].style ) {
8069					this[i].style.display = "none";
8070				}
8071			}
8072
8073			return this;
8074		}
8075	},
8076
8077	// Save the old toggle function
8078	_toggle: jQuery.fn.toggle,
8079
8080	toggle: function( fn, fn2, callback ) {
8081		var bool = typeof fn === "boolean";
8082
8083		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8084			this._toggle.apply( this, arguments );
8085
8086		} else if ( fn == null || bool ) {
8087			this.each(function() {
8088				var state = bool ? fn : jQuery(this).is(":hidden");
8089				jQuery(this)[ state ? "show" : "hide" ]();
8090			});
8091
8092		} else {
8093			this.animate(genFx("toggle", 3), fn, fn2, callback);
8094		}
8095
8096		return this;
8097	},
8098
8099	fadeTo: function( speed, to, easing, callback ) {
8100		return this.filter(":hidden").css("opacity", 0).show().end()
8101					.animate({opacity: to}, speed, easing, callback);
8102	},
8103
8104	animate: function( prop, speed, easing, callback ) {
8105		var optall = jQuery.speed(speed, easing, callback);
8106
8107		if ( jQuery.isEmptyObject( prop ) ) {
8108			return this.each( optall.complete, [ false ] );
8109		}
8110
8111		// Do not change referenced properties as per-property easing will be lost
8112		prop = jQuery.extend( {}, prop );
8113
8114		return this[ optall.queue === false ? "each" : "queue" ](function() {
8115			// XXX 'this' does not always have a nodeName when running the
8116			// test suite
8117
8118			if ( optall.queue === false ) {
8119				jQuery._mark( this );
8120			}
8121
8122			var opt = jQuery.extend( {}, optall ),
8123				isElement = this.nodeType === 1,
8124				hidden = isElement && jQuery(this).is(":hidden"),
8125				name, val, p,
8126				display, e,
8127				parts, start, end, unit;
8128
8129			// will store per property easing and be used to determine when an animation is complete
8130			opt.animatedProperties = {};
8131
8132			for ( p in prop ) {
8133
8134				// property name normalization
8135				name = jQuery.camelCase( p );
8136				if ( p !== name ) {
8137					prop[ name ] = prop[ p ];
8138					delete prop[ p ];
8139				}
8140
8141				val = prop[ name ];
8142
8143				// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8144				if ( jQuery.isArray( val ) ) {
8145					opt.animatedProperties[ name ] = val[ 1 ];
8146					val = prop[ name ] = val[ 0 ];
8147				} else {
8148					opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8149				}
8150
8151				if ( val === "hide" && hidden || val === "show" && !hidden ) {
8152					return opt.complete.call( this );
8153				}
8154
8155				if ( isElement && ( name === "height" || name === "width" ) ) {
8156					// Make sure that nothing sneaks out
8157					// Record all 3 overflow attributes because IE does not
8158					// change the overflow attribute when overflowX and
8159					// overflowY are set to the same value
8160					opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8161
8162					// Set display property to inline-block for height/width
8163					// animations on inline elements that are having width/height
8164					// animated
8165					if ( jQuery.css( this, "display" ) === "inline" &&
8166							jQuery.css( this, "float" ) === "none" ) {
8167						if ( !jQuery.support.inlineBlockNeedsLayout ) {
8168							this.style.display = "inline-block";
8169
8170						} else {
8171							display = defaultDisplay( this.nodeName );
8172
8173							// inline-level elements accept inline-block;
8174							// block-level elements need to be inline with layout
8175							if ( display === "inline" ) {
8176								this.style.display = "inline-block";
8177
8178							} else {
8179								this.style.display = "inline";
8180								this.style.zoom = 1;
8181							}
8182						}
8183					}
8184				}
8185			}
8186
8187			if ( opt.overflow != null ) {
8188				this.style.overflow = "hidden";
8189			}
8190
8191			for ( p in prop ) {
8192				e = new jQuery.fx( this, opt, p );
8193				val = prop[ p ];
8194
8195				if ( rfxtypes.test(val) ) {
8196					e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8197
8198				} else {
8199					parts = rfxnum.exec( val );
8200					start = e.cur();
8201
8202					if ( parts ) {
8203						end = parseFloat( parts[2] );
8204						unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8205
8206						// We need to compute starting value
8207						if ( unit !== "px" ) {
8208							jQuery.style( this, p, (end || 1) + unit);
8209							start = ((end || 1) / e.cur()) * start;
8210							jQuery.style( this, p, start + unit);
8211						}
8212
8213						// If a +=/-= token was provided, we're doing a relative animation
8214						if ( parts[1] ) {
8215							end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8216						}
8217
8218						e.custom( start, end, unit );
8219
8220					} else {
8221						e.custom( start, val, "" );
8222					}
8223				}
8224			}
8225
8226			// For JS strict compliance
8227			return true;
8228		});
8229	},
8230
8231	stop: function( clearQueue, gotoEnd ) {
8232		if ( clearQueue ) {
8233			this.queue([]);
8234		}
8235
8236		this.each(function() {
8237			var timers = jQuery.timers,
8238				i = timers.length;
8239			// clear marker counters if we know they won't be
8240			if ( !gotoEnd ) {
8241				jQuery._unmark( true, this );
8242			}
8243			while ( i-- ) {
8244				if ( timers[i].elem === this ) {
8245					if (gotoEnd) {
8246						// force the next step to be the last
8247						timers[i](true);
8248					}
8249
8250					timers.splice(i, 1);
8251				}
8252			}
8253		});
8254
8255		// start the next in the queue if the last step wasn't forced
8256		if ( !gotoEnd ) {
8257			this.dequeue();
8258		}
8259
8260		return this;
8261	}
8262
8263});
8264
8265// Animations created synchronously will run synchronously
8266function createFxNow() {
8267	setTimeout( clearFxNow, 0 );
8268	return ( fxNow = jQuery.now() );
8269}
8270
8271function clearFxNow() {
8272	fxNow = undefined;
8273}
8274
8275// Generate parameters to create a standard animation
8276function genFx( type, num ) {
8277	var obj = {};
8278
8279	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8280		obj[ this ] = type;
8281	});
8282
8283	return obj;
8284}
8285
8286// Generate shortcuts for custom animations
8287jQuery.each({
8288	slideDown: genFx("show", 1),
8289	slideUp: genFx("hide", 1),
8290	slideToggle: genFx("toggle", 1),
8291	fadeIn: { opacity: "show" },
8292	fadeOut: { opacity: "hide" },
8293	fadeToggle: { opacity: "toggle" }
8294}, function( name, props ) {
8295	jQuery.fn[ name ] = function( speed, easing, callback ) {
8296		return this.animate( props, speed, easing, callback );
8297	};
8298});
8299
8300jQuery.extend({
8301	speed: function( speed, easing, fn ) {
8302		var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8303			complete: fn || !fn && easing ||
8304				jQuery.isFunction( speed ) && speed,
8305			duration: speed,
8306			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8307		};
8308
8309		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8310			opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8311
8312		// Queueing
8313		opt.old = opt.complete;
8314		opt.complete = function( noUnmark ) {
8315			if ( jQuery.isFunction( opt.old ) ) {
8316				opt.old.call( this );
8317			}
8318
8319			if ( opt.queue !== false ) {
8320				jQuery.dequeue( this );
8321			} else if ( noUnmark !== false ) {
8322				jQuery._unmark( this );
8323			}
8324		};
8325
8326		return opt;
8327	},
8328
8329	easing: {
8330		linear: function( p, n, firstNum, diff ) {
8331			return firstNum + diff * p;
8332		},
8333		swing: function( p, n, firstNum, diff ) {
8334			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8335		}
8336	},
8337
8338	timers: [],
8339
8340	fx: function( elem, options, prop ) {
8341		this.options = options;
8342		this.elem = elem;
8343		this.prop = prop;
8344
8345		options.orig = options.orig || {};
8346	}
8347
8348});
8349
8350jQuery.fx.prototype = {
8351	// Simple function for setting a style value
8352	update: function() {
8353		if ( this.options.step ) {
8354			this.options.step.call( this.elem, this.now, this );
8355		}
8356
8357		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8358	},
8359
8360	// Get the current size
8361	cur: function() {
8362		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8363			return this.elem[ this.prop ];
8364		}
8365
8366		var parsed,
8367			r = jQuery.css( this.elem, this.prop );
8368		// Empty strings, null, undefined and "auto" are converted to 0,
8369		// complex values such as "rotate(1rad)" are returned as is,
8370		// simple values such as "10px" are parsed to Float.
8371		return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8372	},
8373
8374	// Start an animation from one number to another
8375	custom: function( from, to, unit ) {
8376		var self = this,
8377			fx = jQuery.fx,
8378			raf;
8379
8380		this.startTime = fxNow || createFxNow();
8381		this.start = from;
8382		this.end = to;
8383		this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8384		this.now = this.start;
8385		this.pos = this.state = 0;
8386
8387		function t( gotoEnd ) {
8388			return self.step(gotoEnd);
8389		}
8390
8391		t.elem = this.elem;
8392
8393		if ( t() && jQuery.timers.push(t) && !timerId ) {
8394			// Use requestAnimationFrame instead of setInterval if available
8395			if ( requestAnimationFrame ) {
8396				timerId = true;
8397				raf = function() {
8398					// When timerId gets set to null at any point, this stops
8399					if ( timerId ) {
8400						requestAnimationFrame( raf );
8401						fx.tick();
8402					}
8403				};
8404				requestAnimationFrame( raf );
8405			} else {
8406				timerId = setInterval( fx.tick, fx.interval );
8407			}
8408		}
8409	},
8410
8411	// Simple 'show' function
8412	show: function() {
8413		// Remember where we started, so that we can go back to it later
8414		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8415		this.options.show = true;
8416
8417		// Begin the animation
8418		// Make sure that we start at a small width/height to avoid any
8419		// flash of content
8420		this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
8421
8422		// Start by showing the element
8423		jQuery( this.elem ).show();
8424	},
8425
8426	// Simple 'hide' function
8427	hide: function() {
8428		// Remember where we started, so that we can go back to it later
8429		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8430		this.options.hide = true;
8431
8432		// Begin the animation
8433		this.custom(this.cur(), 0);
8434	},
8435
8436	// Each step of an animation
8437	step: function( gotoEnd ) {
8438		var t = fxNow || createFxNow(),
8439			done = true,
8440			elem = this.elem,
8441			options = this.options,
8442			i, n;
8443
8444		if ( gotoEnd || t >= options.duration + this.startTime ) {
8445			this.now = this.end;
8446			this.pos = this.state = 1;
8447			this.update();
8448
8449			options.animatedProperties[ this.prop ] = true;
8450
8451			for ( i in options.animatedProperties ) {
8452				if ( options.animatedProperties[i] !== true ) {
8453					done = false;
8454				}
8455			}
8456
8457			if ( done ) {
8458				// Reset the overflow
8459				if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8460
8461					jQuery.each( [ "", "X", "Y" ], function (index, value) {
8462						elem.style[ "overflow" + value ] = options.overflow[index];
8463					});
8464				}
8465
8466				// Hide the element if the "hide" operation was done
8467				if ( options.hide ) {
8468					jQuery(elem).hide();
8469				}
8470
8471				// Reset the properties, if the item has been hidden or shown
8472				if ( options.hide || options.show ) {
8473					for ( var p in options.animatedProperties ) {
8474						jQuery.style( elem, p, options.orig[p] );
8475					}
8476				}
8477
8478				// Execute the complete function
8479				options.complete.call( elem );
8480			}
8481
8482			return false;
8483
8484		} else {
8485			// classical easing cannot be used with an Infinity duration
8486			if ( options.duration == Infinity ) {
8487				this.now = t;
8488			} else {
8489				n = t - this.startTime;
8490				this.state = n / options.duration;
8491
8492				// Perform the easing function, defaults to swing
8493				this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
8494				this.now = this.start + ((this.end - this.start) * this.pos);
8495			}
8496			// Perform the next step of the animation
8497			this.update();
8498		}
8499
8500		return true;
8501	}
8502};
8503
8504jQuery.extend( jQuery.fx, {
8505	tick: function() {
8506		for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
8507			if ( !timers[i]() ) {
8508				timers.splice(i--, 1);
8509			}
8510		}
8511
8512		if ( !timers.length ) {
8513			jQuery.fx.stop();
8514		}
8515	},
8516
8517	interval: 13,
8518
8519	stop: function() {
8520		clearInterval( timerId );
8521		timerId = null;
8522	},
8523
8524	speeds: {
8525		slow: 600,
8526		fast: 200,
8527		// Default speed
8528		_default: 400
8529	},
8530
8531	step: {
8532		opacity: function( fx ) {
8533			jQuery.style( fx.elem, "opacity", fx.now );
8534		},
8535
8536		_default: function( fx ) {
8537			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8538				fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
8539			} else {
8540				fx.elem[ fx.prop ] = fx.now;
8541			}
8542		}
8543	}
8544});
8545
8546if ( jQuery.expr && jQuery.expr.filters ) {
8547	jQuery.expr.filters.animated = function( elem ) {
8548		return jQuery.grep(jQuery.timers, function( fn ) {
8549			return elem === fn.elem;
8550		}).length;
8551	};
8552}
8553
8554// Try to restore the default display value of an element
8555function defaultDisplay( nodeName ) {
8556
8557	if ( !elemdisplay[ nodeName ] ) {
8558
8559		var body = document.body,
8560			elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
8561			display = elem.css( "display" );
8562
8563		elem.remove();
8564
8565		// If the simple way fails,
8566		// get element's real default display by attaching it to a temp iframe
8567		if ( display === "none" || display === "" ) {
8568			// No iframe to use yet, so create it
8569			if ( !iframe ) {
8570				iframe = document.createElement( "iframe" );
8571				iframe.frameBorder = iframe.width = iframe.height = 0;
8572			}
8573
8574			body.appendChild( iframe );
8575
8576			// Create a cacheable copy of the iframe document on first call.
8577			// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
8578			// document to it; WebKit & Firefox won't allow reusing the iframe document.
8579			if ( !iframeDoc || !iframe.createElement ) {
8580				iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8581				iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
8582				iframeDoc.close();
8583			}
8584
8585			elem = iframeDoc.createElement( nodeName );
8586
8587			iframeDoc.body.appendChild( elem );
8588
8589			display = jQuery.css( elem, "display" );
8590
8591			body.removeChild( iframe );
8592		}
8593
8594		// Store the correct default display
8595		elemdisplay[ nodeName ] = display;
8596	}
8597
8598	return elemdisplay[ nodeName ];
8599}
8600
8601
8602
8603
8604var rtable = /^t(?:able|d|h)$/i,
8605	rroot = /^(?:body|html)$/i;
8606
8607if ( "getBoundingClientRect" in document.documentElement ) {
8608	jQuery.fn.offset = function( options ) {
8609		var elem = this[0], box;
8610
8611		if ( options ) {
8612			return this.each(function( i ) {
8613				jQuery.offset.setOffset( this, options, i );
8614			});
8615		}
8616
8617		if ( !elem || !elem.ownerDocument ) {
8618			return null;
8619		}
8620
8621		if ( elem === elem.ownerDocument.body ) {
8622			return jQuery.offset.bodyOffset( elem );
8623		}
8624
8625		try {
8626			box = elem.getBoundingClientRect();
8627		} catch(e) {}
8628
8629		var doc = elem.ownerDocument,
8630			docElem = doc.documentElement;
8631
8632		// Make sure we're not dealing with a disconnected DOM node
8633		if ( !box || !jQuery.contains( docElem, elem ) ) {
8634			return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8635		}
8636
8637		var body = doc.body,
8638			win = getWindow(doc),
8639			clientTop  = docElem.clientTop  || body.clientTop  || 0,
8640			clientLeft = docElem.clientLeft || body.clientLeft || 0,
8641			scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
8642			scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8643			top  = box.top  + scrollTop  - clientTop,
8644			left = box.left + scrollLeft - clientLeft;
8645
8646		return { top: top, left: left };
8647	};
8648
8649} else {
8650	jQuery.fn.offset = function( options ) {
8651		var elem = this[0];
8652
8653		if ( options ) {
8654			return this.each(function( i ) {
8655				jQuery.offset.setOffset( this, options, i );
8656			});
8657		}
8658
8659		if ( !elem || !elem.ownerDocument ) {
8660			return null;
8661		}
8662
8663		if ( elem === elem.ownerDocument.body ) {
8664			return jQuery.offset.bodyOffset( elem );
8665		}
8666
8667		jQuery.offset.initialize();
8668
8669		var computedStyle,
8670			offsetParent = elem.offsetParent,
8671			prevOffsetParent = elem,
8672			doc = elem.ownerDocument,
8673			docElem = doc.documentElement,
8674			body = doc.body,
8675			defaultView = doc.defaultView,
8676			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8677			top = elem.offsetTop,
8678			left = elem.offsetLeft;
8679
8680		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8681			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8682				break;
8683			}
8684
8685			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8686			top  -= elem.scrollTop;
8687			left -= elem.scrollLeft;
8688
8689			if ( elem === offsetParent ) {
8690				top  += elem.offsetTop;
8691				left += elem.offsetLeft;
8692
8693				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8694					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8695					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8696				}
8697
8698				prevOffsetParent = offsetParent;
8699				offsetParent = elem.offsetParent;
8700			}
8701
8702			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8703				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8704				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8705			}
8706
8707			prevComputedStyle = computedStyle;
8708		}
8709
8710		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8711			top  += body.offsetTop;
8712			left += body.offsetLeft;
8713		}
8714
8715		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8716			top  += Math.max( docElem.scrollTop, body.scrollTop );
8717			left += Math.max( docElem.scrollLeft, body.scrollLeft );
8718		}
8719
8720		return { top: top, left: left };
8721	};
8722}
8723
8724jQuery.offset = {
8725	initialize: function() {
8726		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
8727			html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
8728
8729		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8730
8731		container.innerHTML = html;
8732		body.insertBefore( container, body.firstChild );
8733		innerDiv = container.firstChild;
8734		checkDiv = innerDiv.firstChild;
8735		td = innerDiv.nextSibling.firstChild.firstChild;
8736
8737		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8738		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8739
8740		checkDiv.style.position = "fixed";
8741		checkDiv.style.top = "20px";
8742
8743		// safari subtracts parent border width here which is 5px
8744		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
8745		checkDiv.style.position = checkDiv.style.top = "";
8746
8747		innerDiv.style.overflow = "hidden";
8748		innerDiv.style.position = "relative";
8749
8750		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8751
8752		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8753
8754		body.removeChild( container );
8755		jQuery.offset.initialize = jQuery.noop;
8756	},
8757
8758	bodyOffset: function( body ) {
8759		var top = body.offsetTop,
8760			left = body.offsetLeft;
8761
8762		jQuery.offset.initialize();
8763
8764		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8765			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8766			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8767		}
8768
8769		return { top: top, left: left };
8770	},
8771
8772	setOffset: function( elem, options, i ) {
8773		var position = jQuery.css( elem, "position" );
8774
8775		// set position first, in-case top/left are set even on static elem
8776		if ( position === "static" ) {
8777			elem.style.position = "relative";
8778		}
8779
8780		var curElem = jQuery( elem ),
8781			curOffset = curElem.offset(),
8782			curCSSTop = jQuery.css( elem, "top" ),
8783			curCSSLeft = jQuery.css( elem, "left" ),
8784			calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
8785			props = {}, curPosition = {}, curTop, curLeft;
8786
8787		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8788		if ( calculatePosition ) {
8789			curPosition = curElem.position();
8790			curTop = curPosition.top;
8791			curLeft = curPosition.left;
8792		} else {
8793			curTop = parseFloat( curCSSTop ) || 0;
8794			curLeft = parseFloat( curCSSLeft ) || 0;
8795		}
8796
8797		if ( jQuery.isFunction( options ) ) {
8798			options = options.call( elem, i, curOffset );
8799		}
8800
8801		if (options.top != null) {
8802			props.top = (options.top - curOffset.top) + curTop;
8803		}
8804		if (options.left != null) {
8805			props.left = (options.left - curOffset.left) + curLeft;
8806		}
8807
8808		if ( "using" in options ) {
8809			options.using.call( elem, props );
8810		} else {
8811			curElem.css( props );
8812		}
8813	}
8814};
8815
8816
8817jQuery.fn.extend({
8818	position: function() {
8819		if ( !this[0] ) {
8820			return null;
8821		}
8822
8823		var elem = this[0],
8824
8825		// Get *real* offsetParent
8826		offsetParent = this.offsetParent(),
8827
8828		// Get correct offsets
8829		offset       = this.offset(),
8830		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
8831
8832		// Subtract element margins
8833		// note: when an element has margin: auto the offsetLeft and marginLeft
8834		// are the same in Safari causing offset.left to incorrectly be 0
8835		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
8836		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
8837
8838		// Add offsetParent borders
8839		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8840		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8841
8842		// Subtract the two offsets
8843		return {
8844			top:  offset.top  - parentOffset.top,
8845			left: offset.left - parentOffset.left
8846		};
8847	},
8848
8849	offsetParent: function() {
8850		return this.map(function() {
8851			var offsetParent = this.offsetParent || document.body;
8852			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
8853				offsetParent = offsetParent.offsetParent;
8854			}
8855			return offsetParent;
8856		});
8857	}
8858});
8859
8860
8861// Create scrollLeft and scrollTop methods
8862jQuery.each( ["Left", "Top"], function( i, name ) {
8863	var method = "scroll" + name;
8864
8865	jQuery.fn[ method ] = function( val ) {
8866		var elem, win;
8867
8868		if ( val === undefined ) {
8869			elem = this[ 0 ];
8870
8871			if ( !elem ) {
8872				return null;
8873			}
8874
8875			win = getWindow( elem );
8876
8877			// Return the scroll offset
8878			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
8879				jQuery.support.boxModel && win.document.documentElement[ method ] ||
8880					win.document.body[ method ] :
8881				elem[ method ];
8882		}
8883
8884		// Set the scroll offset
8885		return this.each(function() {
8886			win = getWindow( this );
8887
8888			if ( win ) {
8889				win.scrollTo(
8890					!i ? val : jQuery( win ).scrollLeft(),
8891					 i ? val : jQuery( win ).scrollTop()
8892				);
8893
8894			} else {
8895				this[ method ] = val;
8896			}
8897		});
8898	};
8899});
8900
8901function getWindow( elem ) {
8902	return jQuery.isWindow( elem ) ?
8903		elem :
8904		elem.nodeType === 9 ?
8905			elem.defaultView || elem.parentWindow :
8906			false;
8907}
8908
8909
8910
8911
8912// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
8913jQuery.each([ "Height", "Width" ], function( i, name ) {
8914
8915	var type = name.toLowerCase();
8916
8917	// innerHeight and innerWidth
8918	jQuery.fn[ "inner" + name ] = function() {
8919		var elem = this[0];
8920		return elem && elem.style ?
8921			parseFloat( jQuery.css( elem, type, "padding" ) ) :
8922			null;
8923	};
8924
8925	// outerHeight and outerWidth
8926	jQuery.fn[ "outer" + name ] = function( margin ) {
8927		var elem = this[0];
8928		return elem && elem.style ?
8929			parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
8930			null;
8931	};
8932
8933	jQuery.fn[ type ] = function( size ) {
8934		// Get window width or height
8935		var elem = this[0];
8936		if ( !elem ) {
8937			return size == null ? null : this;
8938		}
8939
8940		if ( jQuery.isFunction( size ) ) {
8941			return this.each(function( i ) {
8942				var self = jQuery( this );
8943				self[ type ]( size.call( this, i, self[ type ]() ) );
8944			});
8945		}
8946
8947		if ( jQuery.isWindow( elem ) ) {
8948			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
8949			// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
8950			var docElemProp = elem.document.documentElement[ "client" + name ];
8951			return elem.document.compatMode === "CSS1Compat" && docElemProp ||
8952				elem.document.body[ "client" + name ] || docElemProp;
8953
8954		// Get document width or height
8955		} else if ( elem.nodeType === 9 ) {
8956			// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
8957			return Math.max(
8958				elem.documentElement["client" + name],
8959				elem.body["scroll" + name], elem.documentElement["scroll" + name],
8960				elem.body["offset" + name], elem.documentElement["offset" + name]
8961			);
8962
8963		// Get or set width or height on the element
8964		} else if ( size === undefined ) {
8965			var orig = jQuery.css( elem, type ),
8966				ret = parseFloat( orig );
8967
8968			return jQuery.isNaN( ret ) ? orig : ret;
8969
8970		// Set the width or height on the element (default to pixels if value is unitless)
8971		} else {
8972			return this.css( type, typeof size === "string" ? size : size + "px" );
8973		}
8974	};
8975
8976});
8977
8978
8979// Expose jQuery to the global object
8980window.jQuery = window.$ = jQuery;
8981})(window);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.