xref: /freebsd/contrib/libxo/xohtml/external/jquery.js (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
1/*!
2 * jQuery JavaScript Library v1.7
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 Nov 3 16:18:21 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	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
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]|[0-9])/ig,
70	rmsPrefix = /^-ms-/,
71
72	// Used by jQuery.camelCase as callback to replace()
73	fcamelCase = function( all, letter ) {
74		return ( letter + "" ).toUpperCase();
75	},
76
77	// Keep a UserAgent string for use with jQuery.browser
78	userAgent = navigator.userAgent,
79
80	// For matching the engine and version of the browser
81	browserMatch,
82
83	// The deferred used on DOM ready
84	readyList,
85
86	// The ready event handler
87	DOMContentLoaded,
88
89	// Save a reference to some core methods
90	toString = Object.prototype.toString,
91	hasOwn = Object.prototype.hasOwnProperty,
92	push = Array.prototype.push,
93	slice = Array.prototype.slice,
94	trim = String.prototype.trim,
95	indexOf = Array.prototype.indexOf,
96
97	// [[Class]] -> type pairs
98	class2type = {};
99
100jQuery.fn = jQuery.prototype = {
101	constructor: jQuery,
102	init: function( selector, context, rootjQuery ) {
103		var match, elem, ret, doc;
104
105		// Handle $(""), $(null), or $(undefined)
106		if ( !selector ) {
107			return this;
108		}
109
110		// Handle $(DOMElement)
111		if ( selector.nodeType ) {
112			this.context = this[0] = selector;
113			this.length = 1;
114			return this;
115		}
116
117		// The body element only exists once, optimize finding it
118		if ( selector === "body" && !context && document.body ) {
119			this.context = document;
120			this[0] = document.body;
121			this.selector = selector;
122			this.length = 1;
123			return this;
124		}
125
126		// Handle HTML strings
127		if ( typeof selector === "string" ) {
128			// Are we dealing with HTML string or an ID?
129			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
130				// Assume that strings that start and end with <> are HTML and skip the regex check
131				match = [ null, selector, null ];
132
133			} else {
134				match = quickExpr.exec( selector );
135			}
136
137			// Verify a match, and that no context was specified for #id
138			if ( match && (match[1] || !context) ) {
139
140				// HANDLE: $(html) -> $(array)
141				if ( match[1] ) {
142					context = context instanceof jQuery ? context[0] : context;
143					doc = ( context ? context.ownerDocument || context : document );
144
145					// If a single string is passed in and it's a single tag
146					// just do a createElement and skip the rest
147					ret = rsingleTag.exec( selector );
148
149					if ( ret ) {
150						if ( jQuery.isPlainObject( context ) ) {
151							selector = [ document.createElement( ret[1] ) ];
152							jQuery.fn.attr.call( selector, context, true );
153
154						} else {
155							selector = [ doc.createElement( ret[1] ) ];
156						}
157
158					} else {
159						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
160						selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
161					}
162
163					return jQuery.merge( this, selector );
164
165				// HANDLE: $("#id")
166				} else {
167					elem = document.getElementById( match[2] );
168
169					// Check parentNode to catch when Blackberry 4.6 returns
170					// nodes that are no longer in the document #6963
171					if ( elem && elem.parentNode ) {
172						// Handle the case where IE and Opera return items
173						// by name instead of ID
174						if ( elem.id !== match[2] ) {
175							return rootjQuery.find( selector );
176						}
177
178						// Otherwise, we inject the element directly into the jQuery object
179						this.length = 1;
180						this[0] = elem;
181					}
182
183					this.context = document;
184					this.selector = selector;
185					return this;
186				}
187
188			// HANDLE: $(expr, $(...))
189			} else if ( !context || context.jquery ) {
190				return ( context || rootjQuery ).find( selector );
191
192			// HANDLE: $(expr, context)
193			// (which is just equivalent to: $(context).find(expr)
194			} else {
195				return this.constructor( context ).find( selector );
196			}
197
198		// HANDLE: $(function)
199		// Shortcut for document ready
200		} else if ( jQuery.isFunction( selector ) ) {
201			return rootjQuery.ready( selector );
202		}
203
204		if ( selector.selector !== undefined ) {
205			this.selector = selector.selector;
206			this.context = selector.context;
207		}
208
209		return jQuery.makeArray( selector, this );
210	},
211
212	// Start with an empty selector
213	selector: "",
214
215	// The current version of jQuery being used
216	jquery: "1.7",
217
218	// The default length of a jQuery object is 0
219	length: 0,
220
221	// The number of elements contained in the matched element set
222	size: function() {
223		return this.length;
224	},
225
226	toArray: function() {
227		return slice.call( this, 0 );
228	},
229
230	// Get the Nth element in the matched element set OR
231	// Get the whole matched element set as a clean array
232	get: function( num ) {
233		return num == null ?
234
235			// Return a 'clean' array
236			this.toArray() :
237
238			// Return just the object
239			( num < 0 ? this[ this.length + num ] : this[ num ] );
240	},
241
242	// Take an array of elements and push it onto the stack
243	// (returning the new matched element set)
244	pushStack: function( elems, name, selector ) {
245		// Build a new jQuery matched element set
246		var ret = this.constructor();
247
248		if ( jQuery.isArray( elems ) ) {
249			push.apply( ret, elems );
250
251		} else {
252			jQuery.merge( ret, elems );
253		}
254
255		// Add the old object onto the stack (as a reference)
256		ret.prevObject = this;
257
258		ret.context = this.context;
259
260		if ( name === "find" ) {
261			ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
262		} else if ( name ) {
263			ret.selector = this.selector + "." + name + "(" + selector + ")";
264		}
265
266		// Return the newly-formed element set
267		return ret;
268	},
269
270	// Execute a callback for every element in the matched set.
271	// (You can seed the arguments with an array of args, but this is
272	// only used internally.)
273	each: function( callback, args ) {
274		return jQuery.each( this, callback, args );
275	},
276
277	ready: function( fn ) {
278		// Attach the listeners
279		jQuery.bindReady();
280
281		// Add the callback
282		readyList.add( fn );
283
284		return this;
285	},
286
287	eq: function( i ) {
288		return i === -1 ?
289			this.slice( i ) :
290			this.slice( i, +i + 1 );
291	},
292
293	first: function() {
294		return this.eq( 0 );
295	},
296
297	last: function() {
298		return this.eq( -1 );
299	},
300
301	slice: function() {
302		return this.pushStack( slice.apply( this, arguments ),
303			"slice", slice.call(arguments).join(",") );
304	},
305
306	map: function( callback ) {
307		return this.pushStack( jQuery.map(this, function( elem, i ) {
308			return callback.call( elem, i, elem );
309		}));
310	},
311
312	end: function() {
313		return this.prevObject || this.constructor(null);
314	},
315
316	// For internal use only.
317	// Behaves like an Array's method, not like a jQuery method.
318	push: push,
319	sort: [].sort,
320	splice: [].splice
321};
322
323// Give the init function the jQuery prototype for later instantiation
324jQuery.fn.init.prototype = jQuery.fn;
325
326jQuery.extend = jQuery.fn.extend = function() {
327	var options, name, src, copy, copyIsArray, clone,
328		target = arguments[0] || {},
329		i = 1,
330		length = arguments.length,
331		deep = false;
332
333	// Handle a deep copy situation
334	if ( typeof target === "boolean" ) {
335		deep = target;
336		target = arguments[1] || {};
337		// skip the boolean and the target
338		i = 2;
339	}
340
341	// Handle case when target is a string or something (possible in deep copy)
342	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
343		target = {};
344	}
345
346	// extend jQuery itself if only one argument is passed
347	if ( length === i ) {
348		target = this;
349		--i;
350	}
351
352	for ( ; i < length; i++ ) {
353		// Only deal with non-null/undefined values
354		if ( (options = arguments[ i ]) != null ) {
355			// Extend the base object
356			for ( name in options ) {
357				src = target[ name ];
358				copy = options[ name ];
359
360				// Prevent never-ending loop
361				if ( target === copy ) {
362					continue;
363				}
364
365				// Recurse if we're merging plain objects or arrays
366				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
367					if ( copyIsArray ) {
368						copyIsArray = false;
369						clone = src && jQuery.isArray(src) ? src : [];
370
371					} else {
372						clone = src && jQuery.isPlainObject(src) ? src : {};
373					}
374
375					// Never move original objects, clone them
376					target[ name ] = jQuery.extend( deep, clone, copy );
377
378				// Don't bring in undefined values
379				} else if ( copy !== undefined ) {
380					target[ name ] = copy;
381				}
382			}
383		}
384	}
385
386	// Return the modified object
387	return target;
388};
389
390jQuery.extend({
391	noConflict: function( deep ) {
392		if ( window.$ === jQuery ) {
393			window.$ = _$;
394		}
395
396		if ( deep && window.jQuery === jQuery ) {
397			window.jQuery = _jQuery;
398		}
399
400		return jQuery;
401	},
402
403	// Is the DOM ready to be used? Set to true once it occurs.
404	isReady: false,
405
406	// A counter to track how many items to wait for before
407	// the ready event fires. See #6781
408	readyWait: 1,
409
410	// Hold (or release) the ready event
411	holdReady: function( hold ) {
412		if ( hold ) {
413			jQuery.readyWait++;
414		} else {
415			jQuery.ready( true );
416		}
417	},
418
419	// Handle when the DOM is ready
420	ready: function( wait ) {
421		// Either a released hold or an DOMready/load event and not yet ready
422		if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
423			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
424			if ( !document.body ) {
425				return setTimeout( jQuery.ready, 1 );
426			}
427
428			// Remember that the DOM is ready
429			jQuery.isReady = true;
430
431			// If a normal DOM Ready event fired, decrement, and wait if need be
432			if ( wait !== true && --jQuery.readyWait > 0 ) {
433				return;
434			}
435
436			// If there are functions bound, to execute
437			readyList.fireWith( document, [ jQuery ] );
438
439			// Trigger any bound ready events
440			if ( jQuery.fn.trigger ) {
441				jQuery( document ).trigger( "ready" ).unbind( "ready" );
442			}
443		}
444	},
445
446	bindReady: function() {
447		if ( readyList ) {
448			return;
449		}
450
451		readyList = jQuery.Callbacks( "once memory" );
452
453		// Catch cases where $(document).ready() is called after the
454		// browser event has already occurred.
455		if ( document.readyState === "complete" ) {
456			// Handle it asynchronously to allow scripts the opportunity to delay ready
457			return setTimeout( jQuery.ready, 1 );
458		}
459
460		// Mozilla, Opera and webkit nightlies currently support this event
461		if ( document.addEventListener ) {
462			// Use the handy event callback
463			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
464
465			// A fallback to window.onload, that will always work
466			window.addEventListener( "load", jQuery.ready, false );
467
468		// If IE event model is used
469		} else if ( document.attachEvent ) {
470			// ensure firing before onload,
471			// maybe late but safe also for iframes
472			document.attachEvent( "onreadystatechange", DOMContentLoaded );
473
474			// A fallback to window.onload, that will always work
475			window.attachEvent( "onload", jQuery.ready );
476
477			// If IE and not a frame
478			// continually check to see if the document is ready
479			var toplevel = false;
480
481			try {
482				toplevel = window.frameElement == null;
483			} catch(e) {}
484
485			if ( document.documentElement.doScroll && toplevel ) {
486				doScrollCheck();
487			}
488		}
489	},
490
491	// See test/unit/core.js for details concerning isFunction.
492	// Since version 1.3, DOM methods and functions like alert
493	// aren't supported. They return false on IE (#2968).
494	isFunction: function( obj ) {
495		return jQuery.type(obj) === "function";
496	},
497
498	isArray: Array.isArray || function( obj ) {
499		return jQuery.type(obj) === "array";
500	},
501
502	// A crude way of determining if an object is a window
503	isWindow: function( obj ) {
504		return obj && typeof obj === "object" && "setInterval" in obj;
505	},
506
507	isNumeric: function( obj ) {
508		return obj != null && rdigit.test( obj ) && !isNaN( obj );
509	},
510
511	type: function( obj ) {
512		return obj == null ?
513			String( obj ) :
514			class2type[ toString.call(obj) ] || "object";
515	},
516
517	isPlainObject: function( obj ) {
518		// Must be an Object.
519		// Because of IE, we also have to check the presence of the constructor property.
520		// Make sure that DOM nodes and window objects don't pass through, as well
521		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
522			return false;
523		}
524
525		try {
526			// Not own constructor property must be Object
527			if ( obj.constructor &&
528				!hasOwn.call(obj, "constructor") &&
529				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
530				return false;
531			}
532		} catch ( e ) {
533			// IE8,9 Will throw exceptions on certain host objects #9897
534			return false;
535		}
536
537		// Own properties are enumerated firstly, so to speed up,
538		// if last one is own, then all properties are own.
539
540		var key;
541		for ( key in obj ) {}
542
543		return key === undefined || hasOwn.call( obj, key );
544	},
545
546	isEmptyObject: function( obj ) {
547		for ( var name in obj ) {
548			return false;
549		}
550		return true;
551	},
552
553	error: function( msg ) {
554		throw msg;
555	},
556
557	parseJSON: function( data ) {
558		if ( typeof data !== "string" || !data ) {
559			return null;
560		}
561
562		// Make sure leading/trailing whitespace is removed (IE can't handle it)
563		data = jQuery.trim( data );
564
565		// Attempt to parse using the native JSON parser first
566		if ( window.JSON && window.JSON.parse ) {
567			return window.JSON.parse( data );
568		}
569
570		// Make sure the incoming data is actual JSON
571		// Logic borrowed from http://json.org/json2.js
572		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
573			.replace( rvalidtokens, "]" )
574			.replace( rvalidbraces, "")) ) {
575
576			return ( new Function( "return " + data ) )();
577
578		}
579		jQuery.error( "Invalid JSON: " + data );
580	},
581
582	// Cross-browser xml parsing
583	parseXML: function( data ) {
584		var xml, tmp;
585		try {
586			if ( window.DOMParser ) { // Standard
587				tmp = new DOMParser();
588				xml = tmp.parseFromString( data , "text/xml" );
589			} else { // IE
590				xml = new ActiveXObject( "Microsoft.XMLDOM" );
591				xml.async = "false";
592				xml.loadXML( data );
593			}
594		} catch( e ) {
595			xml = undefined;
596		}
597		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
598			jQuery.error( "Invalid XML: " + data );
599		}
600		return xml;
601	},
602
603	noop: function() {},
604
605	// Evaluates a script in a global context
606	// Workarounds based on findings by Jim Driscoll
607	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
608	globalEval: function( data ) {
609		if ( data && rnotwhite.test( data ) ) {
610			// We use execScript on Internet Explorer
611			// We use an anonymous function so that context is window
612			// rather than jQuery in Firefox
613			( window.execScript || function( data ) {
614				window[ "eval" ].call( window, data );
615			} )( data );
616		}
617	},
618
619	// Convert dashed to camelCase; used by the css and data modules
620	// Microsoft forgot to hump their vendor prefix (#9572)
621	camelCase: function( string ) {
622		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
623	},
624
625	nodeName: function( elem, name ) {
626		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
627	},
628
629	// args is for internal usage only
630	each: function( object, callback, args ) {
631		var name, i = 0,
632			length = object.length,
633			isObj = length === undefined || jQuery.isFunction( object );
634
635		if ( args ) {
636			if ( isObj ) {
637				for ( name in object ) {
638					if ( callback.apply( object[ name ], args ) === false ) {
639						break;
640					}
641				}
642			} else {
643				for ( ; i < length; ) {
644					if ( callback.apply( object[ i++ ], args ) === false ) {
645						break;
646					}
647				}
648			}
649
650		// A special, fast, case for the most common use of each
651		} else {
652			if ( isObj ) {
653				for ( name in object ) {
654					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
655						break;
656					}
657				}
658			} else {
659				for ( ; i < length; ) {
660					if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
661						break;
662					}
663				}
664			}
665		}
666
667		return object;
668	},
669
670	// Use native String.trim function wherever possible
671	trim: trim ?
672		function( text ) {
673			return text == null ?
674				"" :
675				trim.call( text );
676		} :
677
678		// Otherwise use our own trimming functionality
679		function( text ) {
680			return text == null ?
681				"" :
682				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
683		},
684
685	// results is for internal usage only
686	makeArray: function( array, results ) {
687		var ret = results || [];
688
689		if ( array != null ) {
690			// The window, strings (and functions) also have 'length'
691			// The extra typeof function check is to prevent crashes
692			// in Safari 2 (See: #3039)
693			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
694			var type = jQuery.type( array );
695
696			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
697				push.call( ret, array );
698			} else {
699				jQuery.merge( ret, array );
700			}
701		}
702
703		return ret;
704	},
705
706	inArray: function( elem, array, i ) {
707		var len;
708
709		if ( array ) {
710			if ( indexOf ) {
711				return indexOf.call( array, elem, i );
712			}
713
714			len = array.length;
715			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
716
717			for ( ; i < len; i++ ) {
718				// Skip accessing in sparse arrays
719				if ( i in array && array[ i ] === elem ) {
720					return i;
721				}
722			}
723		}
724
725		return -1;
726	},
727
728	merge: function( first, second ) {
729		var i = first.length,
730			j = 0;
731
732		if ( typeof second.length === "number" ) {
733			for ( var l = second.length; j < l; j++ ) {
734				first[ i++ ] = second[ j ];
735			}
736
737		} else {
738			while ( second[j] !== undefined ) {
739				first[ i++ ] = second[ j++ ];
740			}
741		}
742
743		first.length = i;
744
745		return first;
746	},
747
748	grep: function( elems, callback, inv ) {
749		var ret = [], retVal;
750		inv = !!inv;
751
752		// Go through the array, only saving the items
753		// that pass the validator function
754		for ( var i = 0, length = elems.length; i < length; i++ ) {
755			retVal = !!callback( elems[ i ], i );
756			if ( inv !== retVal ) {
757				ret.push( elems[ i ] );
758			}
759		}
760
761		return ret;
762	},
763
764	// arg is for internal usage only
765	map: function( elems, callback, arg ) {
766		var value, key, ret = [],
767			i = 0,
768			length = elems.length,
769			// jquery objects are treated as arrays
770			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
771
772		// Go through the array, translating each of the items to their
773		if ( isArray ) {
774			for ( ; i < length; i++ ) {
775				value = callback( elems[ i ], i, arg );
776
777				if ( value != null ) {
778					ret[ ret.length ] = value;
779				}
780			}
781
782		// Go through every key on the object,
783		} else {
784			for ( key in elems ) {
785				value = callback( elems[ key ], key, arg );
786
787				if ( value != null ) {
788					ret[ ret.length ] = value;
789				}
790			}
791		}
792
793		// Flatten any nested arrays
794		return ret.concat.apply( [], ret );
795	},
796
797	// A global GUID counter for objects
798	guid: 1,
799
800	// Bind a function to a context, optionally partially applying any
801	// arguments.
802	proxy: function( fn, context ) {
803		if ( typeof context === "string" ) {
804			var tmp = fn[ context ];
805			context = fn;
806			fn = tmp;
807		}
808
809		// Quick check to determine if target is callable, in the spec
810		// this throws a TypeError, but we will just return undefined.
811		if ( !jQuery.isFunction( fn ) ) {
812			return undefined;
813		}
814
815		// Simulated bind
816		var args = slice.call( arguments, 2 ),
817			proxy = function() {
818				return fn.apply( context, args.concat( slice.call( arguments ) ) );
819			};
820
821		// Set the guid of unique handler to the same of original handler, so it can be removed
822		proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
823
824		return proxy;
825	},
826
827	// Mutifunctional method to get and set values to a collection
828	// The value/s can optionally be executed if it's a function
829	access: function( elems, key, value, exec, fn, pass ) {
830		var length = elems.length;
831
832		// Setting many attributes
833		if ( typeof key === "object" ) {
834			for ( var k in key ) {
835				jQuery.access( elems, k, key[k], exec, fn, value );
836			}
837			return elems;
838		}
839
840		// Setting one attribute
841		if ( value !== undefined ) {
842			// Optionally, function values get executed if exec is true
843			exec = !pass && exec && jQuery.isFunction(value);
844
845			for ( var i = 0; i < length; i++ ) {
846				fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
847			}
848
849			return elems;
850		}
851
852		// Getting an attribute
853		return length ? fn( elems[0], key ) : undefined;
854	},
855
856	now: function() {
857		return ( new Date() ).getTime();
858	},
859
860	// Use of jQuery.browser is frowned upon.
861	// More details: http://docs.jquery.com/Utilities/jQuery.browser
862	uaMatch: function( ua ) {
863		ua = ua.toLowerCase();
864
865		var match = rwebkit.exec( ua ) ||
866			ropera.exec( ua ) ||
867			rmsie.exec( ua ) ||
868			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
869			[];
870
871		return { browser: match[1] || "", version: match[2] || "0" };
872	},
873
874	sub: function() {
875		function jQuerySub( selector, context ) {
876			return new jQuerySub.fn.init( selector, context );
877		}
878		jQuery.extend( true, jQuerySub, this );
879		jQuerySub.superclass = this;
880		jQuerySub.fn = jQuerySub.prototype = this();
881		jQuerySub.fn.constructor = jQuerySub;
882		jQuerySub.sub = this.sub;
883		jQuerySub.fn.init = function init( selector, context ) {
884			if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
885				context = jQuerySub( context );
886			}
887
888			return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
889		};
890		jQuerySub.fn.init.prototype = jQuerySub.fn;
891		var rootjQuerySub = jQuerySub(document);
892		return jQuerySub;
893	},
894
895	browser: {}
896});
897
898// Populate the class2type map
899jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
900	class2type[ "[object " + name + "]" ] = name.toLowerCase();
901});
902
903browserMatch = jQuery.uaMatch( userAgent );
904if ( browserMatch.browser ) {
905	jQuery.browser[ browserMatch.browser ] = true;
906	jQuery.browser.version = browserMatch.version;
907}
908
909// Deprecated, use jQuery.browser.webkit instead
910if ( jQuery.browser.webkit ) {
911	jQuery.browser.safari = true;
912}
913
914// IE doesn't match non-breaking spaces with \s
915if ( rnotwhite.test( "\xA0" ) ) {
916	trimLeft = /^[\s\xA0]+/;
917	trimRight = /[\s\xA0]+$/;
918}
919
920// All jQuery objects should point back to these
921rootjQuery = jQuery(document);
922
923// Cleanup functions for the document ready method
924if ( document.addEventListener ) {
925	DOMContentLoaded = function() {
926		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
927		jQuery.ready();
928	};
929
930} else if ( document.attachEvent ) {
931	DOMContentLoaded = function() {
932		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
933		if ( document.readyState === "complete" ) {
934			document.detachEvent( "onreadystatechange", DOMContentLoaded );
935			jQuery.ready();
936		}
937	};
938}
939
940// The DOM ready check for Internet Explorer
941function doScrollCheck() {
942	if ( jQuery.isReady ) {
943		return;
944	}
945
946	try {
947		// If IE is used, use the trick by Diego Perini
948		// http://javascript.nwbox.com/IEContentLoaded/
949		document.documentElement.doScroll("left");
950	} catch(e) {
951		setTimeout( doScrollCheck, 1 );
952		return;
953	}
954
955	// and execute any waiting functions
956	jQuery.ready();
957}
958
959// Expose jQuery as an AMD module, but only for AMD loaders that
960// understand the issues with loading multiple versions of jQuery
961// in a page that all might call define(). The loader will indicate
962// they have special allowances for multiple jQuery versions by
963// specifying define.amd.jQuery = true. Register as a named module,
964// since jQuery can be concatenated with other files that may use define,
965// but not use a proper concatenation script that understands anonymous
966// AMD modules. A named AMD is safest and most robust way to register.
967// Lowercase jquery is used because AMD module names are derived from
968// file names, and jQuery is normally delivered in a lowercase file name.
969if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
970	define( "jquery", [], function () { return jQuery; } );
971}
972
973return jQuery;
974
975})();
976
977
978// String to Object flags format cache
979var flagsCache = {};
980
981// Convert String-formatted flags into Object-formatted ones and store in cache
982function createFlags( flags ) {
983	var object = flagsCache[ flags ] = {},
984		i, length;
985	flags = flags.split( /\s+/ );
986	for ( i = 0, length = flags.length; i < length; i++ ) {
987		object[ flags[i] ] = true;
988	}
989	return object;
990}
991
992/*
993 * Create a callback list using the following parameters:
994 *
995 *	flags:	an optional list of space-separated flags that will change how
996 *			the callback list behaves
997 *
998 * By default a callback list will act like an event callback list and can be
999 * "fired" multiple times.
1000 *
1001 * Possible flags:
1002 *
1003 *	once:			will ensure the callback list can only be fired once (like a Deferred)
1004 *
1005 *	memory:			will keep track of previous values and will call any callback added
1006 *					after the list has been fired right away with the latest "memorized"
1007 *					values (like a Deferred)
1008 *
1009 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
1010 *
1011 *	stopOnFalse:	interrupt callings when a callback returns false
1012 *
1013 */
1014jQuery.Callbacks = function( flags ) {
1015
1016	// Convert flags from String-formatted to Object-formatted
1017	// (we check in cache first)
1018	flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};
1019
1020	var // Actual callback list
1021		list = [],
1022		// Stack of fire calls for repeatable lists
1023		stack = [],
1024		// Last fire value (for non-forgettable lists)
1025		memory,
1026		// Flag to know if list is currently firing
1027		firing,
1028		// First callback to fire (used internally by add and fireWith)
1029		firingStart,
1030		// End of the loop when firing
1031		firingLength,
1032		// Index of currently firing callback (modified by remove if needed)
1033		firingIndex,
1034		// Add one or several callbacks to the list
1035		add = function( args ) {
1036			var i,
1037				length,
1038				elem,
1039				type,
1040				actual;
1041			for ( i = 0, length = args.length; i < length; i++ ) {
1042				elem = args[ i ];
1043				type = jQuery.type( elem );
1044				if ( type === "array" ) {
1045					// Inspect recursively
1046					add( elem );
1047				} else if ( type === "function" ) {
1048					// Add if not in unique mode and callback is not in
1049					if ( !flags.unique || !self.has( elem ) ) {
1050						list.push( elem );
1051					}
1052				}
1053			}
1054		},
1055		// Fire callbacks
1056		fire = function( context, args ) {
1057			args = args || [];
1058			memory = !flags.memory || [ context, args ];
1059			firing = true;
1060			firingIndex = firingStart || 0;
1061			firingStart = 0;
1062			firingLength = list.length;
1063			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
1064				if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {
1065					memory = true; // Mark as halted
1066					break;
1067				}
1068			}
1069			firing = false;
1070			if ( list ) {
1071				if ( !flags.once ) {
1072					if ( stack && stack.length ) {
1073						memory = stack.shift();
1074						self.fireWith( memory[ 0 ], memory[ 1 ] );
1075					}
1076				} else if ( memory === true ) {
1077					self.disable();
1078				} else {
1079					list = [];
1080				}
1081			}
1082		},
1083		// Actual Callbacks object
1084		self = {
1085			// Add a callback or a collection of callbacks to the list
1086			add: function() {
1087				if ( list ) {
1088					var length = list.length;
1089					add( arguments );
1090					// Do we need to add the callbacks to the
1091					// current firing batch?
1092					if ( firing ) {
1093						firingLength = list.length;
1094					// With memory, if we're not firing then
1095					// we should call right away, unless previous
1096					// firing was halted (stopOnFalse)
1097					} else if ( memory && memory !== true ) {
1098						firingStart = length;
1099						fire( memory[ 0 ], memory[ 1 ] );
1100					}
1101				}
1102				return this;
1103			},
1104			// Remove a callback from the list
1105			remove: function() {
1106				if ( list ) {
1107					var args = arguments,
1108						argIndex = 0,
1109						argLength = args.length;
1110					for ( ; argIndex < argLength ; argIndex++ ) {
1111						for ( var i = 0; i < list.length; i++ ) {
1112							if ( args[ argIndex ] === list[ i ] ) {
1113								// Handle firingIndex and firingLength
1114								if ( firing ) {
1115									if ( i <= firingLength ) {
1116										firingLength--;
1117										if ( i <= firingIndex ) {
1118											firingIndex--;
1119										}
1120									}
1121								}
1122								// Remove the element
1123								list.splice( i--, 1 );
1124								// If we have some unicity property then
1125								// we only need to do this once
1126								if ( flags.unique ) {
1127									break;
1128								}
1129							}
1130						}
1131					}
1132				}
1133				return this;
1134			},
1135			// Control if a given callback is in the list
1136			has: function( fn ) {
1137				if ( list ) {
1138					var i = 0,
1139						length = list.length;
1140					for ( ; i < length; i++ ) {
1141						if ( fn === list[ i ] ) {
1142							return true;
1143						}
1144					}
1145				}
1146				return false;
1147			},
1148			// Remove all callbacks from the list
1149			empty: function() {
1150				list = [];
1151				return this;
1152			},
1153			// Have the list do nothing anymore
1154			disable: function() {
1155				list = stack = memory = undefined;
1156				return this;
1157			},
1158			// Is it disabled?
1159			disabled: function() {
1160				return !list;
1161			},
1162			// Lock the list in its current state
1163			lock: function() {
1164				stack = undefined;
1165				if ( !memory || memory === true ) {
1166					self.disable();
1167				}
1168				return this;
1169			},
1170			// Is it locked?
1171			locked: function() {
1172				return !stack;
1173			},
1174			// Call all callbacks with the given context and arguments
1175			fireWith: function( context, args ) {
1176				if ( stack ) {
1177					if ( firing ) {
1178						if ( !flags.once ) {
1179							stack.push( [ context, args ] );
1180						}
1181					} else if ( !( flags.once && memory ) ) {
1182						fire( context, args );
1183					}
1184				}
1185				return this;
1186			},
1187			// Call all the callbacks with the given arguments
1188			fire: function() {
1189				self.fireWith( this, arguments );
1190				return this;
1191			},
1192			// To know if the callbacks have already been called at least once
1193			fired: function() {
1194				return !!memory;
1195			}
1196		};
1197
1198	return self;
1199};
1200
1201
1202
1203
1204var // Static reference to slice
1205	sliceDeferred = [].slice;
1206
1207jQuery.extend({
1208
1209	Deferred: function( func ) {
1210		var doneList = jQuery.Callbacks( "once memory" ),
1211			failList = jQuery.Callbacks( "once memory" ),
1212			progressList = jQuery.Callbacks( "memory" ),
1213			state = "pending",
1214			lists = {
1215				resolve: doneList,
1216				reject: failList,
1217				notify: progressList
1218			},
1219			promise = {
1220				done: doneList.add,
1221				fail: failList.add,
1222				progress: progressList.add,
1223
1224				state: function() {
1225					return state;
1226				},
1227
1228				// Deprecated
1229				isResolved: doneList.fired,
1230				isRejected: failList.fired,
1231
1232				then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
1233					deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
1234					return this;
1235				},
1236				always: function() {
1237					return deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
1238				},
1239				pipe: function( fnDone, fnFail, fnProgress ) {
1240					return jQuery.Deferred(function( newDefer ) {
1241						jQuery.each( {
1242							done: [ fnDone, "resolve" ],
1243							fail: [ fnFail, "reject" ],
1244							progress: [ fnProgress, "notify" ]
1245						}, function( handler, data ) {
1246							var fn = data[ 0 ],
1247								action = data[ 1 ],
1248								returned;
1249							if ( jQuery.isFunction( fn ) ) {
1250								deferred[ handler ](function() {
1251									returned = fn.apply( this, arguments );
1252									if ( returned && jQuery.isFunction( returned.promise ) ) {
1253										returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );
1254									} else {
1255										newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1256									}
1257								});
1258							} else {
1259								deferred[ handler ]( newDefer[ action ] );
1260							}
1261						});
1262					}).promise();
1263				},
1264				// Get a promise for this deferred
1265				// If obj is provided, the promise aspect is added to the object
1266				promise: function( obj ) {
1267					if ( obj == null ) {
1268						obj = promise;
1269					} else {
1270						for ( var key in promise ) {
1271							obj[ key ] = promise[ key ];
1272						}
1273					}
1274					return obj;
1275				}
1276			},
1277			deferred = promise.promise({}),
1278			key;
1279
1280		for ( key in lists ) {
1281			deferred[ key ] = lists[ key ].fire;
1282			deferred[ key + "With" ] = lists[ key ].fireWith;
1283		}
1284
1285		// Handle state
1286		deferred.done( function() {
1287			state = "resolved";
1288		}, failList.disable, progressList.lock ).fail( function() {
1289			state = "rejected";
1290		}, doneList.disable, progressList.lock );
1291
1292		// Call given func if any
1293		if ( func ) {
1294			func.call( deferred, deferred );
1295		}
1296
1297		// All done!
1298		return deferred;
1299	},
1300
1301	// Deferred helper
1302	when: function( firstParam ) {
1303		var args = sliceDeferred.call( arguments, 0 ),
1304			i = 0,
1305			length = args.length,
1306			pValues = new Array( length ),
1307			count = length,
1308			pCount = length,
1309			deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1310				firstParam :
1311				jQuery.Deferred(),
1312			promise = deferred.promise();
1313		function resolveFunc( i ) {
1314			return function( value ) {
1315				args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1316				if ( !( --count ) ) {
1317					deferred.resolveWith( deferred, args );
1318				}
1319			};
1320		}
1321		function progressFunc( i ) {
1322			return function( value ) {
1323				pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1324				deferred.notifyWith( promise, pValues );
1325			};
1326		}
1327		if ( length > 1 ) {
1328			for ( ; i < length; i++ ) {
1329				if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {
1330					args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );
1331				} else {
1332					--count;
1333				}
1334			}
1335			if ( !count ) {
1336				deferred.resolveWith( deferred, args );
1337			}
1338		} else if ( deferred !== firstParam ) {
1339			deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1340		}
1341		return promise;
1342	}
1343});
1344
1345
1346
1347
1348jQuery.support = (function() {
1349
1350	var div = document.createElement( "div" ),
1351		documentElement = document.documentElement,
1352		all,
1353		a,
1354		select,
1355		opt,
1356		input,
1357		marginDiv,
1358		support,
1359		fragment,
1360		body,
1361		testElementParent,
1362		testElement,
1363		testElementStyle,
1364		tds,
1365		events,
1366		eventName,
1367		i,
1368		isSupported;
1369
1370	// Preliminary tests
1371	div.setAttribute("className", "t");
1372	div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/><nav></nav>";
1373
1374
1375	all = div.getElementsByTagName( "*" );
1376	a = div.getElementsByTagName( "a" )[ 0 ];
1377
1378	// Can't get basic test support
1379	if ( !all || !all.length || !a ) {
1380		return {};
1381	}
1382
1383	// First batch of supports tests
1384	select = document.createElement( "select" );
1385	opt = select.appendChild( document.createElement("option") );
1386	input = div.getElementsByTagName( "input" )[ 0 ];
1387
1388	support = {
1389		// IE strips leading whitespace when .innerHTML is used
1390		leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1391
1392		// Make sure that tbody elements aren't automatically inserted
1393		// IE will insert them into empty tables
1394		tbody: !div.getElementsByTagName( "tbody" ).length,
1395
1396		// Make sure that link elements get serialized correctly by innerHTML
1397		// This requires a wrapper element in IE
1398		htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1399
1400		// Get the style information from getAttribute
1401		// (IE uses .cssText instead)
1402		style: /top/.test( a.getAttribute("style") ),
1403
1404		// Make sure that URLs aren't manipulated
1405		// (IE normalizes it by default)
1406		hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1407
1408		// Make sure that element opacity exists
1409		// (IE uses filter instead)
1410		// Use a regex to work around a WebKit issue. See #5145
1411		opacity: /^0.55/.test( a.style.opacity ),
1412
1413		// Verify style float existence
1414		// (IE uses styleFloat instead of cssFloat)
1415		cssFloat: !!a.style.cssFloat,
1416
1417		// Make sure unknown elements (like HTML5 elems) are handled appropriately
1418		unknownElems: !!div.getElementsByTagName( "nav" ).length,
1419
1420		// Make sure that if no value is specified for a checkbox
1421		// that it defaults to "on".
1422		// (WebKit defaults to "" instead)
1423		checkOn: ( input.value === "on" ),
1424
1425		// Make sure that a selected-by-default option has a working selected property.
1426		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1427		optSelected: opt.selected,
1428
1429		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1430		getSetAttribute: div.className !== "t",
1431
1432		// Tests for enctype support on a form(#6743)
1433		enctype: !!document.createElement("form").enctype,
1434
1435		// Will be defined later
1436		submitBubbles: true,
1437		changeBubbles: true,
1438		focusinBubbles: false,
1439		deleteExpando: true,
1440		noCloneEvent: true,
1441		inlineBlockNeedsLayout: false,
1442		shrinkWrapBlocks: false,
1443		reliableMarginRight: true
1444	};
1445
1446	// Make sure checked status is properly cloned
1447	input.checked = true;
1448	support.noCloneChecked = input.cloneNode( true ).checked;
1449
1450	// Make sure that the options inside disabled selects aren't marked as disabled
1451	// (WebKit marks them as disabled)
1452	select.disabled = true;
1453	support.optDisabled = !opt.disabled;
1454
1455	// Test to see if it's possible to delete an expando from an element
1456	// Fails in Internet Explorer
1457	try {
1458		delete div.test;
1459	} catch( e ) {
1460		support.deleteExpando = false;
1461	}
1462
1463	if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1464		div.attachEvent( "onclick", function() {
1465			// Cloning a node shouldn't copy over any
1466			// bound event handlers (IE does this)
1467			support.noCloneEvent = false;
1468		});
1469		div.cloneNode( true ).fireEvent( "onclick" );
1470	}
1471
1472	// Check if a radio maintains its value
1473	// after being appended to the DOM
1474	input = document.createElement("input");
1475	input.value = "t";
1476	input.setAttribute("type", "radio");
1477	support.radioValue = input.value === "t";
1478
1479	input.setAttribute("checked", "checked");
1480	div.appendChild( input );
1481	fragment = document.createDocumentFragment();
1482	fragment.appendChild( div.lastChild );
1483
1484	// WebKit doesn't clone checked state correctly in fragments
1485	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1486
1487	div.innerHTML = "";
1488
1489	// Figure out if the W3C box model works as expected
1490	div.style.width = div.style.paddingLeft = "1px";
1491
1492	// We don't want to do body-related feature tests on frameset
1493	// documents, which lack a body. So we use
1494	// document.getElementsByTagName("body")[0], which is undefined in
1495	// frameset documents, while document.body isn’t. (7398)
1496	body = document.getElementsByTagName("body")[ 0 ];
1497	// We use our own, invisible, body unless the body is already present
1498	// in which case we use a div (#9239)
1499	testElement = document.createElement( body ? "div" : "body" );
1500	testElementStyle = {
1501		visibility: "hidden",
1502		width: 0,
1503		height: 0,
1504		border: 0,
1505		margin: 0,
1506		background: "none"
1507	};
1508	if ( body ) {
1509		jQuery.extend( testElementStyle, {
1510			position: "absolute",
1511			left: "-999px",
1512			top: "-999px"
1513		});
1514	}
1515	for ( i in testElementStyle ) {
1516		testElement.style[ i ] = testElementStyle[ i ];
1517	}
1518	testElement.appendChild( div );
1519	testElementParent = body || documentElement;
1520	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1521
1522	// Check if a disconnected checkbox will retain its checked
1523	// value of true after appended to the DOM (IE6/7)
1524	support.appendChecked = input.checked;
1525
1526	support.boxModel = div.offsetWidth === 2;
1527
1528	if ( "zoom" in div.style ) {
1529		// Check if natively block-level elements act like inline-block
1530		// elements when setting their display to 'inline' and giving
1531		// them layout
1532		// (IE < 8 does this)
1533		div.style.display = "inline";
1534		div.style.zoom = 1;
1535		support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1536
1537		// Check if elements with layout shrink-wrap their children
1538		// (IE 6 does this)
1539		div.style.display = "";
1540		div.innerHTML = "<div style='width:4px;'></div>";
1541		support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1542	}
1543
1544	div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1545	tds = div.getElementsByTagName( "td" );
1546
1547	// Check if table cells still have offsetWidth/Height when they are set
1548	// to display:none and there are still other visible table cells in a
1549	// table row; if so, offsetWidth/Height are not reliable for use when
1550	// determining if an element has been hidden directly using
1551	// display:none (it is still safe to use offsets if a parent element is
1552	// hidden; don safety goggles and see bug #4512 for more information).
1553	// (only IE 8 fails this test)
1554	isSupported = ( tds[ 0 ].offsetHeight === 0 );
1555
1556	tds[ 0 ].style.display = "";
1557	tds[ 1 ].style.display = "none";
1558
1559	// Check if empty table cells still have offsetWidth/Height
1560	// (IE < 8 fail this test)
1561	support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1562	div.innerHTML = "";
1563
1564	// Check if div with explicit width and no margin-right incorrectly
1565	// gets computed margin-right based on width of container. For more
1566	// info see bug #3333
1567	// Fails in WebKit before Feb 2011 nightlies
1568	// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1569	if ( document.defaultView && document.defaultView.getComputedStyle ) {
1570		marginDiv = document.createElement( "div" );
1571		marginDiv.style.width = "0";
1572		marginDiv.style.marginRight = "0";
1573		div.appendChild( marginDiv );
1574		support.reliableMarginRight =
1575			( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1576	}
1577
1578	// Technique from Juriy Zaytsev
1579	// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
1580	// We only care about the case where non-standard event systems
1581	// are used, namely in IE. Short-circuiting here helps us to
1582	// avoid an eval call (in setAttribute) which can cause CSP
1583	// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1584	if ( div.attachEvent ) {
1585		for( i in {
1586			submit: 1,
1587			change: 1,
1588			focusin: 1
1589		} ) {
1590			eventName = "on" + i;
1591			isSupported = ( eventName in div );
1592			if ( !isSupported ) {
1593				div.setAttribute( eventName, "return;" );
1594				isSupported = ( typeof div[ eventName ] === "function" );
1595			}
1596			support[ i + "Bubbles" ] = isSupported;
1597		}
1598	}
1599
1600	// Run fixed position tests at doc ready to avoid a crash
1601	// related to the invisible body in IE8
1602	jQuery(function() {
1603		var container, outer, inner, table, td, offsetSupport,
1604			conMarginTop = 1,
1605			ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",
1606			vb = "visibility:hidden;border:0;",
1607			style = "style='" + ptlm + "border:5px solid #000;padding:0;'",
1608			html = "<div " + style + "><div></div></div>" +
1609							"<table " + style + " cellpadding='0' cellspacing='0'>" +
1610							"<tr><td></td></tr></table>";
1611
1612		// Reconstruct a container
1613		body = document.getElementsByTagName("body")[0];
1614		if ( !body ) {
1615			// Return for frameset docs that don't have a body
1616			// These tests cannot be done
1617			return;
1618		}
1619
1620		container = document.createElement("div");
1621		container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
1622		body.insertBefore( container, body.firstChild );
1623
1624		// Construct a test element
1625		testElement = document.createElement("div");
1626		testElement.style.cssText = ptlm + vb;
1627
1628		testElement.innerHTML = html;
1629		container.appendChild( testElement );
1630		outer = testElement.firstChild;
1631		inner = outer.firstChild;
1632		td = outer.nextSibling.firstChild.firstChild;
1633
1634		offsetSupport = {
1635			doesNotAddBorder: ( inner.offsetTop !== 5 ),
1636			doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
1637		};
1638
1639		inner.style.position = "fixed";
1640		inner.style.top = "20px";
1641
1642		// safari subtracts parent border width here which is 5px
1643		offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );
1644		inner.style.position = inner.style.top = "";
1645
1646		outer.style.overflow = "hidden";
1647		outer.style.position = "relative";
1648
1649		offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
1650		offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
1651
1652		body.removeChild( container );
1653		testElement = container = null;
1654
1655		jQuery.extend( support, offsetSupport );
1656	});
1657
1658	testElement.innerHTML = "";
1659	testElementParent.removeChild( testElement );
1660
1661	// Null connected elements to avoid leaks in IE
1662	testElement = fragment = select = opt = body = marginDiv = div = input = null;
1663
1664	return support;
1665})();
1666
1667// Keep track of boxModel
1668jQuery.boxModel = jQuery.support.boxModel;
1669
1670
1671
1672
1673var rbrace = /^(?:\{.*\}|\[.*\])$/,
1674	rmultiDash = /([A-Z])/g;
1675
1676jQuery.extend({
1677	cache: {},
1678
1679	// Please use with caution
1680	uuid: 0,
1681
1682	// Unique for each copy of jQuery on the page
1683	// Non-digits removed to match rinlinejQuery
1684	expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1685
1686	// The following elements throw uncatchable exceptions if you
1687	// attempt to add expando properties to them.
1688	noData: {
1689		"embed": true,
1690		// Ban all objects except for Flash (which handle expandos)
1691		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1692		"applet": true
1693	},
1694
1695	hasData: function( elem ) {
1696		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1697		return !!elem && !isEmptyDataObject( elem );
1698	},
1699
1700	data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1701		if ( !jQuery.acceptData( elem ) ) {
1702			return;
1703		}
1704
1705		var privateCache, thisCache, ret,
1706			internalKey = jQuery.expando,
1707			getByName = typeof name === "string",
1708
1709			// We have to handle DOM nodes and JS objects differently because IE6-7
1710			// can't GC object references properly across the DOM-JS boundary
1711			isNode = elem.nodeType,
1712
1713			// Only DOM nodes need the global jQuery cache; JS object data is
1714			// attached directly to the object so GC can occur automatically
1715			cache = isNode ? jQuery.cache : elem,
1716
1717			// Only defining an ID for JS objects if its cache already exists allows
1718			// the code to shortcut on the same path as a DOM node with no cache
1719			id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando,
1720			isEvents = name === "events";
1721
1722		// Avoid doing any more work than we need to when trying to get data on an
1723		// object that has no data at all
1724		if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {
1725			return;
1726		}
1727
1728		if ( !id ) {
1729			// Only DOM nodes need a new unique ID for each element since their data
1730			// ends up in the global cache
1731			if ( isNode ) {
1732				elem[ jQuery.expando ] = id = ++jQuery.uuid;
1733			} else {
1734				id = jQuery.expando;
1735			}
1736		}
1737
1738		if ( !cache[ id ] ) {
1739			cache[ id ] = {};
1740
1741			// Avoids exposing jQuery metadata on plain JS objects when the object
1742			// is serialized using JSON.stringify
1743			if ( !isNode ) {
1744				cache[ id ].toJSON = jQuery.noop;
1745			}
1746		}
1747
1748		// An object can be passed to jQuery.data instead of a key/value pair; this gets
1749		// shallow copied over onto the existing cache
1750		if ( typeof name === "object" || typeof name === "function" ) {
1751			if ( pvt ) {
1752				cache[ id ] = jQuery.extend( cache[ id ], name );
1753			} else {
1754				cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1755			}
1756		}
1757
1758		privateCache = thisCache = cache[ id ];
1759
1760		// jQuery data() is stored in a separate object inside the object's internal data
1761		// cache in order to avoid key collisions between internal data and user-defined
1762		// data.
1763		if ( !pvt ) {
1764			if ( !thisCache.data ) {
1765				thisCache.data = {};
1766			}
1767
1768			thisCache = thisCache.data;
1769		}
1770
1771		if ( data !== undefined ) {
1772			thisCache[ jQuery.camelCase( name ) ] = data;
1773		}
1774
1775		// Users should not attempt to inspect the internal events object using jQuery.data,
1776		// it is undocumented and subject to change. But does anyone listen? No.
1777		if ( isEvents && !thisCache[ name ] ) {
1778			return privateCache.events;
1779		}
1780
1781		// Check for both converted-to-camel and non-converted data property names
1782		// If a data property was specified
1783		if ( getByName ) {
1784
1785			// First Try to find as-is property data
1786			ret = thisCache[ name ];
1787
1788			// Test for null|undefined property data
1789			if ( ret == null ) {
1790
1791				// Try to find the camelCased property
1792				ret = thisCache[ jQuery.camelCase( name ) ];
1793			}
1794		} else {
1795			ret = thisCache;
1796		}
1797
1798		return ret;
1799	},
1800
1801	removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1802		if ( !jQuery.acceptData( elem ) ) {
1803			return;
1804		}
1805
1806		var thisCache, i, l,
1807
1808			// Reference to internal data cache key
1809			internalKey = jQuery.expando,
1810
1811			isNode = elem.nodeType,
1812
1813			// See jQuery.data for more information
1814			cache = isNode ? jQuery.cache : elem,
1815
1816			// See jQuery.data for more information
1817			id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1818
1819		// If there is already no cache entry for this object, there is no
1820		// purpose in continuing
1821		if ( !cache[ id ] ) {
1822			return;
1823		}
1824
1825		if ( name ) {
1826
1827			thisCache = pvt ? cache[ id ] : cache[ id ].data;
1828
1829			if ( thisCache ) {
1830
1831				// Support space separated names
1832				if ( jQuery.isArray( name ) ) {
1833					name = name;
1834				} else if ( name in thisCache ) {
1835					name = [ name ];
1836				} else {
1837
1838					// split the camel cased version by spaces
1839					name = jQuery.camelCase( name );
1840					if ( name in thisCache ) {
1841						name = [ name ];
1842					} else {
1843						name = name.split( " " );
1844					}
1845				}
1846
1847				for ( i = 0, l = name.length; i < l; i++ ) {
1848					delete thisCache[ name[i] ];
1849				}
1850
1851				// If there is no data left in the cache, we want to continue
1852				// and let the cache object itself get destroyed
1853				if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1854					return;
1855				}
1856			}
1857		}
1858
1859		// See jQuery.data for more information
1860		if ( !pvt ) {
1861			delete cache[ id ].data;
1862
1863			// Don't destroy the parent cache unless the internal data object
1864			// had been the only thing left in it
1865			if ( !isEmptyDataObject(cache[ id ]) ) {
1866				return;
1867			}
1868		}
1869
1870		// Browsers that fail expando deletion also refuse to delete expandos on
1871		// the window, but it will allow it on all other JS objects; other browsers
1872		// don't care
1873		// Ensure that `cache` is not a window object #10080
1874		if ( jQuery.support.deleteExpando || !cache.setInterval ) {
1875			delete cache[ id ];
1876		} else {
1877			cache[ id ] = null;
1878		}
1879
1880		// We destroyed the cache and need to eliminate the expando on the node to avoid
1881		// false lookups in the cache for entries that no longer exist
1882		if ( isNode ) {
1883			// IE does not allow us to delete expando properties from nodes,
1884			// nor does it have a removeAttribute function on Document nodes;
1885			// we must handle all of these cases
1886			if ( jQuery.support.deleteExpando ) {
1887				delete elem[ jQuery.expando ];
1888			} else if ( elem.removeAttribute ) {
1889				elem.removeAttribute( jQuery.expando );
1890			} else {
1891				elem[ jQuery.expando ] = null;
1892			}
1893		}
1894	},
1895
1896	// For internal use only.
1897	_data: function( elem, name, data ) {
1898		return jQuery.data( elem, name, data, true );
1899	},
1900
1901	// A method for determining if a DOM node can handle the data expando
1902	acceptData: function( elem ) {
1903		if ( elem.nodeName ) {
1904			var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1905
1906			if ( match ) {
1907				return !(match === true || elem.getAttribute("classid") !== match);
1908			}
1909		}
1910
1911		return true;
1912	}
1913});
1914
1915jQuery.fn.extend({
1916	data: function( key, value ) {
1917		var parts, attr, name,
1918			data = null;
1919
1920		if ( typeof key === "undefined" ) {
1921			if ( this.length ) {
1922				data = jQuery.data( this[0] );
1923
1924				if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) {
1925					attr = this[0].attributes;
1926					for ( var i = 0, l = attr.length; i < l; i++ ) {
1927						name = attr[i].name;
1928
1929						if ( name.indexOf( "data-" ) === 0 ) {
1930							name = jQuery.camelCase( name.substring(5) );
1931
1932							dataAttr( this[0], name, data[ name ] );
1933						}
1934					}
1935					jQuery._data( this[0], "parsedAttrs", true );
1936				}
1937			}
1938
1939			return data;
1940
1941		} else if ( typeof key === "object" ) {
1942			return this.each(function() {
1943				jQuery.data( this, key );
1944			});
1945		}
1946
1947		parts = key.split(".");
1948		parts[1] = parts[1] ? "." + parts[1] : "";
1949
1950		if ( value === undefined ) {
1951			data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1952
1953			// Try to fetch any internally stored data first
1954			if ( data === undefined && this.length ) {
1955				data = jQuery.data( this[0], key );
1956				data = dataAttr( this[0], key, data );
1957			}
1958
1959			return data === undefined && parts[1] ?
1960				this.data( parts[0] ) :
1961				data;
1962
1963		} else {
1964			return this.each(function() {
1965				var $this = jQuery( this ),
1966					args = [ parts[0], value ];
1967
1968				$this.triggerHandler( "setData" + parts[1] + "!", args );
1969				jQuery.data( this, key, value );
1970				$this.triggerHandler( "changeData" + parts[1] + "!", args );
1971			});
1972		}
1973	},
1974
1975	removeData: function( key ) {
1976		return this.each(function() {
1977			jQuery.removeData( this, key );
1978		});
1979	}
1980});
1981
1982function dataAttr( elem, key, data ) {
1983	// If nothing was found internally, try to fetch any
1984	// data from the HTML5 data-* attribute
1985	if ( data === undefined && elem.nodeType === 1 ) {
1986
1987		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1988
1989		data = elem.getAttribute( name );
1990
1991		if ( typeof data === "string" ) {
1992			try {
1993				data = data === "true" ? true :
1994				data === "false" ? false :
1995				data === "null" ? null :
1996				jQuery.isNumeric( data ) ? parseFloat( data ) :
1997					rbrace.test( data ) ? jQuery.parseJSON( data ) :
1998					data;
1999			} catch( e ) {}
2000
2001			// Make sure we set the data so it isn't changed later
2002			jQuery.data( elem, key, data );
2003
2004		} else {
2005			data = undefined;
2006		}
2007	}
2008
2009	return data;
2010}
2011
2012// checks a cache object for emptiness
2013function isEmptyDataObject( obj ) {
2014	for ( var name in obj ) {
2015
2016		// if the public data object is empty, the private is still empty
2017		if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
2018			continue;
2019		}
2020		if ( name !== "toJSON" ) {
2021			return false;
2022		}
2023	}
2024
2025	return true;
2026}
2027
2028
2029
2030
2031function handleQueueMarkDefer( elem, type, src ) {
2032	var deferDataKey = type + "defer",
2033		queueDataKey = type + "queue",
2034		markDataKey = type + "mark",
2035		defer = jQuery._data( elem, deferDataKey );
2036	if ( defer &&
2037		( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&
2038		( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {
2039		// Give room for hard-coded callbacks to fire first
2040		// and eventually mark/queue something else on the element
2041		setTimeout( function() {
2042			if ( !jQuery._data( elem, queueDataKey ) &&
2043				!jQuery._data( elem, markDataKey ) ) {
2044				jQuery.removeData( elem, deferDataKey, true );
2045				defer.fire();
2046			}
2047		}, 0 );
2048	}
2049}
2050
2051jQuery.extend({
2052
2053	_mark: function( elem, type ) {
2054		if ( elem ) {
2055			type = ( type || "fx" ) + "mark";
2056			jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 );
2057		}
2058	},
2059
2060	_unmark: function( force, elem, type ) {
2061		if ( force !== true ) {
2062			type = elem;
2063			elem = force;
2064			force = false;
2065		}
2066		if ( elem ) {
2067			type = type || "fx";
2068			var key = type + "mark",
2069				count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );
2070			if ( count ) {
2071				jQuery._data( elem, key, count );
2072			} else {
2073				jQuery.removeData( elem, key, true );
2074				handleQueueMarkDefer( elem, type, "mark" );
2075			}
2076		}
2077	},
2078
2079	queue: function( elem, type, data ) {
2080		var q;
2081		if ( elem ) {
2082			type = ( type || "fx" ) + "queue";
2083			q = jQuery._data( elem, type );
2084
2085			// Speed up dequeue by getting out quickly if this is just a lookup
2086			if ( data ) {
2087				if ( !q || jQuery.isArray(data) ) {
2088					q = jQuery._data( elem, type, jQuery.makeArray(data) );
2089				} else {
2090					q.push( data );
2091				}
2092			}
2093			return q || [];
2094		}
2095	},
2096
2097	dequeue: function( elem, type ) {
2098		type = type || "fx";
2099
2100		var queue = jQuery.queue( elem, type ),
2101			fn = queue.shift(),
2102			hooks = {};
2103
2104		// If the fx queue is dequeued, always remove the progress sentinel
2105		if ( fn === "inprogress" ) {
2106			fn = queue.shift();
2107		}
2108
2109		if ( fn ) {
2110			// Add a progress sentinel to prevent the fx queue from being
2111			// automatically dequeued
2112			if ( type === "fx" ) {
2113				queue.unshift( "inprogress" );
2114			}
2115
2116			jQuery._data( elem, type + ".run", hooks );
2117			fn.call( elem, function() {
2118				jQuery.dequeue( elem, type );
2119			}, hooks );
2120		}
2121
2122		if ( !queue.length ) {
2123			jQuery.removeData( elem, type + "queue " + type + ".run", true );
2124			handleQueueMarkDefer( elem, type, "queue" );
2125		}
2126	}
2127});
2128
2129jQuery.fn.extend({
2130	queue: function( type, data ) {
2131		if ( typeof type !== "string" ) {
2132			data = type;
2133			type = "fx";
2134		}
2135
2136		if ( data === undefined ) {
2137			return jQuery.queue( this[0], type );
2138		}
2139		return this.each(function() {
2140			var queue = jQuery.queue( this, type, data );
2141
2142			if ( type === "fx" && queue[0] !== "inprogress" ) {
2143				jQuery.dequeue( this, type );
2144			}
2145		});
2146	},
2147	dequeue: function( type ) {
2148		return this.each(function() {
2149			jQuery.dequeue( this, type );
2150		});
2151	},
2152	// Based off of the plugin by Clint Helfers, with permission.
2153	// http://blindsignals.com/index.php/2009/07/jquery-delay/
2154	delay: function( time, type ) {
2155		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
2156		type = type || "fx";
2157
2158		return this.queue( type, function( next, hooks ) {
2159			var timeout = setTimeout( next, time );
2160			hooks.stop = function() {
2161				clearTimeout( timeout );
2162			};
2163		});
2164	},
2165	clearQueue: function( type ) {
2166		return this.queue( type || "fx", [] );
2167	},
2168	// Get a promise resolved when queues of a certain type
2169	// are emptied (fx is the type by default)
2170	promise: function( type, object ) {
2171		if ( typeof type !== "string" ) {
2172			object = type;
2173			type = undefined;
2174		}
2175		type = type || "fx";
2176		var defer = jQuery.Deferred(),
2177			elements = this,
2178			i = elements.length,
2179			count = 1,
2180			deferDataKey = type + "defer",
2181			queueDataKey = type + "queue",
2182			markDataKey = type + "mark",
2183			tmp;
2184		function resolve() {
2185			if ( !( --count ) ) {
2186				defer.resolveWith( elements, [ elements ] );
2187			}
2188		}
2189		while( i-- ) {
2190			if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
2191					( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
2192						jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
2193					jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {
2194				count++;
2195				tmp.add( resolve );
2196			}
2197		}
2198		resolve();
2199		return defer.promise();
2200	}
2201});
2202
2203
2204
2205
2206var rclass = /[\n\t\r]/g,
2207	rspace = /\s+/,
2208	rreturn = /\r/g,
2209	rtype = /^(?:button|input)$/i,
2210	rfocusable = /^(?:button|input|object|select|textarea)$/i,
2211	rclickable = /^a(?:rea)?$/i,
2212	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2213	getSetAttribute = jQuery.support.getSetAttribute,
2214	nodeHook, boolHook, fixSpecified;
2215
2216jQuery.fn.extend({
2217	attr: function( name, value ) {
2218		return jQuery.access( this, name, value, true, jQuery.attr );
2219	},
2220
2221	removeAttr: function( name ) {
2222		return this.each(function() {
2223			jQuery.removeAttr( this, name );
2224		});
2225	},
2226
2227	prop: function( name, value ) {
2228		return jQuery.access( this, name, value, true, jQuery.prop );
2229	},
2230
2231	removeProp: function( name ) {
2232		name = jQuery.propFix[ name ] || name;
2233		return this.each(function() {
2234			// try/catch handles cases where IE balks (such as removing a property on window)
2235			try {
2236				this[ name ] = undefined;
2237				delete this[ name ];
2238			} catch( e ) {}
2239		});
2240	},
2241
2242	addClass: function( value ) {
2243		var classNames, i, l, elem,
2244			setClass, c, cl;
2245
2246		if ( jQuery.isFunction( value ) ) {
2247			return this.each(function( j ) {
2248				jQuery( this ).addClass( value.call(this, j, this.className) );
2249			});
2250		}
2251
2252		if ( value && typeof value === "string" ) {
2253			classNames = value.split( rspace );
2254
2255			for ( i = 0, l = this.length; i < l; i++ ) {
2256				elem = this[ i ];
2257
2258				if ( elem.nodeType === 1 ) {
2259					if ( !elem.className && classNames.length === 1 ) {
2260						elem.className = value;
2261
2262					} else {
2263						setClass = " " + elem.className + " ";
2264
2265						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2266							if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
2267								setClass += classNames[ c ] + " ";
2268							}
2269						}
2270						elem.className = jQuery.trim( setClass );
2271					}
2272				}
2273			}
2274		}
2275
2276		return this;
2277	},
2278
2279	removeClass: function( value ) {
2280		var classNames, i, l, elem, className, c, cl;
2281
2282		if ( jQuery.isFunction( value ) ) {
2283			return this.each(function( j ) {
2284				jQuery( this ).removeClass( value.call(this, j, this.className) );
2285			});
2286		}
2287
2288		if ( (value && typeof value === "string") || value === undefined ) {
2289			classNames = ( value || "" ).split( rspace );
2290
2291			for ( i = 0, l = this.length; i < l; i++ ) {
2292				elem = this[ i ];
2293
2294				if ( elem.nodeType === 1 && elem.className ) {
2295					if ( value ) {
2296						className = (" " + elem.className + " ").replace( rclass, " " );
2297						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2298							className = className.replace(" " + classNames[ c ] + " ", " ");
2299						}
2300						elem.className = jQuery.trim( className );
2301
2302					} else {
2303						elem.className = "";
2304					}
2305				}
2306			}
2307		}
2308
2309		return this;
2310	},
2311
2312	toggleClass: function( value, stateVal ) {
2313		var type = typeof value,
2314			isBool = typeof stateVal === "boolean";
2315
2316		if ( jQuery.isFunction( value ) ) {
2317			return this.each(function( i ) {
2318				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2319			});
2320		}
2321
2322		return this.each(function() {
2323			if ( type === "string" ) {
2324				// toggle individual class names
2325				var className,
2326					i = 0,
2327					self = jQuery( this ),
2328					state = stateVal,
2329					classNames = value.split( rspace );
2330
2331				while ( (className = classNames[ i++ ]) ) {
2332					// check each className given, space seperated list
2333					state = isBool ? state : !self.hasClass( className );
2334					self[ state ? "addClass" : "removeClass" ]( className );
2335				}
2336
2337			} else if ( type === "undefined" || type === "boolean" ) {
2338				if ( this.className ) {
2339					// store className if set
2340					jQuery._data( this, "__className__", this.className );
2341				}
2342
2343				// toggle whole className
2344				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2345			}
2346		});
2347	},
2348
2349	hasClass: function( selector ) {
2350		var className = " " + selector + " ",
2351			i = 0,
2352			l = this.length;
2353		for ( ; i < l; i++ ) {
2354			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2355				return true;
2356			}
2357		}
2358
2359		return false;
2360	},
2361
2362	val: function( value ) {
2363		var hooks, ret, isFunction,
2364			elem = this[0];
2365
2366		if ( !arguments.length ) {
2367			if ( elem ) {
2368				hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2369
2370				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2371					return ret;
2372				}
2373
2374				ret = elem.value;
2375
2376				return typeof ret === "string" ?
2377					// handle most common string cases
2378					ret.replace(rreturn, "") :
2379					// handle cases where value is null/undef or number
2380					ret == null ? "" : ret;
2381			}
2382
2383			return undefined;
2384		}
2385
2386		isFunction = jQuery.isFunction( value );
2387
2388		return this.each(function( i ) {
2389			var self = jQuery(this), val;
2390
2391			if ( this.nodeType !== 1 ) {
2392				return;
2393			}
2394
2395			if ( isFunction ) {
2396				val = value.call( this, i, self.val() );
2397			} else {
2398				val = value;
2399			}
2400
2401			// Treat null/undefined as ""; convert numbers to string
2402			if ( val == null ) {
2403				val = "";
2404			} else if ( typeof val === "number" ) {
2405				val += "";
2406			} else if ( jQuery.isArray( val ) ) {
2407				val = jQuery.map(val, function ( value ) {
2408					return value == null ? "" : value + "";
2409				});
2410			}
2411
2412			hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2413
2414			// If set returns undefined, fall back to normal setting
2415			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2416				this.value = val;
2417			}
2418		});
2419	}
2420});
2421
2422jQuery.extend({
2423	valHooks: {
2424		option: {
2425			get: function( elem ) {
2426				// attributes.value is undefined in Blackberry 4.7 but
2427				// uses .value. See #6932
2428				var val = elem.attributes.value;
2429				return !val || val.specified ? elem.value : elem.text;
2430			}
2431		},
2432		select: {
2433			get: function( elem ) {
2434				var value, i, max, option,
2435					index = elem.selectedIndex,
2436					values = [],
2437					options = elem.options,
2438					one = elem.type === "select-one";
2439
2440				// Nothing was selected
2441				if ( index < 0 ) {
2442					return null;
2443				}
2444
2445				// Loop through all the selected options
2446				i = one ? index : 0;
2447				max = one ? index + 1 : options.length;
2448				for ( ; i < max; i++ ) {
2449					option = options[ i ];
2450
2451					// Don't return options that are disabled or in a disabled optgroup
2452					if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2453							(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2454
2455						// Get the specific value for the option
2456						value = jQuery( option ).val();
2457
2458						// We don't need an array for one selects
2459						if ( one ) {
2460							return value;
2461						}
2462
2463						// Multi-Selects return an array
2464						values.push( value );
2465					}
2466				}
2467
2468				// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2469				if ( one && !values.length && options.length ) {
2470					return jQuery( options[ index ] ).val();
2471				}
2472
2473				return values;
2474			},
2475
2476			set: function( elem, value ) {
2477				var values = jQuery.makeArray( value );
2478
2479				jQuery(elem).find("option").each(function() {
2480					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2481				});
2482
2483				if ( !values.length ) {
2484					elem.selectedIndex = -1;
2485				}
2486				return values;
2487			}
2488		}
2489	},
2490
2491	attrFn: {
2492		val: true,
2493		css: true,
2494		html: true,
2495		text: true,
2496		data: true,
2497		width: true,
2498		height: true,
2499		offset: true
2500	},
2501
2502	attr: function( elem, name, value, pass ) {
2503		var ret, hooks, notxml,
2504			nType = elem.nodeType;
2505
2506		// don't get/set attributes on text, comment and attribute nodes
2507		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2508			return undefined;
2509		}
2510
2511		if ( pass && name in jQuery.attrFn ) {
2512			return jQuery( elem )[ name ]( value );
2513		}
2514
2515		// Fallback to prop when attributes are not supported
2516		if ( !("getAttribute" in elem) ) {
2517			return jQuery.prop( elem, name, value );
2518		}
2519
2520		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2521
2522		// All attributes are lowercase
2523		// Grab necessary hook if one is defined
2524		if ( notxml ) {
2525			name = name.toLowerCase();
2526			hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2527		}
2528
2529		if ( value !== undefined ) {
2530
2531			if ( value === null ) {
2532				jQuery.removeAttr( elem, name );
2533				return undefined;
2534
2535			} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2536				return ret;
2537
2538			} else {
2539				elem.setAttribute( name, "" + value );
2540				return value;
2541			}
2542
2543		} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2544			return ret;
2545
2546		} else {
2547
2548			ret = elem.getAttribute( name );
2549
2550			// Non-existent attributes return null, we normalize to undefined
2551			return ret === null ?
2552				undefined :
2553				ret;
2554		}
2555	},
2556
2557	removeAttr: function( elem, value ) {
2558		var propName, attrNames, name, l,
2559			i = 0;
2560
2561		if ( elem.nodeType === 1 ) {
2562			attrNames = ( value || "" ).split( rspace );
2563			l = attrNames.length;
2564
2565			for ( ; i < l; i++ ) {
2566				name = attrNames[ i ].toLowerCase();
2567				propName = jQuery.propFix[ name ] || name;
2568
2569				// See #9699 for explanation of this approach (setting first, then removal)
2570				jQuery.attr( elem, name, "" );
2571				elem.removeAttribute( getSetAttribute ? name : propName );
2572
2573				// Set corresponding property to false for boolean attributes
2574				if ( rboolean.test( name ) && propName in elem ) {
2575					elem[ propName ] = false;
2576				}
2577			}
2578		}
2579	},
2580
2581	attrHooks: {
2582		type: {
2583			set: function( elem, value ) {
2584				// We can't allow the type property to be changed (since it causes problems in IE)
2585				if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2586					jQuery.error( "type property can't be changed" );
2587				} else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2588					// Setting the type on a radio button after the value resets the value in IE6-9
2589					// Reset value to it's default in case type is set after value
2590					// This is for element creation
2591					var val = elem.value;
2592					elem.setAttribute( "type", value );
2593					if ( val ) {
2594						elem.value = val;
2595					}
2596					return value;
2597				}
2598			}
2599		},
2600		// Use the value property for back compat
2601		// Use the nodeHook for button elements in IE6/7 (#1954)
2602		value: {
2603			get: function( elem, name ) {
2604				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2605					return nodeHook.get( elem, name );
2606				}
2607				return name in elem ?
2608					elem.value :
2609					null;
2610			},
2611			set: function( elem, value, name ) {
2612				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2613					return nodeHook.set( elem, value, name );
2614				}
2615				// Does not return so that setAttribute is also used
2616				elem.value = value;
2617			}
2618		}
2619	},
2620
2621	propFix: {
2622		tabindex: "tabIndex",
2623		readonly: "readOnly",
2624		"for": "htmlFor",
2625		"class": "className",
2626		maxlength: "maxLength",
2627		cellspacing: "cellSpacing",
2628		cellpadding: "cellPadding",
2629		rowspan: "rowSpan",
2630		colspan: "colSpan",
2631		usemap: "useMap",
2632		frameborder: "frameBorder",
2633		contenteditable: "contentEditable"
2634	},
2635
2636	prop: function( elem, name, value ) {
2637		var ret, hooks, notxml,
2638			nType = elem.nodeType;
2639
2640		// don't get/set properties on text, comment and attribute nodes
2641		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2642			return undefined;
2643		}
2644
2645		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2646
2647		if ( notxml ) {
2648			// Fix name and attach hooks
2649			name = jQuery.propFix[ name ] || name;
2650			hooks = jQuery.propHooks[ name ];
2651		}
2652
2653		if ( value !== undefined ) {
2654			if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2655				return ret;
2656
2657			} else {
2658				return ( elem[ name ] = value );
2659			}
2660
2661		} else {
2662			if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2663				return ret;
2664
2665			} else {
2666				return elem[ name ];
2667			}
2668		}
2669	},
2670
2671	propHooks: {
2672		tabIndex: {
2673			get: function( elem ) {
2674				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2675				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2676				var attributeNode = elem.getAttributeNode("tabindex");
2677
2678				return attributeNode && attributeNode.specified ?
2679					parseInt( attributeNode.value, 10 ) :
2680					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2681						0 :
2682						undefined;
2683			}
2684		}
2685	}
2686});
2687
2688// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)
2689jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;
2690
2691// Hook for boolean attributes
2692boolHook = {
2693	get: function( elem, name ) {
2694		// Align boolean attributes with corresponding properties
2695		// Fall back to attribute presence where some booleans are not supported
2696		var attrNode,
2697			property = jQuery.prop( elem, name );
2698		return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2699			name.toLowerCase() :
2700			undefined;
2701	},
2702	set: function( elem, value, name ) {
2703		var propName;
2704		if ( value === false ) {
2705			// Remove boolean attributes when set to false
2706			jQuery.removeAttr( elem, name );
2707		} else {
2708			// value is true since we know at this point it's type boolean and not false
2709			// Set boolean attributes to the same name and set the DOM property
2710			propName = jQuery.propFix[ name ] || name;
2711			if ( propName in elem ) {
2712				// Only set the IDL specifically if it already exists on the element
2713				elem[ propName ] = true;
2714			}
2715
2716			elem.setAttribute( name, name.toLowerCase() );
2717		}
2718		return name;
2719	}
2720};
2721
2722// IE6/7 do not support getting/setting some attributes with get/setAttribute
2723if ( !getSetAttribute ) {
2724
2725	fixSpecified = {
2726		name: true,
2727		id: true
2728	};
2729
2730	// Use this for any attribute in IE6/7
2731	// This fixes almost every IE6/7 issue
2732	nodeHook = jQuery.valHooks.button = {
2733		get: function( elem, name ) {
2734			var ret;
2735			ret = elem.getAttributeNode( name );
2736			return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?
2737				ret.nodeValue :
2738				undefined;
2739		},
2740		set: function( elem, value, name ) {
2741			// Set the existing or create a new attribute node
2742			var ret = elem.getAttributeNode( name );
2743			if ( !ret ) {
2744				ret = document.createAttribute( name );
2745				elem.setAttributeNode( ret );
2746			}
2747			return ( ret.nodeValue = value + "" );
2748		}
2749	};
2750
2751	// Apply the nodeHook to tabindex
2752	jQuery.attrHooks.tabindex.set = nodeHook.set;
2753
2754	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
2755	// This is for removals
2756	jQuery.each([ "width", "height" ], function( i, name ) {
2757		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2758			set: function( elem, value ) {
2759				if ( value === "" ) {
2760					elem.setAttribute( name, "auto" );
2761					return value;
2762				}
2763			}
2764		});
2765	});
2766
2767	// Set contenteditable to false on removals(#10429)
2768	// Setting to empty string throws an error as an invalid value
2769	jQuery.attrHooks.contenteditable = {
2770		get: nodeHook.get,
2771		set: function( elem, value, name ) {
2772			if ( value === "" ) {
2773				value = "false";
2774			}
2775			nodeHook.set( elem, value, name );
2776		}
2777	};
2778}
2779
2780
2781// Some attributes require a special call on IE
2782if ( !jQuery.support.hrefNormalized ) {
2783	jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2784		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2785			get: function( elem ) {
2786				var ret = elem.getAttribute( name, 2 );
2787				return ret === null ? undefined : ret;
2788			}
2789		});
2790	});
2791}
2792
2793if ( !jQuery.support.style ) {
2794	jQuery.attrHooks.style = {
2795		get: function( elem ) {
2796			// Return undefined in the case of empty string
2797			// Normalize to lowercase since IE uppercases css property names
2798			return elem.style.cssText.toLowerCase() || undefined;
2799		},
2800		set: function( elem, value ) {
2801			return ( elem.style.cssText = "" + value );
2802		}
2803	};
2804}
2805
2806// Safari mis-reports the default selected property of an option
2807// Accessing the parent's selectedIndex property fixes it
2808if ( !jQuery.support.optSelected ) {
2809	jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2810		get: function( elem ) {
2811			var parent = elem.parentNode;
2812
2813			if ( parent ) {
2814				parent.selectedIndex;
2815
2816				// Make sure that it also works with optgroups, see #5701
2817				if ( parent.parentNode ) {
2818					parent.parentNode.selectedIndex;
2819				}
2820			}
2821			return null;
2822		}
2823	});
2824}
2825
2826// IE6/7 call enctype encoding
2827if ( !jQuery.support.enctype ) {
2828	jQuery.propFix.enctype = "encoding";
2829}
2830
2831// Radios and checkboxes getter/setter
2832if ( !jQuery.support.checkOn ) {
2833	jQuery.each([ "radio", "checkbox" ], function() {
2834		jQuery.valHooks[ this ] = {
2835			get: function( elem ) {
2836				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2837				return elem.getAttribute("value") === null ? "on" : elem.value;
2838			}
2839		};
2840	});
2841}
2842jQuery.each([ "radio", "checkbox" ], function() {
2843	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2844		set: function( elem, value ) {
2845			if ( jQuery.isArray( value ) ) {
2846				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2847			}
2848		}
2849	});
2850});
2851
2852
2853
2854
2855var rnamespaces = /\.(.*)$/,
2856	rformElems = /^(?:textarea|input|select)$/i,
2857	rperiod = /\./g,
2858	rspaces = / /g,
2859	rescape = /[^\w\s.|`]/g,
2860	rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,
2861	rhoverHack = /\bhover(\.\S+)?/,
2862	rkeyEvent = /^key/,
2863	rmouseEvent = /^(?:mouse|contextmenu)|click/,
2864	rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,
2865	quickParse = function( selector ) {
2866		var quick = rquickIs.exec( selector );
2867		if ( quick ) {
2868			//   0  1    2   3
2869			// [ _, tag, id, class ]
2870			quick[1] = ( quick[1] || "" ).toLowerCase();
2871			quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );
2872		}
2873		return quick;
2874	},
2875	quickIs = function( elem, m ) {
2876		return (
2877			(!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
2878			(!m[2] || elem.id === m[2]) &&
2879			(!m[3] || m[3].test( elem.className ))
2880		);
2881	},
2882	hoverHack = function( events ) {
2883		return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2884	};
2885
2886/*
2887 * Helper functions for managing events -- not part of the public interface.
2888 * Props to Dean Edwards' addEvent library for many of the ideas.
2889 */
2890jQuery.event = {
2891
2892	add: function( elem, types, handler, data, selector ) {
2893
2894		var elemData, eventHandle, events,
2895			t, tns, type, namespaces, handleObj,
2896			handleObjIn, quick, handlers, special;
2897
2898		// Don't attach events to noData or text/comment nodes (allow plain objects tho)
2899		if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2900			return;
2901		}
2902
2903		// Caller can pass in an object of custom data in lieu of the handler
2904		if ( handler.handler ) {
2905			handleObjIn = handler;
2906			handler = handleObjIn.handler;
2907		}
2908
2909		// Make sure that the handler has a unique ID, used to find/remove it later
2910		if ( !handler.guid ) {
2911			handler.guid = jQuery.guid++;
2912		}
2913
2914		// Init the element's event structure and main handler, if this is the first
2915		events = elemData.events;
2916		if ( !events ) {
2917			elemData.events = events = {};
2918		}
2919		eventHandle = elemData.handle;
2920		if ( !eventHandle ) {
2921			elemData.handle = eventHandle = function( e ) {
2922				// Discard the second event of a jQuery.event.trigger() and
2923				// when an event is called after a page has unloaded
2924				return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2925					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2926					undefined;
2927			};
2928			// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2929			eventHandle.elem = elem;
2930		}
2931
2932		// Handle multiple events separated by a space
2933		// jQuery(...).bind("mouseover mouseout", fn);
2934		types = hoverHack(types).split( " " );
2935		for ( t = 0; t < types.length; t++ ) {
2936
2937			tns = rtypenamespace.exec( types[t] ) || [];
2938			type = tns[1];
2939			namespaces = ( tns[2] || "" ).split( "." ).sort();
2940
2941			// If event changes its type, use the special event handlers for the changed type
2942			special = jQuery.event.special[ type ] || {};
2943
2944			// If selector defined, determine special event api type, otherwise given type
2945			type = ( selector ? special.delegateType : special.bindType ) || type;
2946
2947			// Update special based on newly reset type
2948			special = jQuery.event.special[ type ] || {};
2949
2950			// handleObj is passed to all event handlers
2951			handleObj = jQuery.extend({
2952				type: type,
2953				origType: tns[1],
2954				data: data,
2955				handler: handler,
2956				guid: handler.guid,
2957				selector: selector,
2958				namespace: namespaces.join(".")
2959			}, handleObjIn );
2960
2961			// Delegated event; pre-analyze selector so it's processed quickly on event dispatch
2962			if ( selector ) {
2963				handleObj.quick = quickParse( selector );
2964				if ( !handleObj.quick && jQuery.expr.match.POS.test( selector ) ) {
2965					handleObj.isPositional = true;
2966				}
2967			}
2968
2969			// Init the event handler queue if we're the first
2970			handlers = events[ type ];
2971			if ( !handlers ) {
2972				handlers = events[ type ] = [];
2973				handlers.delegateCount = 0;
2974
2975				// Only use addEventListener/attachEvent if the special events handler returns false
2976				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2977					// Bind the global event handler to the element
2978					if ( elem.addEventListener ) {
2979						elem.addEventListener( type, eventHandle, false );
2980
2981					} else if ( elem.attachEvent ) {
2982						elem.attachEvent( "on" + type, eventHandle );
2983					}
2984				}
2985			}
2986
2987			if ( special.add ) {
2988				special.add.call( elem, handleObj );
2989
2990				if ( !handleObj.handler.guid ) {
2991					handleObj.handler.guid = handler.guid;
2992				}
2993			}
2994
2995			// Add to the element's handler list, delegates in front
2996			if ( selector ) {
2997				handlers.splice( handlers.delegateCount++, 0, handleObj );
2998			} else {
2999				handlers.push( handleObj );
3000			}
3001
3002			// Keep track of which events have ever been used, for event optimization
3003			jQuery.event.global[ type ] = true;
3004		}
3005
3006		// Nullify elem to prevent memory leaks in IE
3007		elem = null;
3008	},
3009
3010	global: {},
3011
3012	// Detach an event or set of events from an element
3013	remove: function( elem, types, handler, selector ) {
3014
3015		var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
3016			t, tns, type, namespaces, origCount,
3017			j, events, special, handle, eventType, handleObj;
3018
3019		if ( !elemData || !(events = elemData.events) ) {
3020			return;
3021		}
3022
3023		// Once for each type.namespace in types; type may be omitted
3024		types = hoverHack( types || "" ).split(" ");
3025		for ( t = 0; t < types.length; t++ ) {
3026			tns = rtypenamespace.exec( types[t] ) || [];
3027			type = tns[1];
3028			namespaces = tns[2];
3029
3030			// Unbind all events (on this namespace, if provided) for the element
3031			if ( !type ) {
3032				namespaces = namespaces? "." + namespaces : "";
3033				for ( j in events ) {
3034					jQuery.event.remove( elem, j + namespaces, handler, selector );
3035				}
3036				return;
3037			}
3038
3039			special = jQuery.event.special[ type ] || {};
3040			type = ( selector? special.delegateType : special.bindType ) || type;
3041			eventType = events[ type ] || [];
3042			origCount = eventType.length;
3043			namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3044
3045			// Only need to loop for special events or selective removal
3046			if ( handler || namespaces || selector || special.remove ) {
3047				for ( j = 0; j < eventType.length; j++ ) {
3048					handleObj = eventType[ j ];
3049
3050					if ( !handler || handler.guid === handleObj.guid ) {
3051						if ( !namespaces || namespaces.test( handleObj.namespace ) ) {
3052							if ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) {
3053								eventType.splice( j--, 1 );
3054
3055								if ( handleObj.selector ) {
3056									eventType.delegateCount--;
3057								}
3058								if ( special.remove ) {
3059									special.remove.call( elem, handleObj );
3060								}
3061							}
3062						}
3063					}
3064				}
3065			} else {
3066				// Removing all events
3067				eventType.length = 0;
3068			}
3069
3070			// Remove generic event handler if we removed something and no more handlers exist
3071			// (avoids potential for endless recursion during removal of special event handlers)
3072			if ( eventType.length === 0 && origCount !== eventType.length ) {
3073				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
3074					jQuery.removeEvent( elem, type, elemData.handle );
3075				}
3076
3077				delete events[ type ];
3078			}
3079		}
3080
3081		// Remove the expando if it's no longer used
3082		if ( jQuery.isEmptyObject( events ) ) {
3083			handle = elemData.handle;
3084			if ( handle ) {
3085				handle.elem = null;
3086			}
3087
3088			// removeData also checks for emptiness and clears the expando if empty
3089			// so use it instead of delete
3090			jQuery.removeData( elem, [ "events", "handle" ], true );
3091		}
3092	},
3093
3094	// Events that are safe to short-circuit if no handlers are attached.
3095	// Native DOM events should not be added, they may have inline handlers.
3096	customEvent: {
3097		"getData": true,
3098		"setData": true,
3099		"changeData": true
3100	},
3101
3102	trigger: function( event, data, elem, onlyHandlers ) {
3103		// Don't do events on text and comment nodes
3104		if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
3105			return;
3106		}
3107
3108		// Event object or event type
3109		var type = event.type || event,
3110			namespaces = [],
3111			cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;
3112
3113		if ( type.indexOf( "!" ) >= 0 ) {
3114			// Exclusive events trigger only for the exact event (no namespaces)
3115			type = type.slice(0, -1);
3116			exclusive = true;
3117		}
3118
3119		if ( type.indexOf( "." ) >= 0 ) {
3120			// Namespaced trigger; create a regexp to match event type in handle()
3121			namespaces = type.split(".");
3122			type = namespaces.shift();
3123			namespaces.sort();
3124		}
3125
3126		if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
3127			// No jQuery handlers for this event type, and it can't have inline handlers
3128			return;
3129		}
3130
3131		// Caller can pass in an Event, Object, or just an event type string
3132		event = typeof event === "object" ?
3133			// jQuery.Event object
3134			event[ jQuery.expando ] ? event :
3135			// Object literal
3136			new jQuery.Event( type, event ) :
3137			// Just the event type (string)
3138			new jQuery.Event( type );
3139
3140		event.type = type;
3141		event.isTrigger = true;
3142		event.exclusive = exclusive;
3143		event.namespace = namespaces.join( "." );
3144		event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3145		ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
3146
3147		// triggerHandler() and global events don't bubble or run the default action
3148		if ( onlyHandlers || !elem ) {
3149			event.preventDefault();
3150		}
3151
3152		// Handle a global trigger
3153		if ( !elem ) {
3154
3155			// TODO: Stop taunting the data cache; remove global events and always attach to document
3156			cache = jQuery.cache;
3157			for ( i in cache ) {
3158				if ( cache[ i ].events && cache[ i ].events[ type ] ) {
3159					jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
3160				}
3161			}
3162			return;
3163		}
3164
3165		// Clean up the event in case it is being reused
3166		event.result = undefined;
3167		if ( !event.target ) {
3168			event.target = elem;
3169		}
3170
3171		// Clone any incoming data and prepend the event, creating the handler arg list
3172		data = data != null ? jQuery.makeArray( data ) : [];
3173		data.unshift( event );
3174
3175		// Allow special events to draw outside the lines
3176		special = jQuery.event.special[ type ] || {};
3177		if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
3178			return;
3179		}
3180
3181		// Determine event propagation path in advance, per W3C events spec (#9951)
3182		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
3183		eventPath = [[ elem, special.bindType || type ]];
3184		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
3185
3186			bubbleType = special.delegateType || type;
3187			old = null;
3188			for ( cur = elem.parentNode; cur; cur = cur.parentNode ) {
3189				eventPath.push([ cur, bubbleType ]);
3190				old = cur;
3191			}
3192
3193			// Only add window if we got to document (e.g., not plain obj or detached DOM)
3194			if ( old && old === elem.ownerDocument ) {
3195				eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
3196			}
3197		}
3198
3199		// Fire handlers on the event path
3200		for ( i = 0; i < eventPath.length; i++ ) {
3201
3202			cur = eventPath[i][0];
3203			event.type = eventPath[i][1];
3204
3205			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
3206			if ( handle ) {
3207				handle.apply( cur, data );
3208			}
3209			handle = ontype && cur[ ontype ];
3210			if ( handle && jQuery.acceptData( cur ) ) {
3211				handle.apply( cur, data );
3212			}
3213
3214			if ( event.isPropagationStopped() ) {
3215				break;
3216			}
3217		}
3218		event.type = type;
3219
3220		// If nobody prevented the default action, do it now
3221		if ( !event.isDefaultPrevented() ) {
3222
3223			if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
3224				!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
3225
3226				// Call a native DOM method on the target with the same name name as the event.
3227				// Can't use an .isFunction() check here because IE6/7 fails that test.
3228				// Don't do default actions on window, that's where global variables be (#6170)
3229				// IE<9 dies on focus/blur to hidden element (#1486)
3230				if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
3231
3232					// Don't re-trigger an onFOO event when we call its FOO() method
3233					old = elem[ ontype ];
3234
3235					if ( old ) {
3236						elem[ ontype ] = null;
3237					}
3238
3239					// Prevent re-triggering of the same event, since we already bubbled it above
3240					jQuery.event.triggered = type;
3241					elem[ type ]();
3242					jQuery.event.triggered = undefined;
3243
3244					if ( old ) {
3245						elem[ ontype ] = old;
3246					}
3247				}
3248			}
3249		}
3250
3251		return event.result;
3252	},
3253
3254	dispatch: function( event ) {
3255
3256		// Make a writable jQuery.Event from the native event object
3257		event = jQuery.event.fix( event || window.event );
3258
3259		var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
3260			delegateCount = handlers.delegateCount,
3261			args = [].slice.call( arguments, 0 ),
3262			run_all = !event.exclusive && !event.namespace,
3263			specialHandle = ( jQuery.event.special[ event.type ] || {} ).handle,
3264			handlerQueue = [],
3265			i, j, cur, ret, selMatch, matched, matches, handleObj, sel, hit, related;
3266
3267		// Use the fix-ed jQuery.Event rather than the (read-only) native event
3268		args[0] = event;
3269		event.delegateTarget = this;
3270
3271		// Determine handlers that should run if there are delegated events
3272		// Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861)
3273		if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) {
3274
3275			for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3276				selMatch = {};
3277				matches = [];
3278				for ( i = 0; i < delegateCount; i++ ) {
3279					handleObj = handlers[ i ];
3280					sel = handleObj.selector;
3281					hit = selMatch[ sel ];
3282
3283					if ( handleObj.isPositional ) {
3284						// Since .is() does not work for positionals; see http://jsfiddle.net/eJ4yd/3/
3285						hit = ( hit || (selMatch[ sel ] = jQuery( sel )) ).index( cur ) >= 0;
3286					} else if ( hit === undefined ) {
3287						hit = selMatch[ sel ] = ( handleObj.quick ? quickIs( cur, handleObj.quick ) : jQuery( cur ).is( sel ) );
3288					}
3289					if ( hit ) {
3290						matches.push( handleObj );
3291					}
3292				}
3293				if ( matches.length ) {
3294					handlerQueue.push({ elem: cur, matches: matches });
3295				}
3296			}
3297		}
3298
3299		// Add the remaining (directly-bound) handlers
3300		if ( handlers.length > delegateCount ) {
3301			handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3302		}
3303
3304		// Run delegates first; they may want to stop propagation beneath us
3305		for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3306			matched = handlerQueue[ i ];
3307			event.currentTarget = matched.elem;
3308
3309			for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3310				handleObj = matched.matches[ j ];
3311
3312				// Triggered event must either 1) be non-exclusive and have no namespace, or
3313				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3314				if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3315
3316					event.data = handleObj.data;
3317					event.handleObj = handleObj;
3318
3319					ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );
3320
3321					if ( ret !== undefined ) {
3322						event.result = ret;
3323						if ( ret === false ) {
3324							event.preventDefault();
3325							event.stopPropagation();
3326						}
3327					}
3328				}
3329			}
3330		}
3331
3332		return event.result;
3333	},
3334
3335	// Includes some event props shared by KeyEvent and MouseEvent
3336	// *** attrChange attrName relatedNode srcElement  are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3337	props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3338
3339	fixHooks: {},
3340
3341	keyHooks: {
3342		props: "char charCode key keyCode".split(" "),
3343		filter: function( event, original ) {
3344
3345			// Add which for key events
3346			if ( event.which == null ) {
3347				event.which = original.charCode != null ? original.charCode : original.keyCode;
3348			}
3349
3350			return event;
3351		}
3352	},
3353
3354	mouseHooks: {
3355		props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement wheelDelta".split(" "),
3356		filter: function( event, original ) {
3357			var eventDoc, doc, body,
3358				button = original.button,
3359				fromElement = original.fromElement;
3360
3361			// Calculate pageX/Y if missing and clientX/Y available
3362			if ( event.pageX == null && original.clientX != null ) {
3363				eventDoc = event.target.ownerDocument || document;
3364				doc = eventDoc.documentElement;
3365				body = eventDoc.body;
3366
3367				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3368				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
3369			}
3370
3371			// Add relatedTarget, if necessary
3372			if ( !event.relatedTarget && fromElement ) {
3373				event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3374			}
3375
3376			// Add which for click: 1 === left; 2 === middle; 3 === right
3377			// Note: button is not normalized, so don't use it
3378			if ( !event.which && button !== undefined ) {
3379				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3380			}
3381
3382			return event;
3383		}
3384	},
3385
3386	fix: function( event ) {
3387		if ( event[ jQuery.expando ] ) {
3388			return event;
3389		}
3390
3391		// Create a writable copy of the event object and normalize some properties
3392		var i, prop,
3393			originalEvent = event,
3394			fixHook = jQuery.event.fixHooks[ event.type ] || {},
3395			copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3396
3397		event = jQuery.Event( originalEvent );
3398
3399		for ( i = copy.length; i; ) {
3400			prop = copy[ --i ];
3401			event[ prop ] = originalEvent[ prop ];
3402		}
3403
3404		// Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3405		if ( !event.target ) {
3406			event.target = originalEvent.srcElement || document;
3407		}
3408
3409		// Target should not be a text node (#504, Safari)
3410		if ( event.target.nodeType === 3 ) {
3411			event.target = event.target.parentNode;
3412		}
3413
3414		// For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)
3415		if ( event.metaKey === undefined ) {
3416			event.metaKey = event.ctrlKey;
3417		}
3418
3419		return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3420	},
3421
3422	special: {
3423		ready: {
3424			// Make sure the ready event is setup
3425			setup: jQuery.bindReady
3426		},
3427
3428		focus: {
3429			delegateType: "focusin",
3430			noBubble: true
3431		},
3432		blur: {
3433			delegateType: "focusout",
3434			noBubble: true
3435		},
3436
3437		beforeunload: {
3438			setup: function( data, namespaces, eventHandle ) {
3439				// We only want to do this special case on windows
3440				if ( jQuery.isWindow( this ) ) {
3441					this.onbeforeunload = eventHandle;
3442				}
3443			},
3444
3445			teardown: function( namespaces, eventHandle ) {
3446				if ( this.onbeforeunload === eventHandle ) {
3447					this.onbeforeunload = null;
3448				}
3449			}
3450		}
3451	},
3452
3453	simulate: function( type, elem, event, bubble ) {
3454		// Piggyback on a donor event to simulate a different one.
3455		// Fake originalEvent to avoid donor's stopPropagation, but if the
3456		// simulated event prevents default then we do the same on the donor.
3457		var e = jQuery.extend(
3458			new jQuery.Event(),
3459			event,
3460			{ type: type,
3461				isSimulated: true,
3462				originalEvent: {}
3463			}
3464		);
3465		if ( bubble ) {
3466			jQuery.event.trigger( e, null, elem );
3467		} else {
3468			jQuery.event.dispatch.call( elem, e );
3469		}
3470		if ( e.isDefaultPrevented() ) {
3471			event.preventDefault();
3472		}
3473	}
3474};
3475
3476// Some plugins are using, but it's undocumented/deprecated and will be removed.
3477// The 1.7 special event interface should provide all the hooks needed now.
3478jQuery.event.handle = jQuery.event.dispatch;
3479
3480jQuery.removeEvent = document.removeEventListener ?
3481	function( elem, type, handle ) {
3482		if ( elem.removeEventListener ) {
3483			elem.removeEventListener( type, handle, false );
3484		}
3485	} :
3486	function( elem, type, handle ) {
3487		if ( elem.detachEvent ) {
3488			elem.detachEvent( "on" + type, handle );
3489		}
3490	};
3491
3492jQuery.Event = function( src, props ) {
3493	// Allow instantiation without the 'new' keyword
3494	if ( !(this instanceof jQuery.Event) ) {
3495		return new jQuery.Event( src, props );
3496	}
3497
3498	// Event object
3499	if ( src && src.type ) {
3500		this.originalEvent = src;
3501		this.type = src.type;
3502
3503		// Events bubbling up the document may have been marked as prevented
3504		// by a handler lower down the tree; reflect the correct value.
3505		this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
3506			src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
3507
3508	// Event type
3509	} else {
3510		this.type = src;
3511	}
3512
3513	// Put explicitly provided properties onto the event object
3514	if ( props ) {
3515		jQuery.extend( this, props );
3516	}
3517
3518	// Create a timestamp if incoming event doesn't have one
3519	this.timeStamp = src && src.timeStamp || jQuery.now();
3520
3521	// Mark it as fixed
3522	this[ jQuery.expando ] = true;
3523};
3524
3525function returnFalse() {
3526	return false;
3527}
3528function returnTrue() {
3529	return true;
3530}
3531
3532// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3533// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3534jQuery.Event.prototype = {
3535	preventDefault: function() {
3536		this.isDefaultPrevented = returnTrue;
3537
3538		var e = this.originalEvent;
3539		if ( !e ) {
3540			return;
3541		}
3542
3543		// if preventDefault exists run it on the original event
3544		if ( e.preventDefault ) {
3545			e.preventDefault();
3546
3547		// otherwise set the returnValue property of the original event to false (IE)
3548		} else {
3549			e.returnValue = false;
3550		}
3551	},
3552	stopPropagation: function() {
3553		this.isPropagationStopped = returnTrue;
3554
3555		var e = this.originalEvent;
3556		if ( !e ) {
3557			return;
3558		}
3559		// if stopPropagation exists run it on the original event
3560		if ( e.stopPropagation ) {
3561			e.stopPropagation();
3562		}
3563		// otherwise set the cancelBubble property of the original event to true (IE)
3564		e.cancelBubble = true;
3565	},
3566	stopImmediatePropagation: function() {
3567		this.isImmediatePropagationStopped = returnTrue;
3568		this.stopPropagation();
3569	},
3570	isDefaultPrevented: returnFalse,
3571	isPropagationStopped: returnFalse,
3572	isImmediatePropagationStopped: returnFalse
3573};
3574
3575// Create mouseenter/leave events using mouseover/out and event-time checks
3576jQuery.each({
3577	mouseenter: "mouseover",
3578	mouseleave: "mouseout"
3579}, function( orig, fix ) {
3580	jQuery.event.special[ orig ] = jQuery.event.special[ fix ] = {
3581		delegateType: fix,
3582		bindType: fix,
3583
3584		handle: function( event ) {
3585			var target = this,
3586				related = event.relatedTarget,
3587				handleObj = event.handleObj,
3588				selector = handleObj.selector,
3589				oldType, ret;
3590
3591			// For a real mouseover/out, always call the handler; for
3592			// mousenter/leave call the handler if related is outside the target.
3593			// NB: No relatedTarget if the mouse left/entered the browser window
3594			if ( !related || handleObj.origType === event.type || (related !== target && !jQuery.contains( target, related )) ) {
3595				oldType = event.type;
3596				event.type = handleObj.origType;
3597				ret = handleObj.handler.apply( this, arguments );
3598				event.type = oldType;
3599			}
3600			return ret;
3601		}
3602	};
3603});
3604
3605// IE submit delegation
3606if ( !jQuery.support.submitBubbles ) {
3607
3608	jQuery.event.special.submit = {
3609		setup: function() {
3610			// Only need this for delegated form submit events
3611			if ( jQuery.nodeName( this, "form" ) ) {
3612				return false;
3613			}
3614
3615			// Lazy-add a submit handler when a descendant form may potentially be submitted
3616			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3617				// Node name check avoids a VML-related crash in IE (#9807)
3618				var elem = e.target,
3619					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3620				if ( form && !form._submit_attached ) {
3621					jQuery.event.add( form, "submit._submit", function( event ) {
3622						// Form was submitted, bubble the event up the tree
3623						if ( this.parentNode ) {
3624							jQuery.event.simulate( "submit", this.parentNode, event, true );
3625						}
3626					});
3627					form._submit_attached = true;
3628				}
3629			});
3630			// return undefined since we don't need an event listener
3631		},
3632
3633		teardown: function() {
3634			// Only need this for delegated form submit events
3635			if ( jQuery.nodeName( this, "form" ) ) {
3636				return false;
3637			}
3638
3639			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3640			jQuery.event.remove( this, "._submit" );
3641		}
3642	};
3643}
3644
3645// IE change delegation and checkbox/radio fix
3646if ( !jQuery.support.changeBubbles ) {
3647
3648	jQuery.event.special.change = {
3649
3650		setup: function() {
3651
3652			if ( rformElems.test( this.nodeName ) ) {
3653				// IE doesn't fire change on a check/radio until blur; trigger it on click
3654				// after a propertychange. Eat the blur-change in special.change.handle.
3655				// This still fires onchange a second time for check/radio after blur.
3656				if ( this.type === "checkbox" || this.type === "radio" ) {
3657					jQuery.event.add( this, "propertychange._change", function( event ) {
3658						if ( event.originalEvent.propertyName === "checked" ) {
3659							this._just_changed = true;
3660						}
3661					});
3662					jQuery.event.add( this, "click._change", function( event ) {
3663						if ( this._just_changed ) {
3664							this._just_changed = false;
3665							jQuery.event.simulate( "change", this, event, true );
3666						}
3667					});
3668				}
3669				return false;
3670			}
3671			// Delegated event; lazy-add a change handler on descendant inputs
3672			jQuery.event.add( this, "beforeactivate._change", function( e ) {
3673				var elem = e.target;
3674
3675				if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {
3676					jQuery.event.add( elem, "change._change", function( event ) {
3677						if ( this.parentNode && !event.isSimulated ) {
3678							jQuery.event.simulate( "change", this.parentNode, event, true );
3679						}
3680					});
3681					elem._change_attached = true;
3682				}
3683			});
3684		},
3685
3686		handle: function( event ) {
3687			var elem = event.target;
3688
3689			// Swallow native change events from checkbox/radio, we already triggered them above
3690			if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3691				return event.handleObj.handler.apply( this, arguments );
3692			}
3693		},
3694
3695		teardown: function() {
3696			jQuery.event.remove( this, "._change" );
3697
3698			return rformElems.test( this.nodeName );
3699		}
3700	};
3701}
3702
3703// Create "bubbling" focus and blur events
3704if ( !jQuery.support.focusinBubbles ) {
3705	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3706
3707		// Attach a single capturing handler while someone wants focusin/focusout
3708		var attaches = 0,
3709			handler = function( event ) {
3710				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
3711			};
3712
3713		jQuery.event.special[ fix ] = {
3714			setup: function() {
3715				if ( attaches++ === 0 ) {
3716					document.addEventListener( orig, handler, true );
3717				}
3718			},
3719			teardown: function() {
3720				if ( --attaches === 0 ) {
3721					document.removeEventListener( orig, handler, true );
3722				}
3723			}
3724		};
3725	});
3726}
3727
3728jQuery.fn.extend({
3729
3730	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3731		var origFn, type;
3732
3733		// Types can be a map of types/handlers
3734		if ( typeof types === "object" ) {
3735			// ( types-Object, selector, data )
3736			if ( typeof selector !== "string" ) {
3737				// ( types-Object, data )
3738				data = selector;
3739				selector = undefined;
3740			}
3741			for ( type in types ) {
3742				this.on( type, selector, data, types[ type ], one );
3743			}
3744			return this;
3745		}
3746
3747		if ( data == null && fn == null ) {
3748			// ( types, fn )
3749			fn = selector;
3750			data = selector = undefined;
3751		} else if ( fn == null ) {
3752			if ( typeof selector === "string" ) {
3753				// ( types, selector, fn )
3754				fn = data;
3755				data = undefined;
3756			} else {
3757				// ( types, data, fn )
3758				fn = data;
3759				data = selector;
3760				selector = undefined;
3761			}
3762		}
3763		if ( fn === false ) {
3764			fn = returnFalse;
3765		} else if ( !fn ) {
3766			return this;
3767		}
3768
3769		if ( one === 1 ) {
3770			origFn = fn;
3771			fn = function( event ) {
3772				// Can use an empty set, since event contains the info
3773				jQuery().off( event );
3774				return origFn.apply( this, arguments );
3775			};
3776			// Use same guid so caller can remove using origFn
3777			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3778		}
3779		return this.each( function() {
3780			jQuery.event.add( this, types, fn, data, selector );
3781		});
3782	},
3783	one: function( types, selector, data, fn ) {
3784		return this.on.call( this, types, selector, data, fn, 1 );
3785	},
3786	off: function( types, selector, fn ) {
3787		if ( types && types.preventDefault && types.handleObj ) {
3788			// ( event )  dispatched jQuery.Event
3789			var handleObj = types.handleObj;
3790			jQuery( types.delegateTarget ).off(
3791				handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type,
3792				handleObj.selector,
3793				handleObj.handler
3794			);
3795			return this;
3796		}
3797		if ( typeof types === "object" ) {
3798			// ( types-object [, selector] )
3799			for ( var type in types ) {
3800				this.off( type, selector, types[ type ] );
3801			}
3802			return this;
3803		}
3804		if ( selector === false || typeof selector === "function" ) {
3805			// ( types [, fn] )
3806			fn = selector;
3807			selector = undefined;
3808		}
3809		if ( fn === false ) {
3810			fn = returnFalse;
3811		}
3812		return this.each(function() {
3813			jQuery.event.remove( this, types, fn, selector );
3814		});
3815	},
3816
3817	bind: function( types, data, fn ) {
3818		return this.on( types, null, data, fn );
3819	},
3820	unbind: function( types, fn ) {
3821		return this.off( types, null, fn );
3822	},
3823
3824	live: function( types, data, fn ) {
3825		jQuery( this.context ).on( types, this.selector, data, fn );
3826		return this;
3827	},
3828	die: function( types, fn ) {
3829		jQuery( this.context ).off( types, this.selector || "**", fn );
3830		return this;
3831	},
3832
3833	delegate: function( selector, types, data, fn ) {
3834		return this.on( types, selector, data, fn );
3835	},
3836	undelegate: function( selector, types, fn ) {
3837		// ( namespace ) or ( selector, types [, fn] )
3838		return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );
3839	},
3840
3841	trigger: function( type, data ) {
3842		return this.each(function() {
3843			jQuery.event.trigger( type, data, this );
3844		});
3845	},
3846	triggerHandler: function( type, data ) {
3847		if ( this[0] ) {
3848			return jQuery.event.trigger( type, data, this[0], true );
3849		}
3850	},
3851
3852	toggle: function( fn ) {
3853		// Save reference to arguments for access in closure
3854		var args = arguments,
3855			guid = fn.guid || jQuery.guid++,
3856			i = 0,
3857			toggler = function( event ) {
3858				// Figure out which function to execute
3859				var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3860				jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3861
3862				// Make sure that clicks stop
3863				event.preventDefault();
3864
3865				// and execute the function
3866				return args[ lastToggle ].apply( this, arguments ) || false;
3867			};
3868
3869		// link all the functions, so any of them can unbind this click handler
3870		toggler.guid = guid;
3871		while ( i < args.length ) {
3872			args[ i++ ].guid = guid;
3873		}
3874
3875		return this.click( toggler );
3876	},
3877
3878	hover: function( fnOver, fnOut ) {
3879		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3880	}
3881});
3882
3883jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3884	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3885	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3886
3887	// Handle event binding
3888	jQuery.fn[ name ] = function( data, fn ) {
3889		if ( fn == null ) {
3890			fn = data;
3891			data = null;
3892		}
3893
3894		return arguments.length > 0 ?
3895			this.bind( name, data, fn ) :
3896			this.trigger( name );
3897	};
3898
3899	if ( jQuery.attrFn ) {
3900		jQuery.attrFn[ name ] = true;
3901	}
3902
3903	if ( rkeyEvent.test( name ) ) {
3904		jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
3905	}
3906
3907	if ( rmouseEvent.test( name ) ) {
3908		jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
3909	}
3910});
3911
3912
3913
3914/*!
3915 * Sizzle CSS Selector Engine
3916 *  Copyright 2011, The Dojo Foundation
3917 *  Released under the MIT, BSD, and GPL Licenses.
3918 *  More information: http://sizzlejs.com/
3919 */
3920(function(){
3921
3922var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3923	expando = "sizcache" + (Math.random() + '').replace('.', ''),
3924	done = 0,
3925	toString = Object.prototype.toString,
3926	hasDuplicate = false,
3927	baseHasDuplicate = true,
3928	rBackslash = /\\/g,
3929	rReturn = /\r\n/g,
3930	rNonWord = /\W/;
3931
3932// Here we check if the JavaScript engine is using some sort of
3933// optimization where it does not always call our comparision
3934// function. If that is the case, discard the hasDuplicate value.
3935//   Thus far that includes Google Chrome.
3936[0, 0].sort(function() {
3937	baseHasDuplicate = false;
3938	return 0;
3939});
3940
3941var Sizzle = function( selector, context, results, seed ) {
3942	results = results || [];
3943	context = context || document;
3944
3945	var origContext = context;
3946
3947	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3948		return [];
3949	}
3950
3951	if ( !selector || typeof selector !== "string" ) {
3952		return results;
3953	}
3954
3955	var m, set, checkSet, extra, ret, cur, pop, i,
3956		prune = true,
3957		contextXML = Sizzle.isXML( context ),
3958		parts = [],
3959		soFar = selector;
3960
3961	// Reset the position of the chunker regexp (start from head)
3962	do {
3963		chunker.exec( "" );
3964		m = chunker.exec( soFar );
3965
3966		if ( m ) {
3967			soFar = m[3];
3968
3969			parts.push( m[1] );
3970
3971			if ( m[2] ) {
3972				extra = m[3];
3973				break;
3974			}
3975		}
3976	} while ( m );
3977
3978	if ( parts.length > 1 && origPOS.exec( selector ) ) {
3979
3980		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3981			set = posProcess( parts[0] + parts[1], context, seed );
3982
3983		} else {
3984			set = Expr.relative[ parts[0] ] ?
3985				[ context ] :
3986				Sizzle( parts.shift(), context );
3987
3988			while ( parts.length ) {
3989				selector = parts.shift();
3990
3991				if ( Expr.relative[ selector ] ) {
3992					selector += parts.shift();
3993				}
3994
3995				set = posProcess( selector, set, seed );
3996			}
3997		}
3998
3999	} else {
4000		// Take a shortcut and set the context if the root selector is an ID
4001		// (but not if it'll be faster if the inner selector is an ID)
4002		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4003				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4004
4005			ret = Sizzle.find( parts.shift(), context, contextXML );
4006			context = ret.expr ?
4007				Sizzle.filter( ret.expr, ret.set )[0] :
4008				ret.set[0];
4009		}
4010
4011		if ( context ) {
4012			ret = seed ?
4013				{ expr: parts.pop(), set: makeArray(seed) } :
4014				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4015
4016			set = ret.expr ?
4017				Sizzle.filter( ret.expr, ret.set ) :
4018				ret.set;
4019
4020			if ( parts.length > 0 ) {
4021				checkSet = makeArray( set );
4022
4023			} else {
4024				prune = false;
4025			}
4026
4027			while ( parts.length ) {
4028				cur = parts.pop();
4029				pop = cur;
4030
4031				if ( !Expr.relative[ cur ] ) {
4032					cur = "";
4033				} else {
4034					pop = parts.pop();
4035				}
4036
4037				if ( pop == null ) {
4038					pop = context;
4039				}
4040
4041				Expr.relative[ cur ]( checkSet, pop, contextXML );
4042			}
4043
4044		} else {
4045			checkSet = parts = [];
4046		}
4047	}
4048
4049	if ( !checkSet ) {
4050		checkSet = set;
4051	}
4052
4053	if ( !checkSet ) {
4054		Sizzle.error( cur || selector );
4055	}
4056
4057	if ( toString.call(checkSet) === "[object Array]" ) {
4058		if ( !prune ) {
4059			results.push.apply( results, checkSet );
4060
4061		} else if ( context && context.nodeType === 1 ) {
4062			for ( i = 0; checkSet[i] != null; i++ ) {
4063				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
4064					results.push( set[i] );
4065				}
4066			}
4067
4068		} else {
4069			for ( i = 0; checkSet[i] != null; i++ ) {
4070				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4071					results.push( set[i] );
4072				}
4073			}
4074		}
4075
4076	} else {
4077		makeArray( checkSet, results );
4078	}
4079
4080	if ( extra ) {
4081		Sizzle( extra, origContext, results, seed );
4082		Sizzle.uniqueSort( results );
4083	}
4084
4085	return results;
4086};
4087
4088Sizzle.uniqueSort = function( results ) {
4089	if ( sortOrder ) {
4090		hasDuplicate = baseHasDuplicate;
4091		results.sort( sortOrder );
4092
4093		if ( hasDuplicate ) {
4094			for ( var i = 1; i < results.length; i++ ) {
4095				if ( results[i] === results[ i - 1 ] ) {
4096					results.splice( i--, 1 );
4097				}
4098			}
4099		}
4100	}
4101
4102	return results;
4103};
4104
4105Sizzle.matches = function( expr, set ) {
4106	return Sizzle( expr, null, null, set );
4107};
4108
4109Sizzle.matchesSelector = function( node, expr ) {
4110	return Sizzle( expr, null, null, [node] ).length > 0;
4111};
4112
4113Sizzle.find = function( expr, context, isXML ) {
4114	var set, i, len, match, type, left;
4115
4116	if ( !expr ) {
4117		return [];
4118	}
4119
4120	for ( i = 0, len = Expr.order.length; i < len; i++ ) {
4121		type = Expr.order[i];
4122
4123		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4124			left = match[1];
4125			match.splice( 1, 1 );
4126
4127			if ( left.substr( left.length - 1 ) !== "\\" ) {
4128				match[1] = (match[1] || "").replace( rBackslash, "" );
4129				set = Expr.find[ type ]( match, context, isXML );
4130
4131				if ( set != null ) {
4132					expr = expr.replace( Expr.match[ type ], "" );
4133					break;
4134				}
4135			}
4136		}
4137	}
4138
4139	if ( !set ) {
4140		set = typeof context.getElementsByTagName !== "undefined" ?
4141			context.getElementsByTagName( "*" ) :
4142			[];
4143	}
4144
4145	return { set: set, expr: expr };
4146};
4147
4148Sizzle.filter = function( expr, set, inplace, not ) {
4149	var match, anyFound,
4150		type, found, item, filter, left,
4151		i, pass,
4152		old = expr,
4153		result = [],
4154		curLoop = set,
4155		isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4156
4157	while ( expr && set.length ) {
4158		for ( type in Expr.filter ) {
4159			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4160				filter = Expr.filter[ type ];
4161				left = match[1];
4162
4163				anyFound = false;
4164
4165				match.splice(1,1);
4166
4167				if ( left.substr( left.length - 1 ) === "\\" ) {
4168					continue;
4169				}
4170
4171				if ( curLoop === result ) {
4172					result = [];
4173				}
4174
4175				if ( Expr.preFilter[ type ] ) {
4176					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4177
4178					if ( !match ) {
4179						anyFound = found = true;
4180
4181					} else if ( match === true ) {
4182						continue;
4183					}
4184				}
4185
4186				if ( match ) {
4187					for ( i = 0; (item = curLoop[i]) != null; i++ ) {
4188						if ( item ) {
4189							found = filter( item, match, i, curLoop );
4190							pass = not ^ found;
4191
4192							if ( inplace && found != null ) {
4193								if ( pass ) {
4194									anyFound = true;
4195
4196								} else {
4197									curLoop[i] = false;
4198								}
4199
4200							} else if ( pass ) {
4201								result.push( item );
4202								anyFound = true;
4203							}
4204						}
4205					}
4206				}
4207
4208				if ( found !== undefined ) {
4209					if ( !inplace ) {
4210						curLoop = result;
4211					}
4212
4213					expr = expr.replace( Expr.match[ type ], "" );
4214
4215					if ( !anyFound ) {
4216						return [];
4217					}
4218
4219					break;
4220				}
4221			}
4222		}
4223
4224		// Improper expression
4225		if ( expr === old ) {
4226			if ( anyFound == null ) {
4227				Sizzle.error( expr );
4228
4229			} else {
4230				break;
4231			}
4232		}
4233
4234		old = expr;
4235	}
4236
4237	return curLoop;
4238};
4239
4240Sizzle.error = function( msg ) {
4241	throw "Syntax error, unrecognized expression: " + msg;
4242};
4243
4244/**
4245 * Utility function for retreiving the text value of an array of DOM nodes
4246 * @param {Array|Element} elem
4247 */
4248var getText = Sizzle.getText = function( elem ) {
4249    var i, node,
4250		nodeType = elem.nodeType,
4251		ret = "";
4252
4253	if ( nodeType ) {
4254		if ( nodeType === 1 ) {
4255			// Use textContent || innerText for elements
4256			if ( typeof elem.textContent === 'string' ) {
4257				return elem.textContent;
4258			} else if ( typeof elem.innerText === 'string' ) {
4259				// Replace IE's carriage returns
4260				return elem.innerText.replace( rReturn, '' );
4261			} else {
4262				// Traverse it's children
4263				for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
4264					ret += getText( elem );
4265				}
4266			}
4267		} else if ( nodeType === 3 || nodeType === 4 ) {
4268			return elem.nodeValue;
4269		}
4270	} else {
4271
4272		// If no nodeType, this is expected to be an array
4273		for ( i = 0; (node = elem[i]); i++ ) {
4274			// Do not traverse comment nodes
4275			if ( node.nodeType !== 8 ) {
4276				ret += getText( node );
4277			}
4278		}
4279	}
4280	return ret;
4281};
4282
4283var Expr = Sizzle.selectors = {
4284	order: [ "ID", "NAME", "TAG" ],
4285
4286	match: {
4287		ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4288		CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4289		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4290		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4291		TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4292		CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4293		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4294		PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4295	},
4296
4297	leftMatch: {},
4298
4299	attrMap: {
4300		"class": "className",
4301		"for": "htmlFor"
4302	},
4303
4304	attrHandle: {
4305		href: function( elem ) {
4306			return elem.getAttribute( "href" );
4307		},
4308		type: function( elem ) {
4309			return elem.getAttribute( "type" );
4310		}
4311	},
4312
4313	relative: {
4314		"+": function(checkSet, part){
4315			var isPartStr = typeof part === "string",
4316				isTag = isPartStr && !rNonWord.test( part ),
4317				isPartStrNotTag = isPartStr && !isTag;
4318
4319			if ( isTag ) {
4320				part = part.toLowerCase();
4321			}
4322
4323			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4324				if ( (elem = checkSet[i]) ) {
4325					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4326
4327					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4328						elem || false :
4329						elem === part;
4330				}
4331			}
4332
4333			if ( isPartStrNotTag ) {
4334				Sizzle.filter( part, checkSet, true );
4335			}
4336		},
4337
4338		">": function( checkSet, part ) {
4339			var elem,
4340				isPartStr = typeof part === "string",
4341				i = 0,
4342				l = checkSet.length;
4343
4344			if ( isPartStr && !rNonWord.test( part ) ) {
4345				part = part.toLowerCase();
4346
4347				for ( ; i < l; i++ ) {
4348					elem = checkSet[i];
4349
4350					if ( elem ) {
4351						var parent = elem.parentNode;
4352						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4353					}
4354				}
4355
4356			} else {
4357				for ( ; i < l; i++ ) {
4358					elem = checkSet[i];
4359
4360					if ( elem ) {
4361						checkSet[i] = isPartStr ?
4362							elem.parentNode :
4363							elem.parentNode === part;
4364					}
4365				}
4366
4367				if ( isPartStr ) {
4368					Sizzle.filter( part, checkSet, true );
4369				}
4370			}
4371		},
4372
4373		"": function(checkSet, part, isXML){
4374			var nodeCheck,
4375				doneName = done++,
4376				checkFn = dirCheck;
4377
4378			if ( typeof part === "string" && !rNonWord.test( part ) ) {
4379				part = part.toLowerCase();
4380				nodeCheck = part;
4381				checkFn = dirNodeCheck;
4382			}
4383
4384			checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4385		},
4386
4387		"~": function( checkSet, part, isXML ) {
4388			var nodeCheck,
4389				doneName = done++,
4390				checkFn = dirCheck;
4391
4392			if ( typeof part === "string" && !rNonWord.test( part ) ) {
4393				part = part.toLowerCase();
4394				nodeCheck = part;
4395				checkFn = dirNodeCheck;
4396			}
4397
4398			checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4399		}
4400	},
4401
4402	find: {
4403		ID: function( match, context, isXML ) {
4404			if ( typeof context.getElementById !== "undefined" && !isXML ) {
4405				var m = context.getElementById(match[1]);
4406				// Check parentNode to catch when Blackberry 4.6 returns
4407				// nodes that are no longer in the document #6963
4408				return m && m.parentNode ? [m] : [];
4409			}
4410		},
4411
4412		NAME: function( match, context ) {
4413			if ( typeof context.getElementsByName !== "undefined" ) {
4414				var ret = [],
4415					results = context.getElementsByName( match[1] );
4416
4417				for ( var i = 0, l = results.length; i < l; i++ ) {
4418					if ( results[i].getAttribute("name") === match[1] ) {
4419						ret.push( results[i] );
4420					}
4421				}
4422
4423				return ret.length === 0 ? null : ret;
4424			}
4425		},
4426
4427		TAG: function( match, context ) {
4428			if ( typeof context.getElementsByTagName !== "undefined" ) {
4429				return context.getElementsByTagName( match[1] );
4430			}
4431		}
4432	},
4433	preFilter: {
4434		CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4435			match = " " + match[1].replace( rBackslash, "" ) + " ";
4436
4437			if ( isXML ) {
4438				return match;
4439			}
4440
4441			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4442				if ( elem ) {
4443					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4444						if ( !inplace ) {
4445							result.push( elem );
4446						}
4447
4448					} else if ( inplace ) {
4449						curLoop[i] = false;
4450					}
4451				}
4452			}
4453
4454			return false;
4455		},
4456
4457		ID: function( match ) {
4458			return match[1].replace( rBackslash, "" );
4459		},
4460
4461		TAG: function( match, curLoop ) {
4462			return match[1].replace( rBackslash, "" ).toLowerCase();
4463		},
4464
4465		CHILD: function( match ) {
4466			if ( match[1] === "nth" ) {
4467				if ( !match[2] ) {
4468					Sizzle.error( match[0] );
4469				}
4470
4471				match[2] = match[2].replace(/^\+|\s*/g, '');
4472
4473				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4474				var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4475					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4476					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4477
4478				// calculate the numbers (first)n+(last) including if they are negative
4479				match[2] = (test[1] + (test[2] || 1)) - 0;
4480				match[3] = test[3] - 0;
4481			}
4482			else if ( match[2] ) {
4483				Sizzle.error( match[0] );
4484			}
4485
4486			// TODO: Move to normal caching system
4487			match[0] = done++;
4488
4489			return match;
4490		},
4491
4492		ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4493			var name = match[1] = match[1].replace( rBackslash, "" );
4494
4495			if ( !isXML && Expr.attrMap[name] ) {
4496				match[1] = Expr.attrMap[name];
4497			}
4498
4499			// Handle if an un-quoted value was used
4500			match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4501
4502			if ( match[2] === "~=" ) {
4503				match[4] = " " + match[4] + " ";
4504			}
4505
4506			return match;
4507		},
4508
4509		PSEUDO: function( match, curLoop, inplace, result, not ) {
4510			if ( match[1] === "not" ) {
4511				// If we're dealing with a complex expression, or a simple one
4512				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4513					match[3] = Sizzle(match[3], null, null, curLoop);
4514
4515				} else {
4516					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4517
4518					if ( !inplace ) {
4519						result.push.apply( result, ret );
4520					}
4521
4522					return false;
4523				}
4524
4525			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4526				return true;
4527			}
4528
4529			return match;
4530		},
4531
4532		POS: function( match ) {
4533			match.unshift( true );
4534
4535			return match;
4536		}
4537	},
4538
4539	filters: {
4540		enabled: function( elem ) {
4541			return elem.disabled === false && elem.type !== "hidden";
4542		},
4543
4544		disabled: function( elem ) {
4545			return elem.disabled === true;
4546		},
4547
4548		checked: function( elem ) {
4549			return elem.checked === true;
4550		},
4551
4552		selected: function( elem ) {
4553			// Accessing this property makes selected-by-default
4554			// options in Safari work properly
4555			if ( elem.parentNode ) {
4556				elem.parentNode.selectedIndex;
4557			}
4558
4559			return elem.selected === true;
4560		},
4561
4562		parent: function( elem ) {
4563			return !!elem.firstChild;
4564		},
4565
4566		empty: function( elem ) {
4567			return !elem.firstChild;
4568		},
4569
4570		has: function( elem, i, match ) {
4571			return !!Sizzle( match[3], elem ).length;
4572		},
4573
4574		header: function( elem ) {
4575			return (/h\d/i).test( elem.nodeName );
4576		},
4577
4578		text: function( elem ) {
4579			var attr = elem.getAttribute( "type" ), type = elem.type;
4580			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4581			// use getAttribute instead to test this case
4582			return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4583		},
4584
4585		radio: function( elem ) {
4586			return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4587		},
4588
4589		checkbox: function( elem ) {
4590			return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4591		},
4592
4593		file: function( elem ) {
4594			return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4595		},
4596
4597		password: function( elem ) {
4598			return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4599		},
4600
4601		submit: function( elem ) {
4602			var name = elem.nodeName.toLowerCase();
4603			return (name === "input" || name === "button") && "submit" === elem.type;
4604		},
4605
4606		image: function( elem ) {
4607			return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4608		},
4609
4610		reset: function( elem ) {
4611			var name = elem.nodeName.toLowerCase();
4612			return (name === "input" || name === "button") && "reset" === elem.type;
4613		},
4614
4615		button: function( elem ) {
4616			var name = elem.nodeName.toLowerCase();
4617			return name === "input" && "button" === elem.type || name === "button";
4618		},
4619
4620		input: function( elem ) {
4621			return (/input|select|textarea|button/i).test( elem.nodeName );
4622		},
4623
4624		focus: function( elem ) {
4625			return elem === elem.ownerDocument.activeElement;
4626		}
4627	},
4628	setFilters: {
4629		first: function( elem, i ) {
4630			return i === 0;
4631		},
4632
4633		last: function( elem, i, match, array ) {
4634			return i === array.length - 1;
4635		},
4636
4637		even: function( elem, i ) {
4638			return i % 2 === 0;
4639		},
4640
4641		odd: function( elem, i ) {
4642			return i % 2 === 1;
4643		},
4644
4645		lt: function( elem, i, match ) {
4646			return i < match[3] - 0;
4647		},
4648
4649		gt: function( elem, i, match ) {
4650			return i > match[3] - 0;
4651		},
4652
4653		nth: function( elem, i, match ) {
4654			return match[3] - 0 === i;
4655		},
4656
4657		eq: function( elem, i, match ) {
4658			return match[3] - 0 === i;
4659		}
4660	},
4661	filter: {
4662		PSEUDO: function( elem, match, i, array ) {
4663			var name = match[1],
4664				filter = Expr.filters[ name ];
4665
4666			if ( filter ) {
4667				return filter( elem, i, match, array );
4668
4669			} else if ( name === "contains" ) {
4670				return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
4671
4672			} else if ( name === "not" ) {
4673				var not = match[3];
4674
4675				for ( var j = 0, l = not.length; j < l; j++ ) {
4676					if ( not[j] === elem ) {
4677						return false;
4678					}
4679				}
4680
4681				return true;
4682
4683			} else {
4684				Sizzle.error( name );
4685			}
4686		},
4687
4688		CHILD: function( elem, match ) {
4689			var first, last,
4690				doneName, parent, cache,
4691				count, diff,
4692				type = match[1],
4693				node = elem;
4694
4695			switch ( type ) {
4696				case "only":
4697				case "first":
4698					while ( (node = node.previousSibling) )	 {
4699						if ( node.nodeType === 1 ) {
4700							return false;
4701						}
4702					}
4703
4704					if ( type === "first" ) {
4705						return true;
4706					}
4707
4708					node = elem;
4709
4710				case "last":
4711					while ( (node = node.nextSibling) )	 {
4712						if ( node.nodeType === 1 ) {
4713							return false;
4714						}
4715					}
4716
4717					return true;
4718
4719				case "nth":
4720					first = match[2];
4721					last = match[3];
4722
4723					if ( first === 1 && last === 0 ) {
4724						return true;
4725					}
4726
4727					doneName = match[0];
4728					parent = elem.parentNode;
4729
4730					if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
4731						count = 0;
4732
4733						for ( node = parent.firstChild; node; node = node.nextSibling ) {
4734							if ( node.nodeType === 1 ) {
4735								node.nodeIndex = ++count;
4736							}
4737						}
4738
4739						parent[ expando ] = doneName;
4740					}
4741
4742					diff = elem.nodeIndex - last;
4743
4744					if ( first === 0 ) {
4745						return diff === 0;
4746
4747					} else {
4748						return ( diff % first === 0 && diff / first >= 0 );
4749					}
4750			}
4751		},
4752
4753		ID: function( elem, match ) {
4754			return elem.nodeType === 1 && elem.getAttribute("id") === match;
4755		},
4756
4757		TAG: function( elem, match ) {
4758			return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
4759		},
4760
4761		CLASS: function( elem, match ) {
4762			return (" " + (elem.className || elem.getAttribute("class")) + " ")
4763				.indexOf( match ) > -1;
4764		},
4765
4766		ATTR: function( elem, match ) {
4767			var name = match[1],
4768				result = Sizzle.attr ?
4769					Sizzle.attr( elem, name ) :
4770					Expr.attrHandle[ name ] ?
4771					Expr.attrHandle[ name ]( elem ) :
4772					elem[ name ] != null ?
4773						elem[ name ] :
4774						elem.getAttribute( name ),
4775				value = result + "",
4776				type = match[2],
4777				check = match[4];
4778
4779			return result == null ?
4780				type === "!=" :
4781				!type && Sizzle.attr ?
4782				result != null :
4783				type === "=" ?
4784				value === check :
4785				type === "*=" ?
4786				value.indexOf(check) >= 0 :
4787				type === "~=" ?
4788				(" " + value + " ").indexOf(check) >= 0 :
4789				!check ?
4790				value && result !== false :
4791				type === "!=" ?
4792				value !== check :
4793				type === "^=" ?
4794				value.indexOf(check) === 0 :
4795				type === "$=" ?
4796				value.substr(value.length - check.length) === check :
4797				type === "|=" ?
4798				value === check || value.substr(0, check.length + 1) === check + "-" :
4799				false;
4800		},
4801
4802		POS: function( elem, match, i, array ) {
4803			var name = match[2],
4804				filter = Expr.setFilters[ name ];
4805
4806			if ( filter ) {
4807				return filter( elem, i, match, array );
4808			}
4809		}
4810	}
4811};
4812
4813var origPOS = Expr.match.POS,
4814	fescape = function(all, num){
4815		return "\\" + (num - 0 + 1);
4816	};
4817
4818for ( var type in Expr.match ) {
4819	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4820	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4821}
4822
4823var makeArray = function( array, results ) {
4824	array = Array.prototype.slice.call( array, 0 );
4825
4826	if ( results ) {
4827		results.push.apply( results, array );
4828		return results;
4829	}
4830
4831	return array;
4832};
4833
4834// Perform a simple check to determine if the browser is capable of
4835// converting a NodeList to an array using builtin methods.
4836// Also verifies that the returned array holds DOM nodes
4837// (which is not the case in the Blackberry browser)
4838try {
4839	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4840
4841// Provide a fallback method if it does not work
4842} catch( e ) {
4843	makeArray = function( array, results ) {
4844		var i = 0,
4845			ret = results || [];
4846
4847		if ( toString.call(array) === "[object Array]" ) {
4848			Array.prototype.push.apply( ret, array );
4849
4850		} else {
4851			if ( typeof array.length === "number" ) {
4852				for ( var l = array.length; i < l; i++ ) {
4853					ret.push( array[i] );
4854				}
4855
4856			} else {
4857				for ( ; array[i]; i++ ) {
4858					ret.push( array[i] );
4859				}
4860			}
4861		}
4862
4863		return ret;
4864	};
4865}
4866
4867var sortOrder, siblingCheck;
4868
4869if ( document.documentElement.compareDocumentPosition ) {
4870	sortOrder = function( a, b ) {
4871		if ( a === b ) {
4872			hasDuplicate = true;
4873			return 0;
4874		}
4875
4876		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4877			return a.compareDocumentPosition ? -1 : 1;
4878		}
4879
4880		return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4881	};
4882
4883} else {
4884	sortOrder = function( a, b ) {
4885		// The nodes are identical, we can exit early
4886		if ( a === b ) {
4887			hasDuplicate = true;
4888			return 0;
4889
4890		// Fallback to using sourceIndex (in IE) if it's available on both nodes
4891		} else if ( a.sourceIndex && b.sourceIndex ) {
4892			return a.sourceIndex - b.sourceIndex;
4893		}
4894
4895		var al, bl,
4896			ap = [],
4897			bp = [],
4898			aup = a.parentNode,
4899			bup = b.parentNode,
4900			cur = aup;
4901
4902		// If the nodes are siblings (or identical) we can do a quick check
4903		if ( aup === bup ) {
4904			return siblingCheck( a, b );
4905
4906		// If no parents were found then the nodes are disconnected
4907		} else if ( !aup ) {
4908			return -1;
4909
4910		} else if ( !bup ) {
4911			return 1;
4912		}
4913
4914		// Otherwise they're somewhere else in the tree so we need
4915		// to build up a full list of the parentNodes for comparison
4916		while ( cur ) {
4917			ap.unshift( cur );
4918			cur = cur.parentNode;
4919		}
4920
4921		cur = bup;
4922
4923		while ( cur ) {
4924			bp.unshift( cur );
4925			cur = cur.parentNode;
4926		}
4927
4928		al = ap.length;
4929		bl = bp.length;
4930
4931		// Start walking down the tree looking for a discrepancy
4932		for ( var i = 0; i < al && i < bl; i++ ) {
4933			if ( ap[i] !== bp[i] ) {
4934				return siblingCheck( ap[i], bp[i] );
4935			}
4936		}
4937
4938		// We ended someplace up the tree so do a sibling check
4939		return i === al ?
4940			siblingCheck( a, bp[i], -1 ) :
4941			siblingCheck( ap[i], b, 1 );
4942	};
4943
4944	siblingCheck = function( a, b, ret ) {
4945		if ( a === b ) {
4946			return ret;
4947		}
4948
4949		var cur = a.nextSibling;
4950
4951		while ( cur ) {
4952			if ( cur === b ) {
4953				return -1;
4954			}
4955
4956			cur = cur.nextSibling;
4957		}
4958
4959		return 1;
4960	};
4961}
4962
4963// Check to see if the browser returns elements by name when
4964// querying by getElementById (and provide a workaround)
4965(function(){
4966	// We're going to inject a fake input element with a specified name
4967	var form = document.createElement("div"),
4968		id = "script" + (new Date()).getTime(),
4969		root = document.documentElement;
4970
4971	form.innerHTML = "<a name='" + id + "'/>";
4972
4973	// Inject it into the root element, check its status, and remove it quickly
4974	root.insertBefore( form, root.firstChild );
4975
4976	// The workaround has to do additional checks after a getElementById
4977	// Which slows things down for other browsers (hence the branching)
4978	if ( document.getElementById( id ) ) {
4979		Expr.find.ID = function( match, context, isXML ) {
4980			if ( typeof context.getElementById !== "undefined" && !isXML ) {
4981				var m = context.getElementById(match[1]);
4982
4983				return m ?
4984					m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4985						[m] :
4986						undefined :
4987					[];
4988			}
4989		};
4990
4991		Expr.filter.ID = function( elem, match ) {
4992			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4993
4994			return elem.nodeType === 1 && node && node.nodeValue === match;
4995		};
4996	}
4997
4998	root.removeChild( form );
4999
5000	// release memory in IE
5001	root = form = null;
5002})();
5003
5004(function(){
5005	// Check to see if the browser returns only elements
5006	// when doing getElementsByTagName("*")
5007
5008	// Create a fake element
5009	var div = document.createElement("div");
5010	div.appendChild( document.createComment("") );
5011
5012	// Make sure no comments are found
5013	if ( div.getElementsByTagName("*").length > 0 ) {
5014		Expr.find.TAG = function( match, context ) {
5015			var results = context.getElementsByTagName( match[1] );
5016
5017			// Filter out possible comments
5018			if ( match[1] === "*" ) {
5019				var tmp = [];
5020
5021				for ( var i = 0; results[i]; i++ ) {
5022					if ( results[i].nodeType === 1 ) {
5023						tmp.push( results[i] );
5024					}
5025				}
5026
5027				results = tmp;
5028			}
5029
5030			return results;
5031		};
5032	}
5033
5034	// Check to see if an attribute returns normalized href attributes
5035	div.innerHTML = "<a href='#'></a>";
5036
5037	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
5038			div.firstChild.getAttribute("href") !== "#" ) {
5039
5040		Expr.attrHandle.href = function( elem ) {
5041			return elem.getAttribute( "href", 2 );
5042		};
5043	}
5044
5045	// release memory in IE
5046	div = null;
5047})();
5048
5049if ( document.querySelectorAll ) {
5050	(function(){
5051		var oldSizzle = Sizzle,
5052			div = document.createElement("div"),
5053			id = "__sizzle__";
5054
5055		div.innerHTML = "<p class='TEST'></p>";
5056
5057		// Safari can't handle uppercase or unicode characters when
5058		// in quirks mode.
5059		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
5060			return;
5061		}
5062
5063		Sizzle = function( query, context, extra, seed ) {
5064			context = context || document;
5065
5066			// Only use querySelectorAll on non-XML documents
5067			// (ID selectors don't work in non-HTML documents)
5068			if ( !seed && !Sizzle.isXML(context) ) {
5069				// See if we find a selector to speed up
5070				var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
5071
5072				if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
5073					// Speed-up: Sizzle("TAG")
5074					if ( match[1] ) {
5075						return makeArray( context.getElementsByTagName( query ), extra );
5076
5077					// Speed-up: Sizzle(".CLASS")
5078					} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
5079						return makeArray( context.getElementsByClassName( match[2] ), extra );
5080					}
5081				}
5082
5083				if ( context.nodeType === 9 ) {
5084					// Speed-up: Sizzle("body")
5085					// The body element only exists once, optimize finding it
5086					if ( query === "body" && context.body ) {
5087						return makeArray( [ context.body ], extra );
5088
5089					// Speed-up: Sizzle("#ID")
5090					} else if ( match && match[3] ) {
5091						var elem = context.getElementById( match[3] );
5092
5093						// Check parentNode to catch when Blackberry 4.6 returns
5094						// nodes that are no longer in the document #6963
5095						if ( elem && elem.parentNode ) {
5096							// Handle the case where IE and Opera return items
5097							// by name instead of ID
5098							if ( elem.id === match[3] ) {
5099								return makeArray( [ elem ], extra );
5100							}
5101
5102						} else {
5103							return makeArray( [], extra );
5104						}
5105					}
5106
5107					try {
5108						return makeArray( context.querySelectorAll(query), extra );
5109					} catch(qsaError) {}
5110
5111				// qSA works strangely on Element-rooted queries
5112				// We can work around this by specifying an extra ID on the root
5113				// and working up from there (Thanks to Andrew Dupont for the technique)
5114				// IE 8 doesn't work on object elements
5115				} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5116					var oldContext = context,
5117						old = context.getAttribute( "id" ),
5118						nid = old || id,
5119						hasParent = context.parentNode,
5120						relativeHierarchySelector = /^\s*[+~]/.test( query );
5121
5122					if ( !old ) {
5123						context.setAttribute( "id", nid );
5124					} else {
5125						nid = nid.replace( /'/g, "\\$&" );
5126					}
5127					if ( relativeHierarchySelector && hasParent ) {
5128						context = context.parentNode;
5129					}
5130
5131					try {
5132						if ( !relativeHierarchySelector || hasParent ) {
5133							return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
5134						}
5135
5136					} catch(pseudoError) {
5137					} finally {
5138						if ( !old ) {
5139							oldContext.removeAttribute( "id" );
5140						}
5141					}
5142				}
5143			}
5144
5145			return oldSizzle(query, context, extra, seed);
5146		};
5147
5148		for ( var prop in oldSizzle ) {
5149			Sizzle[ prop ] = oldSizzle[ prop ];
5150		}
5151
5152		// release memory in IE
5153		div = null;
5154	})();
5155}
5156
5157(function(){
5158	var html = document.documentElement,
5159		matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
5160
5161	if ( matches ) {
5162		// Check to see if it's possible to do matchesSelector
5163		// on a disconnected node (IE 9 fails this)
5164		var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
5165			pseudoWorks = false;
5166
5167		try {
5168			// This should fail with an exception
5169			// Gecko does not error, returns false instead
5170			matches.call( document.documentElement, "[test!='']:sizzle" );
5171
5172		} catch( pseudoError ) {
5173			pseudoWorks = true;
5174		}
5175
5176		Sizzle.matchesSelector = function( node, expr ) {
5177			// Make sure that attribute selectors are quoted
5178			expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5179
5180			if ( !Sizzle.isXML( node ) ) {
5181				try {
5182					if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5183						var ret = matches.call( node, expr );
5184
5185						// IE 9's matchesSelector returns false on disconnected nodes
5186						if ( ret || !disconnectedMatch ||
5187								// As well, disconnected nodes are said to be in a document
5188								// fragment in IE 9, so check for that
5189								node.document && node.document.nodeType !== 11 ) {
5190							return ret;
5191						}
5192					}
5193				} catch(e) {}
5194			}
5195
5196			return Sizzle(expr, null, null, [node]).length > 0;
5197		};
5198	}
5199})();
5200
5201(function(){
5202	var div = document.createElement("div");
5203
5204	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5205
5206	// Opera can't find a second classname (in 9.6)
5207	// Also, make sure that getElementsByClassName actually exists
5208	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5209		return;
5210	}
5211
5212	// Safari caches class attributes, doesn't catch changes (in 3.2)
5213	div.lastChild.className = "e";
5214
5215	if ( div.getElementsByClassName("e").length === 1 ) {
5216		return;
5217	}
5218
5219	Expr.order.splice(1, 0, "CLASS");
5220	Expr.find.CLASS = function( match, context, isXML ) {
5221		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5222			return context.getElementsByClassName(match[1]);
5223		}
5224	};
5225
5226	// release memory in IE
5227	div = null;
5228})();
5229
5230function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5231	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5232		var elem = checkSet[i];
5233
5234		if ( elem ) {
5235			var match = false;
5236
5237			elem = elem[dir];
5238
5239			while ( elem ) {
5240				if ( elem[ expando ] === doneName ) {
5241					match = checkSet[elem.sizset];
5242					break;
5243				}
5244
5245				if ( elem.nodeType === 1 && !isXML ){
5246					elem[ expando ] = doneName;
5247					elem.sizset = i;
5248				}
5249
5250				if ( elem.nodeName.toLowerCase() === cur ) {
5251					match = elem;
5252					break;
5253				}
5254
5255				elem = elem[dir];
5256			}
5257
5258			checkSet[i] = match;
5259		}
5260	}
5261}
5262
5263function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5264	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5265		var elem = checkSet[i];
5266
5267		if ( elem ) {
5268			var match = false;
5269
5270			elem = elem[dir];
5271
5272			while ( elem ) {
5273				if ( elem[ expando ] === doneName ) {
5274					match = checkSet[elem.sizset];
5275					break;
5276				}
5277
5278				if ( elem.nodeType === 1 ) {
5279					if ( !isXML ) {
5280						elem[ expando ] = doneName;
5281						elem.sizset = i;
5282					}
5283
5284					if ( typeof cur !== "string" ) {
5285						if ( elem === cur ) {
5286							match = true;
5287							break;
5288						}
5289
5290					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5291						match = elem;
5292						break;
5293					}
5294				}
5295
5296				elem = elem[dir];
5297			}
5298
5299			checkSet[i] = match;
5300		}
5301	}
5302}
5303
5304if ( document.documentElement.contains ) {
5305	Sizzle.contains = function( a, b ) {
5306		return a !== b && (a.contains ? a.contains(b) : true);
5307	};
5308
5309} else if ( document.documentElement.compareDocumentPosition ) {
5310	Sizzle.contains = function( a, b ) {
5311		return !!(a.compareDocumentPosition(b) & 16);
5312	};
5313
5314} else {
5315	Sizzle.contains = function() {
5316		return false;
5317	};
5318}
5319
5320Sizzle.isXML = function( elem ) {
5321	// documentElement is verified for cases where it doesn't yet exist
5322	// (such as loading iframes in IE - #4833)
5323	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5324
5325	return documentElement ? documentElement.nodeName !== "HTML" : false;
5326};
5327
5328var posProcess = function( selector, context, seed ) {
5329	var match,
5330		tmpSet = [],
5331		later = "",
5332		root = context.nodeType ? [context] : context;
5333
5334	// Position selectors must be done after the filter
5335	// And so must :not(positional) so we move all PSEUDOs to the end
5336	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5337		later += match[0];
5338		selector = selector.replace( Expr.match.PSEUDO, "" );
5339	}
5340
5341	selector = Expr.relative[selector] ? selector + "*" : selector;
5342
5343	for ( var i = 0, l = root.length; i < l; i++ ) {
5344		Sizzle( selector, root[i], tmpSet, seed );
5345	}
5346
5347	return Sizzle.filter( later, tmpSet );
5348};
5349
5350// EXPOSE
5351// Override sizzle attribute retrieval
5352Sizzle.attr = jQuery.attr;
5353Sizzle.selectors.attrMap = {};
5354jQuery.find = Sizzle;
5355jQuery.expr = Sizzle.selectors;
5356jQuery.expr[":"] = jQuery.expr.filters;
5357jQuery.unique = Sizzle.uniqueSort;
5358jQuery.text = Sizzle.getText;
5359jQuery.isXMLDoc = Sizzle.isXML;
5360jQuery.contains = Sizzle.contains;
5361
5362
5363})();
5364
5365
5366var runtil = /Until$/,
5367	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5368	// Note: This RegExp should be improved, or likely pulled from Sizzle
5369	rmultiselector = /,/,
5370	isSimple = /^.[^:#\[\.,]*$/,
5371	slice = Array.prototype.slice,
5372	POS = jQuery.expr.match.POS,
5373	// methods guaranteed to produce a unique set when starting from a unique set
5374	guaranteedUnique = {
5375		children: true,
5376		contents: true,
5377		next: true,
5378		prev: true
5379	};
5380
5381jQuery.fn.extend({
5382	find: function( selector ) {
5383		var self = this,
5384			i, l;
5385
5386		if ( typeof selector !== "string" ) {
5387			return jQuery( selector ).filter(function() {
5388				for ( i = 0, l = self.length; i < l; i++ ) {
5389					if ( jQuery.contains( self[ i ], this ) ) {
5390						return true;
5391					}
5392				}
5393			});
5394		}
5395
5396		var ret = this.pushStack( "", "find", selector ),
5397			length, n, r;
5398
5399		for ( i = 0, l = this.length; i < l; i++ ) {
5400			length = ret.length;
5401			jQuery.find( selector, this[i], ret );
5402
5403			if ( i > 0 ) {
5404				// Make sure that the results are unique
5405				for ( n = length; n < ret.length; n++ ) {
5406					for ( r = 0; r < length; r++ ) {
5407						if ( ret[r] === ret[n] ) {
5408							ret.splice(n--, 1);
5409							break;
5410						}
5411					}
5412				}
5413			}
5414		}
5415
5416		return ret;
5417	},
5418
5419	has: function( target ) {
5420		var targets = jQuery( target );
5421		return this.filter(function() {
5422			for ( var i = 0, l = targets.length; i < l; i++ ) {
5423				if ( jQuery.contains( this, targets[i] ) ) {
5424					return true;
5425				}
5426			}
5427		});
5428	},
5429
5430	not: function( selector ) {
5431		return this.pushStack( winnow(this, selector, false), "not", selector);
5432	},
5433
5434	filter: function( selector ) {
5435		return this.pushStack( winnow(this, selector, true), "filter", selector );
5436	},
5437
5438	is: function( selector ) {
5439		return !!selector && (
5440			typeof selector === "string" ?
5441				// If this is a positional selector, check membership in the returned set
5442				// so $("p:first").is("p:last") won't return true for a doc with two "p".
5443				POS.test( selector ) ?
5444					jQuery( selector, this.context ).index( this[0] ) >= 0 :
5445					jQuery.filter( selector, this ).length > 0 :
5446				this.filter( selector ).length > 0 );
5447	},
5448
5449	closest: function( selectors, context ) {
5450		var ret = [], i, l, cur = this[0];
5451
5452		// Array (deprecated as of jQuery 1.7)
5453		if ( jQuery.isArray( selectors ) ) {
5454			var level = 1;
5455
5456			while ( cur && cur.ownerDocument && cur !== context ) {
5457				for ( i = 0; i < selectors.length; i++ ) {
5458
5459					if ( jQuery( cur ).is( selectors[ i ] ) ) {
5460						ret.push({ selector: selectors[ i ], elem: cur, level: level });
5461					}
5462				}
5463
5464				cur = cur.parentNode;
5465				level++;
5466			}
5467
5468			return ret;
5469		}
5470
5471		// String
5472		var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5473				jQuery( selectors, context || this.context ) :
5474				0;
5475
5476		for ( i = 0, l = this.length; i < l; i++ ) {
5477			cur = this[i];
5478
5479			while ( cur ) {
5480				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5481					ret.push( cur );
5482					break;
5483
5484				} else {
5485					cur = cur.parentNode;
5486					if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5487						break;
5488					}
5489				}
5490			}
5491		}
5492
5493		ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5494
5495		return this.pushStack( ret, "closest", selectors );
5496	},
5497
5498	// Determine the position of an element within
5499	// the matched set of elements
5500	index: function( elem ) {
5501
5502		// No argument, return index in parent
5503		if ( !elem ) {
5504			return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5505		}
5506
5507		// index in selector
5508		if ( typeof elem === "string" ) {
5509			return jQuery.inArray( this[0], jQuery( elem ) );
5510		}
5511
5512		// Locate the position of the desired element
5513		return jQuery.inArray(
5514			// If it receives a jQuery object, the first element is used
5515			elem.jquery ? elem[0] : elem, this );
5516	},
5517
5518	add: function( selector, context ) {
5519		var set = typeof selector === "string" ?
5520				jQuery( selector, context ) :
5521				jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5522			all = jQuery.merge( this.get(), set );
5523
5524		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5525			all :
5526			jQuery.unique( all ) );
5527	},
5528
5529	andSelf: function() {
5530		return this.add( this.prevObject );
5531	}
5532});
5533
5534// A painfully simple check to see if an element is disconnected
5535// from a document (should be improved, where feasible).
5536function isDisconnected( node ) {
5537	return !node || !node.parentNode || node.parentNode.nodeType === 11;
5538}
5539
5540jQuery.each({
5541	parent: function( elem ) {
5542		var parent = elem.parentNode;
5543		return parent && parent.nodeType !== 11 ? parent : null;
5544	},
5545	parents: function( elem ) {
5546		return jQuery.dir( elem, "parentNode" );
5547	},
5548	parentsUntil: function( elem, i, until ) {
5549		return jQuery.dir( elem, "parentNode", until );
5550	},
5551	next: function( elem ) {
5552		return jQuery.nth( elem, 2, "nextSibling" );
5553	},
5554	prev: function( elem ) {
5555		return jQuery.nth( elem, 2, "previousSibling" );
5556	},
5557	nextAll: function( elem ) {
5558		return jQuery.dir( elem, "nextSibling" );
5559	},
5560	prevAll: function( elem ) {
5561		return jQuery.dir( elem, "previousSibling" );
5562	},
5563	nextUntil: function( elem, i, until ) {
5564		return jQuery.dir( elem, "nextSibling", until );
5565	},
5566	prevUntil: function( elem, i, until ) {
5567		return jQuery.dir( elem, "previousSibling", until );
5568	},
5569	siblings: function( elem ) {
5570		return jQuery.sibling( elem.parentNode.firstChild, elem );
5571	},
5572	children: function( elem ) {
5573		return jQuery.sibling( elem.firstChild );
5574	},
5575	contents: function( elem ) {
5576		return jQuery.nodeName( elem, "iframe" ) ?
5577			elem.contentDocument || elem.contentWindow.document :
5578			jQuery.makeArray( elem.childNodes );
5579	}
5580}, function( name, fn ) {
5581	jQuery.fn[ name ] = function( until, selector ) {
5582		var ret = jQuery.map( this, fn, until ),
5583			// The variable 'args' was introduced in
5584			// https://github.com/jquery/jquery/commit/52a0238
5585			// to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5586			// http://code.google.com/p/v8/issues/detail?id=1050
5587			args = slice.call(arguments);
5588
5589		if ( !runtil.test( name ) ) {
5590			selector = until;
5591		}
5592
5593		if ( selector && typeof selector === "string" ) {
5594			ret = jQuery.filter( selector, ret );
5595		}
5596
5597		ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5598
5599		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5600			ret = ret.reverse();
5601		}
5602
5603		return this.pushStack( ret, name, args.join(",") );
5604	};
5605});
5606
5607jQuery.extend({
5608	filter: function( expr, elems, not ) {
5609		if ( not ) {
5610			expr = ":not(" + expr + ")";
5611		}
5612
5613		return elems.length === 1 ?
5614			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5615			jQuery.find.matches(expr, elems);
5616	},
5617
5618	dir: function( elem, dir, until ) {
5619		var matched = [],
5620			cur = elem[ dir ];
5621
5622		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5623			if ( cur.nodeType === 1 ) {
5624				matched.push( cur );
5625			}
5626			cur = cur[dir];
5627		}
5628		return matched;
5629	},
5630
5631	nth: function( cur, result, dir, elem ) {
5632		result = result || 1;
5633		var num = 0;
5634
5635		for ( ; cur; cur = cur[dir] ) {
5636			if ( cur.nodeType === 1 && ++num === result ) {
5637				break;
5638			}
5639		}
5640
5641		return cur;
5642	},
5643
5644	sibling: function( n, elem ) {
5645		var r = [];
5646
5647		for ( ; n; n = n.nextSibling ) {
5648			if ( n.nodeType === 1 && n !== elem ) {
5649				r.push( n );
5650			}
5651		}
5652
5653		return r;
5654	}
5655});
5656
5657// Implement the identical functionality for filter and not
5658function winnow( elements, qualifier, keep ) {
5659
5660	// Can't pass null or undefined to indexOf in Firefox 4
5661	// Set to 0 to skip string check
5662	qualifier = qualifier || 0;
5663
5664	if ( jQuery.isFunction( qualifier ) ) {
5665		return jQuery.grep(elements, function( elem, i ) {
5666			var retVal = !!qualifier.call( elem, i, elem );
5667			return retVal === keep;
5668		});
5669
5670	} else if ( qualifier.nodeType ) {
5671		return jQuery.grep(elements, function( elem, i ) {
5672			return ( elem === qualifier ) === keep;
5673		});
5674
5675	} else if ( typeof qualifier === "string" ) {
5676		var filtered = jQuery.grep(elements, function( elem ) {
5677			return elem.nodeType === 1;
5678		});
5679
5680		if ( isSimple.test( qualifier ) ) {
5681			return jQuery.filter(qualifier, filtered, !keep);
5682		} else {
5683			qualifier = jQuery.filter( qualifier, filtered );
5684		}
5685	}
5686
5687	return jQuery.grep(elements, function( elem, i ) {
5688		return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
5689	});
5690}
5691
5692
5693
5694
5695function createSafeFragment( document ) {
5696	var list = nodeNames.split( " " ),
5697	safeFrag = document.createDocumentFragment();
5698
5699	if ( safeFrag.createElement ) {
5700		while ( list.length ) {
5701			safeFrag.createElement(
5702				list.pop()
5703			);
5704		}
5705	}
5706	return safeFrag;
5707}
5708
5709var nodeNames = "abbr article aside audio canvas datalist details figcaption figure footer " +
5710		"header hgroup mark meter nav output progress section summary time video",
5711	rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5712	rleadingWhitespace = /^\s+/,
5713	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5714	rtagName = /<([\w:]+)/,
5715	rtbody = /<tbody/i,
5716	rhtml = /<|&#?\w+;/,
5717	rnoInnerhtml = /<(?:script|style)/i,
5718	rnocache = /<(?:script|object|embed|option|style)/i,
5719	rnoshimcache = new RegExp("<(?:" + nodeNames.replace(" ", "|") + ")", "i"),
5720	// checked="checked" or checked
5721	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5722	rscriptType = /\/(java|ecma)script/i,
5723	rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5724	wrapMap = {
5725		option: [ 1, "<select multiple='multiple'>", "</select>" ],
5726		legend: [ 1, "<fieldset>", "</fieldset>" ],
5727		thead: [ 1, "<table>", "</table>" ],
5728		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5729		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5730		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5731		area: [ 1, "<map>", "</map>" ],
5732		_default: [ 0, "", "" ]
5733	},
5734	safeFragment = createSafeFragment( document );
5735
5736wrapMap.optgroup = wrapMap.option;
5737wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5738wrapMap.th = wrapMap.td;
5739
5740// IE can't serialize <link> and <script> tags normally
5741if ( !jQuery.support.htmlSerialize ) {
5742	wrapMap._default = [ 1, "div<div>", "</div>" ];
5743}
5744
5745jQuery.fn.extend({
5746	text: function( text ) {
5747		if ( jQuery.isFunction(text) ) {
5748			return this.each(function(i) {
5749				var self = jQuery( this );
5750
5751				self.text( text.call(this, i, self.text()) );
5752			});
5753		}
5754
5755		if ( typeof text !== "object" && text !== undefined ) {
5756			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5757		}
5758
5759		return jQuery.text( this );
5760	},
5761
5762	wrapAll: function( html ) {
5763		if ( jQuery.isFunction( html ) ) {
5764			return this.each(function(i) {
5765				jQuery(this).wrapAll( html.call(this, i) );
5766			});
5767		}
5768
5769		if ( this[0] ) {
5770			// The elements to wrap the target around
5771			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5772
5773			if ( this[0].parentNode ) {
5774				wrap.insertBefore( this[0] );
5775			}
5776
5777			wrap.map(function() {
5778				var elem = this;
5779
5780				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5781					elem = elem.firstChild;
5782				}
5783
5784				return elem;
5785			}).append( this );
5786		}
5787
5788		return this;
5789	},
5790
5791	wrapInner: function( html ) {
5792		if ( jQuery.isFunction( html ) ) {
5793			return this.each(function(i) {
5794				jQuery(this).wrapInner( html.call(this, i) );
5795			});
5796		}
5797
5798		return this.each(function() {
5799			var self = jQuery( this ),
5800				contents = self.contents();
5801
5802			if ( contents.length ) {
5803				contents.wrapAll( html );
5804
5805			} else {
5806				self.append( html );
5807			}
5808		});
5809	},
5810
5811	wrap: function( html ) {
5812		return this.each(function() {
5813			jQuery( this ).wrapAll( html );
5814		});
5815	},
5816
5817	unwrap: function() {
5818		return this.parent().each(function() {
5819			if ( !jQuery.nodeName( this, "body" ) ) {
5820				jQuery( this ).replaceWith( this.childNodes );
5821			}
5822		}).end();
5823	},
5824
5825	append: function() {
5826		return this.domManip(arguments, true, function( elem ) {
5827			if ( this.nodeType === 1 ) {
5828				this.appendChild( elem );
5829			}
5830		});
5831	},
5832
5833	prepend: function() {
5834		return this.domManip(arguments, true, function( elem ) {
5835			if ( this.nodeType === 1 ) {
5836				this.insertBefore( elem, this.firstChild );
5837			}
5838		});
5839	},
5840
5841	before: function() {
5842		if ( this[0] && this[0].parentNode ) {
5843			return this.domManip(arguments, false, function( elem ) {
5844				this.parentNode.insertBefore( elem, this );
5845			});
5846		} else if ( arguments.length ) {
5847			var set = jQuery(arguments[0]);
5848			set.push.apply( set, this.toArray() );
5849			return this.pushStack( set, "before", arguments );
5850		}
5851	},
5852
5853	after: function() {
5854		if ( this[0] && this[0].parentNode ) {
5855			return this.domManip(arguments, false, function( elem ) {
5856				this.parentNode.insertBefore( elem, this.nextSibling );
5857			});
5858		} else if ( arguments.length ) {
5859			var set = this.pushStack( this, "after", arguments );
5860			set.push.apply( set, jQuery(arguments[0]).toArray() );
5861			return set;
5862		}
5863	},
5864
5865	// keepData is for internal use only--do not document
5866	remove: function( selector, keepData ) {
5867		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5868			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5869				if ( !keepData && elem.nodeType === 1 ) {
5870					jQuery.cleanData( elem.getElementsByTagName("*") );
5871					jQuery.cleanData( [ elem ] );
5872				}
5873
5874				if ( elem.parentNode ) {
5875					elem.parentNode.removeChild( elem );
5876				}
5877			}
5878		}
5879
5880		return this;
5881	},
5882
5883	empty: function() {
5884		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5885			// Remove element nodes and prevent memory leaks
5886			if ( elem.nodeType === 1 ) {
5887				jQuery.cleanData( elem.getElementsByTagName("*") );
5888			}
5889
5890			// Remove any remaining nodes
5891			while ( elem.firstChild ) {
5892				elem.removeChild( elem.firstChild );
5893			}
5894		}
5895
5896		return this;
5897	},
5898
5899	clone: function( dataAndEvents, deepDataAndEvents ) {
5900		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5901		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5902
5903		return this.map( function () {
5904			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5905		});
5906	},
5907
5908	html: function( value ) {
5909		if ( value === undefined ) {
5910			return this[0] && this[0].nodeType === 1 ?
5911				this[0].innerHTML.replace(rinlinejQuery, "") :
5912				null;
5913
5914		// See if we can take a shortcut and just use innerHTML
5915		} else if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5916			(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5917			!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5918
5919			value = value.replace(rxhtmlTag, "<$1></$2>");
5920
5921			try {
5922				for ( var i = 0, l = this.length; i < l; i++ ) {
5923					// Remove element nodes and prevent memory leaks
5924					if ( this[i].nodeType === 1 ) {
5925						jQuery.cleanData( this[i].getElementsByTagName("*") );
5926						this[i].innerHTML = value;
5927					}
5928				}
5929
5930			// If using innerHTML throws an exception, use the fallback method
5931			} catch(e) {
5932				this.empty().append( value );
5933			}
5934
5935		} else if ( jQuery.isFunction( value ) ) {
5936			this.each(function(i){
5937				var self = jQuery( this );
5938
5939				self.html( value.call(this, i, self.html()) );
5940			});
5941
5942		} else {
5943			this.empty().append( value );
5944		}
5945
5946		return this;
5947	},
5948
5949	replaceWith: function( value ) {
5950		if ( this[0] && this[0].parentNode ) {
5951			// Make sure that the elements are removed from the DOM before they are inserted
5952			// this can help fix replacing a parent with child elements
5953			if ( jQuery.isFunction( value ) ) {
5954				return this.each(function(i) {
5955					var self = jQuery(this), old = self.html();
5956					self.replaceWith( value.call( this, i, old ) );
5957				});
5958			}
5959
5960			if ( typeof value !== "string" ) {
5961				value = jQuery( value ).detach();
5962			}
5963
5964			return this.each(function() {
5965				var next = this.nextSibling,
5966					parent = this.parentNode;
5967
5968				jQuery( this ).remove();
5969
5970				if ( next ) {
5971					jQuery(next).before( value );
5972				} else {
5973					jQuery(parent).append( value );
5974				}
5975			});
5976		} else {
5977			return this.length ?
5978				this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5979				this;
5980		}
5981	},
5982
5983	detach: function( selector ) {
5984		return this.remove( selector, true );
5985	},
5986
5987	domManip: function( args, table, callback ) {
5988		var results, first, fragment, parent,
5989			value = args[0],
5990			scripts = [];
5991
5992		// We can't cloneNode fragments that contain checked, in WebKit
5993		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5994			return this.each(function() {
5995				jQuery(this).domManip( args, table, callback, true );
5996			});
5997		}
5998
5999		if ( jQuery.isFunction(value) ) {
6000			return this.each(function(i) {
6001				var self = jQuery(this);
6002				args[0] = value.call(this, i, table ? self.html() : undefined);
6003				self.domManip( args, table, callback );
6004			});
6005		}
6006
6007		if ( this[0] ) {
6008			parent = value && value.parentNode;
6009
6010			// If we're in a fragment, just use that instead of building a new one
6011			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
6012				results = { fragment: parent };
6013
6014			} else {
6015				results = jQuery.buildFragment( args, this, scripts );
6016			}
6017
6018			fragment = results.fragment;
6019
6020			if ( fragment.childNodes.length === 1 ) {
6021				first = fragment = fragment.firstChild;
6022			} else {
6023				first = fragment.firstChild;
6024			}
6025
6026			if ( first ) {
6027				table = table && jQuery.nodeName( first, "tr" );
6028
6029				for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
6030					callback.call(
6031						table ?
6032							root(this[i], first) :
6033							this[i],
6034						// Make sure that we do not leak memory by inadvertently discarding
6035						// the original fragment (which might have attached data) instead of
6036						// using it; in addition, use the original fragment object for the last
6037						// item instead of first because it can end up being emptied incorrectly
6038						// in certain situations (Bug #8070).
6039						// Fragments from the fragment cache must always be cloned and never used
6040						// in place.
6041						results.cacheable || ( l > 1 && i < lastIndex ) ?
6042							jQuery.clone( fragment, true, true ) :
6043							fragment
6044					);
6045				}
6046			}
6047
6048			if ( scripts.length ) {
6049				jQuery.each( scripts, evalScript );
6050			}
6051		}
6052
6053		return this;
6054	}
6055});
6056
6057function root( elem, cur ) {
6058	return jQuery.nodeName(elem, "table") ?
6059		(elem.getElementsByTagName("tbody")[0] ||
6060		elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
6061		elem;
6062}
6063
6064function cloneCopyEvent( src, dest ) {
6065
6066	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6067		return;
6068	}
6069
6070	var type, i, l,
6071		oldData = jQuery._data( src ),
6072		curData = jQuery._data( dest, oldData ),
6073		events = oldData.events;
6074
6075	if ( events ) {
6076		delete curData.handle;
6077		curData.events = {};
6078
6079		for ( type in events ) {
6080			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6081				jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
6082			}
6083		}
6084	}
6085
6086	// make the cloned public data object a copy from the original
6087	if ( curData.data ) {
6088		curData.data = jQuery.extend( {}, curData.data );
6089	}
6090}
6091
6092function cloneFixAttributes( src, dest ) {
6093	var nodeName;
6094
6095	// We do not need to do anything for non-Elements
6096	if ( dest.nodeType !== 1 ) {
6097		return;
6098	}
6099
6100	// clearAttributes removes the attributes, which we don't want,
6101	// but also removes the attachEvent events, which we *do* want
6102	if ( dest.clearAttributes ) {
6103		dest.clearAttributes();
6104	}
6105
6106	// mergeAttributes, in contrast, only merges back on the
6107	// original attributes, not the events
6108	if ( dest.mergeAttributes ) {
6109		dest.mergeAttributes( src );
6110	}
6111
6112	nodeName = dest.nodeName.toLowerCase();
6113
6114	// IE6-8 fail to clone children inside object elements that use
6115	// the proprietary classid attribute value (rather than the type
6116	// attribute) to identify the type of content to display
6117	if ( nodeName === "object" ) {
6118		dest.outerHTML = src.outerHTML;
6119
6120	} else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
6121		// IE6-8 fails to persist the checked state of a cloned checkbox
6122		// or radio button. Worse, IE6-7 fail to give the cloned element
6123		// a checked appearance if the defaultChecked value isn't also set
6124		if ( src.checked ) {
6125			dest.defaultChecked = dest.checked = src.checked;
6126		}
6127
6128		// IE6-7 get confused and end up setting the value of a cloned
6129		// checkbox/radio button to an empty string instead of "on"
6130		if ( dest.value !== src.value ) {
6131			dest.value = src.value;
6132		}
6133
6134	// IE6-8 fails to return the selected option to the default selected
6135	// state when cloning options
6136	} else if ( nodeName === "option" ) {
6137		dest.selected = src.defaultSelected;
6138
6139	// IE6-8 fails to set the defaultValue to the correct value when
6140	// cloning other types of input fields
6141	} else if ( nodeName === "input" || nodeName === "textarea" ) {
6142		dest.defaultValue = src.defaultValue;
6143	}
6144
6145	// Event data gets referenced instead of copied if the expando
6146	// gets copied too
6147	dest.removeAttribute( jQuery.expando );
6148}
6149
6150jQuery.buildFragment = function( args, nodes, scripts ) {
6151	var fragment, cacheable, cacheresults, doc,
6152	first = args[ 0 ];
6153
6154	// nodes may contain either an explicit document object,
6155	// a jQuery collection or context object.
6156	// If nodes[0] contains a valid object to assign to doc
6157	if ( nodes && nodes[0] ) {
6158		doc = nodes[0].ownerDocument || nodes[0];
6159	}
6160
6161  // Ensure that an attr object doesn't incorrectly stand in as a document object
6162	// Chrome and Firefox seem to allow this to occur and will throw exception
6163	// Fixes #8950
6164	if ( !doc.createDocumentFragment ) {
6165		doc = document;
6166	}
6167
6168	// Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6169	// Cloning options loses the selected state, so don't cache them
6170	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6171	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6172	// Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
6173	if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&
6174		first.charAt(0) === "<" && !rnocache.test( first ) &&
6175		(jQuery.support.checkClone || !rchecked.test( first )) &&
6176		(!jQuery.support.unknownElems && rnoshimcache.test( first )) ) {
6177
6178		cacheable = true;
6179
6180		cacheresults = jQuery.fragments[ first ];
6181		if ( cacheresults && cacheresults !== 1 ) {
6182			fragment = cacheresults;
6183		}
6184	}
6185
6186	if ( !fragment ) {
6187		fragment = doc.createDocumentFragment();
6188		jQuery.clean( args, doc, fragment, scripts );
6189	}
6190
6191	if ( cacheable ) {
6192		jQuery.fragments[ first ] = cacheresults ? fragment : 1;
6193	}
6194
6195	return { fragment: fragment, cacheable: cacheable };
6196};
6197
6198jQuery.fragments = {};
6199
6200jQuery.each({
6201	appendTo: "append",
6202	prependTo: "prepend",
6203	insertBefore: "before",
6204	insertAfter: "after",
6205	replaceAll: "replaceWith"
6206}, function( name, original ) {
6207	jQuery.fn[ name ] = function( selector ) {
6208		var ret = [],
6209			insert = jQuery( selector ),
6210			parent = this.length === 1 && this[0].parentNode;
6211
6212		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
6213			insert[ original ]( this[0] );
6214			return this;
6215
6216		} else {
6217			for ( var i = 0, l = insert.length; i < l; i++ ) {
6218				var elems = ( i > 0 ? this.clone(true) : this ).get();
6219				jQuery( insert[i] )[ original ]( elems );
6220				ret = ret.concat( elems );
6221			}
6222
6223			return this.pushStack( ret, name, insert.selector );
6224		}
6225	};
6226});
6227
6228function getAll( elem ) {
6229	if ( typeof elem.getElementsByTagName !== "undefined" ) {
6230		return elem.getElementsByTagName( "*" );
6231
6232	} else if ( typeof elem.querySelectorAll !== "undefined" ) {
6233		return elem.querySelectorAll( "*" );
6234
6235	} else {
6236		return [];
6237	}
6238}
6239
6240// Used in clean, fixes the defaultChecked property
6241function fixDefaultChecked( elem ) {
6242	if ( elem.type === "checkbox" || elem.type === "radio" ) {
6243		elem.defaultChecked = elem.checked;
6244	}
6245}
6246// Finds all inputs and passes them to fixDefaultChecked
6247function findInputs( elem ) {
6248	var nodeName = ( elem.nodeName || "" ).toLowerCase();
6249	if ( nodeName === "input" ) {
6250		fixDefaultChecked( elem );
6251	// Skip scripts, get other children
6252	} else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {
6253		jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6254	}
6255}
6256
6257jQuery.extend({
6258	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6259		var clone = elem.cloneNode(true),
6260				srcElements,
6261				destElements,
6262				i;
6263
6264		if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6265				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6266			// IE copies events bound via attachEvent when using cloneNode.
6267			// Calling detachEvent on the clone will also remove the events
6268			// from the original. In order to get around this, we use some
6269			// proprietary methods to clear the events. Thanks to MooTools
6270			// guys for this hotness.
6271
6272			cloneFixAttributes( elem, clone );
6273
6274			// Using Sizzle here is crazy slow, so we use getElementsByTagName
6275			// instead
6276			srcElements = getAll( elem );
6277			destElements = getAll( clone );
6278
6279			// Weird iteration because IE will replace the length property
6280			// with an element if you are cloning the body and one of the
6281			// elements on the page has a name or id of "length"
6282			for ( i = 0; srcElements[i]; ++i ) {
6283				// Ensure that the destination node is not null; Fixes #9587
6284				if ( destElements[i] ) {
6285					cloneFixAttributes( srcElements[i], destElements[i] );
6286				}
6287			}
6288		}
6289
6290		// Copy the events from the original to the clone
6291		if ( dataAndEvents ) {
6292			cloneCopyEvent( elem, clone );
6293
6294			if ( deepDataAndEvents ) {
6295				srcElements = getAll( elem );
6296				destElements = getAll( clone );
6297
6298				for ( i = 0; srcElements[i]; ++i ) {
6299					cloneCopyEvent( srcElements[i], destElements[i] );
6300				}
6301			}
6302		}
6303
6304		srcElements = destElements = null;
6305
6306		// Return the cloned set
6307		return clone;
6308	},
6309
6310	clean: function( elems, context, fragment, scripts ) {
6311		var checkScriptType;
6312
6313		context = context || document;
6314
6315		// !context.createElement fails in IE with an error but returns typeof 'object'
6316		if ( typeof context.createElement === "undefined" ) {
6317			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6318		}
6319
6320		var ret = [], j;
6321
6322		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6323			if ( typeof elem === "number" ) {
6324				elem += "";
6325			}
6326
6327			if ( !elem ) {
6328				continue;
6329			}
6330
6331			// Convert html string into DOM nodes
6332			if ( typeof elem === "string" ) {
6333				if ( !rhtml.test( elem ) ) {
6334					elem = context.createTextNode( elem );
6335				} else {
6336					// Fix "XHTML"-style tags in all browsers
6337					elem = elem.replace(rxhtmlTag, "<$1></$2>");
6338
6339					// Trim whitespace, otherwise indexOf won't work as expected
6340					var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(),
6341						wrap = wrapMap[ tag ] || wrapMap._default,
6342						depth = wrap[0],
6343						div = context.createElement("div");
6344
6345					// Append wrapper element to unknown element safe doc fragment
6346					if ( context === document ) {
6347						// Use the fragment we've already created for this document
6348						safeFragment.appendChild( div );
6349					} else {
6350						// Use a fragment created with the owner document
6351						createSafeFragment( context ).appendChild( div );
6352					}
6353
6354					// Go to html and back, then peel off extra wrappers
6355					div.innerHTML = wrap[1] + elem + wrap[2];
6356
6357					// Move to the right depth
6358					while ( depth-- ) {
6359						div = div.lastChild;
6360					}
6361
6362					// Remove IE's autoinserted <tbody> from table fragments
6363					if ( !jQuery.support.tbody ) {
6364
6365						// String was a <table>, *may* have spurious <tbody>
6366						var hasBody = rtbody.test(elem),
6367							tbody = tag === "table" && !hasBody ?
6368								div.firstChild && div.firstChild.childNodes :
6369
6370								// String was a bare <thead> or <tfoot>
6371								wrap[1] === "<table>" && !hasBody ?
6372									div.childNodes :
6373									[];
6374
6375						for ( j = tbody.length - 1; j >= 0 ; --j ) {
6376							if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6377								tbody[ j ].parentNode.removeChild( tbody[ j ] );
6378							}
6379						}
6380					}
6381
6382					// IE completely kills leading whitespace when innerHTML is used
6383					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6384						div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6385					}
6386
6387					elem = div.childNodes;
6388				}
6389			}
6390
6391			// Resets defaultChecked for any radios and checkboxes
6392			// about to be appended to the DOM in IE 6/7 (#8060)
6393			var len;
6394			if ( !jQuery.support.appendChecked ) {
6395				if ( elem[0] && typeof (len = elem.length) === "number" ) {
6396					for ( j = 0; j < len; j++ ) {
6397						findInputs( elem[j] );
6398					}
6399				} else {
6400					findInputs( elem );
6401				}
6402			}
6403
6404			if ( elem.nodeType ) {
6405				ret.push( elem );
6406			} else {
6407				ret = jQuery.merge( ret, elem );
6408			}
6409		}
6410
6411		if ( fragment ) {
6412			checkScriptType = function( elem ) {
6413				return !elem.type || rscriptType.test( elem.type );
6414			};
6415			for ( i = 0; ret[i]; i++ ) {
6416				if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6417					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6418
6419				} else {
6420					if ( ret[i].nodeType === 1 ) {
6421						var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6422
6423						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6424					}
6425					fragment.appendChild( ret[i] );
6426				}
6427			}
6428		}
6429
6430		return ret;
6431	},
6432
6433	cleanData: function( elems ) {
6434		var data, id,
6435			cache = jQuery.cache,
6436			special = jQuery.event.special,
6437			deleteExpando = jQuery.support.deleteExpando;
6438
6439		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6440			if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6441				continue;
6442			}
6443
6444			id = elem[ jQuery.expando ];
6445
6446			if ( id ) {
6447				data = cache[ id ];
6448
6449				if ( data && data.events ) {
6450					for ( var type in data.events ) {
6451						if ( special[ type ] ) {
6452							jQuery.event.remove( elem, type );
6453
6454						// This is a shortcut to avoid jQuery.event.remove's overhead
6455						} else {
6456							jQuery.removeEvent( elem, type, data.handle );
6457						}
6458					}
6459
6460					// Null the DOM reference to avoid IE6/7/8 leak (#7054)
6461					if ( data.handle ) {
6462						data.handle.elem = null;
6463					}
6464				}
6465
6466				if ( deleteExpando ) {
6467					delete elem[ jQuery.expando ];
6468
6469				} else if ( elem.removeAttribute ) {
6470					elem.removeAttribute( jQuery.expando );
6471				}
6472
6473				delete cache[ id ];
6474			}
6475		}
6476	}
6477});
6478
6479function evalScript( i, elem ) {
6480	if ( elem.src ) {
6481		jQuery.ajax({
6482			url: elem.src,
6483			async: false,
6484			dataType: "script"
6485		});
6486	} else {
6487		jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6488	}
6489
6490	if ( elem.parentNode ) {
6491		elem.parentNode.removeChild( elem );
6492	}
6493}
6494
6495
6496
6497
6498var ralpha = /alpha\([^)]*\)/i,
6499	ropacity = /opacity=([^)]*)/,
6500	// fixed for IE9, see #8346
6501	rupper = /([A-Z]|^ms)/g,
6502	rnumpx = /^-?\d+(?:px)?$/i,
6503	rnum = /^-?\d/,
6504	rrelNum = /^([\-+])=([\-+.\de]+)/,
6505
6506	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6507	cssWidth = [ "Left", "Right" ],
6508	cssHeight = [ "Top", "Bottom" ],
6509	curCSS,
6510
6511	getComputedStyle,
6512	currentStyle;
6513
6514jQuery.fn.css = function( name, value ) {
6515	// Setting 'undefined' is a no-op
6516	if ( arguments.length === 2 && value === undefined ) {
6517		return this;
6518	}
6519
6520	return jQuery.access( this, name, value, true, function( elem, name, value ) {
6521		return value !== undefined ?
6522			jQuery.style( elem, name, value ) :
6523			jQuery.css( elem, name );
6524	});
6525};
6526
6527jQuery.extend({
6528	// Add in style property hooks for overriding the default
6529	// behavior of getting and setting a style property
6530	cssHooks: {
6531		opacity: {
6532			get: function( elem, computed ) {
6533				if ( computed ) {
6534					// We should always get a number back from opacity
6535					var ret = curCSS( elem, "opacity", "opacity" );
6536					return ret === "" ? "1" : ret;
6537
6538				} else {
6539					return elem.style.opacity;
6540				}
6541			}
6542		}
6543	},
6544
6545	// Exclude the following css properties to add px
6546	cssNumber: {
6547		"fillOpacity": true,
6548		"fontWeight": true,
6549		"lineHeight": true,
6550		"opacity": true,
6551		"orphans": true,
6552		"widows": true,
6553		"zIndex": true,
6554		"zoom": true
6555	},
6556
6557	// Add in properties whose names you wish to fix before
6558	// setting or getting the value
6559	cssProps: {
6560		// normalize float css property
6561		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6562	},
6563
6564	// Get and set the style property on a DOM Node
6565	style: function( elem, name, value, extra ) {
6566		// Don't set styles on text and comment nodes
6567		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6568			return;
6569		}
6570
6571		// Make sure that we're working with the right name
6572		var ret, type, origName = jQuery.camelCase( name ),
6573			style = elem.style, hooks = jQuery.cssHooks[ origName ];
6574
6575		name = jQuery.cssProps[ origName ] || origName;
6576
6577		// Check if we're setting a value
6578		if ( value !== undefined ) {
6579			type = typeof value;
6580
6581			// convert relative number strings (+= or -=) to relative numbers. #7345
6582			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6583				value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
6584				// Fixes bug #9237
6585				type = "number";
6586			}
6587
6588			// Make sure that NaN and null values aren't set. See: #7116
6589			if ( value == null || type === "number" && isNaN( value ) ) {
6590				return;
6591			}
6592
6593			// If a number was passed in, add 'px' to the (except for certain CSS properties)
6594			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6595				value += "px";
6596			}
6597
6598			// If a hook was provided, use that value, otherwise just set the specified value
6599			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6600				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6601				// Fixes bug #5509
6602				try {
6603					style[ name ] = value;
6604				} catch(e) {}
6605			}
6606
6607		} else {
6608			// If a hook was provided get the non-computed value from there
6609			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6610				return ret;
6611			}
6612
6613			// Otherwise just get the value from the style object
6614			return style[ name ];
6615		}
6616	},
6617
6618	css: function( elem, name, extra ) {
6619		var ret, hooks;
6620
6621		// Make sure that we're working with the right name
6622		name = jQuery.camelCase( name );
6623		hooks = jQuery.cssHooks[ name ];
6624		name = jQuery.cssProps[ name ] || name;
6625
6626		// cssFloat needs a special treatment
6627		if ( name === "cssFloat" ) {
6628			name = "float";
6629		}
6630
6631		// If a hook was provided get the computed value from there
6632		if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6633			return ret;
6634
6635		// Otherwise, if a way to get the computed value exists, use that
6636		} else if ( curCSS ) {
6637			return curCSS( elem, name );
6638		}
6639	},
6640
6641	// A method for quickly swapping in/out CSS properties to get correct calculations
6642	swap: function( elem, options, callback ) {
6643		var old = {};
6644
6645		// Remember the old values, and insert the new ones
6646		for ( var name in options ) {
6647			old[ name ] = elem.style[ name ];
6648			elem.style[ name ] = options[ name ];
6649		}
6650
6651		callback.call( elem );
6652
6653		// Revert the old values
6654		for ( name in options ) {
6655			elem.style[ name ] = old[ name ];
6656		}
6657	}
6658});
6659
6660// DEPRECATED, Use jQuery.css() instead
6661jQuery.curCSS = jQuery.css;
6662
6663jQuery.each(["height", "width"], function( i, name ) {
6664	jQuery.cssHooks[ name ] = {
6665		get: function( elem, computed, extra ) {
6666			var val;
6667
6668			if ( computed ) {
6669				if ( elem.offsetWidth !== 0 ) {
6670					return getWH( elem, name, extra );
6671				} else {
6672					jQuery.swap( elem, cssShow, function() {
6673						val = getWH( elem, name, extra );
6674					});
6675				}
6676
6677				return val;
6678			}
6679		},
6680
6681		set: function( elem, value ) {
6682			if ( rnumpx.test( value ) ) {
6683				// ignore negative width and height values #1599
6684				value = parseFloat( value );
6685
6686				if ( value >= 0 ) {
6687					return value + "px";
6688				}
6689
6690			} else {
6691				return value;
6692			}
6693		}
6694	};
6695});
6696
6697if ( !jQuery.support.opacity ) {
6698	jQuery.cssHooks.opacity = {
6699		get: function( elem, computed ) {
6700			// IE uses filters for opacity
6701			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6702				( parseFloat( RegExp.$1 ) / 100 ) + "" :
6703				computed ? "1" : "";
6704		},
6705
6706		set: function( elem, value ) {
6707			var style = elem.style,
6708				currentStyle = elem.currentStyle,
6709				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
6710				filter = currentStyle && currentStyle.filter || style.filter || "";
6711
6712			// IE has trouble with opacity if it does not have layout
6713			// Force it by setting the zoom level
6714			style.zoom = 1;
6715
6716			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6717			if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
6718
6719				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6720				// if "filter:" is present at all, clearType is disabled, we want to avoid this
6721				// style.removeAttribute is IE Only, but so apparently is this code path...
6722				style.removeAttribute( "filter" );
6723
6724				// if there there is no filter style applied in a css rule, we are done
6725				if ( currentStyle && !currentStyle.filter ) {
6726					return;
6727				}
6728			}
6729
6730			// otherwise, set new filter values
6731			style.filter = ralpha.test( filter ) ?
6732				filter.replace( ralpha, opacity ) :
6733				filter + " " + opacity;
6734		}
6735	};
6736}
6737
6738jQuery(function() {
6739	// This hook cannot be added until DOM ready because the support test
6740	// for it is not run until after DOM ready
6741	if ( !jQuery.support.reliableMarginRight ) {
6742		jQuery.cssHooks.marginRight = {
6743			get: function( elem, computed ) {
6744				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6745				// Work around by temporarily setting element display to inline-block
6746				var ret;
6747				jQuery.swap( elem, { "display": "inline-block" }, function() {
6748					if ( computed ) {
6749						ret = curCSS( elem, "margin-right", "marginRight" );
6750					} else {
6751						ret = elem.style.marginRight;
6752					}
6753				});
6754				return ret;
6755			}
6756		};
6757	}
6758});
6759
6760if ( document.defaultView && document.defaultView.getComputedStyle ) {
6761	getComputedStyle = function( elem, name ) {
6762		var ret, defaultView, computedStyle;
6763
6764		name = name.replace( rupper, "-$1" ).toLowerCase();
6765
6766		if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6767			return undefined;
6768		}
6769
6770		if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6771			ret = computedStyle.getPropertyValue( name );
6772			if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6773				ret = jQuery.style( elem, name );
6774			}
6775		}
6776
6777		return ret;
6778	};
6779}
6780
6781if ( document.documentElement.currentStyle ) {
6782	currentStyle = function( elem, name ) {
6783		var left, rsLeft, uncomputed,
6784			ret = elem.currentStyle && elem.currentStyle[ name ],
6785			style = elem.style;
6786
6787		// Avoid setting ret to empty string here
6788		// so we don't default to auto
6789		if ( ret === null && style && (uncomputed = style[ name ]) ) {
6790			ret = uncomputed;
6791		}
6792
6793		// From the awesome hack by Dean Edwards
6794		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6795
6796		// If we're not dealing with a regular pixel number
6797		// but a number that has a weird ending, we need to convert it to pixels
6798		if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6799
6800			// Remember the original values
6801			left = style.left;
6802			rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
6803
6804			// Put in the new values to get a computed value out
6805			if ( rsLeft ) {
6806				elem.runtimeStyle.left = elem.currentStyle.left;
6807			}
6808			style.left = name === "fontSize" ? "1em" : ( ret || 0 );
6809			ret = style.pixelLeft + "px";
6810
6811			// Revert the changed values
6812			style.left = left;
6813			if ( rsLeft ) {
6814				elem.runtimeStyle.left = rsLeft;
6815			}
6816		}
6817
6818		return ret === "" ? "auto" : ret;
6819	};
6820}
6821
6822curCSS = getComputedStyle || currentStyle;
6823
6824function getWH( elem, name, extra ) {
6825
6826	// Start with offset property
6827	var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6828		which = name === "width" ? cssWidth : cssHeight;
6829
6830	if ( val > 0 ) {
6831		if ( extra !== "border" ) {
6832			jQuery.each( which, function() {
6833				if ( !extra ) {
6834					val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6835				}
6836				if ( extra === "margin" ) {
6837					val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6838				} else {
6839					val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6840				}
6841			});
6842		}
6843
6844		return val + "px";
6845	}
6846
6847	// Fall back to computed then uncomputed css if necessary
6848	val = curCSS( elem, name, name );
6849	if ( val < 0 || val == null ) {
6850		val = elem.style[ name ] || 0;
6851	}
6852	// Normalize "", auto, and prepare for extra
6853	val = parseFloat( val ) || 0;
6854
6855	// Add padding, border, margin
6856	if ( extra ) {
6857		jQuery.each( which, function() {
6858			val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6859			if ( extra !== "padding" ) {
6860				val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6861			}
6862			if ( extra === "margin" ) {
6863				val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6864			}
6865		});
6866	}
6867
6868	return val + "px";
6869}
6870
6871if ( jQuery.expr && jQuery.expr.filters ) {
6872	jQuery.expr.filters.hidden = function( elem ) {
6873		var width = elem.offsetWidth,
6874			height = elem.offsetHeight;
6875
6876		return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
6877	};
6878
6879	jQuery.expr.filters.visible = function( elem ) {
6880		return !jQuery.expr.filters.hidden( elem );
6881	};
6882}
6883
6884
6885
6886
6887var r20 = /%20/g,
6888	rbracket = /\[\]$/,
6889	rCRLF = /\r?\n/g,
6890	rhash = /#.*$/,
6891	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6892	rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6893	// #7653, #8125, #8152: local protocol detection
6894	rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
6895	rnoContent = /^(?:GET|HEAD)$/,
6896	rprotocol = /^\/\//,
6897	rquery = /\?/,
6898	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6899	rselectTextarea = /^(?:select|textarea)/i,
6900	rspacesAjax = /\s+/,
6901	rts = /([?&])_=[^&]*/,
6902	rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6903
6904	// Keep a copy of the old load method
6905	_load = jQuery.fn.load,
6906
6907	/* Prefilters
6908	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6909	 * 2) These are called:
6910	 *    - BEFORE asking for a transport
6911	 *    - AFTER param serialization (s.data is a string if s.processData is true)
6912	 * 3) key is the dataType
6913	 * 4) the catchall symbol "*" can be used
6914	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6915	 */
6916	prefilters = {},
6917
6918	/* Transports bindings
6919	 * 1) key is the dataType
6920	 * 2) the catchall symbol "*" can be used
6921	 * 3) selection will start with transport dataType and THEN go to "*" if needed
6922	 */
6923	transports = {},
6924
6925	// Document location
6926	ajaxLocation,
6927
6928	// Document location segments
6929	ajaxLocParts,
6930
6931	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
6932	allTypes = ["*/"] + ["*"];
6933
6934// #8138, IE may throw an exception when accessing
6935// a field from window.location if document.domain has been set
6936try {
6937	ajaxLocation = location.href;
6938} catch( e ) {
6939	// Use the href attribute of an A element
6940	// since IE will modify it given document.location
6941	ajaxLocation = document.createElement( "a" );
6942	ajaxLocation.href = "";
6943	ajaxLocation = ajaxLocation.href;
6944}
6945
6946// Segment location into parts
6947ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6948
6949// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6950function addToPrefiltersOrTransports( structure ) {
6951
6952	// dataTypeExpression is optional and defaults to "*"
6953	return function( dataTypeExpression, func ) {
6954
6955		if ( typeof dataTypeExpression !== "string" ) {
6956			func = dataTypeExpression;
6957			dataTypeExpression = "*";
6958		}
6959
6960		if ( jQuery.isFunction( func ) ) {
6961			var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6962				i = 0,
6963				length = dataTypes.length,
6964				dataType,
6965				list,
6966				placeBefore;
6967
6968			// For each dataType in the dataTypeExpression
6969			for ( ; i < length; i++ ) {
6970				dataType = dataTypes[ i ];
6971				// We control if we're asked to add before
6972				// any existing element
6973				placeBefore = /^\+/.test( dataType );
6974				if ( placeBefore ) {
6975					dataType = dataType.substr( 1 ) || "*";
6976				}
6977				list = structure[ dataType ] = structure[ dataType ] || [];
6978				// then we add to the structure accordingly
6979				list[ placeBefore ? "unshift" : "push" ]( func );
6980			}
6981		}
6982	};
6983}
6984
6985// Base inspection function for prefilters and transports
6986function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6987		dataType /* internal */, inspected /* internal */ ) {
6988
6989	dataType = dataType || options.dataTypes[ 0 ];
6990	inspected = inspected || {};
6991
6992	inspected[ dataType ] = true;
6993
6994	var list = structure[ dataType ],
6995		i = 0,
6996		length = list ? list.length : 0,
6997		executeOnly = ( structure === prefilters ),
6998		selection;
6999
7000	for ( ; i < length && ( executeOnly || !selection ); i++ ) {
7001		selection = list[ i ]( options, originalOptions, jqXHR );
7002		// If we got redirected to another dataType
7003		// we try there if executing only and not done already
7004		if ( typeof selection === "string" ) {
7005			if ( !executeOnly || inspected[ selection ] ) {
7006				selection = undefined;
7007			} else {
7008				options.dataTypes.unshift( selection );
7009				selection = inspectPrefiltersOrTransports(
7010						structure, options, originalOptions, jqXHR, selection, inspected );
7011			}
7012		}
7013	}
7014	// If we're only executing or nothing was selected
7015	// we try the catchall dataType if not done already
7016	if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7017		selection = inspectPrefiltersOrTransports(
7018				structure, options, originalOptions, jqXHR, "*", inspected );
7019	}
7020	// unnecessary when only executing (prefilters)
7021	// but it'll be ignored by the caller in that case
7022	return selection;
7023}
7024
7025// A special extend for ajax options
7026// that takes "flat" options (not to be deep extended)
7027// Fixes #9887
7028function ajaxExtend( target, src ) {
7029	var key, deep,
7030		flatOptions = jQuery.ajaxSettings.flatOptions || {};
7031	for ( key in src ) {
7032		if ( src[ key ] !== undefined ) {
7033			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
7034		}
7035	}
7036	if ( deep ) {
7037		jQuery.extend( true, target, deep );
7038	}
7039}
7040
7041jQuery.fn.extend({
7042	load: function( url, params, callback ) {
7043		if ( typeof url !== "string" && _load ) {
7044			return _load.apply( this, arguments );
7045
7046		// Don't do a request if no elements are being requested
7047		} else if ( !this.length ) {
7048			return this;
7049		}
7050
7051		var off = url.indexOf( " " );
7052		if ( off >= 0 ) {
7053			var selector = url.slice( off, url.length );
7054			url = url.slice( 0, off );
7055		}
7056
7057		// Default to a GET request
7058		var type = "GET";
7059
7060		// If the second parameter was provided
7061		if ( params ) {
7062			// If it's a function
7063			if ( jQuery.isFunction( params ) ) {
7064				// We assume that it's the callback
7065				callback = params;
7066				params = undefined;
7067
7068			// Otherwise, build a param string
7069			} else if ( typeof params === "object" ) {
7070				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
7071				type = "POST";
7072			}
7073		}
7074
7075		var self = this;
7076
7077		// Request the remote document
7078		jQuery.ajax({
7079			url: url,
7080			type: type,
7081			dataType: "html",
7082			data: params,
7083			// Complete callback (responseText is used internally)
7084			complete: function( jqXHR, status, responseText ) {
7085				// Store the response as specified by the jqXHR object
7086				responseText = jqXHR.responseText;
7087				// If successful, inject the HTML into all the matched elements
7088				if ( jqXHR.isResolved() ) {
7089					// #4825: Get the actual response in case
7090					// a dataFilter is present in ajaxSettings
7091					jqXHR.done(function( r ) {
7092						responseText = r;
7093					});
7094					// See if a selector was specified
7095					self.html( selector ?
7096						// Create a dummy div to hold the results
7097						jQuery("<div>")
7098							// inject the contents of the document in, removing the scripts
7099							// to avoid any 'Permission Denied' errors in IE
7100							.append(responseText.replace(rscript, ""))
7101
7102							// Locate the specified elements
7103							.find(selector) :
7104
7105						// If not, just inject the full result
7106						responseText );
7107				}
7108
7109				if ( callback ) {
7110					self.each( callback, [ responseText, status, jqXHR ] );
7111				}
7112			}
7113		});
7114
7115		return this;
7116	},
7117
7118	serialize: function() {
7119		return jQuery.param( this.serializeArray() );
7120	},
7121
7122	serializeArray: function() {
7123		return this.map(function(){
7124			return this.elements ? jQuery.makeArray( this.elements ) : this;
7125		})
7126		.filter(function(){
7127			return this.name && !this.disabled &&
7128				( this.checked || rselectTextarea.test( this.nodeName ) ||
7129					rinput.test( this.type ) );
7130		})
7131		.map(function( i, elem ){
7132			var val = jQuery( this ).val();
7133
7134			return val == null ?
7135				null :
7136				jQuery.isArray( val ) ?
7137					jQuery.map( val, function( val, i ){
7138						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7139					}) :
7140					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7141		}).get();
7142	}
7143});
7144
7145// Attach a bunch of functions for handling common AJAX events
7146jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7147	jQuery.fn[ o ] = function( f ){
7148		return this.bind( o, f );
7149	};
7150});
7151
7152jQuery.each( [ "get", "post" ], function( i, method ) {
7153	jQuery[ method ] = function( url, data, callback, type ) {
7154		// shift arguments if data argument was omitted
7155		if ( jQuery.isFunction( data ) ) {
7156			type = type || callback;
7157			callback = data;
7158			data = undefined;
7159		}
7160
7161		return jQuery.ajax({
7162			type: method,
7163			url: url,
7164			data: data,
7165			success: callback,
7166			dataType: type
7167		});
7168	};
7169});
7170
7171jQuery.extend({
7172
7173	getScript: function( url, callback ) {
7174		return jQuery.get( url, undefined, callback, "script" );
7175	},
7176
7177	getJSON: function( url, data, callback ) {
7178		return jQuery.get( url, data, callback, "json" );
7179	},
7180
7181	// Creates a full fledged settings object into target
7182	// with both ajaxSettings and settings fields.
7183	// If target is omitted, writes into ajaxSettings.
7184	ajaxSetup: function( target, settings ) {
7185		if ( settings ) {
7186			// Building a settings object
7187			ajaxExtend( target, jQuery.ajaxSettings );
7188		} else {
7189			// Extending ajaxSettings
7190			settings = target;
7191			target = jQuery.ajaxSettings;
7192		}
7193		ajaxExtend( target, settings );
7194		return target;
7195	},
7196
7197	ajaxSettings: {
7198		url: ajaxLocation,
7199		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7200		global: true,
7201		type: "GET",
7202		contentType: "application/x-www-form-urlencoded",
7203		processData: true,
7204		async: true,
7205		/*
7206		timeout: 0,
7207		data: null,
7208		dataType: null,
7209		username: null,
7210		password: null,
7211		cache: null,
7212		traditional: false,
7213		headers: {},
7214		*/
7215
7216		accepts: {
7217			xml: "application/xml, text/xml",
7218			html: "text/html",
7219			text: "text/plain",
7220			json: "application/json, text/javascript",
7221			"*": allTypes
7222		},
7223
7224		contents: {
7225			xml: /xml/,
7226			html: /html/,
7227			json: /json/
7228		},
7229
7230		responseFields: {
7231			xml: "responseXML",
7232			text: "responseText"
7233		},
7234
7235		// List of data converters
7236		// 1) key format is "source_type destination_type" (a single space in-between)
7237		// 2) the catchall symbol "*" can be used for source_type
7238		converters: {
7239
7240			// Convert anything to text
7241			"* text": window.String,
7242
7243			// Text to html (true = no transformation)
7244			"text html": true,
7245
7246			// Evaluate text as a json expression
7247			"text json": jQuery.parseJSON,
7248
7249			// Parse text as xml
7250			"text xml": jQuery.parseXML
7251		},
7252
7253		// For options that shouldn't be deep extended:
7254		// you can add your own custom options here if
7255		// and when you create one that shouldn't be
7256		// deep extended (see ajaxExtend)
7257		flatOptions: {
7258			context: true,
7259			url: true
7260		}
7261	},
7262
7263	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7264	ajaxTransport: addToPrefiltersOrTransports( transports ),
7265
7266	// Main method
7267	ajax: function( url, options ) {
7268
7269		// If url is an object, simulate pre-1.5 signature
7270		if ( typeof url === "object" ) {
7271			options = url;
7272			url = undefined;
7273		}
7274
7275		// Force options to be an object
7276		options = options || {};
7277
7278		var // Create the final options object
7279			s = jQuery.ajaxSetup( {}, options ),
7280			// Callbacks context
7281			callbackContext = s.context || s,
7282			// Context for global events
7283			// It's the callbackContext if one was provided in the options
7284			// and if it's a DOM node or a jQuery collection
7285			globalEventContext = callbackContext !== s &&
7286				( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7287						jQuery( callbackContext ) : jQuery.event,
7288			// Deferreds
7289			deferred = jQuery.Deferred(),
7290			completeDeferred = jQuery.Callbacks( "once memory" ),
7291			// Status-dependent callbacks
7292			statusCode = s.statusCode || {},
7293			// ifModified key
7294			ifModifiedKey,
7295			// Headers (they are sent all at once)
7296			requestHeaders = {},
7297			requestHeadersNames = {},
7298			// Response headers
7299			responseHeadersString,
7300			responseHeaders,
7301			// transport
7302			transport,
7303			// timeout handle
7304			timeoutTimer,
7305			// Cross-domain detection vars
7306			parts,
7307			// The jqXHR state
7308			state = 0,
7309			// To know if global events are to be dispatched
7310			fireGlobals,
7311			// Loop variable
7312			i,
7313			// Fake xhr
7314			jqXHR = {
7315
7316				readyState: 0,
7317
7318				// Caches the header
7319				setRequestHeader: function( name, value ) {
7320					if ( !state ) {
7321						var lname = name.toLowerCase();
7322						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7323						requestHeaders[ name ] = value;
7324					}
7325					return this;
7326				},
7327
7328				// Raw string
7329				getAllResponseHeaders: function() {
7330					return state === 2 ? responseHeadersString : null;
7331				},
7332
7333				// Builds headers hashtable if needed
7334				getResponseHeader: function( key ) {
7335					var match;
7336					if ( state === 2 ) {
7337						if ( !responseHeaders ) {
7338							responseHeaders = {};
7339							while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7340								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7341							}
7342						}
7343						match = responseHeaders[ key.toLowerCase() ];
7344					}
7345					return match === undefined ? null : match;
7346				},
7347
7348				// Overrides response content-type header
7349				overrideMimeType: function( type ) {
7350					if ( !state ) {
7351						s.mimeType = type;
7352					}
7353					return this;
7354				},
7355
7356				// Cancel the request
7357				abort: function( statusText ) {
7358					statusText = statusText || "abort";
7359					if ( transport ) {
7360						transport.abort( statusText );
7361					}
7362					done( 0, statusText );
7363					return this;
7364				}
7365			};
7366
7367		// Callback for when everything is done
7368		// It is defined here because jslint complains if it is declared
7369		// at the end of the function (which would be more logical and readable)
7370		function done( status, nativeStatusText, responses, headers ) {
7371
7372			// Called once
7373			if ( state === 2 ) {
7374				return;
7375			}
7376
7377			// State is "done" now
7378			state = 2;
7379
7380			// Clear timeout if it exists
7381			if ( timeoutTimer ) {
7382				clearTimeout( timeoutTimer );
7383			}
7384
7385			// Dereference transport for early garbage collection
7386			// (no matter how long the jqXHR object will be used)
7387			transport = undefined;
7388
7389			// Cache response headers
7390			responseHeadersString = headers || "";
7391
7392			// Set readyState
7393			jqXHR.readyState = status > 0 ? 4 : 0;
7394
7395			var isSuccess,
7396				success,
7397				error,
7398				statusText = nativeStatusText,
7399				response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7400				lastModified,
7401				etag;
7402
7403			// If successful, handle type chaining
7404			if ( status >= 200 && status < 300 || status === 304 ) {
7405
7406				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7407				if ( s.ifModified ) {
7408
7409					if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7410						jQuery.lastModified[ ifModifiedKey ] = lastModified;
7411					}
7412					if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7413						jQuery.etag[ ifModifiedKey ] = etag;
7414					}
7415				}
7416
7417				// If not modified
7418				if ( status === 304 ) {
7419
7420					statusText = "notmodified";
7421					isSuccess = true;
7422
7423				// If we have data
7424				} else {
7425
7426					try {
7427						success = ajaxConvert( s, response );
7428						statusText = "success";
7429						isSuccess = true;
7430					} catch(e) {
7431						// We have a parsererror
7432						statusText = "parsererror";
7433						error = e;
7434					}
7435				}
7436			} else {
7437				// We extract error from statusText
7438				// then normalize statusText and status for non-aborts
7439				error = statusText;
7440				if ( !statusText || status ) {
7441					statusText = "error";
7442					if ( status < 0 ) {
7443						status = 0;
7444					}
7445				}
7446			}
7447
7448			// Set data for the fake xhr object
7449			jqXHR.status = status;
7450			jqXHR.statusText = "" + ( nativeStatusText || statusText );
7451
7452			// Success/Error
7453			if ( isSuccess ) {
7454				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7455			} else {
7456				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7457			}
7458
7459			// Status-dependent callbacks
7460			jqXHR.statusCode( statusCode );
7461			statusCode = undefined;
7462
7463			if ( fireGlobals ) {
7464				globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7465						[ jqXHR, s, isSuccess ? success : error ] );
7466			}
7467
7468			// Complete
7469			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7470
7471			if ( fireGlobals ) {
7472				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7473				// Handle the global AJAX counter
7474				if ( !( --jQuery.active ) ) {
7475					jQuery.event.trigger( "ajaxStop" );
7476				}
7477			}
7478		}
7479
7480		// Attach deferreds
7481		deferred.promise( jqXHR );
7482		jqXHR.success = jqXHR.done;
7483		jqXHR.error = jqXHR.fail;
7484		jqXHR.complete = completeDeferred.add;
7485
7486		// Status-dependent callbacks
7487		jqXHR.statusCode = function( map ) {
7488			if ( map ) {
7489				var tmp;
7490				if ( state < 2 ) {
7491					for ( tmp in map ) {
7492						statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7493					}
7494				} else {
7495					tmp = map[ jqXHR.status ];
7496					jqXHR.then( tmp, tmp );
7497				}
7498			}
7499			return this;
7500		};
7501
7502		// Remove hash character (#7531: and string promotion)
7503		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7504		// We also use the url parameter if available
7505		s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7506
7507		// Extract dataTypes list
7508		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7509
7510		// Determine if a cross-domain request is in order
7511		if ( s.crossDomain == null ) {
7512			parts = rurl.exec( s.url.toLowerCase() );
7513			s.crossDomain = !!( parts &&
7514				( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7515					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7516						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7517			);
7518		}
7519
7520		// Convert data if not already a string
7521		if ( s.data && s.processData && typeof s.data !== "string" ) {
7522			s.data = jQuery.param( s.data, s.traditional );
7523		}
7524
7525		// Apply prefilters
7526		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7527
7528		// If request was aborted inside a prefiler, stop there
7529		if ( state === 2 ) {
7530			return false;
7531		}
7532
7533		// We can fire global events as of now if asked to
7534		fireGlobals = s.global;
7535
7536		// Uppercase the type
7537		s.type = s.type.toUpperCase();
7538
7539		// Determine if request has content
7540		s.hasContent = !rnoContent.test( s.type );
7541
7542		// Watch for a new set of requests
7543		if ( fireGlobals && jQuery.active++ === 0 ) {
7544			jQuery.event.trigger( "ajaxStart" );
7545		}
7546
7547		// More options handling for requests with no content
7548		if ( !s.hasContent ) {
7549
7550			// If data is available, append data to url
7551			if ( s.data ) {
7552				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7553				// #9682: remove data so that it's not used in an eventual retry
7554				delete s.data;
7555			}
7556
7557			// Get ifModifiedKey before adding the anti-cache parameter
7558			ifModifiedKey = s.url;
7559
7560			// Add anti-cache in url if needed
7561			if ( s.cache === false ) {
7562
7563				var ts = jQuery.now(),
7564					// try replacing _= if it is there
7565					ret = s.url.replace( rts, "$1_=" + ts );
7566
7567				// if nothing was replaced, add timestamp to the end
7568				s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7569			}
7570		}
7571
7572		// Set the correct header, if data is being sent
7573		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7574			jqXHR.setRequestHeader( "Content-Type", s.contentType );
7575		}
7576
7577		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7578		if ( s.ifModified ) {
7579			ifModifiedKey = ifModifiedKey || s.url;
7580			if ( jQuery.lastModified[ ifModifiedKey ] ) {
7581				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7582			}
7583			if ( jQuery.etag[ ifModifiedKey ] ) {
7584				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7585			}
7586		}
7587
7588		// Set the Accepts header for the server, depending on the dataType
7589		jqXHR.setRequestHeader(
7590			"Accept",
7591			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7592				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7593				s.accepts[ "*" ]
7594		);
7595
7596		// Check for headers option
7597		for ( i in s.headers ) {
7598			jqXHR.setRequestHeader( i, s.headers[ i ] );
7599		}
7600
7601		// Allow custom headers/mimetypes and early abort
7602		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7603				// Abort if not done already
7604				jqXHR.abort();
7605				return false;
7606
7607		}
7608
7609		// Install callbacks on deferreds
7610		for ( i in { success: 1, error: 1, complete: 1 } ) {
7611			jqXHR[ i ]( s[ i ] );
7612		}
7613
7614		// Get transport
7615		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7616
7617		// If no transport, we auto-abort
7618		if ( !transport ) {
7619			done( -1, "No Transport" );
7620		} else {
7621			jqXHR.readyState = 1;
7622			// Send global event
7623			if ( fireGlobals ) {
7624				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7625			}
7626			// Timeout
7627			if ( s.async && s.timeout > 0 ) {
7628				timeoutTimer = setTimeout( function(){
7629					jqXHR.abort( "timeout" );
7630				}, s.timeout );
7631			}
7632
7633			try {
7634				state = 1;
7635				transport.send( requestHeaders, done );
7636			} catch (e) {
7637				// Propagate exception as error if not done
7638				if ( state < 2 ) {
7639					done( -1, e );
7640				// Simply rethrow otherwise
7641				} else {
7642					jQuery.error( e );
7643				}
7644			}
7645		}
7646
7647		return jqXHR;
7648	},
7649
7650	// Serialize an array of form elements or a set of
7651	// key/values into a query string
7652	param: function( a, traditional ) {
7653		var s = [],
7654			add = function( key, value ) {
7655				// If value is a function, invoke it and return its value
7656				value = jQuery.isFunction( value ) ? value() : value;
7657				s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7658			};
7659
7660		// Set traditional to true for jQuery <= 1.3.2 behavior.
7661		if ( traditional === undefined ) {
7662			traditional = jQuery.ajaxSettings.traditional;
7663		}
7664
7665		// If an array was passed in, assume that it is an array of form elements.
7666		if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7667			// Serialize the form elements
7668			jQuery.each( a, function() {
7669				add( this.name, this.value );
7670			});
7671
7672		} else {
7673			// If traditional, encode the "old" way (the way 1.3.2 or older
7674			// did it), otherwise encode params recursively.
7675			for ( var prefix in a ) {
7676				buildParams( prefix, a[ prefix ], traditional, add );
7677			}
7678		}
7679
7680		// Return the resulting serialization
7681		return s.join( "&" ).replace( r20, "+" );
7682	}
7683});
7684
7685function buildParams( prefix, obj, traditional, add ) {
7686	if ( jQuery.isArray( obj ) ) {
7687		// Serialize array item.
7688		jQuery.each( obj, function( i, v ) {
7689			if ( traditional || rbracket.test( prefix ) ) {
7690				// Treat each array item as a scalar.
7691				add( prefix, v );
7692
7693			} else {
7694				// If array item is non-scalar (array or object), encode its
7695				// numeric index to resolve deserialization ambiguity issues.
7696				// Note that rack (as of 1.0.0) can't currently deserialize
7697				// nested arrays properly, and attempting to do so may cause
7698				// a server error. Possible fixes are to modify rack's
7699				// deserialization algorithm or to provide an option or flag
7700				// to force array serialization to be shallow.
7701				buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7702			}
7703		});
7704
7705	} else if ( !traditional && obj != null && typeof obj === "object" ) {
7706		// Serialize object item.
7707		for ( var name in obj ) {
7708			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7709		}
7710
7711	} else {
7712		// Serialize scalar item.
7713		add( prefix, obj );
7714	}
7715}
7716
7717// This is still on the jQuery object... for now
7718// Want to move this to jQuery.ajax some day
7719jQuery.extend({
7720
7721	// Counter for holding the number of active queries
7722	active: 0,
7723
7724	// Last-Modified header cache for next request
7725	lastModified: {},
7726	etag: {}
7727
7728});
7729
7730/* Handles responses to an ajax request:
7731 * - sets all responseXXX fields accordingly
7732 * - finds the right dataType (mediates between content-type and expected dataType)
7733 * - returns the corresponding response
7734 */
7735function ajaxHandleResponses( s, jqXHR, responses ) {
7736
7737	var contents = s.contents,
7738		dataTypes = s.dataTypes,
7739		responseFields = s.responseFields,
7740		ct,
7741		type,
7742		finalDataType,
7743		firstDataType;
7744
7745	// Fill responseXXX fields
7746	for ( type in responseFields ) {
7747		if ( type in responses ) {
7748			jqXHR[ responseFields[type] ] = responses[ type ];
7749		}
7750	}
7751
7752	// Remove auto dataType and get content-type in the process
7753	while( dataTypes[ 0 ] === "*" ) {
7754		dataTypes.shift();
7755		if ( ct === undefined ) {
7756			ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7757		}
7758	}
7759
7760	// Check if we're dealing with a known content-type
7761	if ( ct ) {
7762		for ( type in contents ) {
7763			if ( contents[ type ] && contents[ type ].test( ct ) ) {
7764				dataTypes.unshift( type );
7765				break;
7766			}
7767		}
7768	}
7769
7770	// Check to see if we have a response for the expected dataType
7771	if ( dataTypes[ 0 ] in responses ) {
7772		finalDataType = dataTypes[ 0 ];
7773	} else {
7774		// Try convertible dataTypes
7775		for ( type in responses ) {
7776			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7777				finalDataType = type;
7778				break;
7779			}
7780			if ( !firstDataType ) {
7781				firstDataType = type;
7782			}
7783		}
7784		// Or just use first one
7785		finalDataType = finalDataType || firstDataType;
7786	}
7787
7788	// If we found a dataType
7789	// We add the dataType to the list if needed
7790	// and return the corresponding response
7791	if ( finalDataType ) {
7792		if ( finalDataType !== dataTypes[ 0 ] ) {
7793			dataTypes.unshift( finalDataType );
7794		}
7795		return responses[ finalDataType ];
7796	}
7797}
7798
7799// Chain conversions given the request and the original response
7800function ajaxConvert( s, response ) {
7801
7802	// Apply the dataFilter if provided
7803	if ( s.dataFilter ) {
7804		response = s.dataFilter( response, s.dataType );
7805	}
7806
7807	var dataTypes = s.dataTypes,
7808		converters = {},
7809		i,
7810		key,
7811		length = dataTypes.length,
7812		tmp,
7813		// Current and previous dataTypes
7814		current = dataTypes[ 0 ],
7815		prev,
7816		// Conversion expression
7817		conversion,
7818		// Conversion function
7819		conv,
7820		// Conversion functions (transitive conversion)
7821		conv1,
7822		conv2;
7823
7824	// For each dataType in the chain
7825	for ( i = 1; i < length; i++ ) {
7826
7827		// Create converters map
7828		// with lowercased keys
7829		if ( i === 1 ) {
7830			for ( key in s.converters ) {
7831				if ( typeof key === "string" ) {
7832					converters[ key.toLowerCase() ] = s.converters[ key ];
7833				}
7834			}
7835		}
7836
7837		// Get the dataTypes
7838		prev = current;
7839		current = dataTypes[ i ];
7840
7841		// If current is auto dataType, update it to prev
7842		if ( current === "*" ) {
7843			current = prev;
7844		// If no auto and dataTypes are actually different
7845		} else if ( prev !== "*" && prev !== current ) {
7846
7847			// Get the converter
7848			conversion = prev + " " + current;
7849			conv = converters[ conversion ] || converters[ "* " + current ];
7850
7851			// If there is no direct converter, search transitively
7852			if ( !conv ) {
7853				conv2 = undefined;
7854				for ( conv1 in converters ) {
7855					tmp = conv1.split( " " );
7856					if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7857						conv2 = converters[ tmp[1] + " " + current ];
7858						if ( conv2 ) {
7859							conv1 = converters[ conv1 ];
7860							if ( conv1 === true ) {
7861								conv = conv2;
7862							} else if ( conv2 === true ) {
7863								conv = conv1;
7864							}
7865							break;
7866						}
7867					}
7868				}
7869			}
7870			// If we found no converter, dispatch an error
7871			if ( !( conv || conv2 ) ) {
7872				jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7873			}
7874			// If found converter is not an equivalence
7875			if ( conv !== true ) {
7876				// Convert with 1 or 2 converters accordingly
7877				response = conv ? conv( response ) : conv2( conv1(response) );
7878			}
7879		}
7880	}
7881	return response;
7882}
7883
7884
7885
7886
7887var jsc = jQuery.now(),
7888	jsre = /(\=)\?(&|$)|\?\?/i;
7889
7890// Default jsonp settings
7891jQuery.ajaxSetup({
7892	jsonp: "callback",
7893	jsonpCallback: function() {
7894		return jQuery.expando + "_" + ( jsc++ );
7895	}
7896});
7897
7898// Detect, normalize options and install callbacks for jsonp requests
7899jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7900
7901	var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7902		( typeof s.data === "string" );
7903
7904	if ( s.dataTypes[ 0 ] === "jsonp" ||
7905		s.jsonp !== false && ( jsre.test( s.url ) ||
7906				inspectData && jsre.test( s.data ) ) ) {
7907
7908		var responseContainer,
7909			jsonpCallback = s.jsonpCallback =
7910				jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7911			previous = window[ jsonpCallback ],
7912			url = s.url,
7913			data = s.data,
7914			replace = "$1" + jsonpCallback + "$2";
7915
7916		if ( s.jsonp !== false ) {
7917			url = url.replace( jsre, replace );
7918			if ( s.url === url ) {
7919				if ( inspectData ) {
7920					data = data.replace( jsre, replace );
7921				}
7922				if ( s.data === data ) {
7923					// Add callback manually
7924					url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7925				}
7926			}
7927		}
7928
7929		s.url = url;
7930		s.data = data;
7931
7932		// Install callback
7933		window[ jsonpCallback ] = function( response ) {
7934			responseContainer = [ response ];
7935		};
7936
7937		// Clean-up function
7938		jqXHR.always(function() {
7939			// Set callback back to previous value
7940			window[ jsonpCallback ] = previous;
7941			// Call if it was a function and we have a response
7942			if ( responseContainer && jQuery.isFunction( previous ) ) {
7943				window[ jsonpCallback ]( responseContainer[ 0 ] );
7944			}
7945		});
7946
7947		// Use data converter to retrieve json after script execution
7948		s.converters["script json"] = function() {
7949			if ( !responseContainer ) {
7950				jQuery.error( jsonpCallback + " was not called" );
7951			}
7952			return responseContainer[ 0 ];
7953		};
7954
7955		// force json dataType
7956		s.dataTypes[ 0 ] = "json";
7957
7958		// Delegate to script
7959		return "script";
7960	}
7961});
7962
7963
7964
7965
7966// Install script dataType
7967jQuery.ajaxSetup({
7968	accepts: {
7969		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7970	},
7971	contents: {
7972		script: /javascript|ecmascript/
7973	},
7974	converters: {
7975		"text script": function( text ) {
7976			jQuery.globalEval( text );
7977			return text;
7978		}
7979	}
7980});
7981
7982// Handle cache's special case and global
7983jQuery.ajaxPrefilter( "script", function( s ) {
7984	if ( s.cache === undefined ) {
7985		s.cache = false;
7986	}
7987	if ( s.crossDomain ) {
7988		s.type = "GET";
7989		s.global = false;
7990	}
7991});
7992
7993// Bind script tag hack transport
7994jQuery.ajaxTransport( "script", function(s) {
7995
7996	// This transport only deals with cross domain requests
7997	if ( s.crossDomain ) {
7998
7999		var script,
8000			head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8001
8002		return {
8003
8004			send: function( _, callback ) {
8005
8006				script = document.createElement( "script" );
8007
8008				script.async = "async";
8009
8010				if ( s.scriptCharset ) {
8011					script.charset = s.scriptCharset;
8012				}
8013
8014				script.src = s.url;
8015
8016				// Attach handlers for all browsers
8017				script.onload = script.onreadystatechange = function( _, isAbort ) {
8018
8019					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8020
8021						// Handle memory leak in IE
8022						script.onload = script.onreadystatechange = null;
8023
8024						// Remove the script
8025						if ( head && script.parentNode ) {
8026							head.removeChild( script );
8027						}
8028
8029						// Dereference the script
8030						script = undefined;
8031
8032						// Callback if not abort
8033						if ( !isAbort ) {
8034							callback( 200, "success" );
8035						}
8036					}
8037				};
8038				// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
8039				// This arises when a base node is used (#2709 and #4378).
8040				head.insertBefore( script, head.firstChild );
8041			},
8042
8043			abort: function() {
8044				if ( script ) {
8045					script.onload( 0, 1 );
8046				}
8047			}
8048		};
8049	}
8050});
8051
8052
8053
8054
8055var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
8056	xhrOnUnloadAbort = window.ActiveXObject ? function() {
8057		// Abort all pending requests
8058		for ( var key in xhrCallbacks ) {
8059			xhrCallbacks[ key ]( 0, 1 );
8060		}
8061	} : false,
8062	xhrId = 0,
8063	xhrCallbacks;
8064
8065// Functions to create xhrs
8066function createStandardXHR() {
8067	try {
8068		return new window.XMLHttpRequest();
8069	} catch( e ) {}
8070}
8071
8072function createActiveXHR() {
8073	try {
8074		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8075	} catch( e ) {}
8076}
8077
8078// Create the request object
8079// (This is still attached to ajaxSettings for backward compatibility)
8080jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8081	/* Microsoft failed to properly
8082	 * implement the XMLHttpRequest in IE7 (can't request local files),
8083	 * so we use the ActiveXObject when it is available
8084	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8085	 * we need a fallback.
8086	 */
8087	function() {
8088		return !this.isLocal && createStandardXHR() || createActiveXHR();
8089	} :
8090	// For all other browsers, use the standard XMLHttpRequest object
8091	createStandardXHR;
8092
8093// Determine support properties
8094(function( xhr ) {
8095	jQuery.extend( jQuery.support, {
8096		ajax: !!xhr,
8097		cors: !!xhr && ( "withCredentials" in xhr )
8098	});
8099})( jQuery.ajaxSettings.xhr() );
8100
8101// Create transport if the browser can provide an xhr
8102if ( jQuery.support.ajax ) {
8103
8104	jQuery.ajaxTransport(function( s ) {
8105		// Cross domain only allowed if supported through XMLHttpRequest
8106		if ( !s.crossDomain || jQuery.support.cors ) {
8107
8108			var callback;
8109
8110			return {
8111				send: function( headers, complete ) {
8112
8113					// Get a new xhr
8114					var xhr = s.xhr(),
8115						handle,
8116						i;
8117
8118					// Open the socket
8119					// Passing null username, generates a login popup on Opera (#2865)
8120					if ( s.username ) {
8121						xhr.open( s.type, s.url, s.async, s.username, s.password );
8122					} else {
8123						xhr.open( s.type, s.url, s.async );
8124					}
8125
8126					// Apply custom fields if provided
8127					if ( s.xhrFields ) {
8128						for ( i in s.xhrFields ) {
8129							xhr[ i ] = s.xhrFields[ i ];
8130						}
8131					}
8132
8133					// Override mime type if needed
8134					if ( s.mimeType && xhr.overrideMimeType ) {
8135						xhr.overrideMimeType( s.mimeType );
8136					}
8137
8138					// X-Requested-With header
8139					// For cross-domain requests, seeing as conditions for a preflight are
8140					// akin to a jigsaw puzzle, we simply never set it to be sure.
8141					// (it can always be set on a per-request basis or even using ajaxSetup)
8142					// For same-domain requests, won't change header if already provided.
8143					if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8144						headers[ "X-Requested-With" ] = "XMLHttpRequest";
8145					}
8146
8147					// Need an extra try/catch for cross domain requests in Firefox 3
8148					try {
8149						for ( i in headers ) {
8150							xhr.setRequestHeader( i, headers[ i ] );
8151						}
8152					} catch( _ ) {}
8153
8154					// Do send the request
8155					// This may raise an exception which is actually
8156					// handled in jQuery.ajax (so no try/catch here)
8157					xhr.send( ( s.hasContent && s.data ) || null );
8158
8159					// Listener
8160					callback = function( _, isAbort ) {
8161
8162						var status,
8163							statusText,
8164							responseHeaders,
8165							responses,
8166							xml;
8167
8168						// Firefox throws exceptions when accessing properties
8169						// of an xhr when a network error occured
8170						// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8171						try {
8172
8173							// Was never called and is aborted or complete
8174							if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8175
8176								// Only called once
8177								callback = undefined;
8178
8179								// Do not keep as active anymore
8180								if ( handle ) {
8181									xhr.onreadystatechange = jQuery.noop;
8182									if ( xhrOnUnloadAbort ) {
8183										delete xhrCallbacks[ handle ];
8184									}
8185								}
8186
8187								// If it's an abort
8188								if ( isAbort ) {
8189									// Abort it manually if needed
8190									if ( xhr.readyState !== 4 ) {
8191										xhr.abort();
8192									}
8193								} else {
8194									status = xhr.status;
8195									responseHeaders = xhr.getAllResponseHeaders();
8196									responses = {};
8197									xml = xhr.responseXML;
8198
8199									// Construct response list
8200									if ( xml && xml.documentElement /* #4958 */ ) {
8201										responses.xml = xml;
8202									}
8203									responses.text = xhr.responseText;
8204
8205									// Firefox throws an exception when accessing
8206									// statusText for faulty cross-domain requests
8207									try {
8208										statusText = xhr.statusText;
8209									} catch( e ) {
8210										// We normalize with Webkit giving an empty statusText
8211										statusText = "";
8212									}
8213
8214									// Filter status for non standard behaviors
8215
8216									// If the request is local and we have data: assume a success
8217									// (success with no data won't get notified, that's the best we
8218									// can do given current implementations)
8219									if ( !status && s.isLocal && !s.crossDomain ) {
8220										status = responses.text ? 200 : 404;
8221									// IE - #1450: sometimes returns 1223 when it should be 204
8222									} else if ( status === 1223 ) {
8223										status = 204;
8224									}
8225								}
8226							}
8227						} catch( firefoxAccessException ) {
8228							if ( !isAbort ) {
8229								complete( -1, firefoxAccessException );
8230							}
8231						}
8232
8233						// Call complete if needed
8234						if ( responses ) {
8235							complete( status, statusText, responses, responseHeaders );
8236						}
8237					};
8238
8239					// if we're in sync mode or it's in cache
8240					// and has been retrieved directly (IE6 & IE7)
8241					// we need to manually fire the callback
8242					if ( !s.async || xhr.readyState === 4 ) {
8243						callback();
8244					} else {
8245						handle = ++xhrId;
8246						if ( xhrOnUnloadAbort ) {
8247							// Create the active xhrs callbacks list if needed
8248							// and attach the unload handler
8249							if ( !xhrCallbacks ) {
8250								xhrCallbacks = {};
8251								jQuery( window ).unload( xhrOnUnloadAbort );
8252							}
8253							// Add to list of active xhrs callbacks
8254							xhrCallbacks[ handle ] = callback;
8255						}
8256						xhr.onreadystatechange = callback;
8257					}
8258				},
8259
8260				abort: function() {
8261					if ( callback ) {
8262						callback(0,1);
8263					}
8264				}
8265			};
8266		}
8267	});
8268}
8269
8270
8271
8272
8273var elemdisplay = {},
8274	iframe, iframeDoc,
8275	rfxtypes = /^(?:toggle|show|hide)$/,
8276	rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
8277	timerId,
8278	fxAttrs = [
8279		// height animations
8280		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
8281		// width animations
8282		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
8283		// opacity animations
8284		[ "opacity" ]
8285	],
8286	fxNow;
8287
8288jQuery.fn.extend({
8289	show: function( speed, easing, callback ) {
8290		var elem, display;
8291
8292		if ( speed || speed === 0 ) {
8293			return this.animate( genFx("show", 3), speed, easing, callback );
8294
8295		} else {
8296			for ( var i = 0, j = this.length; i < j; i++ ) {
8297				elem = this[ i ];
8298
8299				if ( elem.style ) {
8300					display = elem.style.display;
8301
8302					// Reset the inline display of this element to learn if it is
8303					// being hidden by cascaded rules or not
8304					if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8305						display = elem.style.display = "";
8306					}
8307
8308					// Set elements which have been overridden with display: none
8309					// in a stylesheet to whatever the default browser style is
8310					// for such an element
8311					if ( display === "" && jQuery.css(elem, "display") === "none" ) {
8312						jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
8313					}
8314				}
8315			}
8316
8317			// Set the display of most of the elements in a second loop
8318			// to avoid the constant reflow
8319			for ( i = 0; i < j; i++ ) {
8320				elem = this[ i ];
8321
8322				if ( elem.style ) {
8323					display = elem.style.display;
8324
8325					if ( display === "" || display === "none" ) {
8326						elem.style.display = jQuery._data( elem, "olddisplay" ) || "";
8327					}
8328				}
8329			}
8330
8331			return this;
8332		}
8333	},
8334
8335	hide: function( speed, easing, callback ) {
8336		if ( speed || speed === 0 ) {
8337			return this.animate( genFx("hide", 3), speed, easing, callback);
8338
8339		} else {
8340			var elem, display,
8341				i = 0,
8342				j = this.length;
8343
8344			for ( ; i < j; i++ ) {
8345				elem = this[i];
8346				if ( elem.style ) {
8347					display = jQuery.css( elem, "display" );
8348
8349					if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {
8350						jQuery._data( elem, "olddisplay", display );
8351					}
8352				}
8353			}
8354
8355			// Set the display of the elements in a second loop
8356			// to avoid the constant reflow
8357			for ( i = 0; i < j; i++ ) {
8358				if ( this[i].style ) {
8359					this[i].style.display = "none";
8360				}
8361			}
8362
8363			return this;
8364		}
8365	},
8366
8367	// Save the old toggle function
8368	_toggle: jQuery.fn.toggle,
8369
8370	toggle: function( fn, fn2, callback ) {
8371		var bool = typeof fn === "boolean";
8372
8373		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8374			this._toggle.apply( this, arguments );
8375
8376		} else if ( fn == null || bool ) {
8377			this.each(function() {
8378				var state = bool ? fn : jQuery(this).is(":hidden");
8379				jQuery(this)[ state ? "show" : "hide" ]();
8380			});
8381
8382		} else {
8383			this.animate(genFx("toggle", 3), fn, fn2, callback);
8384		}
8385
8386		return this;
8387	},
8388
8389	fadeTo: function( speed, to, easing, callback ) {
8390		return this.filter(":hidden").css("opacity", 0).show().end()
8391					.animate({opacity: to}, speed, easing, callback);
8392	},
8393
8394	animate: function( prop, speed, easing, callback ) {
8395		var optall = jQuery.speed( speed, easing, callback );
8396
8397		if ( jQuery.isEmptyObject( prop ) ) {
8398			return this.each( optall.complete, [ false ] );
8399		}
8400
8401		// Do not change referenced properties as per-property easing will be lost
8402		prop = jQuery.extend( {}, prop );
8403
8404		function doAnimation() {
8405			// XXX 'this' does not always have a nodeName when running the
8406			// test suite
8407
8408			if ( optall.queue === false ) {
8409				jQuery._mark( this );
8410			}
8411
8412			var opt = jQuery.extend( {}, optall ),
8413				isElement = this.nodeType === 1,
8414				hidden = isElement && jQuery(this).is(":hidden"),
8415				name, val, p, e,
8416				parts, start, end, unit,
8417				method;
8418
8419			// will store per property easing and be used to determine when an animation is complete
8420			opt.animatedProperties = {};
8421
8422			for ( p in prop ) {
8423
8424				// property name normalization
8425				name = jQuery.camelCase( p );
8426				if ( p !== name ) {
8427					prop[ name ] = prop[ p ];
8428					delete prop[ p ];
8429				}
8430
8431				val = prop[ name ];
8432
8433				// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8434				if ( jQuery.isArray( val ) ) {
8435					opt.animatedProperties[ name ] = val[ 1 ];
8436					val = prop[ name ] = val[ 0 ];
8437				} else {
8438					opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8439				}
8440
8441				if ( val === "hide" && hidden || val === "show" && !hidden ) {
8442					return opt.complete.call( this );
8443				}
8444
8445				if ( isElement && ( name === "height" || name === "width" ) ) {
8446					// Make sure that nothing sneaks out
8447					// Record all 3 overflow attributes because IE does not
8448					// change the overflow attribute when overflowX and
8449					// overflowY are set to the same value
8450					opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8451
8452					// Set display property to inline-block for height/width
8453					// animations on inline elements that are having width/height animated
8454					if ( jQuery.css( this, "display" ) === "inline" &&
8455							jQuery.css( this, "float" ) === "none" ) {
8456
8457						// inline-level elements accept inline-block;
8458						// block-level elements need to be inline with layout
8459						if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {
8460							this.style.display = "inline-block";
8461
8462						} else {
8463							this.style.zoom = 1;
8464						}
8465					}
8466				}
8467			}
8468
8469			if ( opt.overflow != null ) {
8470				this.style.overflow = "hidden";
8471			}
8472
8473			for ( p in prop ) {
8474				e = new jQuery.fx( this, opt, p );
8475				val = prop[ p ];
8476
8477				if ( rfxtypes.test( val ) ) {
8478
8479					// Tracks whether to show or hide based on private
8480					// data attached to the element
8481					method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );
8482					if ( method ) {
8483						jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );
8484						e[ method ]();
8485					} else {
8486						e[ val ]();
8487					}
8488
8489				} else {
8490					parts = rfxnum.exec( val );
8491					start = e.cur();
8492
8493					if ( parts ) {
8494						end = parseFloat( parts[2] );
8495						unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8496
8497						// We need to compute starting value
8498						if ( unit !== "px" ) {
8499							jQuery.style( this, p, (end || 1) + unit);
8500							start = ( (end || 1) / e.cur() ) * start;
8501							jQuery.style( this, p, start + unit);
8502						}
8503
8504						// If a +=/-= token was provided, we're doing a relative animation
8505						if ( parts[1] ) {
8506							end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8507						}
8508
8509						e.custom( start, end, unit );
8510
8511					} else {
8512						e.custom( start, val, "" );
8513					}
8514				}
8515			}
8516
8517			// For JS strict compliance
8518			return true;
8519		}
8520
8521		return optall.queue === false ?
8522			this.each( doAnimation ) :
8523			this.queue( optall.queue, doAnimation );
8524	},
8525
8526	stop: function( type, clearQueue, gotoEnd ) {
8527		if ( typeof type !== "string" ) {
8528			gotoEnd = clearQueue;
8529			clearQueue = type;
8530			type = undefined;
8531		}
8532		if ( clearQueue && type !== false ) {
8533			this.queue( type || "fx", [] );
8534		}
8535
8536		return this.each(function() {
8537			var i,
8538				hadTimers = false,
8539				timers = jQuery.timers,
8540				data = jQuery._data( this );
8541
8542			// clear marker counters if we know they won't be
8543			if ( !gotoEnd ) {
8544				jQuery._unmark( true, this );
8545			}
8546
8547			function stopQueue( elem, data, i ) {
8548				var hooks = data[ i ];
8549				jQuery.removeData( elem, i, true );
8550				hooks.stop( gotoEnd );
8551			}
8552
8553			if ( type == null ) {
8554				for ( i in data ) {
8555					if ( data[ i ].stop && i.indexOf(".run") === i.length - 4 ) {
8556						stopQueue( this, data, i );
8557					}
8558				}
8559			} else if ( data[ i = type + ".run" ] && data[ i ].stop ){
8560				stopQueue( this, data, i );
8561			}
8562
8563			for ( i = timers.length; i--; ) {
8564				if ( timers[ i ].elem === this && (type == null || timers[ i ].queue === type) ) {
8565					if ( gotoEnd ) {
8566
8567						// force the next step to be the last
8568						timers[ i ]( true );
8569					} else {
8570						timers[ i ].saveState();
8571					}
8572					hadTimers = true;
8573					timers.splice( i, 1 );
8574				}
8575			}
8576
8577			// start the next in the queue if the last step wasn't forced
8578			// timers currently will call their complete callbacks, which will dequeue
8579			// but only if they were gotoEnd
8580			if ( !( gotoEnd && hadTimers ) ) {
8581				jQuery.dequeue( this, type );
8582			}
8583		});
8584	}
8585
8586});
8587
8588// Animations created synchronously will run synchronously
8589function createFxNow() {
8590	setTimeout( clearFxNow, 0 );
8591	return ( fxNow = jQuery.now() );
8592}
8593
8594function clearFxNow() {
8595	fxNow = undefined;
8596}
8597
8598// Generate parameters to create a standard animation
8599function genFx( type, num ) {
8600	var obj = {};
8601
8602	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() {
8603		obj[ this ] = type;
8604	});
8605
8606	return obj;
8607}
8608
8609// Generate shortcuts for custom animations
8610jQuery.each({
8611	slideDown: genFx( "show", 1 ),
8612	slideUp: genFx( "hide", 1 ),
8613	slideToggle: genFx( "toggle", 1 ),
8614	fadeIn: { opacity: "show" },
8615	fadeOut: { opacity: "hide" },
8616	fadeToggle: { opacity: "toggle" }
8617}, function( name, props ) {
8618	jQuery.fn[ name ] = function( speed, easing, callback ) {
8619		return this.animate( props, speed, easing, callback );
8620	};
8621});
8622
8623jQuery.extend({
8624	speed: function( speed, easing, fn ) {
8625		var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
8626			complete: fn || !fn && easing ||
8627				jQuery.isFunction( speed ) && speed,
8628			duration: speed,
8629			easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
8630		};
8631
8632		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8633			opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
8634
8635		// normalize opt.queue - true/undefined/null -> "fx"
8636		if ( opt.queue == null || opt.queue === true ) {
8637			opt.queue = "fx";
8638		}
8639
8640		// Queueing
8641		opt.old = opt.complete;
8642
8643		opt.complete = function( noUnmark ) {
8644			if ( jQuery.isFunction( opt.old ) ) {
8645				opt.old.call( this );
8646			}
8647
8648			if ( opt.queue ) {
8649				jQuery.dequeue( this, opt.queue );
8650			} else if ( noUnmark !== false ) {
8651				jQuery._unmark( this );
8652			}
8653		};
8654
8655		return opt;
8656	},
8657
8658	easing: {
8659		linear: function( p, n, firstNum, diff ) {
8660			return firstNum + diff * p;
8661		},
8662		swing: function( p, n, firstNum, diff ) {
8663			return ( ( -Math.cos( p*Math.PI ) / 2 ) + 0.5 ) * diff + firstNum;
8664		}
8665	},
8666
8667	timers: [],
8668
8669	fx: function( elem, options, prop ) {
8670		this.options = options;
8671		this.elem = elem;
8672		this.prop = prop;
8673
8674		options.orig = options.orig || {};
8675	}
8676
8677});
8678
8679jQuery.fx.prototype = {
8680	// Simple function for setting a style value
8681	update: function() {
8682		if ( this.options.step ) {
8683			this.options.step.call( this.elem, this.now, this );
8684		}
8685
8686		( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this );
8687	},
8688
8689	// Get the current size
8690	cur: function() {
8691		if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {
8692			return this.elem[ this.prop ];
8693		}
8694
8695		var parsed,
8696			r = jQuery.css( this.elem, this.prop );
8697		// Empty strings, null, undefined and "auto" are converted to 0,
8698		// complex values such as "rotate(1rad)" are returned as is,
8699		// simple values such as "10px" are parsed to Float.
8700		return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8701	},
8702
8703	// Start an animation from one number to another
8704	custom: function( from, to, unit ) {
8705		var self = this,
8706			fx = jQuery.fx;
8707
8708		this.startTime = fxNow || createFxNow();
8709		this.end = to;
8710		this.now = this.start = from;
8711		this.pos = this.state = 0;
8712		this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8713
8714		function t( gotoEnd ) {
8715			return self.step( gotoEnd );
8716		}
8717
8718		t.queue = this.options.queue;
8719		t.elem = this.elem;
8720		t.saveState = function() {
8721			if ( self.options.hide && jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {
8722				jQuery._data( self.elem, "fxshow" + self.prop, self.start );
8723			}
8724		};
8725
8726		if ( t() && jQuery.timers.push(t) && !timerId ) {
8727			timerId = setInterval( fx.tick, fx.interval );
8728		}
8729	},
8730
8731	// Simple 'show' function
8732	show: function() {
8733		var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );
8734
8735		// Remember where we started, so that we can go back to it later
8736		this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );
8737		this.options.show = true;
8738
8739		// Begin the animation
8740		// Make sure that we start at a small width/height to avoid any flash of content
8741		if ( dataShow !== undefined ) {
8742			// This show is picking up where a previous hide or show left off
8743			this.custom( this.cur(), dataShow );
8744		} else {
8745			this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );
8746		}
8747
8748		// Start by showing the element
8749		jQuery( this.elem ).show();
8750	},
8751
8752	// Simple 'hide' function
8753	hide: function() {
8754		// Remember where we started, so that we can go back to it later
8755		this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );
8756		this.options.hide = true;
8757
8758		// Begin the animation
8759		this.custom( this.cur(), 0 );
8760	},
8761
8762	// Each step of an animation
8763	step: function( gotoEnd ) {
8764		var p, n, complete,
8765			t = fxNow || createFxNow(),
8766			done = true,
8767			elem = this.elem,
8768			options = this.options;
8769
8770		if ( gotoEnd || t >= options.duration + this.startTime ) {
8771			this.now = this.end;
8772			this.pos = this.state = 1;
8773			this.update();
8774
8775			options.animatedProperties[ this.prop ] = true;
8776
8777			for ( p in options.animatedProperties ) {
8778				if ( options.animatedProperties[ p ] !== true ) {
8779					done = false;
8780				}
8781			}
8782
8783			if ( done ) {
8784				// Reset the overflow
8785				if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8786
8787					jQuery.each( [ "", "X", "Y" ], function( index, value ) {
8788						elem.style[ "overflow" + value ] = options.overflow[ index ];
8789					});
8790				}
8791
8792				// Hide the element if the "hide" operation was done
8793				if ( options.hide ) {
8794					jQuery( elem ).hide();
8795				}
8796
8797				// Reset the properties, if the item has been hidden or shown
8798				if ( options.hide || options.show ) {
8799					for ( p in options.animatedProperties ) {
8800						jQuery.style( elem, p, options.orig[ p ] );
8801						jQuery.removeData( elem, "fxshow" + p, true );
8802						// Toggle data is no longer needed
8803						jQuery.removeData( elem, "toggle" + p, true );
8804					}
8805				}
8806
8807				// Execute the complete function
8808				// in the event that the complete function throws an exception
8809				// we must ensure it won't be called twice. #5684
8810
8811				complete = options.complete;
8812				if ( complete ) {
8813
8814					options.complete = false;
8815					complete.call( elem );
8816				}
8817			}
8818
8819			return false;
8820
8821		} else {
8822			// classical easing cannot be used with an Infinity duration
8823			if ( options.duration == Infinity ) {
8824				this.now = t;
8825			} else {
8826				n = t - this.startTime;
8827				this.state = n / options.duration;
8828
8829				// Perform the easing function, defaults to swing
8830				this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );
8831				this.now = this.start + ( (this.end - this.start) * this.pos );
8832			}
8833			// Perform the next step of the animation
8834			this.update();
8835		}
8836
8837		return true;
8838	}
8839};
8840
8841jQuery.extend( jQuery.fx, {
8842	tick: function() {
8843		var timer,
8844			timers = jQuery.timers,
8845			i = 0;
8846
8847		for ( ; i < timers.length; i++ ) {
8848			timer = timers[ i ];
8849			// Checks the timer has not already been removed
8850			if ( !timer() && timers[ i ] === timer ) {
8851				timers.splice( i--, 1 );
8852			}
8853		}
8854
8855		if ( !timers.length ) {
8856			jQuery.fx.stop();
8857		}
8858	},
8859
8860	interval: 13,
8861
8862	stop: function() {
8863		clearInterval( timerId );
8864		timerId = null;
8865	},
8866
8867	speeds: {
8868		slow: 600,
8869		fast: 200,
8870		// Default speed
8871		_default: 400
8872	},
8873
8874	step: {
8875		opacity: function( fx ) {
8876			jQuery.style( fx.elem, "opacity", fx.now );
8877		},
8878
8879		_default: function( fx ) {
8880			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8881				fx.elem.style[ fx.prop ] = fx.now + fx.unit;
8882			} else {
8883				fx.elem[ fx.prop ] = fx.now;
8884			}
8885		}
8886	}
8887});
8888
8889// Adds width/height step functions
8890// Do not set anything below 0
8891jQuery.each([ "width", "height" ], function( i, prop ) {
8892	jQuery.fx.step[ prop ] = function( fx ) {
8893		jQuery.style( fx.elem, prop, Math.max(0, fx.now) );
8894	};
8895});
8896
8897if ( jQuery.expr && jQuery.expr.filters ) {
8898	jQuery.expr.filters.animated = function( elem ) {
8899		return jQuery.grep(jQuery.timers, function( fn ) {
8900			return elem === fn.elem;
8901		}).length;
8902	};
8903}
8904
8905// Try to restore the default display value of an element
8906function defaultDisplay( nodeName ) {
8907
8908	if ( !elemdisplay[ nodeName ] ) {
8909
8910		var body = document.body,
8911			elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
8912			display = elem.css( "display" );
8913		elem.remove();
8914
8915		// If the simple way fails,
8916		// get element's real default display by attaching it to a temp iframe
8917		if ( display === "none" || display === "" ) {
8918			// No iframe to use yet, so create it
8919			if ( !iframe ) {
8920				iframe = document.createElement( "iframe" );
8921				iframe.frameBorder = iframe.width = iframe.height = 0;
8922			}
8923
8924			body.appendChild( iframe );
8925
8926			// Create a cacheable copy of the iframe document on first call.
8927			// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
8928			// document to it; WebKit & Firefox won't allow reusing the iframe document.
8929			if ( !iframeDoc || !iframe.createElement ) {
8930				iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8931				iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
8932				iframeDoc.close();
8933			}
8934
8935			elem = iframeDoc.createElement( nodeName );
8936
8937			iframeDoc.body.appendChild( elem );
8938
8939			display = jQuery.css( elem, "display" );
8940			body.removeChild( iframe );
8941		}
8942
8943		// Store the correct default display
8944		elemdisplay[ nodeName ] = display;
8945	}
8946
8947	return elemdisplay[ nodeName ];
8948}
8949
8950
8951
8952
8953var rtable = /^t(?:able|d|h)$/i,
8954	rroot = /^(?:body|html)$/i;
8955
8956if ( "getBoundingClientRect" in document.documentElement ) {
8957	jQuery.fn.offset = function( options ) {
8958		var elem = this[0], box;
8959
8960		if ( options ) {
8961			return this.each(function( i ) {
8962				jQuery.offset.setOffset( this, options, i );
8963			});
8964		}
8965
8966		if ( !elem || !elem.ownerDocument ) {
8967			return null;
8968		}
8969
8970		if ( elem === elem.ownerDocument.body ) {
8971			return jQuery.offset.bodyOffset( elem );
8972		}
8973
8974		try {
8975			box = elem.getBoundingClientRect();
8976		} catch(e) {}
8977
8978		var doc = elem.ownerDocument,
8979			docElem = doc.documentElement;
8980
8981		// Make sure we're not dealing with a disconnected DOM node
8982		if ( !box || !jQuery.contains( docElem, elem ) ) {
8983			return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8984		}
8985
8986		var body = doc.body,
8987			win = getWindow(doc),
8988			clientTop  = docElem.clientTop  || body.clientTop  || 0,
8989			clientLeft = docElem.clientLeft || body.clientLeft || 0,
8990			scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
8991			scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8992			top  = box.top  + scrollTop  - clientTop,
8993			left = box.left + scrollLeft - clientLeft;
8994
8995		return { top: top, left: left };
8996	};
8997
8998} else {
8999	jQuery.fn.offset = function( options ) {
9000		var elem = this[0];
9001
9002		if ( options ) {
9003			return this.each(function( i ) {
9004				jQuery.offset.setOffset( this, options, i );
9005			});
9006		}
9007
9008		if ( !elem || !elem.ownerDocument ) {
9009			return null;
9010		}
9011
9012		if ( elem === elem.ownerDocument.body ) {
9013			return jQuery.offset.bodyOffset( elem );
9014		}
9015
9016		var computedStyle,
9017			offsetParent = elem.offsetParent,
9018			prevOffsetParent = elem,
9019			doc = elem.ownerDocument,
9020			docElem = doc.documentElement,
9021			body = doc.body,
9022			defaultView = doc.defaultView,
9023			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
9024			top = elem.offsetTop,
9025			left = elem.offsetLeft;
9026
9027		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
9028			if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
9029				break;
9030			}
9031
9032			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
9033			top  -= elem.scrollTop;
9034			left -= elem.scrollLeft;
9035
9036			if ( elem === offsetParent ) {
9037				top  += elem.offsetTop;
9038				left += elem.offsetLeft;
9039
9040				if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
9041					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
9042					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9043				}
9044
9045				prevOffsetParent = offsetParent;
9046				offsetParent = elem.offsetParent;
9047			}
9048
9049			if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
9050				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
9051				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9052			}
9053
9054			prevComputedStyle = computedStyle;
9055		}
9056
9057		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
9058			top  += body.offsetTop;
9059			left += body.offsetLeft;
9060		}
9061
9062		if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
9063			top  += Math.max( docElem.scrollTop, body.scrollTop );
9064			left += Math.max( docElem.scrollLeft, body.scrollLeft );
9065		}
9066
9067		return { top: top, left: left };
9068	};
9069}
9070
9071jQuery.offset = {
9072
9073	bodyOffset: function( body ) {
9074		var top = body.offsetTop,
9075			left = body.offsetLeft;
9076
9077		if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
9078			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9079			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9080		}
9081
9082		return { top: top, left: left };
9083	},
9084
9085	setOffset: function( elem, options, i ) {
9086		var position = jQuery.css( elem, "position" );
9087
9088		// set position first, in-case top/left are set even on static elem
9089		if ( position === "static" ) {
9090			elem.style.position = "relative";
9091		}
9092
9093		var curElem = jQuery( elem ),
9094			curOffset = curElem.offset(),
9095			curCSSTop = jQuery.css( elem, "top" ),
9096			curCSSLeft = jQuery.css( elem, "left" ),
9097			calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9098			props = {}, curPosition = {}, curTop, curLeft;
9099
9100		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9101		if ( calculatePosition ) {
9102			curPosition = curElem.position();
9103			curTop = curPosition.top;
9104			curLeft = curPosition.left;
9105		} else {
9106			curTop = parseFloat( curCSSTop ) || 0;
9107			curLeft = parseFloat( curCSSLeft ) || 0;
9108		}
9109
9110		if ( jQuery.isFunction( options ) ) {
9111			options = options.call( elem, i, curOffset );
9112		}
9113
9114		if ( options.top != null ) {
9115			props.top = ( options.top - curOffset.top ) + curTop;
9116		}
9117		if ( options.left != null ) {
9118			props.left = ( options.left - curOffset.left ) + curLeft;
9119		}
9120
9121		if ( "using" in options ) {
9122			options.using.call( elem, props );
9123		} else {
9124			curElem.css( props );
9125		}
9126	}
9127};
9128
9129
9130jQuery.fn.extend({
9131
9132	position: function() {
9133		if ( !this[0] ) {
9134			return null;
9135		}
9136
9137		var elem = this[0],
9138
9139		// Get *real* offsetParent
9140		offsetParent = this.offsetParent(),
9141
9142		// Get correct offsets
9143		offset       = this.offset(),
9144		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9145
9146		// Subtract element margins
9147		// note: when an element has margin: auto the offsetLeft and marginLeft
9148		// are the same in Safari causing offset.left to incorrectly be 0
9149		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9150		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9151
9152		// Add offsetParent borders
9153		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9154		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9155
9156		// Subtract the two offsets
9157		return {
9158			top:  offset.top  - parentOffset.top,
9159			left: offset.left - parentOffset.left
9160		};
9161	},
9162
9163	offsetParent: function() {
9164		return this.map(function() {
9165			var offsetParent = this.offsetParent || document.body;
9166			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9167				offsetParent = offsetParent.offsetParent;
9168			}
9169			return offsetParent;
9170		});
9171	}
9172});
9173
9174
9175// Create scrollLeft and scrollTop methods
9176jQuery.each( ["Left", "Top"], function( i, name ) {
9177	var method = "scroll" + name;
9178
9179	jQuery.fn[ method ] = function( val ) {
9180		var elem, win;
9181
9182		if ( val === undefined ) {
9183			elem = this[ 0 ];
9184
9185			if ( !elem ) {
9186				return null;
9187			}
9188
9189			win = getWindow( elem );
9190
9191			// Return the scroll offset
9192			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
9193				jQuery.support.boxModel && win.document.documentElement[ method ] ||
9194					win.document.body[ method ] :
9195				elem[ method ];
9196		}
9197
9198		// Set the scroll offset
9199		return this.each(function() {
9200			win = getWindow( this );
9201
9202			if ( win ) {
9203				win.scrollTo(
9204					!i ? val : jQuery( win ).scrollLeft(),
9205					 i ? val : jQuery( win ).scrollTop()
9206				);
9207
9208			} else {
9209				this[ method ] = val;
9210			}
9211		});
9212	};
9213});
9214
9215function getWindow( elem ) {
9216	return jQuery.isWindow( elem ) ?
9217		elem :
9218		elem.nodeType === 9 ?
9219			elem.defaultView || elem.parentWindow :
9220			false;
9221}
9222
9223
9224
9225
9226// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
9227jQuery.each([ "Height", "Width" ], function( i, name ) {
9228
9229	var type = name.toLowerCase();
9230
9231	// innerHeight and innerWidth
9232	jQuery.fn[ "inner" + name ] = function() {
9233		var elem = this[0];
9234		return elem ?
9235			elem.style ?
9236			parseFloat( jQuery.css( elem, type, "padding" ) ) :
9237			this[ type ]() :
9238			null;
9239	};
9240
9241	// outerHeight and outerWidth
9242	jQuery.fn[ "outer" + name ] = function( margin ) {
9243		var elem = this[0];
9244		return elem ?
9245			elem.style ?
9246			parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
9247			this[ type ]() :
9248			null;
9249	};
9250
9251	jQuery.fn[ type ] = function( size ) {
9252		// Get window width or height
9253		var elem = this[0];
9254		if ( !elem ) {
9255			return size == null ? null : this;
9256		}
9257
9258		if ( jQuery.isFunction( size ) ) {
9259			return this.each(function( i ) {
9260				var self = jQuery( this );
9261				self[ type ]( size.call( this, i, self[ type ]() ) );
9262			});
9263		}
9264
9265		if ( jQuery.isWindow( elem ) ) {
9266			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
9267			// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
9268			var docElemProp = elem.document.documentElement[ "client" + name ],
9269				body = elem.document.body;
9270			return elem.document.compatMode === "CSS1Compat" && docElemProp ||
9271				body && body[ "client" + name ] || docElemProp;
9272
9273		// Get document width or height
9274		} else if ( elem.nodeType === 9 ) {
9275			// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
9276			return Math.max(
9277				elem.documentElement["client" + name],
9278				elem.body["scroll" + name], elem.documentElement["scroll" + name],
9279				elem.body["offset" + name], elem.documentElement["offset" + name]
9280			);
9281
9282		// Get or set width or height on the element
9283		} else if ( size === undefined ) {
9284			var orig = jQuery.css( elem, type ),
9285				ret = parseFloat( orig );
9286
9287			return jQuery.isNumeric( ret ) ? ret : orig;
9288
9289		// Set the width or height on the element (default to pixels if value is unitless)
9290		} else {
9291			return this.css( type, typeof size === "string" ? size : size + "px" );
9292		}
9293	};
9294
9295});
9296
9297
9298// Expose jQuery to the global object
9299window.jQuery = window.$ = jQuery;
9300})( window );
9301