• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*!
2 * jQuery JavaScript Library v1.3.2
3 * http://jquery.com/
4 *
5 * Copyright (c) 2009 John Resig
6 * Dual licensed under the MIT and GPL licenses.
7 * http://docs.jquery.com/License
8 *
9 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
10 * Revision: 6246
11 */
12(function(){
13
14var
15	// Will speed up references to window, and allows munging its name.
16	window = this,
17	// Will speed up references to undefined, and allows munging its name.
18	undefined,
19	// Map over jQuery in case of overwrite
20	_jQuery = window.jQuery,
21	// Map over the $ in case of overwrite
22	_$ = window.$,
23
24	jQuery = window.jQuery = window.$ = function( selector, context ) {
25		// The jQuery object is actually just the init constructor 'enhanced'
26		return new jQuery.fn.init( selector, context );
27	},
28
29	// A simple way to check for HTML strings or ID strings
30	// (both of which we optimize for)
31	quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
32	// Is it a simple selector
33	isSimple = /^.[^:#\[\.,]*$/;
34
35jQuery.fn = jQuery.prototype = {
36	init: function( selector, context ) {
37		// Make sure that a selection was provided
38		selector = selector || document;
39
40		// Handle $(DOMElement)
41		if ( selector.nodeType ) {
42			this[0] = selector;
43			this.length = 1;
44			this.context = selector;
45			return this;
46		}
47		// Handle HTML strings
48		if ( typeof selector === "string" ) {
49			// Are we dealing with HTML string or an ID?
50			var match = quickExpr.exec( selector );
51
52			// Verify a match, and that no context was specified for #id
53			if ( match && (match[1] || !context) ) {
54
55				// HANDLE: $(html) -> $(array)
56				if ( match[1] )
57					selector = jQuery.clean( [ match[1] ], context );
58
59				// HANDLE: $("#id")
60				else {
61					var elem = document.getElementById( match[3] );
62
63					// Handle the case where IE and Opera return items
64					// by name instead of ID
65					if ( elem && elem.id != match[3] )
66						return jQuery().find( selector );
67
68					// Otherwise, we inject the element directly into the jQuery object
69					var ret = jQuery( elem || [] );
70					ret.context = document;
71					ret.selector = selector;
72					return ret;
73				}
74
75			// HANDLE: $(expr, [context])
76			// (which is just equivalent to: $(content).find(expr)
77			} else
78				return jQuery( context ).find( selector );
79
80		// HANDLE: $(function)
81		// Shortcut for document ready
82		} else if ( jQuery.isFunction( selector ) )
83			return jQuery( document ).ready( selector );
84
85		// Make sure that old selector state is passed along
86		if ( selector.selector && selector.context ) {
87			this.selector = selector.selector;
88			this.context = selector.context;
89		}
90
91		return this.setArray(jQuery.isArray( selector ) ?
92			selector :
93			jQuery.makeArray(selector));
94	},
95
96	// Start with an empty selector
97	selector: "",
98
99	// The current version of jQuery being used
100	jquery: "1.3.2",
101
102	// The number of elements contained in the matched element set
103	size: function() {
104		return this.length;
105	},
106
107	// Get the Nth element in the matched element set OR
108	// Get the whole matched element set as a clean array
109	get: function( num ) {
110		return num === undefined ?
111
112			// Return a 'clean' array
113			Array.prototype.slice.call( this ) :
114
115			// Return just the object
116			this[ num ];
117	},
118
119	// Take an array of elements and push it onto the stack
120	// (returning the new matched element set)
121	pushStack: function( elems, name, selector ) {
122		// Build a new jQuery matched element set
123		var ret = jQuery( elems );
124
125		// Add the old object onto the stack (as a reference)
126		ret.prevObject = this;
127
128		ret.context = this.context;
129
130		if ( name === "find" )
131			ret.selector = this.selector + (this.selector ? " " : "") + selector;
132		else if ( name )
133			ret.selector = this.selector + "." + name + "(" + selector + ")";
134
135		// Return the newly-formed element set
136		return ret;
137	},
138
139	// Force the current matched set of elements to become
140	// the specified array of elements (destroying the stack in the process)
141	// You should use pushStack() in order to do this, but maintain the stack
142	setArray: function( elems ) {
143		// Resetting the length to 0, then using the native Array push
144		// is a super-fast way to populate an object with array-like properties
145		this.length = 0;
146		Array.prototype.push.apply( this, elems );
147
148		return this;
149	},
150
151	// Execute a callback for every element in the matched set.
152	// (You can seed the arguments with an array of args, but this is
153	// only used internally.)
154	each: function( callback, args ) {
155		return jQuery.each( this, callback, args );
156	},
157
158	// Determine the position of an element within
159	// the matched set of elements
160	index: function( elem ) {
161		// Locate the position of the desired element
162		return jQuery.inArray(
163			// If it receives a jQuery object, the first element is used
164			elem && elem.jquery ? elem[0] : elem
165		, this );
166	},
167
168	attr: function( name, value, type ) {
169		var options = name;
170
171		// Look for the case where we're accessing a style value
172		if ( typeof name === "string" )
173			if ( value === undefined )
174				return this[0] && jQuery[ type || "attr" ]( this[0], name );
175
176			else {
177				options = {};
178				options[ name ] = value;
179			}
180
181		// Check to see if we're setting style values
182		return this.each(function(i){
183			// Set all the styles
184			for ( name in options )
185				jQuery.attr(
186					type ?
187						this.style :
188						this,
189					name, jQuery.prop( this, options[ name ], type, i, name )
190				);
191		});
192	},
193
194	css: function( key, value ) {
195		// ignore negative width and height values
196		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
197			value = undefined;
198		return this.attr( key, value, "curCSS" );
199	},
200
201	text: function( text ) {
202		if ( typeof text !== "object" && text != null )
203			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
204
205		var ret = "";
206
207		jQuery.each( text || this, function(){
208			jQuery.each( this.childNodes, function(){
209				if ( this.nodeType != 8 )
210					ret += this.nodeType != 1 ?
211						this.nodeValue :
212						jQuery.fn.text( [ this ] );
213			});
214		});
215
216		return ret;
217	},
218
219	wrapAll: function( html ) {
220		if ( this[0] ) {
221			// The elements to wrap the target around
222			var wrap = jQuery( html, this[0].ownerDocument ).clone();
223
224			if ( this[0].parentNode )
225				wrap.insertBefore( this[0] );
226
227			wrap.map(function(){
228				var elem = this;
229
230				while ( elem.firstChild )
231					elem = elem.firstChild;
232
233				return elem;
234			}).append(this);
235		}
236
237		return this;
238	},
239
240	wrapInner: function( html ) {
241		return this.each(function(){
242			jQuery( this ).contents().wrapAll( html );
243		});
244	},
245
246	wrap: function( html ) {
247		return this.each(function(){
248			jQuery( this ).wrapAll( html );
249		});
250	},
251
252	append: function() {
253		return this.domManip(arguments, true, function(elem){
254			if (this.nodeType == 1)
255				this.appendChild( elem );
256		});
257	},
258
259	prepend: function() {
260		return this.domManip(arguments, true, function(elem){
261			if (this.nodeType == 1)
262				this.insertBefore( elem, this.firstChild );
263		});
264	},
265
266	before: function() {
267		return this.domManip(arguments, false, function(elem){
268			this.parentNode.insertBefore( elem, this );
269		});
270	},
271
272	after: function() {
273		return this.domManip(arguments, false, function(elem){
274			this.parentNode.insertBefore( elem, this.nextSibling );
275		});
276	},
277
278	end: function() {
279		return this.prevObject || jQuery( [] );
280	},
281
282	// For internal use only.
283	// Behaves like an Array's method, not like a jQuery method.
284	push: [].push,
285	sort: [].sort,
286	splice: [].splice,
287
288	find: function( selector ) {
289		if ( this.length === 1 ) {
290			var ret = this.pushStack( [], "find", selector );
291			ret.length = 0;
292			jQuery.find( selector, this[0], ret );
293			return ret;
294		} else {
295			return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
296				return jQuery.find( selector, elem );
297			})), "find", selector );
298		}
299	},
300
301	clone: function( events ) {
302		// Do the clone
303		var ret = this.map(function(){
304			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
305				// IE copies events bound via attachEvent when
306				// using cloneNode. Calling detachEvent on the
307				// clone will also remove the events from the orignal
308				// In order to get around this, we use innerHTML.
309				// Unfortunately, this means some modifications to
310				// attributes in IE that are actually only stored
311				// as properties will not be copied (such as the
312				// the name attribute on an input).
313				var html = this.outerHTML;
314				if ( !html ) {
315					var div = this.ownerDocument.createElement("div");
316					div.appendChild( this.cloneNode(true) );
317					html = div.innerHTML;
318				}
319
320				return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
321			} else
322				return this.cloneNode(true);
323		});
324
325		// Copy the events from the original to the clone
326		if ( events === true ) {
327			var orig = this.find("*").andSelf(), i = 0;
328
329			ret.find("*").andSelf().each(function(){
330				if ( this.nodeName !== orig[i].nodeName )
331					return;
332
333				var events = jQuery.data( orig[i], "events" );
334
335				for ( var type in events ) {
336					for ( var handler in events[ type ] ) {
337						jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
338					}
339				}
340
341				i++;
342			});
343		}
344
345		// Return the cloned set
346		return ret;
347	},
348
349	filter: function( selector ) {
350		return this.pushStack(
351			jQuery.isFunction( selector ) &&
352			jQuery.grep(this, function(elem, i){
353				return selector.call( elem, i );
354			}) ||
355
356			jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
357				return elem.nodeType === 1;
358			}) ), "filter", selector );
359	},
360
361	closest: function( selector ) {
362		var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
363			closer = 0;
364
365		return this.map(function(){
366			var cur = this;
367			while ( cur && cur.ownerDocument ) {
368				if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
369					jQuery.data(cur, "closest", closer);
370					return cur;
371				}
372				cur = cur.parentNode;
373				closer++;
374			}
375		});
376	},
377
378	not: function( selector ) {
379		if ( typeof selector === "string" )
380			// test special case where just one selector is passed in
381			if ( isSimple.test( selector ) )
382				return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
383			else
384				selector = jQuery.multiFilter( selector, this );
385
386		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
387		return this.filter(function() {
388			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
389		});
390	},
391
392	add: function( selector ) {
393		return this.pushStack( jQuery.unique( jQuery.merge(
394			this.get(),
395			typeof selector === "string" ?
396				jQuery( selector ) :
397				jQuery.makeArray( selector )
398		)));
399	},
400
401	is: function( selector ) {
402		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
403	},
404
405	hasClass: function( selector ) {
406		return !!selector && this.is( "." + selector );
407	},
408
409	val: function( value ) {
410		if ( value === undefined ) {
411			var elem = this[0];
412
413			if ( elem ) {
414				if( jQuery.nodeName( elem, 'option' ) )
415					return (elem.attributes.value || {}).specified ? elem.value : elem.text;
416
417				// We need to handle select boxes special
418				if ( jQuery.nodeName( elem, "select" ) ) {
419					var index = elem.selectedIndex,
420						values = [],
421						options = elem.options,
422						one = elem.type == "select-one";
423
424					// Nothing was selected
425					if ( index < 0 )
426						return null;
427
428					// Loop through all the selected options
429					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
430						var option = options[ i ];
431
432						if ( option.selected ) {
433							// Get the specifc value for the option
434							value = jQuery(option).val();
435
436							// We don't need an array for one selects
437							if ( one )
438								return value;
439
440							// Multi-Selects return an array
441							values.push( value );
442						}
443					}
444
445					return values;
446				}
447
448				// Everything else, we just grab the value
449				return (elem.value || "").replace(/\r/g, "");
450
451			}
452
453			return undefined;
454		}
455
456		if ( typeof value === "number" )
457			value += '';
458
459		return this.each(function(){
460			if ( this.nodeType != 1 )
461				return;
462
463			if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
464				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
465					jQuery.inArray(this.name, value) >= 0);
466
467			else if ( jQuery.nodeName( this, "select" ) ) {
468				var values = jQuery.makeArray(value);
469
470				jQuery( "option", this ).each(function(){
471					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
472						jQuery.inArray( this.text, values ) >= 0);
473				});
474
475				if ( !values.length )
476					this.selectedIndex = -1;
477
478			} else
479				this.value = value;
480		});
481	},
482
483	html: function( value ) {
484		return value === undefined ?
485			(this[0] ?
486				this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
487				null) :
488			this.empty().append( value );
489	},
490
491	replaceWith: function( value ) {
492		return this.after( value ).remove();
493	},
494
495	eq: function( i ) {
496		return this.slice( i, +i + 1 );
497	},
498
499	slice: function() {
500		return this.pushStack( Array.prototype.slice.apply( this, arguments ),
501			"slice", Array.prototype.slice.call(arguments).join(",") );
502	},
503
504	map: function( callback ) {
505		return this.pushStack( jQuery.map(this, function(elem, i){
506			return callback.call( elem, i, elem );
507		}));
508	},
509
510	andSelf: function() {
511		return this.add( this.prevObject );
512	},
513
514	domManip: function( args, table, callback ) {
515		if ( this[0] ) {
516			var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
517				scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
518				first = fragment.firstChild;
519
520			if ( first )
521				for ( var i = 0, l = this.length; i < l; i++ )
522					callback.call( root(this[i], first), this.length > 1 || i > 0 ?
523							fragment.cloneNode(true) : fragment );
524
525			if ( scripts )
526				jQuery.each( scripts, evalScript );
527		}
528
529		return this;
530
531		function root( elem, cur ) {
532			return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
533				(elem.getElementsByTagName("tbody")[0] ||
534				elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
535				elem;
536		}
537	}
538};
539
540// Give the init function the jQuery prototype for later instantiation
541jQuery.fn.init.prototype = jQuery.fn;
542
543function evalScript( i, elem ) {
544	if ( elem.src )
545		jQuery.ajax({
546			url: elem.src,
547			async: false,
548			dataType: "script"
549		});
550
551	else
552		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
553
554	if ( elem.parentNode )
555		elem.parentNode.removeChild( elem );
556}
557
558function now(){
559	return +new Date;
560}
561
562jQuery.extend = jQuery.fn.extend = function() {
563	// copy reference to target object
564	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
565
566	// Handle a deep copy situation
567	if ( typeof target === "boolean" ) {
568		deep = target;
569		target = arguments[1] || {};
570		// skip the boolean and the target
571		i = 2;
572	}
573
574	// Handle case when target is a string or something (possible in deep copy)
575	if ( typeof target !== "object" && !jQuery.isFunction(target) )
576		target = {};
577
578	// extend jQuery itself if only one argument is passed
579	if ( length == i ) {
580		target = this;
581		--i;
582	}
583
584	for ( ; i < length; i++ )
585		// Only deal with non-null/undefined values
586		if ( (options = arguments[ i ]) != null )
587			// Extend the base object
588			for ( var name in options ) {
589				var src = target[ name ], copy = options[ name ];
590
591				// Prevent never-ending loop
592				if ( target === copy )
593					continue;
594
595				// Recurse if we're merging object values
596				if ( deep && copy && typeof copy === "object" && !copy.nodeType )
597					target[ name ] = jQuery.extend( deep,
598						// Never move original objects, clone them
599						src || ( copy.length != null ? [ ] : { } )
600					, copy );
601
602				// Don't bring in undefined values
603				else if ( copy !== undefined )
604					target[ name ] = copy;
605
606			}
607
608	// Return the modified object
609	return target;
610};
611
612// exclude the following css properties to add px
613var	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
614	// cache defaultView
615	defaultView = document.defaultView || {},
616	toString = Object.prototype.toString;
617
618jQuery.extend({
619	noConflict: function( deep ) {
620		window.$ = _$;
621
622		if ( deep )
623			window.jQuery = _jQuery;
624
625		return jQuery;
626	},
627
628	// See test/unit/core.js for details concerning isFunction.
629	// Since version 1.3, DOM methods and functions like alert
630	// aren't supported. They return false on IE (#2968).
631	isFunction: function( obj ) {
632		return toString.call(obj) === "[object Function]";
633	},
634
635	isArray: function( obj ) {
636		return toString.call(obj) === "[object Array]";
637	},
638
639	// check if an element is in a (or is an) XML document
640	isXMLDoc: function( elem ) {
641		return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
642			!!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
643	},
644
645	// Evalulates a script in a global context
646	globalEval: function( data ) {
647		if ( data && /\S/.test(data) ) {
648			// Inspired by code by Andrea Giammarchi
649			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
650			var head = document.getElementsByTagName("head")[0] || document.documentElement,
651				script = document.createElement("script");
652
653			script.type = "text/javascript";
654			if ( jQuery.support.scriptEval )
655				script.appendChild( document.createTextNode( data ) );
656			else
657				script.text = data;
658
659			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
660			// This arises when a base node is used (#2709).
661			head.insertBefore( script, head.firstChild );
662			head.removeChild( script );
663		}
664	},
665
666	nodeName: function( elem, name ) {
667		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
668	},
669
670	// args is for internal usage only
671	each: function( object, callback, args ) {
672		var name, i = 0, length = object.length;
673
674		if ( args ) {
675			if ( length === undefined ) {
676				for ( name in object )
677					if ( callback.apply( object[ name ], args ) === false )
678						break;
679			} else
680				for ( ; i < length; )
681					if ( callback.apply( object[ i++ ], args ) === false )
682						break;
683
684		// A special, fast, case for the most common use of each
685		} else {
686			if ( length === undefined ) {
687				for ( name in object )
688					if ( callback.call( object[ name ], name, object[ name ] ) === false )
689						break;
690			} else
691				for ( var value = object[0];
692					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
693		}
694
695		return object;
696	},
697
698	prop: function( elem, value, type, i, name ) {
699		// Handle executable functions
700		if ( jQuery.isFunction( value ) )
701			value = value.call( elem, i );
702
703		// Handle passing in a number to a CSS property
704		return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
705			value + "px" :
706			value;
707	},
708
709	className: {
710		// internal only, use addClass("class")
711		add: function( elem, classNames ) {
712			jQuery.each((classNames || "").split(/\s+/), function(i, className){
713				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
714					elem.className += (elem.className ? " " : "") + className;
715			});
716		},
717
718		// internal only, use removeClass("class")
719		remove: function( elem, classNames ) {
720			if (elem.nodeType == 1)
721				elem.className = classNames !== undefined ?
722					jQuery.grep(elem.className.split(/\s+/), function(className){
723						return !jQuery.className.has( classNames, className );
724					}).join(" ") :
725					"";
726		},
727
728		// internal only, use hasClass("class")
729		has: function( elem, className ) {
730			return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
731		}
732	},
733
734	// A method for quickly swapping in/out CSS properties to get correct calculations
735	swap: function( elem, options, callback ) {
736		var old = {};
737		// Remember the old values, and insert the new ones
738		for ( var name in options ) {
739			old[ name ] = elem.style[ name ];
740			elem.style[ name ] = options[ name ];
741		}
742
743		callback.call( elem );
744
745		// Revert the old values
746		for ( var name in options )
747			elem.style[ name ] = old[ name ];
748	},
749
750	css: function( elem, name, force, extra ) {
751		if ( name == "width" || name == "height" ) {
752			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
753
754			function getWH() {
755				val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
756
757				if ( extra === "border" )
758					return;
759
760				jQuery.each( which, function() {
761					if ( !extra )
762						val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
763					if ( extra === "margin" )
764						val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
765					else
766						val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
767				});
768			}
769
770			if ( elem.offsetWidth !== 0 )
771				getWH();
772			else
773				jQuery.swap( elem, props, getWH );
774
775			return Math.max(0, Math.round(val));
776		}
777
778		return jQuery.curCSS( elem, name, force );
779	},
780
781	curCSS: function( elem, name, force ) {
782		var ret, style = elem.style;
783
784		// We need to handle opacity special in IE
785		if ( name == "opacity" && !jQuery.support.opacity ) {
786			ret = jQuery.attr( style, "opacity" );
787
788			return ret == "" ?
789				"1" :
790				ret;
791		}
792
793		// Make sure we're using the right name for getting the float value
794		if ( name.match( /float/i ) )
795			name = styleFloat;
796
797		if ( !force && style && style[ name ] )
798			ret = style[ name ];
799
800		else if ( defaultView.getComputedStyle ) {
801
802			// Only "float" is needed here
803			if ( name.match( /float/i ) )
804				name = "float";
805
806			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
807
808			var computedStyle = defaultView.getComputedStyle( elem, null );
809
810			if ( computedStyle )
811				ret = computedStyle.getPropertyValue( name );
812
813			// We should always get a number back from opacity
814			if ( name == "opacity" && ret == "" )
815				ret = "1";
816
817		} else if ( elem.currentStyle ) {
818			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
819				return letter.toUpperCase();
820			});
821
822			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
823
824			// From the awesome hack by Dean Edwards
825			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
826
827			// If we're not dealing with a regular pixel number
828			// but a number that has a weird ending, we need to convert it to pixels
829			if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
830				// Remember the original values
831				var left = style.left, rsLeft = elem.runtimeStyle.left;
832
833				// Put in the new values to get a computed value out
834				elem.runtimeStyle.left = elem.currentStyle.left;
835				style.left = ret || 0;
836				ret = style.pixelLeft + "px";
837
838				// Revert the changed values
839				style.left = left;
840				elem.runtimeStyle.left = rsLeft;
841			}
842		}
843
844		return ret;
845	},
846
847	clean: function( elems, context, fragment ) {
848		context = context || document;
849
850		// !context.createElement fails in IE with an error but returns typeof 'object'
851		if ( typeof context.createElement === "undefined" )
852			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
853
854		// If a single string is passed in and it's a single tag
855		// just do a createElement and skip the rest
856		if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
857			var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
858			if ( match )
859				return [ context.createElement( match[1] ) ];
860		}
861
862		var ret = [], scripts = [], div = context.createElement("div");
863
864		jQuery.each(elems, function(i, elem){
865			if ( typeof elem === "number" )
866				elem += '';
867
868			if ( !elem )
869				return;
870
871			// Convert html string into DOM nodes
872			if ( typeof elem === "string" ) {
873				// Fix "XHTML"-style tags in all browsers
874				elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
875					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
876						all :
877						front + "></" + tag + ">";
878				});
879
880				// Trim whitespace, otherwise indexOf won't work as expected
881				var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
882
883				var wrap =
884					// option or optgroup
885					!tags.indexOf("<opt") &&
886					[ 1, "<select multiple='multiple'>", "</select>" ] ||
887
888					!tags.indexOf("<leg") &&
889					[ 1, "<fieldset>", "</fieldset>" ] ||
890
891					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
892					[ 1, "<table>", "</table>" ] ||
893
894					!tags.indexOf("<tr") &&
895					[ 2, "<table><tbody>", "</tbody></table>" ] ||
896
897				 	// <thead> matched above
898					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
899					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
900
901					!tags.indexOf("<col") &&
902					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
903
904					// IE can't serialize <link> and <script> tags normally
905					!jQuery.support.htmlSerialize &&
906					[ 1, "div<div>", "</div>" ] ||
907
908					[ 0, "", "" ];
909
910				// Go to html and back, then peel off extra wrappers
911				div.innerHTML = wrap[1] + elem + wrap[2];
912
913				// Move to the right depth
914				while ( wrap[0]-- )
915					div = div.lastChild;
916
917				// Remove IE's autoinserted <tbody> from table fragments
918				if ( !jQuery.support.tbody ) {
919
920					// String was a <table>, *may* have spurious <tbody>
921					var hasBody = /<tbody/i.test(elem),
922						tbody = !tags.indexOf("<table") && !hasBody ?
923							div.firstChild && div.firstChild.childNodes :
924
925						// String was a bare <thead> or <tfoot>
926						wrap[1] == "<table>" && !hasBody ?
927							div.childNodes :
928							[];
929
930					for ( var j = tbody.length - 1; j >= 0 ; --j )
931						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
932							tbody[ j ].parentNode.removeChild( tbody[ j ] );
933
934					}
935
936				// IE completely kills leading whitespace when innerHTML is used
937				if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
938					div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
939
940				elem = jQuery.makeArray( div.childNodes );
941			}
942
943			if ( elem.nodeType )
944				ret.push( elem );
945			else
946				ret = jQuery.merge( ret, elem );
947
948		});
949
950		if ( fragment ) {
951			for ( var i = 0; ret[i]; i++ ) {
952				if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
953					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
954				} else {
955					if ( ret[i].nodeType === 1 )
956						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
957					fragment.appendChild( ret[i] );
958				}
959			}
960
961			return scripts;
962		}
963
964		return ret;
965	},
966
967	attr: function( elem, name, value ) {
968		// don't set attributes on text and comment nodes
969		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
970			return undefined;
971
972		var notxml = !jQuery.isXMLDoc( elem ),
973			// Whether we are setting (or getting)
974			set = value !== undefined;
975
976		// Try to normalize/fix the name
977		name = notxml && jQuery.props[ name ] || name;
978
979		// Only do all the following if this is a node (faster for style)
980		// IE elem.getAttribute passes even for style
981		if ( elem.tagName ) {
982
983			// These attributes require special treatment
984			var special = /href|src|style/.test( name );
985
986			// Safari mis-reports the default selected property of a hidden option
987			// Accessing the parent's selectedIndex property fixes it
988			if ( name == "selected" && elem.parentNode )
989				elem.parentNode.selectedIndex;
990
991			// If applicable, access the attribute via the DOM 0 way
992			if ( name in elem && notxml && !special ) {
993				if ( set ){
994					// We can't allow the type property to be changed (since it causes problems in IE)
995					if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
996						throw "type property can't be changed";
997
998					elem[ name ] = value;
999				}
1000
1001				// browsers index elements by id/name on forms, give priority to attributes.
1002				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1003					return elem.getAttributeNode( name ).nodeValue;
1004
1005				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1006				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1007				if ( name == "tabIndex" ) {
1008					var attributeNode = elem.getAttributeNode( "tabIndex" );
1009					return attributeNode && attributeNode.specified
1010						? attributeNode.value
1011						: elem.nodeName.match(/(button|input|object|select|textarea)/i)
1012							? 0
1013							: elem.nodeName.match(/^(a|area)$/i) && elem.href
1014								? 0
1015								: undefined;
1016				}
1017
1018				return elem[ name ];
1019			}
1020
1021			if ( !jQuery.support.style && notxml &&  name == "style" )
1022				return jQuery.attr( elem.style, "cssText", value );
1023
1024			if ( set )
1025				// convert the value to a string (all browsers do this but IE) see #1070
1026				elem.setAttribute( name, "" + value );
1027
1028			var attr = !jQuery.support.hrefNormalized && notxml && special
1029					// Some attributes require a special call on IE
1030					? elem.getAttribute( name, 2 )
1031					: elem.getAttribute( name );
1032
1033			// Non-existent attributes return null, we normalize to undefined
1034			return attr === null ? undefined : attr;
1035		}
1036
1037		// elem is actually elem.style ... set the style
1038
1039		// IE uses filters for opacity
1040		if ( !jQuery.support.opacity && name == "opacity" ) {
1041			if ( set ) {
1042				// IE has trouble with opacity if it does not have layout
1043				// Force it by setting the zoom level
1044				elem.zoom = 1;
1045
1046				// Set the alpha filter to set the opacity
1047				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1048					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1049			}
1050
1051			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1052				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1053				"";
1054		}
1055
1056		name = name.replace(/-([a-z])/ig, function(all, letter){
1057			return letter.toUpperCase();
1058		});
1059
1060		if ( set )
1061			elem[ name ] = value;
1062
1063		return elem[ name ];
1064	},
1065
1066	trim: function( text ) {
1067		return (text || "").replace( /^\s+|\s+$/g, "" );
1068	},
1069
1070	makeArray: function( array ) {
1071		var ret = [];
1072
1073		if( array != null ){
1074			var i = array.length;
1075			// The window, strings (and functions) also have 'length'
1076			if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
1077				ret[0] = array;
1078			else
1079				while( i )
1080					ret[--i] = array[i];
1081		}
1082
1083		return ret;
1084	},
1085
1086	inArray: function( elem, array ) {
1087		for ( var i = 0, length = array.length; i < length; i++ )
1088		// Use === because on IE, window == document
1089			if ( array[ i ] === elem )
1090				return i;
1091
1092		return -1;
1093	},
1094
1095	merge: function( first, second ) {
1096		// We have to loop this way because IE & Opera overwrite the length
1097		// expando of getElementsByTagName
1098		var i = 0, elem, pos = first.length;
1099		// Also, we need to make sure that the correct elements are being returned
1100		// (IE returns comment nodes in a '*' query)
1101		if ( !jQuery.support.getAll ) {
1102			while ( (elem = second[ i++ ]) != null )
1103				if ( elem.nodeType != 8 )
1104					first[ pos++ ] = elem;
1105
1106		} else
1107			while ( (elem = second[ i++ ]) != null )
1108				first[ pos++ ] = elem;
1109
1110		return first;
1111	},
1112
1113	unique: function( array ) {
1114		var ret = [], done = {};
1115
1116		try {
1117
1118			for ( var i = 0, length = array.length; i < length; i++ ) {
1119				var id = jQuery.data( array[ i ] );
1120
1121				if ( !done[ id ] ) {
1122					done[ id ] = true;
1123					ret.push( array[ i ] );
1124				}
1125			}
1126
1127		} catch( e ) {
1128			ret = array;
1129		}
1130
1131		return ret;
1132	},
1133
1134	grep: function( elems, callback, inv ) {
1135		var ret = [];
1136
1137		// Go through the array, only saving the items
1138		// that pass the validator function
1139		for ( var i = 0, length = elems.length; i < length; i++ )
1140			if ( !inv != !callback( elems[ i ], i ) )
1141				ret.push( elems[ i ] );
1142
1143		return ret;
1144	},
1145
1146	map: function( elems, callback ) {
1147		var ret = [];
1148
1149		// Go through the array, translating each of the items to their
1150		// new value (or values).
1151		for ( var i = 0, length = elems.length; i < length; i++ ) {
1152			var value = callback( elems[ i ], i );
1153
1154			if ( value != null )
1155				ret[ ret.length ] = value;
1156		}
1157
1158		return ret.concat.apply( [], ret );
1159	}
1160});
1161
1162// Use of jQuery.browser is deprecated.
1163// It's included for backwards compatibility and plugins,
1164// although they should work to migrate away.
1165
1166var userAgent = navigator.userAgent.toLowerCase();
1167
1168// Figure out what browser is being used
1169jQuery.browser = {
1170	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1171	safari: /webkit/.test( userAgent ),
1172	opera: /opera/.test( userAgent ),
1173	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1174	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1175};
1176
1177jQuery.each({
1178	parent: function(elem){return elem.parentNode;},
1179	parents: function(elem){return jQuery.dir(elem,"parentNode");},
1180	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1181	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1182	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1183	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1184	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1185	children: function(elem){return jQuery.sibling(elem.firstChild);},
1186	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1187}, function(name, fn){
1188	jQuery.fn[ name ] = function( selector ) {
1189		var ret = jQuery.map( this, fn );
1190
1191		if ( selector && typeof selector == "string" )
1192			ret = jQuery.multiFilter( selector, ret );
1193
1194		return this.pushStack( jQuery.unique( ret ), name, selector );
1195	};
1196});
1197
1198jQuery.each({
1199	appendTo: "append",
1200	prependTo: "prepend",
1201	insertBefore: "before",
1202	insertAfter: "after",
1203	replaceAll: "replaceWith"
1204}, function(name, original){
1205	jQuery.fn[ name ] = function( selector ) {
1206		var ret = [], insert = jQuery( selector );
1207
1208		for ( var i = 0, l = insert.length; i < l; i++ ) {
1209			var elems = (i > 0 ? this.clone(true) : this).get();
1210			jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
1211			ret = ret.concat( elems );
1212		}
1213
1214		return this.pushStack( ret, name, selector );
1215	};
1216});
1217
1218jQuery.each({
1219	removeAttr: function( name ) {
1220		jQuery.attr( this, name, "" );
1221		if (this.nodeType == 1)
1222			this.removeAttribute( name );
1223	},
1224
1225	addClass: function( classNames ) {
1226		jQuery.className.add( this, classNames );
1227	},
1228
1229	removeClass: function( classNames ) {
1230		jQuery.className.remove( this, classNames );
1231	},
1232
1233	toggleClass: function( classNames, state ) {
1234		if( typeof state !== "boolean" )
1235			state = !jQuery.className.has( this, classNames );
1236		jQuery.className[ state ? "add" : "remove" ]( this, classNames );
1237	},
1238
1239	remove: function( selector ) {
1240		if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
1241			// Prevent memory leaks
1242			jQuery( "*", this ).add([this]).each(function(){
1243				jQuery.event.remove(this);
1244				jQuery.removeData(this);
1245			});
1246			if (this.parentNode)
1247				this.parentNode.removeChild( this );
1248		}
1249	},
1250
1251	empty: function() {
1252		// Remove element nodes and prevent memory leaks
1253		jQuery(this).children().remove();
1254
1255		// Remove any remaining nodes
1256		while ( this.firstChild )
1257			this.removeChild( this.firstChild );
1258	}
1259}, function(name, fn){
1260	jQuery.fn[ name ] = function(){
1261		return this.each( fn, arguments );
1262	};
1263});
1264
1265// Helper function used by the dimensions and offset modules
1266function num(elem, prop) {
1267	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1268}
1269var expando = "jQuery" + now(), uuid = 0, windowData = {};
1270
1271jQuery.extend({
1272	cache: {},
1273
1274	data: function( elem, name, data ) {
1275		elem = elem == window ?
1276			windowData :
1277			elem;
1278
1279		var id = elem[ expando ];
1280
1281		// Compute a unique ID for the element
1282		if ( !id )
1283			id = elem[ expando ] = ++uuid;
1284
1285		// Only generate the data cache if we're
1286		// trying to access or manipulate it
1287		if ( name && !jQuery.cache[ id ] )
1288			jQuery.cache[ id ] = {};
1289
1290		// Prevent overriding the named cache with undefined values
1291		if ( data !== undefined )
1292			jQuery.cache[ id ][ name ] = data;
1293
1294		// Return the named cache data, or the ID for the element
1295		return name ?
1296			jQuery.cache[ id ][ name ] :
1297			id;
1298	},
1299
1300	removeData: function( elem, name ) {
1301		elem = elem == window ?
1302			windowData :
1303			elem;
1304
1305		var id = elem[ expando ];
1306
1307		// If we want to remove a specific section of the element's data
1308		if ( name ) {
1309			if ( jQuery.cache[ id ] ) {
1310				// Remove the section of cache data
1311				delete jQuery.cache[ id ][ name ];
1312
1313				// If we've removed all the data, remove the element's cache
1314				name = "";
1315
1316				for ( name in jQuery.cache[ id ] )
1317					break;
1318
1319				if ( !name )
1320					jQuery.removeData( elem );
1321			}
1322
1323		// Otherwise, we want to remove all of the element's data
1324		} else {
1325			// Clean up the element expando
1326			try {
1327				delete elem[ expando ];
1328			} catch(e){
1329				// IE has trouble directly removing the expando
1330				// but it's ok with using removeAttribute
1331				if ( elem.removeAttribute )
1332					elem.removeAttribute( expando );
1333			}
1334
1335			// Completely remove the data cache
1336			delete jQuery.cache[ id ];
1337		}
1338	},
1339	queue: function( elem, type, data ) {
1340		if ( elem ){
1341
1342			type = (type || "fx") + "queue";
1343
1344			var q = jQuery.data( elem, type );
1345
1346			if ( !q || jQuery.isArray(data) )
1347				q = jQuery.data( elem, type, jQuery.makeArray(data) );
1348			else if( data )
1349				q.push( data );
1350
1351		}
1352		return q;
1353	},
1354
1355	dequeue: function( elem, type ){
1356		var queue = jQuery.queue( elem, type ),
1357			fn = queue.shift();
1358
1359		if( !type || type === "fx" )
1360			fn = queue[0];
1361
1362		if( fn !== undefined )
1363			fn.call(elem);
1364	}
1365});
1366
1367jQuery.fn.extend({
1368	data: function( key, value ){
1369		var parts = key.split(".");
1370		parts[1] = parts[1] ? "." + parts[1] : "";
1371
1372		if ( value === undefined ) {
1373			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1374
1375			if ( data === undefined && this.length )
1376				data = jQuery.data( this[0], key );
1377
1378			return data === undefined && parts[1] ?
1379				this.data( parts[0] ) :
1380				data;
1381		} else
1382			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1383				jQuery.data( this, key, value );
1384			});
1385	},
1386
1387	removeData: function( key ){
1388		return this.each(function(){
1389			jQuery.removeData( this, key );
1390		});
1391	},
1392	queue: function(type, data){
1393		if ( typeof type !== "string" ) {
1394			data = type;
1395			type = "fx";
1396		}
1397
1398		if ( data === undefined )
1399			return jQuery.queue( this[0], type );
1400
1401		return this.each(function(){
1402			var queue = jQuery.queue( this, type, data );
1403
1404			 if( type == "fx" && queue.length == 1 )
1405				queue[0].call(this);
1406		});
1407	},
1408	dequeue: function(type){
1409		return this.each(function(){
1410			jQuery.dequeue( this, type );
1411		});
1412	}
1413});/*!
1414 * Sizzle CSS Selector Engine - v0.9.3
1415 *  Copyright 2009, The Dojo Foundation
1416 *  Released under the MIT, BSD, and GPL Licenses.
1417 *  More information: http://sizzlejs.com/
1418 */
1419(function(){
1420
1421var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
1422	done = 0,
1423	toString = Object.prototype.toString;
1424
1425var Sizzle = function(selector, context, results, seed) {
1426	results = results || [];
1427	context = context || document;
1428
1429	if ( context.nodeType !== 1 && context.nodeType !== 9 )
1430		return [];
1431
1432	if ( !selector || typeof selector !== "string" ) {
1433		return results;
1434	}
1435
1436	var parts = [], m, set, checkSet, check, mode, extra, prune = true;
1437
1438	// Reset the position of the chunker regexp (start from head)
1439	chunker.lastIndex = 0;
1440
1441	while ( (m = chunker.exec(selector)) !== null ) {
1442		parts.push( m[1] );
1443
1444		if ( m[2] ) {
1445			extra = RegExp.rightContext;
1446			break;
1447		}
1448	}
1449
1450	if ( parts.length > 1 && origPOS.exec( selector ) ) {
1451		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
1452			set = posProcess( parts[0] + parts[1], context );
1453		} else {
1454			set = Expr.relative[ parts[0] ] ?
1455				[ context ] :
1456				Sizzle( parts.shift(), context );
1457
1458			while ( parts.length ) {
1459				selector = parts.shift();
1460
1461				if ( Expr.relative[ selector ] )
1462					selector += parts.shift();
1463
1464				set = posProcess( selector, set );
1465			}
1466		}
1467	} else {
1468		var ret = seed ?
1469			{ expr: parts.pop(), set: makeArray(seed) } :
1470			Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
1471		set = Sizzle.filter( ret.expr, ret.set );
1472
1473		if ( parts.length > 0 ) {
1474			checkSet = makeArray(set);
1475		} else {
1476			prune = false;
1477		}
1478
1479		while ( parts.length ) {
1480			var cur = parts.pop(), pop = cur;
1481
1482			if ( !Expr.relative[ cur ] ) {
1483				cur = "";
1484			} else {
1485				pop = parts.pop();
1486			}
1487
1488			if ( pop == null ) {
1489				pop = context;
1490			}
1491
1492			Expr.relative[ cur ]( checkSet, pop, isXML(context) );
1493		}
1494	}
1495
1496	if ( !checkSet ) {
1497		checkSet = set;
1498	}
1499
1500	if ( !checkSet ) {
1501		throw "Syntax error, unrecognized expression: " + (cur || selector);
1502	}
1503
1504	if ( toString.call(checkSet) === "[object Array]" ) {
1505		if ( !prune ) {
1506			results.push.apply( results, checkSet );
1507		} else if ( context.nodeType === 1 ) {
1508			for ( var i = 0; checkSet[i] != null; i++ ) {
1509				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
1510					results.push( set[i] );
1511				}
1512			}
1513		} else {
1514			for ( var i = 0; checkSet[i] != null; i++ ) {
1515				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
1516					results.push( set[i] );
1517				}
1518			}
1519		}
1520	} else {
1521		makeArray( checkSet, results );
1522	}
1523
1524	if ( extra ) {
1525		Sizzle( extra, context, results, seed );
1526
1527		if ( sortOrder ) {
1528			hasDuplicate = false;
1529			results.sort(sortOrder);
1530
1531			if ( hasDuplicate ) {
1532				for ( var i = 1; i < results.length; i++ ) {
1533					if ( results[i] === results[i-1] ) {
1534						results.splice(i--, 1);
1535					}
1536				}
1537			}
1538		}
1539	}
1540
1541	return results;
1542};
1543
1544Sizzle.matches = function(expr, set){
1545	return Sizzle(expr, null, null, set);
1546};
1547
1548Sizzle.find = function(expr, context, isXML){
1549	var set, match;
1550
1551	if ( !expr ) {
1552		return [];
1553	}
1554
1555	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
1556		var type = Expr.order[i], match;
1557
1558		if ( (match = Expr.match[ type ].exec( expr )) ) {
1559			var left = RegExp.leftContext;
1560
1561			if ( left.substr( left.length - 1 ) !== "\\" ) {
1562				match[1] = (match[1] || "").replace(/\\/g, "");
1563				set = Expr.find[ type ]( match, context, isXML );
1564				if ( set != null ) {
1565					expr = expr.replace( Expr.match[ type ], "" );
1566					break;
1567				}
1568			}
1569		}
1570	}
1571
1572	if ( !set ) {
1573		set = context.getElementsByTagName("*");
1574	}
1575
1576	return {set: set, expr: expr};
1577};
1578
1579Sizzle.filter = function(expr, set, inplace, not){
1580	var old = expr, result = [], curLoop = set, match, anyFound,
1581		isXMLFilter = set && set[0] && isXML(set[0]);
1582
1583	while ( expr && set.length ) {
1584		for ( var type in Expr.filter ) {
1585			if ( (match = Expr.match[ type ].exec( expr )) != null ) {
1586				var filter = Expr.filter[ type ], found, item;
1587				anyFound = false;
1588
1589				if ( curLoop == result ) {
1590					result = [];
1591				}
1592
1593				if ( Expr.preFilter[ type ] ) {
1594					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
1595
1596					if ( !match ) {
1597						anyFound = found = true;
1598					} else if ( match === true ) {
1599						continue;
1600					}
1601				}
1602
1603				if ( match ) {
1604					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
1605						if ( item ) {
1606							found = filter( item, match, i, curLoop );
1607							var pass = not ^ !!found;
1608
1609							if ( inplace && found != null ) {
1610								if ( pass ) {
1611									anyFound = true;
1612								} else {
1613									curLoop[i] = false;
1614								}
1615							} else if ( pass ) {
1616								result.push( item );
1617								anyFound = true;
1618							}
1619						}
1620					}
1621				}
1622
1623				if ( found !== undefined ) {
1624					if ( !inplace ) {
1625						curLoop = result;
1626					}
1627
1628					expr = expr.replace( Expr.match[ type ], "" );
1629
1630					if ( !anyFound ) {
1631						return [];
1632					}
1633
1634					break;
1635				}
1636			}
1637		}
1638
1639		// Improper expression
1640		if ( expr == old ) {
1641			if ( anyFound == null ) {
1642				throw "Syntax error, unrecognized expression: " + expr;
1643			} else {
1644				break;
1645			}
1646		}
1647
1648		old = expr;
1649	}
1650
1651	return curLoop;
1652};
1653
1654var Expr = Sizzle.selectors = {
1655	order: [ "ID", "NAME", "TAG" ],
1656	match: {
1657		ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1658		CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1659		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
1660		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
1661		TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
1662		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
1663		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
1664		PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
1665	},
1666	attrMap: {
1667		"class": "className",
1668		"for": "htmlFor"
1669	},
1670	attrHandle: {
1671		href: function(elem){
1672			return elem.getAttribute("href");
1673		}
1674	},
1675	relative: {
1676		"+": function(checkSet, part, isXML){
1677			var isPartStr = typeof part === "string",
1678				isTag = isPartStr && !/\W/.test(part),
1679				isPartStrNotTag = isPartStr && !isTag;
1680
1681			if ( isTag && !isXML ) {
1682				part = part.toUpperCase();
1683			}
1684
1685			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
1686				if ( (elem = checkSet[i]) ) {
1687					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
1688
1689					checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
1690						elem || false :
1691						elem === part;
1692				}
1693			}
1694
1695			if ( isPartStrNotTag ) {
1696				Sizzle.filter( part, checkSet, true );
1697			}
1698		},
1699		">": function(checkSet, part, isXML){
1700			var isPartStr = typeof part === "string";
1701
1702			if ( isPartStr && !/\W/.test(part) ) {
1703				part = isXML ? part : part.toUpperCase();
1704
1705				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1706					var elem = checkSet[i];
1707					if ( elem ) {
1708						var parent = elem.parentNode;
1709						checkSet[i] = parent.nodeName === part ? parent : false;
1710					}
1711				}
1712			} else {
1713				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1714					var elem = checkSet[i];
1715					if ( elem ) {
1716						checkSet[i] = isPartStr ?
1717							elem.parentNode :
1718							elem.parentNode === part;
1719					}
1720				}
1721
1722				if ( isPartStr ) {
1723					Sizzle.filter( part, checkSet, true );
1724				}
1725			}
1726		},
1727		"": function(checkSet, part, isXML){
1728			var doneName = done++, checkFn = dirCheck;
1729
1730			if ( !part.match(/\W/) ) {
1731				var nodeCheck = part = isXML ? part : part.toUpperCase();
1732				checkFn = dirNodeCheck;
1733			}
1734
1735			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1736		},
1737		"~": function(checkSet, part, isXML){
1738			var doneName = done++, checkFn = dirCheck;
1739
1740			if ( typeof part === "string" && !part.match(/\W/) ) {
1741				var nodeCheck = part = isXML ? part : part.toUpperCase();
1742				checkFn = dirNodeCheck;
1743			}
1744
1745			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
1746		}
1747	},
1748	find: {
1749		ID: function(match, context, isXML){
1750			if ( typeof context.getElementById !== "undefined" && !isXML ) {
1751				var m = context.getElementById(match[1]);
1752				return m ? [m] : [];
1753			}
1754		},
1755		NAME: function(match, context, isXML){
1756			if ( typeof context.getElementsByName !== "undefined" ) {
1757				var ret = [], results = context.getElementsByName(match[1]);
1758
1759				for ( var i = 0, l = results.length; i < l; i++ ) {
1760					if ( results[i].getAttribute("name") === match[1] ) {
1761						ret.push( results[i] );
1762					}
1763				}
1764
1765				return ret.length === 0 ? null : ret;
1766			}
1767		},
1768		TAG: function(match, context){
1769			return context.getElementsByTagName(match[1]);
1770		}
1771	},
1772	preFilter: {
1773		CLASS: function(match, curLoop, inplace, result, not, isXML){
1774			match = " " + match[1].replace(/\\/g, "") + " ";
1775
1776			if ( isXML ) {
1777				return match;
1778			}
1779
1780			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
1781				if ( elem ) {
1782					if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
1783						if ( !inplace )
1784							result.push( elem );
1785					} else if ( inplace ) {
1786						curLoop[i] = false;
1787					}
1788				}
1789			}
1790
1791			return false;
1792		},
1793		ID: function(match){
1794			return match[1].replace(/\\/g, "");
1795		},
1796		TAG: function(match, curLoop){
1797			for ( var i = 0; curLoop[i] === false; i++ ){}
1798			return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
1799		},
1800		CHILD: function(match){
1801			if ( match[1] == "nth" ) {
1802				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1803				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1804					match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
1805					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
1806
1807				// calculate the numbers (first)n+(last) including if they are negative
1808				match[2] = (test[1] + (test[2] || 1)) - 0;
1809				match[3] = test[3] - 0;
1810			}
1811
1812			// TODO: Move to normal caching system
1813			match[0] = done++;
1814
1815			return match;
1816		},
1817		ATTR: function(match, curLoop, inplace, result, not, isXML){
1818			var name = match[1].replace(/\\/g, "");
1819
1820			if ( !isXML && Expr.attrMap[name] ) {
1821				match[1] = Expr.attrMap[name];
1822			}
1823
1824			if ( match[2] === "~=" ) {
1825				match[4] = " " + match[4] + " ";
1826			}
1827
1828			return match;
1829		},
1830		PSEUDO: function(match, curLoop, inplace, result, not){
1831			if ( match[1] === "not" ) {
1832				// If we're dealing with a complex expression, or a simple one
1833				if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
1834					match[3] = Sizzle(match[3], null, null, curLoop);
1835				} else {
1836					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
1837					if ( !inplace ) {
1838						result.push.apply( result, ret );
1839					}
1840					return false;
1841				}
1842			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
1843				return true;
1844			}
1845
1846			return match;
1847		},
1848		POS: function(match){
1849			match.unshift( true );
1850			return match;
1851		}
1852	},
1853	filters: {
1854		enabled: function(elem){
1855			return elem.disabled === false && elem.type !== "hidden";
1856		},
1857		disabled: function(elem){
1858			return elem.disabled === true;
1859		},
1860		checked: function(elem){
1861			return elem.checked === true;
1862		},
1863		selected: function(elem){
1864			// Accessing this property makes selected-by-default
1865			// options in Safari work properly
1866			elem.parentNode.selectedIndex;
1867			return elem.selected === true;
1868		},
1869		parent: function(elem){
1870			return !!elem.firstChild;
1871		},
1872		empty: function(elem){
1873			return !elem.firstChild;
1874		},
1875		has: function(elem, i, match){
1876			return !!Sizzle( match[3], elem ).length;
1877		},
1878		header: function(elem){
1879			return /h\d/i.test( elem.nodeName );
1880		},
1881		text: function(elem){
1882			return "text" === elem.type;
1883		},
1884		radio: function(elem){
1885			return "radio" === elem.type;
1886		},
1887		checkbox: function(elem){
1888			return "checkbox" === elem.type;
1889		},
1890		file: function(elem){
1891			return "file" === elem.type;
1892		},
1893		password: function(elem){
1894			return "password" === elem.type;
1895		},
1896		submit: function(elem){
1897			return "submit" === elem.type;
1898		},
1899		image: function(elem){
1900			return "image" === elem.type;
1901		},
1902		reset: function(elem){
1903			return "reset" === elem.type;
1904		},
1905		button: function(elem){
1906			return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
1907		},
1908		input: function(elem){
1909			return /input|select|textarea|button/i.test(elem.nodeName);
1910		}
1911	},
1912	setFilters: {
1913		first: function(elem, i){
1914			return i === 0;
1915		},
1916		last: function(elem, i, match, array){
1917			return i === array.length - 1;
1918		},
1919		even: function(elem, i){
1920			return i % 2 === 0;
1921		},
1922		odd: function(elem, i){
1923			return i % 2 === 1;
1924		},
1925		lt: function(elem, i, match){
1926			return i < match[3] - 0;
1927		},
1928		gt: function(elem, i, match){
1929			return i > match[3] - 0;
1930		},
1931		nth: function(elem, i, match){
1932			return match[3] - 0 == i;
1933		},
1934		eq: function(elem, i, match){
1935			return match[3] - 0 == i;
1936		}
1937	},
1938	filter: {
1939		PSEUDO: function(elem, match, i, array){
1940			var name = match[1], filter = Expr.filters[ name ];
1941
1942			if ( filter ) {
1943				return filter( elem, i, match, array );
1944			} else if ( name === "contains" ) {
1945				return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
1946			} else if ( name === "not" ) {
1947				var not = match[3];
1948
1949				for ( var i = 0, l = not.length; i < l; i++ ) {
1950					if ( not[i] === elem ) {
1951						return false;
1952					}
1953				}
1954
1955				return true;
1956			}
1957		},
1958		CHILD: function(elem, match){
1959			var type = match[1], node = elem;
1960			switch (type) {
1961				case 'only':
1962				case 'first':
1963					while (node = node.previousSibling)  {
1964						if ( node.nodeType === 1 ) return false;
1965					}
1966					if ( type == 'first') return true;
1967					node = elem;
1968				case 'last':
1969					while (node = node.nextSibling)  {
1970						if ( node.nodeType === 1 ) return false;
1971					}
1972					return true;
1973				case 'nth':
1974					var first = match[2], last = match[3];
1975
1976					if ( first == 1 && last == 0 ) {
1977						return true;
1978					}
1979
1980					var doneName = match[0],
1981						parent = elem.parentNode;
1982
1983					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
1984						var count = 0;
1985						for ( node = parent.firstChild; node; node = node.nextSibling ) {
1986							if ( node.nodeType === 1 ) {
1987								node.nodeIndex = ++count;
1988							}
1989						}
1990						parent.sizcache = doneName;
1991					}
1992
1993					var diff = elem.nodeIndex - last;
1994					if ( first == 0 ) {
1995						return diff == 0;
1996					} else {
1997						return ( diff % first == 0 && diff / first >= 0 );
1998					}
1999			}
2000		},
2001		ID: function(elem, match){
2002			return elem.nodeType === 1 && elem.getAttribute("id") === match;
2003		},
2004		TAG: function(elem, match){
2005			return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
2006		},
2007		CLASS: function(elem, match){
2008			return (" " + (elem.className || elem.getAttribute("class")) + " ")
2009				.indexOf( match ) > -1;
2010		},
2011		ATTR: function(elem, match){
2012			var name = match[1],
2013				result = Expr.attrHandle[ name ] ?
2014					Expr.attrHandle[ name ]( elem ) :
2015					elem[ name ] != null ?
2016						elem[ name ] :
2017						elem.getAttribute( name ),
2018				value = result + "",
2019				type = match[2],
2020				check = match[4];
2021
2022			return result == null ?
2023				type === "!=" :
2024				type === "=" ?
2025				value === check :
2026				type === "*=" ?
2027				value.indexOf(check) >= 0 :
2028				type === "~=" ?
2029				(" " + value + " ").indexOf(check) >= 0 :
2030				!check ?
2031				value && result !== false :
2032				type === "!=" ?
2033				value != check :
2034				type === "^=" ?
2035				value.indexOf(check) === 0 :
2036				type === "$=" ?
2037				value.substr(value.length - check.length) === check :
2038				type === "|=" ?
2039				value === check || value.substr(0, check.length + 1) === check + "-" :
2040				false;
2041		},
2042		POS: function(elem, match, i, array){
2043			var name = match[2], filter = Expr.setFilters[ name ];
2044
2045			if ( filter ) {
2046				return filter( elem, i, match, array );
2047			}
2048		}
2049	}
2050};
2051
2052var origPOS = Expr.match.POS;
2053
2054for ( var type in Expr.match ) {
2055	Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
2056}
2057
2058var makeArray = function(array, results) {
2059	array = Array.prototype.slice.call( array );
2060
2061	if ( results ) {
2062		results.push.apply( results, array );
2063		return results;
2064	}
2065
2066	return array;
2067};
2068
2069// Perform a simple check to determine if the browser is capable of
2070// converting a NodeList to an array using builtin methods.
2071try {
2072	Array.prototype.slice.call( document.documentElement.childNodes );
2073
2074// Provide a fallback method if it does not work
2075} catch(e){
2076	makeArray = function(array, results) {
2077		var ret = results || [];
2078
2079		if ( toString.call(array) === "[object Array]" ) {
2080			Array.prototype.push.apply( ret, array );
2081		} else {
2082			if ( typeof array.length === "number" ) {
2083				for ( var i = 0, l = array.length; i < l; i++ ) {
2084					ret.push( array[i] );
2085				}
2086			} else {
2087				for ( var i = 0; array[i]; i++ ) {
2088					ret.push( array[i] );
2089				}
2090			}
2091		}
2092
2093		return ret;
2094	};
2095}
2096
2097var sortOrder;
2098
2099if ( document.documentElement.compareDocumentPosition ) {
2100	sortOrder = function( a, b ) {
2101		var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
2102		if ( ret === 0 ) {
2103			hasDuplicate = true;
2104		}
2105		return ret;
2106	};
2107} else if ( "sourceIndex" in document.documentElement ) {
2108	sortOrder = function( a, b ) {
2109		var ret = a.sourceIndex - b.sourceIndex;
2110		if ( ret === 0 ) {
2111			hasDuplicate = true;
2112		}
2113		return ret;
2114	};
2115} else if ( document.createRange ) {
2116	sortOrder = function( a, b ) {
2117		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
2118		aRange.selectNode(a);
2119		aRange.collapse(true);
2120		bRange.selectNode(b);
2121		bRange.collapse(true);
2122		var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
2123		if ( ret === 0 ) {
2124			hasDuplicate = true;
2125		}
2126		return ret;
2127	};
2128}
2129
2130// Check to see if the browser returns elements by name when
2131// querying by getElementById (and provide a workaround)
2132(function(){
2133	// We're going to inject a fake input element with a specified name
2134	var form = document.createElement("form"),
2135		id = "script" + (new Date).getTime();
2136	form.innerHTML = "<input name='" + id + "'/>";
2137
2138	// Inject it into the root element, check its status, and remove it quickly
2139	var root = document.documentElement;
2140	root.insertBefore( form, root.firstChild );
2141
2142	// The workaround has to do additional checks after a getElementById
2143	// Which slows things down for other browsers (hence the branching)
2144	if ( !!document.getElementById( id ) ) {
2145		Expr.find.ID = function(match, context, isXML){
2146			if ( typeof context.getElementById !== "undefined" && !isXML ) {
2147				var m = context.getElementById(match[1]);
2148				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
2149			}
2150		};
2151
2152		Expr.filter.ID = function(elem, match){
2153			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
2154			return elem.nodeType === 1 && node && node.nodeValue === match;
2155		};
2156	}
2157
2158	root.removeChild( form );
2159})();
2160
2161(function(){
2162	// Check to see if the browser returns only elements
2163	// when doing getElementsByTagName("*")
2164
2165	// Create a fake element
2166	var div = document.createElement("div");
2167	div.appendChild( document.createComment("") );
2168
2169	// Make sure no comments are found
2170	if ( div.getElementsByTagName("*").length > 0 ) {
2171		Expr.find.TAG = function(match, context){
2172			var results = context.getElementsByTagName(match[1]);
2173
2174			// Filter out possible comments
2175			if ( match[1] === "*" ) {
2176				var tmp = [];
2177
2178				for ( var i = 0; results[i]; i++ ) {
2179					if ( results[i].nodeType === 1 ) {
2180						tmp.push( results[i] );
2181					}
2182				}
2183
2184				results = tmp;
2185			}
2186
2187			return results;
2188		};
2189	}
2190
2191	// Check to see if an attribute returns normalized href attributes
2192	div.innerHTML = "<a href='#'></a>";
2193	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
2194			div.firstChild.getAttribute("href") !== "#" ) {
2195		Expr.attrHandle.href = function(elem){
2196			return elem.getAttribute("href", 2);
2197		};
2198	}
2199})();
2200
2201if ( document.querySelectorAll ) (function(){
2202	var oldSizzle = Sizzle, div = document.createElement("div");
2203	div.innerHTML = "<p class='TEST'></p>";
2204
2205	// Safari can't handle uppercase or unicode characters when
2206	// in quirks mode.
2207	if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
2208		return;
2209	}
2210
2211	Sizzle = function(query, context, extra, seed){
2212		context = context || document;
2213
2214		// Only use querySelectorAll on non-XML documents
2215		// (ID selectors don't work in non-HTML documents)
2216		if ( !seed && context.nodeType === 9 && !isXML(context) ) {
2217			try {
2218				return makeArray( context.querySelectorAll(query), extra );
2219			} catch(e){}
2220		}
2221
2222		return oldSizzle(query, context, extra, seed);
2223	};
2224
2225	Sizzle.find = oldSizzle.find;
2226	Sizzle.filter = oldSizzle.filter;
2227	Sizzle.selectors = oldSizzle.selectors;
2228	Sizzle.matches = oldSizzle.matches;
2229})();
2230
2231if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
2232	var div = document.createElement("div");
2233	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
2234
2235	// Opera can't find a second classname (in 9.6)
2236	if ( div.getElementsByClassName("e").length === 0 )
2237		return;
2238
2239	// Safari caches class attributes, doesn't catch changes (in 3.2)
2240	div.lastChild.className = "e";
2241
2242	if ( div.getElementsByClassName("e").length === 1 )
2243		return;
2244
2245	Expr.order.splice(1, 0, "CLASS");
2246	Expr.find.CLASS = function(match, context, isXML) {
2247		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
2248			return context.getElementsByClassName(match[1]);
2249		}
2250	};
2251})();
2252
2253function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2254	var sibDir = dir == "previousSibling" && !isXML;
2255	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2256		var elem = checkSet[i];
2257		if ( elem ) {
2258			if ( sibDir && elem.nodeType === 1 ){
2259				elem.sizcache = doneName;
2260				elem.sizset = i;
2261			}
2262			elem = elem[dir];
2263			var match = false;
2264
2265			while ( elem ) {
2266				if ( elem.sizcache === doneName ) {
2267					match = checkSet[elem.sizset];
2268					break;
2269				}
2270
2271				if ( elem.nodeType === 1 && !isXML ){
2272					elem.sizcache = doneName;
2273					elem.sizset = i;
2274				}
2275
2276				if ( elem.nodeName === cur ) {
2277					match = elem;
2278					break;
2279				}
2280
2281				elem = elem[dir];
2282			}
2283
2284			checkSet[i] = match;
2285		}
2286	}
2287}
2288
2289function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2290	var sibDir = dir == "previousSibling" && !isXML;
2291	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2292		var elem = checkSet[i];
2293		if ( elem ) {
2294			if ( sibDir && elem.nodeType === 1 ) {
2295				elem.sizcache = doneName;
2296				elem.sizset = i;
2297			}
2298			elem = elem[dir];
2299			var match = false;
2300
2301			while ( elem ) {
2302				if ( elem.sizcache === doneName ) {
2303					match = checkSet[elem.sizset];
2304					break;
2305				}
2306
2307				if ( elem.nodeType === 1 ) {
2308					if ( !isXML ) {
2309						elem.sizcache = doneName;
2310						elem.sizset = i;
2311					}
2312					if ( typeof cur !== "string" ) {
2313						if ( elem === cur ) {
2314							match = true;
2315							break;
2316						}
2317
2318					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
2319						match = elem;
2320						break;
2321					}
2322				}
2323
2324				elem = elem[dir];
2325			}
2326
2327			checkSet[i] = match;
2328		}
2329	}
2330}
2331
2332var contains = document.compareDocumentPosition ?  function(a, b){
2333	return a.compareDocumentPosition(b) & 16;
2334} : function(a, b){
2335	return a !== b && (a.contains ? a.contains(b) : true);
2336};
2337
2338var isXML = function(elem){
2339	return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
2340		!!elem.ownerDocument && isXML( elem.ownerDocument );
2341};
2342
2343var posProcess = function(selector, context){
2344	var tmpSet = [], later = "", match,
2345		root = context.nodeType ? [context] : context;
2346
2347	// Position selectors must be done after the filter
2348	// And so must :not(positional) so we move all PSEUDOs to the end
2349	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
2350		later += match[0];
2351		selector = selector.replace( Expr.match.PSEUDO, "" );
2352	}
2353
2354	selector = Expr.relative[selector] ? selector + "*" : selector;
2355
2356	for ( var i = 0, l = root.length; i < l; i++ ) {
2357		Sizzle( selector, root[i], tmpSet );
2358	}
2359
2360	return Sizzle.filter( later, tmpSet );
2361};
2362
2363// EXPOSE
2364jQuery.find = Sizzle;
2365jQuery.filter = Sizzle.filter;
2366jQuery.expr = Sizzle.selectors;
2367jQuery.expr[":"] = jQuery.expr.filters;
2368
2369Sizzle.selectors.filters.hidden = function(elem){
2370	return elem.offsetWidth === 0 || elem.offsetHeight === 0;
2371};
2372
2373Sizzle.selectors.filters.visible = function(elem){
2374	return elem.offsetWidth > 0 || elem.offsetHeight > 0;
2375};
2376
2377Sizzle.selectors.filters.animated = function(elem){
2378	return jQuery.grep(jQuery.timers, function(fn){
2379		return elem === fn.elem;
2380	}).length;
2381};
2382
2383jQuery.multiFilter = function( expr, elems, not ) {
2384	if ( not ) {
2385		expr = ":not(" + expr + ")";
2386	}
2387
2388	return Sizzle.matches(expr, elems);
2389};
2390
2391jQuery.dir = function( elem, dir ){
2392	var matched = [], cur = elem[dir];
2393	while ( cur && cur != document ) {
2394		if ( cur.nodeType == 1 )
2395			matched.push( cur );
2396		cur = cur[dir];
2397	}
2398	return matched;
2399};
2400
2401jQuery.nth = function(cur, result, dir, elem){
2402	result = result || 1;
2403	var num = 0;
2404
2405	for ( ; cur; cur = cur[dir] )
2406		if ( cur.nodeType == 1 && ++num == result )
2407			break;
2408
2409	return cur;
2410};
2411
2412jQuery.sibling = function(n, elem){
2413	var r = [];
2414
2415	for ( ; n; n = n.nextSibling ) {
2416		if ( n.nodeType == 1 && n != elem )
2417			r.push( n );
2418	}
2419
2420	return r;
2421};
2422
2423return;
2424
2425window.Sizzle = Sizzle;
2426
2427})();
2428/*
2429 * A number of helper functions used for managing events.
2430 * Many of the ideas behind this code originated from
2431 * Dean Edwards' addEvent library.
2432 */
2433jQuery.event = {
2434
2435	// Bind an event to an element
2436	// Original by Dean Edwards
2437	add: function(elem, types, handler, data) {
2438		if ( elem.nodeType == 3 || elem.nodeType == 8 )
2439			return;
2440
2441		// For whatever reason, IE has trouble passing the window object
2442		// around, causing it to be cloned in the process
2443		if ( elem.setInterval && elem != window )
2444			elem = window;
2445
2446		// Make sure that the function being executed has a unique ID
2447		if ( !handler.guid )
2448			handler.guid = this.guid++;
2449
2450		// if data is passed, bind to handler
2451		if ( data !== undefined ) {
2452			// Create temporary function pointer to original handler
2453			var fn = handler;
2454
2455			// Create unique handler function, wrapped around original handler
2456			handler = this.proxy( fn );
2457
2458			// Store data in unique handler
2459			handler.data = data;
2460		}
2461
2462		// Init the element's event structure
2463		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
2464			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
2465				// Handle the second event of a trigger and when
2466				// an event is called after a page has unloaded
2467				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
2468					jQuery.event.handle.apply(arguments.callee.elem, arguments) :
2469					undefined;
2470			});
2471		// Add elem as a property of the handle function
2472		// This is to prevent a memory leak with non-native
2473		// event in IE.
2474		handle.elem = elem;
2475
2476		// Handle multiple events separated by a space
2477		// jQuery(...).bind("mouseover mouseout", fn);
2478		jQuery.each(types.split(/\s+/), function(index, type) {
2479			// Namespaced event handlers
2480			var namespaces = type.split(".");
2481			type = namespaces.shift();
2482			handler.type = namespaces.slice().sort().join(".");
2483
2484			// Get the current list of functions bound to this event
2485			var handlers = events[type];
2486
2487			if ( jQuery.event.specialAll[type] )
2488				jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
2489
2490			// Init the event handler queue
2491			if (!handlers) {
2492				handlers = events[type] = {};
2493
2494				// Check for a special event handler
2495				// Only use addEventListener/attachEvent if the special
2496				// events handler returns false
2497				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
2498					// Bind the global event handler to the element
2499					if (elem.addEventListener)
2500						elem.addEventListener(type, handle, false);
2501					else if (elem.attachEvent)
2502						elem.attachEvent("on" + type, handle);
2503				}
2504			}
2505
2506			// Add the function to the element's handler list
2507			handlers[handler.guid] = handler;
2508
2509			// Keep track of which events have been used, for global triggering
2510			jQuery.event.global[type] = true;
2511		});
2512
2513		// Nullify elem to prevent memory leaks in IE
2514		elem = null;
2515	},
2516
2517	guid: 1,
2518	global: {},
2519
2520	// Detach an event or set of events from an element
2521	remove: function(elem, types, handler) {
2522		// don't do events on text and comment nodes
2523		if ( elem.nodeType == 3 || elem.nodeType == 8 )
2524			return;
2525
2526		var events = jQuery.data(elem, "events"), ret, index;
2527
2528		if ( events ) {
2529			// Unbind all events for the element
2530			if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
2531				for ( var type in events )
2532					this.remove( elem, type + (types || "") );
2533			else {
2534				// types is actually an event object here
2535				if ( types.type ) {
2536					handler = types.handler;
2537					types = types.type;
2538				}
2539
2540				// Handle multiple events seperated by a space
2541				// jQuery(...).unbind("mouseover mouseout", fn);
2542				jQuery.each(types.split(/\s+/), function(index, type){
2543					// Namespaced event handlers
2544					var namespaces = type.split(".");
2545					type = namespaces.shift();
2546					var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2547
2548					if ( events[type] ) {
2549						// remove the given handler for the given type
2550						if ( handler )
2551							delete events[type][handler.guid];
2552
2553						// remove all handlers for the given type
2554						else
2555							for ( var handle in events[type] )
2556								// Handle the removal of namespaced events
2557								if ( namespace.test(events[type][handle].type) )
2558									delete events[type][handle];
2559
2560						if ( jQuery.event.specialAll[type] )
2561							jQuery.event.specialAll[type].teardown.call(elem, namespaces);
2562
2563						// remove generic event handler if no more handlers exist
2564						for ( ret in events[type] ) break;
2565						if ( !ret ) {
2566							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
2567								if (elem.removeEventListener)
2568									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
2569								else if (elem.detachEvent)
2570									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
2571							}
2572							ret = null;
2573							delete events[type];
2574						}
2575					}
2576				});
2577			}
2578
2579			// Remove the expando if it's no longer used
2580			for ( ret in events ) break;
2581			if ( !ret ) {
2582				var handle = jQuery.data( elem, "handle" );
2583				if ( handle ) handle.elem = null;
2584				jQuery.removeData( elem, "events" );
2585				jQuery.removeData( elem, "handle" );
2586			}
2587		}
2588	},
2589
2590	// bubbling is internal
2591	trigger: function( event, data, elem, bubbling ) {
2592		// Event object or event type
2593		var type = event.type || event;
2594
2595		if( !bubbling ){
2596			event = typeof event === "object" ?
2597				// jQuery.Event object
2598				event[expando] ? event :
2599				// Object literal
2600				jQuery.extend( jQuery.Event(type), event ) :
2601				// Just the event type (string)
2602				jQuery.Event(type);
2603
2604			if ( type.indexOf("!") >= 0 ) {
2605				event.type = type = type.slice(0, -1);
2606				event.exclusive = true;
2607			}
2608
2609			// Handle a global trigger
2610			if ( !elem ) {
2611				// Don't bubble custom events when global (to avoid too much overhead)
2612				event.stopPropagation();
2613				// Only trigger if we've ever bound an event for it
2614				if ( this.global[type] )
2615					jQuery.each( jQuery.cache, function(){
2616						if ( this.events && this.events[type] )
2617							jQuery.event.trigger( event, data, this.handle.elem );
2618					});
2619			}
2620
2621			// Handle triggering a single element
2622
2623			// don't do events on text and comment nodes
2624			if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
2625				return undefined;
2626
2627			// Clean up in case it is reused
2628			event.result = undefined;
2629			event.target = elem;
2630
2631			// Clone the incoming data, if any
2632			data = jQuery.makeArray(data);
2633			data.unshift( event );
2634		}
2635
2636		event.currentTarget = elem;
2637
2638		// Trigger the event, it is assumed that "handle" is a function
2639		var handle = jQuery.data(elem, "handle");
2640		if ( handle )
2641			handle.apply( elem, data );
2642
2643		// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2644		if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2645			event.result = false;
2646
2647		// Trigger the native events (except for clicks on links)
2648		if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2649			this.triggered = true;
2650			try {
2651				elem[ type ]();
2652			// prevent IE from throwing an error for some hidden elements
2653			} catch (e) {}
2654		}
2655
2656		this.triggered = false;
2657
2658		if ( !event.isPropagationStopped() ) {
2659			var parent = elem.parentNode || elem.ownerDocument;
2660			if ( parent )
2661				jQuery.event.trigger(event, data, parent, true);
2662		}
2663	},
2664
2665	handle: function(event) {
2666		// returned undefined or false
2667		var all, handlers;
2668
2669		event = arguments[0] = jQuery.event.fix( event || window.event );
2670		event.currentTarget = this;
2671
2672		// Namespaced event handlers
2673		var namespaces = event.type.split(".");
2674		event.type = namespaces.shift();
2675
2676		// Cache this now, all = true means, any handler
2677		all = !namespaces.length && !event.exclusive;
2678
2679		var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2680
2681		handlers = ( jQuery.data(this, "events") || {} )[event.type];
2682
2683		for ( var j in handlers ) {
2684			var handler = handlers[j];
2685
2686			// Filter the functions by class
2687			if ( all || namespace.test(handler.type) ) {
2688				// Pass in a reference to the handler function itself
2689				// So that we can later remove it
2690				event.handler = handler;
2691				event.data = handler.data;
2692
2693				var ret = handler.apply(this, arguments);
2694
2695				if( ret !== undefined ){
2696					event.result = ret;
2697					if ( ret === false ) {
2698						event.preventDefault();
2699						event.stopPropagation();
2700					}
2701				}
2702
2703				if( event.isImmediatePropagationStopped() )
2704					break;
2705
2706			}
2707		}
2708	},
2709
2710	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2711
2712	fix: function(event) {
2713		if ( event[expando] )
2714			return event;
2715
2716		// store a copy of the original event object
2717		// and "clone" to set read-only properties
2718		var originalEvent = event;
2719		event = jQuery.Event( originalEvent );
2720
2721		for ( var i = this.props.length, prop; i; ){
2722			prop = this.props[ --i ];
2723			event[ prop ] = originalEvent[ prop ];
2724		}
2725
2726		// Fix target property, if necessary
2727		if ( !event.target )
2728			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2729
2730		// check if target is a textnode (safari)
2731		if ( event.target.nodeType == 3 )
2732			event.target = event.target.parentNode;
2733
2734		// Add relatedTarget, if necessary
2735		if ( !event.relatedTarget && event.fromElement )
2736			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2737
2738		// Calculate pageX/Y if missing and clientX/Y available
2739		if ( event.pageX == null && event.clientX != null ) {
2740			var doc = document.documentElement, body = document.body;
2741			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2742			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2743		}
2744
2745		// Add which for key events
2746		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2747			event.which = event.charCode || event.keyCode;
2748
2749		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2750		if ( !event.metaKey && event.ctrlKey )
2751			event.metaKey = event.ctrlKey;
2752
2753		// Add which for click: 1 == left; 2 == middle; 3 == right
2754		// Note: button is not normalized, so don't use it
2755		if ( !event.which && event.button )
2756			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2757
2758		return event;
2759	},
2760
2761	proxy: function( fn, proxy ){
2762		proxy = proxy || function(){ return fn.apply(this, arguments); };
2763		// Set the guid of unique handler to the same of original handler, so it can be removed
2764		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2765		// So proxy can be declared as an argument
2766		return proxy;
2767	},
2768
2769	special: {
2770		ready: {
2771			// Make sure the ready event is setup
2772			setup: bindReady,
2773			teardown: function() {}
2774		}
2775	},
2776
2777	specialAll: {
2778		live: {
2779			setup: function( selector, namespaces ){
2780				jQuery.event.add( this, namespaces[0], liveHandler );
2781			},
2782			teardown:  function( namespaces ){
2783				if ( namespaces.length ) {
2784					var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
2785
2786					jQuery.each( (jQuery.data(this, "events").live || {}), function(){
2787						if ( name.test(this.type) )
2788							remove++;
2789					});
2790
2791					if ( remove < 1 )
2792						jQuery.event.remove( this, namespaces[0], liveHandler );
2793				}
2794			}
2795		}
2796	}
2797};
2798
2799jQuery.Event = function( src ){
2800	// Allow instantiation without the 'new' keyword
2801	if( !this.preventDefault )
2802		return new jQuery.Event(src);
2803
2804	// Event object
2805	if( src && src.type ){
2806		this.originalEvent = src;
2807		this.type = src.type;
2808	// Event type
2809	}else
2810		this.type = src;
2811
2812	// timeStamp is buggy for some events on Firefox(#3843)
2813	// So we won't rely on the native value
2814	this.timeStamp = now();
2815
2816	// Mark it as fixed
2817	this[expando] = true;
2818};
2819
2820function returnFalse(){
2821	return false;
2822}
2823function returnTrue(){
2824	return true;
2825}
2826
2827// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2828// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2829jQuery.Event.prototype = {
2830	preventDefault: function() {
2831		this.isDefaultPrevented = returnTrue;
2832
2833		var e = this.originalEvent;
2834		if( !e )
2835			return;
2836		// if preventDefault exists run it on the original event
2837		if (e.preventDefault)
2838			e.preventDefault();
2839		// otherwise set the returnValue property of the original event to false (IE)
2840		e.returnValue = false;
2841	},
2842	stopPropagation: function() {
2843		this.isPropagationStopped = returnTrue;
2844
2845		var e = this.originalEvent;
2846		if( !e )
2847			return;
2848		// if stopPropagation exists run it on the original event
2849		if (e.stopPropagation)
2850			e.stopPropagation();
2851		// otherwise set the cancelBubble property of the original event to true (IE)
2852		e.cancelBubble = true;
2853	},
2854	stopImmediatePropagation:function(){
2855		this.isImmediatePropagationStopped = returnTrue;
2856		this.stopPropagation();
2857	},
2858	isDefaultPrevented: returnFalse,
2859	isPropagationStopped: returnFalse,
2860	isImmediatePropagationStopped: returnFalse
2861};
2862// Checks if an event happened on an element within another element
2863// Used in jQuery.event.special.mouseenter and mouseleave handlers
2864var withinElement = function(event) {
2865	// Check if mouse(over|out) are still within the same parent element
2866	var parent = event.relatedTarget;
2867	// Traverse up the tree
2868	while ( parent && parent != this )
2869		try { parent = parent.parentNode; }
2870		catch(e) { parent = this; }
2871
2872	if( parent != this ){
2873		// set the correct event type
2874		event.type = event.data;
2875		// handle event if we actually just moused on to a non sub-element
2876		jQuery.event.handle.apply( this, arguments );
2877	}
2878};
2879
2880jQuery.each({
2881	mouseover: 'mouseenter',
2882	mouseout: 'mouseleave'
2883}, function( orig, fix ){
2884	jQuery.event.special[ fix ] = {
2885		setup: function(){
2886			jQuery.event.add( this, orig, withinElement, fix );
2887		},
2888		teardown: function(){
2889			jQuery.event.remove( this, orig, withinElement );
2890		}
2891	};
2892});
2893
2894jQuery.fn.extend({
2895	bind: function( type, data, fn ) {
2896		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2897			jQuery.event.add( this, type, fn || data, fn && data );
2898		});
2899	},
2900
2901	one: function( type, data, fn ) {
2902		var one = jQuery.event.proxy( fn || data, function(event) {
2903			jQuery(this).unbind(event, one);
2904			return (fn || data).apply( this, arguments );
2905		});
2906		return this.each(function(){
2907			jQuery.event.add( this, type, one, fn && data);
2908		});
2909	},
2910
2911	unbind: function( type, fn ) {
2912		return this.each(function(){
2913			jQuery.event.remove( this, type, fn );
2914		});
2915	},
2916
2917	trigger: function( type, data ) {
2918		return this.each(function(){
2919			jQuery.event.trigger( type, data, this );
2920		});
2921	},
2922
2923	triggerHandler: function( type, data ) {
2924		if( this[0] ){
2925			var event = jQuery.Event(type);
2926			event.preventDefault();
2927			event.stopPropagation();
2928			jQuery.event.trigger( event, data, this[0] );
2929			return event.result;
2930		}
2931	},
2932
2933	toggle: function( fn ) {
2934		// Save reference to arguments for access in closure
2935		var args = arguments, i = 1;
2936
2937		// link all the functions, so any of them can unbind this click handler
2938		while( i < args.length )
2939			jQuery.event.proxy( fn, args[i++] );
2940
2941		return this.click( jQuery.event.proxy( fn, function(event) {
2942			// Figure out which function to execute
2943			this.lastToggle = ( this.lastToggle || 0 ) % i;
2944
2945			// Make sure that clicks stop
2946			event.preventDefault();
2947
2948			// and execute the function
2949			return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2950		}));
2951	},
2952
2953	hover: function(fnOver, fnOut) {
2954		return this.mouseenter(fnOver).mouseleave(fnOut);
2955	},
2956
2957	ready: function(fn) {
2958		// Attach the listeners
2959		bindReady();
2960
2961		// If the DOM is already ready
2962		if ( jQuery.isReady )
2963			// Execute the function immediately
2964			fn.call( document, jQuery );
2965
2966		// Otherwise, remember the function for later
2967		else
2968			// Add the function to the wait list
2969			jQuery.readyList.push( fn );
2970
2971		return this;
2972	},
2973
2974	live: function( type, fn ){
2975		var proxy = jQuery.event.proxy( fn );
2976		proxy.guid += this.selector + type;
2977
2978		jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
2979
2980		return this;
2981	},
2982
2983	die: function( type, fn ){
2984		jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
2985		return this;
2986	}
2987});
2988
2989function liveHandler( event ){
2990	var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
2991		stop = true,
2992		elems = [];
2993
2994	jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
2995		if ( check.test(fn.type) ) {
2996			var elem = jQuery(event.target).closest(fn.data)[0];
2997			if ( elem )
2998				elems.push({ elem: elem, fn: fn });
2999		}
3000	});
3001
3002	elems.sort(function(a,b) {
3003		return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
3004	});
3005
3006	jQuery.each(elems, function(){
3007		if ( this.fn.call(this.elem, event, this.fn.data) === false )
3008			return (stop = false);
3009	});
3010
3011	return stop;
3012}
3013
3014function liveConvert(type, selector){
3015	return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
3016}
3017
3018jQuery.extend({
3019	isReady: false,
3020	readyList: [],
3021	// Handle when the DOM is ready
3022	ready: function() {
3023		// Make sure that the DOM is not already loaded
3024		if ( !jQuery.isReady ) {
3025			// Remember that the DOM is ready
3026			jQuery.isReady = true;
3027
3028			// If there are functions bound, to execute
3029			if ( jQuery.readyList ) {
3030				// Execute all of them
3031				jQuery.each( jQuery.readyList, function(){
3032					this.call( document, jQuery );
3033				});
3034
3035				// Reset the list of functions
3036				jQuery.readyList = null;
3037			}
3038
3039			// Trigger any bound ready events
3040			jQuery(document).triggerHandler("ready");
3041		}
3042	}
3043});
3044
3045var readyBound = false;
3046
3047function bindReady(){
3048	if ( readyBound ) return;
3049	readyBound = true;
3050
3051	// Mozilla, Opera and webkit nightlies currently support this event
3052	if ( document.addEventListener ) {
3053		// Use the handy event callback
3054		document.addEventListener( "DOMContentLoaded", function(){
3055			document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
3056			jQuery.ready();
3057		}, false );
3058
3059	// If IE event model is used
3060	} else if ( document.attachEvent ) {
3061		// ensure firing before onload,
3062		// maybe late but safe also for iframes
3063		document.attachEvent("onreadystatechange", function(){
3064			if ( document.readyState === "complete" ) {
3065				document.detachEvent( "onreadystatechange", arguments.callee );
3066				jQuery.ready();
3067			}
3068		});
3069
3070		// If IE and not an iframe
3071		// continually check to see if the document is ready
3072		if ( document.documentElement.doScroll && window == window.top ) (function(){
3073			if ( jQuery.isReady ) return;
3074
3075			try {
3076				// If IE is used, use the trick by Diego Perini
3077				// http://javascript.nwbox.com/IEContentLoaded/
3078				document.documentElement.doScroll("left");
3079			} catch( error ) {
3080				setTimeout( arguments.callee, 0 );
3081				return;
3082			}
3083
3084			// and execute any waiting functions
3085			jQuery.ready();
3086		})();
3087	}
3088
3089	// A fallback to window.onload, that will always work
3090	jQuery.event.add( window, "load", jQuery.ready );
3091}
3092
3093jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
3094	"mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
3095	"change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
3096
3097	// Handle event binding
3098	jQuery.fn[name] = function(fn){
3099		return fn ? this.bind(name, fn) : this.trigger(name);
3100	};
3101});
3102
3103// Prevent memory leaks in IE
3104// And prevent errors on refresh with events like mouseover in other browsers
3105// Window isn't included so as not to unbind existing unload events
3106jQuery( window ).bind( 'unload', function(){
3107	for ( var id in jQuery.cache )
3108		// Skip the window
3109		if ( id != 1 && jQuery.cache[ id ].handle )
3110			jQuery.event.remove( jQuery.cache[ id ].handle.elem );
3111});
3112(function(){
3113
3114	jQuery.support = {};
3115
3116	var root = document.documentElement,
3117		script = document.createElement("script"),
3118		div = document.createElement("div"),
3119		id = "script" + (new Date).getTime();
3120
3121	div.style.display = "none";
3122	div.innerHTML = '   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
3123
3124	var all = div.getElementsByTagName("*"),
3125		a = div.getElementsByTagName("a")[0];
3126
3127	// Can't get basic test support
3128	if ( !all || !all.length || !a ) {
3129		return;
3130	}
3131
3132	jQuery.support = {
3133		// IE strips leading whitespace when .innerHTML is used
3134		leadingWhitespace: div.firstChild.nodeType == 3,
3135
3136		// Make sure that tbody elements aren't automatically inserted
3137		// IE will insert them into empty tables
3138		tbody: !div.getElementsByTagName("tbody").length,
3139
3140		// Make sure that you can get all elements in an <object> element
3141		// IE 7 always returns no results
3142		objectAll: !!div.getElementsByTagName("object")[0]
3143			.getElementsByTagName("*").length,
3144
3145		// Make sure that link elements get serialized correctly by innerHTML
3146		// This requires a wrapper element in IE
3147		htmlSerialize: !!div.getElementsByTagName("link").length,
3148
3149		// Get the style information from getAttribute
3150		// (IE uses .cssText insted)
3151		style: /red/.test( a.getAttribute("style") ),
3152
3153		// Make sure that URLs aren't manipulated
3154		// (IE normalizes it by default)
3155		hrefNormalized: a.getAttribute("href") === "/a",
3156
3157		// Make sure that element opacity exists
3158		// (IE uses filter instead)
3159		opacity: a.style.opacity === "0.5",
3160
3161		// Verify style float existence
3162		// (IE uses styleFloat instead of cssFloat)
3163		cssFloat: !!a.style.cssFloat,
3164
3165		// Will be defined later
3166		scriptEval: false,
3167		noCloneEvent: true,
3168		boxModel: null
3169	};
3170
3171	script.type = "text/javascript";
3172	try {
3173		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
3174	} catch(e){}
3175
3176	root.insertBefore( script, root.firstChild );
3177
3178	// Make sure that the execution of code works by injecting a script
3179	// tag with appendChild/createTextNode
3180	// (IE doesn't support this, fails, and uses .text instead)
3181	if ( window[ id ] ) {
3182		jQuery.support.scriptEval = true;
3183		delete window[ id ];
3184	}
3185
3186	root.removeChild( script );
3187
3188	if ( div.attachEvent && div.fireEvent ) {
3189		div.attachEvent("onclick", function(){
3190			// Cloning a node shouldn't copy over any
3191			// bound event handlers (IE does this)
3192			jQuery.support.noCloneEvent = false;
3193			div.detachEvent("onclick", arguments.callee);
3194		});
3195		div.cloneNode(true).fireEvent("onclick");
3196	}
3197
3198	// Figure out if the W3C box model works as expected
3199	// document.body must exist before we can do this
3200	jQuery(function(){
3201		var div = document.createElement("div");
3202		div.style.width = div.style.paddingLeft = "1px";
3203
3204		document.body.appendChild( div );
3205		jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
3206		document.body.removeChild( div ).style.display = 'none';
3207	});
3208})();
3209
3210var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
3211
3212jQuery.props = {
3213	"for": "htmlFor",
3214	"class": "className",
3215	"float": styleFloat,
3216	cssFloat: styleFloat,
3217	styleFloat: styleFloat,
3218	readonly: "readOnly",
3219	maxlength: "maxLength",
3220	cellspacing: "cellSpacing",
3221	rowspan: "rowSpan",
3222	tabindex: "tabIndex"
3223};
3224jQuery.fn.extend({
3225	// Keep a copy of the old load
3226	_load: jQuery.fn.load,
3227
3228	load: function( url, params, callback ) {
3229		if ( typeof url !== "string" )
3230			return this._load( url );
3231
3232		var off = url.indexOf(" ");
3233		if ( off >= 0 ) {
3234			var selector = url.slice(off, url.length);
3235			url = url.slice(0, off);
3236		}
3237
3238		// Default to a GET request
3239		var type = "GET";
3240
3241		// If the second parameter was provided
3242		if ( params )
3243			// If it's a function
3244			if ( jQuery.isFunction( params ) ) {
3245				// We assume that it's the callback
3246				callback = params;
3247				params = null;
3248
3249			// Otherwise, build a param string
3250			} else if( typeof params === "object" ) {
3251				params = jQuery.param( params );
3252				type = "POST";
3253			}
3254
3255		var self = this;
3256
3257		// Request the remote document
3258		jQuery.ajax({
3259			url: url,
3260			type: type,
3261			dataType: "html",
3262			data: params,
3263			complete: function(res, status){
3264				// If successful, inject the HTML into all the matched elements
3265				if ( status == "success" || status == "notmodified" )
3266					// See if a selector was specified
3267					self.html( selector ?
3268						// Create a dummy div to hold the results
3269						jQuery("<div/>")
3270							// inject the contents of the document in, removing the scripts
3271							// to avoid any 'Permission Denied' errors in IE
3272							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
3273
3274							// Locate the specified elements
3275							.find(selector) :
3276
3277						// If not, just inject the full result
3278						res.responseText );
3279
3280				if( callback )
3281					self.each( callback, [res.responseText, status, res] );
3282			}
3283		});
3284		return this;
3285	},
3286
3287	serialize: function() {
3288		return jQuery.param(this.serializeArray());
3289	},
3290	serializeArray: function() {
3291		return this.map(function(){
3292			return this.elements ? jQuery.makeArray(this.elements) : this;
3293		})
3294		.filter(function(){
3295			return this.name && !this.disabled &&
3296				(this.checked || /select|textarea/i.test(this.nodeName) ||
3297					/text|hidden|password|search/i.test(this.type));
3298		})
3299		.map(function(i, elem){
3300			var val = jQuery(this).val();
3301			return val == null ? null :
3302				jQuery.isArray(val) ?
3303					jQuery.map( val, function(val, i){
3304						return {name: elem.name, value: val};
3305					}) :
3306					{name: elem.name, value: val};
3307		}).get();
3308	}
3309});
3310
3311// Attach a bunch of functions for handling common AJAX events
3312jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
3313	jQuery.fn[o] = function(f){
3314		return this.bind(o, f);
3315	};
3316});
3317
3318var jsc = now();
3319
3320jQuery.extend({
3321
3322	get: function( url, data, callback, type ) {
3323		// shift arguments if data argument was ommited
3324		if ( jQuery.isFunction( data ) ) {
3325			callback = data;
3326			data = null;
3327		}
3328
3329		return jQuery.ajax({
3330			type: "GET",
3331			url: url,
3332			data: data,
3333			success: callback,
3334			dataType: type
3335		});
3336	},
3337
3338	getScript: function( url, callback ) {
3339		return jQuery.get(url, null, callback, "script");
3340	},
3341
3342	getJSON: function( url, data, callback ) {
3343		return jQuery.get(url, data, callback, "json");
3344	},
3345
3346	post: function( url, data, callback, type ) {
3347		if ( jQuery.isFunction( data ) ) {
3348			callback = data;
3349			data = {};
3350		}
3351
3352		return jQuery.ajax({
3353			type: "POST",
3354			url: url,
3355			data: data,
3356			success: callback,
3357			dataType: type
3358		});
3359	},
3360
3361	ajaxSetup: function( settings ) {
3362		jQuery.extend( jQuery.ajaxSettings, settings );
3363	},
3364
3365	ajaxSettings: {
3366		url: location.href,
3367		global: true,
3368		type: "GET",
3369		contentType: "application/x-www-form-urlencoded",
3370		processData: true,
3371		async: true,
3372		/*
3373		timeout: 0,
3374		data: null,
3375		username: null,
3376		password: null,
3377		*/
3378		// Create the request object; Microsoft failed to properly
3379		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
3380		// This function can be overriden by calling jQuery.ajaxSetup
3381		xhr:function(){
3382			return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
3383		},
3384		accepts: {
3385			xml: "application/xml, text/xml",
3386			html: "text/html",
3387			script: "text/javascript, application/javascript",
3388			json: "application/json, text/javascript",
3389			text: "text/plain",
3390			_default: "*/*"
3391		}
3392	},
3393
3394	// Last-Modified header cache for next request
3395	lastModified: {},
3396
3397	ajax: function( s ) {
3398		// Extend the settings, but re-extend 's' so that it can be
3399		// checked again later (in the test suite, specifically)
3400		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
3401
3402		var jsonp, jsre = /=\?(&|$)/g, status, data,
3403			type = s.type.toUpperCase();
3404
3405		// convert data if not already a string
3406		if ( s.data && s.processData && typeof s.data !== "string" )
3407			s.data = jQuery.param(s.data);
3408
3409		// Handle JSONP Parameter Callbacks
3410		if ( s.dataType == "jsonp" ) {
3411			if ( type == "GET" ) {
3412				if ( !s.url.match(jsre) )
3413					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
3414			} else if ( !s.data || !s.data.match(jsre) )
3415				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
3416			s.dataType = "json";
3417		}
3418
3419		// Build temporary JSONP function
3420		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
3421			jsonp = "jsonp" + jsc++;
3422
3423			// Replace the =? sequence both in the query string and the data
3424			if ( s.data )
3425				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
3426			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
3427
3428			// We need to make sure
3429			// that a JSONP style response is executed properly
3430			s.dataType = "script";
3431
3432			// Handle JSONP-style loading
3433			window[ jsonp ] = function(tmp){
3434				data = tmp;
3435				success();
3436				complete();
3437				// Garbage collect
3438				window[ jsonp ] = undefined;
3439				try{ delete window[ jsonp ]; } catch(e){}
3440				if ( head )
3441					head.removeChild( script );
3442			};
3443		}
3444
3445		if ( s.dataType == "script" && s.cache == null )
3446			s.cache = false;
3447
3448		if ( s.cache === false && type == "GET" ) {
3449			var ts = now();
3450			// try replacing _= if it is there
3451			var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
3452			// if nothing was replaced, add timestamp to the end
3453			s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
3454		}
3455
3456		// If data is available, append data to url for get requests
3457		if ( s.data && type == "GET" ) {
3458			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
3459
3460			// IE likes to send both get and post data, prevent this
3461			s.data = null;
3462		}
3463
3464		// Watch for a new set of requests
3465		if ( s.global && ! jQuery.active++ )
3466			jQuery.event.trigger( "ajaxStart" );
3467
3468		// Matches an absolute URL, and saves the domain
3469		var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
3470
3471		// If we're requesting a remote document
3472		// and trying to load JSON or Script with a GET
3473		if ( s.dataType == "script" && type == "GET" && parts
3474			&& ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
3475
3476			var head = document.getElementsByTagName("head")[0];
3477			var script = document.createElement("script");
3478			script.src = s.url;
3479			if (s.scriptCharset)
3480				script.charset = s.scriptCharset;
3481
3482			// Handle Script loading
3483			if ( !jsonp ) {
3484				var done = false;
3485
3486				// Attach handlers for all browsers
3487				script.onload = script.onreadystatechange = function(){
3488					if ( !done && (!this.readyState ||
3489							this.readyState == "loaded" || this.readyState == "complete") ) {
3490						done = true;
3491						success();
3492						complete();
3493
3494						// Handle memory leak in IE
3495						script.onload = script.onreadystatechange = null;
3496						head.removeChild( script );
3497					}
3498				};
3499			}
3500
3501			head.appendChild(script);
3502
3503			// We handle everything using the script element injection
3504			return undefined;
3505		}
3506
3507		var requestDone = false;
3508
3509		// Create the request object
3510		var xhr = s.xhr();
3511
3512		// Open the socket
3513		// Passing null username, generates a login popup on Opera (#2865)
3514		if( s.username )
3515			xhr.open(type, s.url, s.async, s.username, s.password);
3516		else
3517			xhr.open(type, s.url, s.async);
3518
3519		// Need an extra try/catch for cross domain requests in Firefox 3
3520		try {
3521			// Set the correct header, if data is being sent
3522			if ( s.data )
3523				xhr.setRequestHeader("Content-Type", s.contentType);
3524
3525			// Set the If-Modified-Since header, if ifModified mode.
3526			if ( s.ifModified )
3527				xhr.setRequestHeader("If-Modified-Since",
3528					jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
3529
3530			// Set header so the called script knows that it's an XMLHttpRequest
3531			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
3532
3533			// Set the Accepts header for the server, depending on the dataType
3534			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
3535				s.accepts[ s.dataType ] + ", */*" :
3536				s.accepts._default );
3537		} catch(e){}
3538
3539		// Allow custom headers/mimetypes and early abort
3540		if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
3541			// Handle the global AJAX counter
3542			if ( s.global && ! --jQuery.active )
3543				jQuery.event.trigger( "ajaxStop" );
3544			// close opended socket
3545			xhr.abort();
3546			return false;
3547		}
3548
3549		if ( s.global )
3550			jQuery.event.trigger("ajaxSend", [xhr, s]);
3551
3552		// Wait for a response to come back
3553		var onreadystatechange = function(isTimeout){
3554			// The request was aborted, clear the interval and decrement jQuery.active
3555			if (xhr.readyState == 0) {
3556				if (ival) {
3557					// clear poll interval
3558					clearInterval(ival);
3559					ival = null;
3560					// Handle the global AJAX counter
3561					if ( s.global && ! --jQuery.active )
3562						jQuery.event.trigger( "ajaxStop" );
3563				}
3564			// The transfer is complete and the data is available, or the request timed out
3565			} else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
3566				requestDone = true;
3567
3568				// clear poll interval
3569				if (ival) {
3570					clearInterval(ival);
3571					ival = null;
3572				}
3573
3574				status = isTimeout == "timeout" ? "timeout" :
3575					!jQuery.httpSuccess( xhr ) ? "error" :
3576					s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
3577					"success";
3578
3579				if ( status == "success" ) {
3580					// Watch for, and catch, XML document parse errors
3581					try {
3582						// process the data (runs the xml through httpData regardless of callback)
3583						data = jQuery.httpData( xhr, s.dataType, s );
3584					} catch(e) {
3585						status = "parsererror";
3586					}
3587				}
3588
3589				// Make sure that the request was successful or notmodified
3590				if ( status == "success" ) {
3591					// Cache Last-Modified header, if ifModified mode.
3592					var modRes;
3593					try {
3594						modRes = xhr.getResponseHeader("Last-Modified");
3595					} catch(e) {} // swallow exception thrown by FF if header is not available
3596
3597					if ( s.ifModified && modRes )
3598						jQuery.lastModified[s.url] = modRes;
3599
3600					// JSONP handles its own success callback
3601					if ( !jsonp )
3602						success();
3603				} else
3604					jQuery.handleError(s, xhr, status);
3605
3606				// Fire the complete handlers
3607				complete();
3608
3609				if ( isTimeout )
3610					xhr.abort();
3611
3612				// Stop memory leaks
3613				if ( s.async )
3614					xhr = null;
3615			}
3616		};
3617
3618		if ( s.async ) {
3619			// don't attach the handler to the request, just poll it instead
3620			var ival = setInterval(onreadystatechange, 13);
3621
3622			// Timeout checker
3623			if ( s.timeout > 0 )
3624				setTimeout(function(){
3625					// Check to see if the request is still happening
3626					if ( xhr && !requestDone )
3627						onreadystatechange( "timeout" );
3628				}, s.timeout);
3629		}
3630
3631		// Send the data
3632		try {
3633			xhr.send(s.data);
3634		} catch(e) {
3635			jQuery.handleError(s, xhr, null, e);
3636		}
3637
3638		// firefox 1.5 doesn't fire statechange for sync requests
3639		if ( !s.async )
3640			onreadystatechange();
3641
3642		function success(){
3643			// If a local callback was specified, fire it and pass it the data
3644			if ( s.success )
3645				s.success( data, status );
3646
3647			// Fire the global callback
3648			if ( s.global )
3649				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
3650		}
3651
3652		function complete(){
3653			// Process result
3654			if ( s.complete )
3655				s.complete(xhr, status);
3656
3657			// The request was completed
3658			if ( s.global )
3659				jQuery.event.trigger( "ajaxComplete", [xhr, s] );
3660
3661			// Handle the global AJAX counter
3662			if ( s.global && ! --jQuery.active )
3663				jQuery.event.trigger( "ajaxStop" );
3664		}
3665
3666		// return XMLHttpRequest to allow aborting the request etc.
3667		return xhr;
3668	},
3669
3670	handleError: function( s, xhr, status, e ) {
3671		// If a local callback was specified, fire it
3672		if ( s.error ) s.error( xhr, status, e );
3673
3674		// Fire the global callback
3675		if ( s.global )
3676			jQuery.event.trigger( "ajaxError", [xhr, s, e] );
3677	},
3678
3679	// Counter for holding the number of active queries
3680	active: 0,
3681
3682	// Determines if an XMLHttpRequest was successful or not
3683	httpSuccess: function( xhr ) {
3684		try {
3685			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
3686			return !xhr.status && location.protocol == "file:" ||
3687				( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
3688		} catch(e){}
3689		return false;
3690	},
3691
3692	// Determines if an XMLHttpRequest returns NotModified
3693	httpNotModified: function( xhr, url ) {
3694		try {
3695			var xhrRes = xhr.getResponseHeader("Last-Modified");
3696
3697			// Firefox always returns 200. check Last-Modified date
3698			return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
3699		} catch(e){}
3700		return false;
3701	},
3702
3703	httpData: function( xhr, type, s ) {
3704		var ct = xhr.getResponseHeader("content-type"),
3705			xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
3706			data = xml ? xhr.responseXML : xhr.responseText;
3707
3708		if ( xml && data.documentElement.tagName == "parsererror" )
3709			throw "parsererror";
3710
3711		// Allow a pre-filtering function to sanitize the response
3712		// s != null is checked to keep backwards compatibility
3713		if( s && s.dataFilter )
3714			data = s.dataFilter( data, type );
3715
3716		// The filter can actually parse the response
3717		if( typeof data === "string" ){
3718
3719			// If the type is "script", eval it in global context
3720			if ( type == "script" )
3721				jQuery.globalEval( data );
3722
3723			// Get the JavaScript object, if JSON is used.
3724			if ( type == "json" )
3725				data = window["eval"]("(" + data + ")");
3726		}
3727
3728		return data;
3729	},
3730
3731	// Serialize an array of form elements or a set of
3732	// key/values into a query string
3733	param: function( a ) {
3734		var s = [ ];
3735
3736		function add( key, value ){
3737			s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
3738		};
3739
3740		// If an array was passed in, assume that it is an array
3741		// of form elements
3742		if ( jQuery.isArray(a) || a.jquery )
3743			// Serialize the form elements
3744			jQuery.each( a, function(){
3745				add( this.name, this.value );
3746			});
3747
3748		// Otherwise, assume that it's an object of key/value pairs
3749		else
3750			// Serialize the key/values
3751			for ( var j in a )
3752				// If the value is an array then the key names need to be repeated
3753				if ( jQuery.isArray(a[j]) )
3754					jQuery.each( a[j], function(){
3755						add( j, this );
3756					});
3757				else
3758					add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
3759
3760		// Return the resulting serialization
3761		return s.join("&").replace(/%20/g, "+");
3762	}
3763
3764});
3765var elemdisplay = {},
3766	timerId,
3767	fxAttrs = [
3768		// height animations
3769		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
3770		// width animations
3771		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
3772		// opacity animations
3773		[ "opacity" ]
3774	];
3775
3776function genFx( type, num ){
3777	var obj = {};
3778	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
3779		obj[ this ] = type;
3780	});
3781	return obj;
3782}
3783
3784jQuery.fn.extend({
3785	show: function(speed,callback){
3786		if ( speed ) {
3787			return this.animate( genFx("show", 3), speed, callback);
3788		} else {
3789			for ( var i = 0, l = this.length; i < l; i++ ){
3790				var old = jQuery.data(this[i], "olddisplay");
3791
3792				this[i].style.display = old || "";
3793
3794				if ( jQuery.css(this[i], "display") === "none" ) {
3795					var tagName = this[i].tagName, display;
3796
3797					if ( elemdisplay[ tagName ] ) {
3798						display = elemdisplay[ tagName ];
3799					} else {
3800						var elem = jQuery("<" + tagName + " />").appendTo("body");
3801
3802						display = elem.css("display");
3803						if ( display === "none" )
3804							display = "block";
3805
3806						elem.remove();
3807
3808						elemdisplay[ tagName ] = display;
3809					}
3810
3811					jQuery.data(this[i], "olddisplay", display);
3812				}
3813			}
3814
3815			// Set the display of the elements in a second loop
3816			// to avoid the constant reflow
3817			for ( var i = 0, l = this.length; i < l; i++ ){
3818				this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
3819			}
3820
3821			return this;
3822		}
3823	},
3824
3825	hide: function(speed,callback){
3826		if ( speed ) {
3827			return this.animate( genFx("hide", 3), speed, callback);
3828		} else {
3829			for ( var i = 0, l = this.length; i < l; i++ ){
3830				var old = jQuery.data(this[i], "olddisplay");
3831				if ( !old && old !== "none" )
3832					jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
3833			}
3834
3835			// Set the display of the elements in a second loop
3836			// to avoid the constant reflow
3837			for ( var i = 0, l = this.length; i < l; i++ ){
3838				this[i].style.display = "none";
3839			}
3840
3841			return this;
3842		}
3843	},
3844
3845	// Save the old toggle function
3846	_toggle: jQuery.fn.toggle,
3847
3848	toggle: function( fn, fn2 ){
3849		var bool = typeof fn === "boolean";
3850
3851		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
3852			this._toggle.apply( this, arguments ) :
3853			fn == null || bool ?
3854				this.each(function(){
3855					var state = bool ? fn : jQuery(this).is(":hidden");
3856					jQuery(this)[ state ? "show" : "hide" ]();
3857				}) :
3858				this.animate(genFx("toggle", 3), fn, fn2);
3859	},
3860
3861	fadeTo: function(speed,to,callback){
3862		return this.animate({opacity: to}, speed, callback);
3863	},
3864
3865	animate: function( prop, speed, easing, callback ) {
3866		var optall = jQuery.speed(speed, easing, callback);
3867
3868		return this[ optall.queue === false ? "each" : "queue" ](function(){
3869
3870			var opt = jQuery.extend({}, optall), p,
3871				hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
3872				self = this;
3873
3874			for ( p in prop ) {
3875				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3876					return opt.complete.call(this);
3877
3878				if ( ( p == "height" || p == "width" ) && this.style ) {
3879					// Store display property
3880					opt.display = jQuery.css(this, "display");
3881
3882					// Make sure that nothing sneaks out
3883					opt.overflow = this.style.overflow;
3884				}
3885			}
3886
3887			if ( opt.overflow != null )
3888				this.style.overflow = "hidden";
3889
3890			opt.curAnim = jQuery.extend({}, prop);
3891
3892			jQuery.each( prop, function(name, val){
3893				var e = new jQuery.fx( self, opt, name );
3894
3895				if ( /toggle|show|hide/.test(val) )
3896					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
3897				else {
3898					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3899						start = e.cur(true) || 0;
3900
3901					if ( parts ) {
3902						var end = parseFloat(parts[2]),
3903							unit = parts[3] || "px";
3904
3905						// We need to compute starting value
3906						if ( unit != "px" ) {
3907							self.style[ name ] = (end || 1) + unit;
3908							start = ((end || 1) / e.cur(true)) * start;
3909							self.style[ name ] = start + unit;
3910						}
3911
3912						// If a +=/-= token was provided, we're doing a relative animation
3913						if ( parts[1] )
3914							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3915
3916						e.custom( start, end, unit );
3917					} else
3918						e.custom( start, val, "" );
3919				}
3920			});
3921
3922			// For JS strict compliance
3923			return true;
3924		});
3925	},
3926
3927	stop: function(clearQueue, gotoEnd){
3928		var timers = jQuery.timers;
3929
3930		if (clearQueue)
3931			this.queue([]);
3932
3933		this.each(function(){
3934			// go in reverse order so anything added to the queue during the loop is ignored
3935			for ( var i = timers.length - 1; i >= 0; i-- )
3936				if ( timers[i].elem == this ) {
3937					if (gotoEnd)
3938						// force the next step to be the last
3939						timers[i](true);
3940					timers.splice(i, 1);
3941				}
3942		});
3943
3944		// start the next in the queue if the last step wasn't forced
3945		if (!gotoEnd)
3946			this.dequeue();
3947
3948		return this;
3949	}
3950
3951});
3952
3953// Generate shortcuts for custom animations
3954jQuery.each({
3955	slideDown: genFx("show", 1),
3956	slideUp: genFx("hide", 1),
3957	slideToggle: genFx("toggle", 1),
3958	fadeIn: { opacity: "show" },
3959	fadeOut: { opacity: "hide" }
3960}, function( name, props ){
3961	jQuery.fn[ name ] = function( speed, callback ){
3962		return this.animate( props, speed, callback );
3963	};
3964});
3965
3966jQuery.extend({
3967
3968	speed: function(speed, easing, fn) {
3969		var opt = typeof speed === "object" ? speed : {
3970			complete: fn || !fn && easing ||
3971				jQuery.isFunction( speed ) && speed,
3972			duration: speed,
3973			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
3974		};
3975
3976		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
3977			jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
3978
3979		// Queueing
3980		opt.old = opt.complete;
3981		opt.complete = function(){
3982			if ( opt.queue !== false )
3983				jQuery(this).dequeue();
3984			if ( jQuery.isFunction( opt.old ) )
3985				opt.old.call( this );
3986		};
3987
3988		return opt;
3989	},
3990
3991	easing: {
3992		linear: function( p, n, firstNum, diff ) {
3993			return firstNum + diff * p;
3994		},
3995		swing: function( p, n, firstNum, diff ) {
3996			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3997		}
3998	},
3999
4000	timers: [],
4001
4002	fx: function( elem, options, prop ){
4003		this.options = options;
4004		this.elem = elem;
4005		this.prop = prop;
4006
4007		if ( !options.orig )
4008			options.orig = {};
4009	}
4010
4011});
4012
4013jQuery.fx.prototype = {
4014
4015	// Simple function for setting a style value
4016	update: function(){
4017		if ( this.options.step )
4018			this.options.step.call( this.elem, this.now, this );
4019
4020		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
4021
4022		// Set display property to block for height/width animations
4023		if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
4024			this.elem.style.display = "block";
4025	},
4026
4027	// Get the current size
4028	cur: function(force){
4029		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
4030			return this.elem[ this.prop ];
4031
4032		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
4033		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
4034	},
4035
4036	// Start an animation from one number to another
4037	custom: function(from, to, unit){
4038		this.startTime = now();
4039		this.start = from;
4040		this.end = to;
4041		this.unit = unit || this.unit || "px";
4042		this.now = this.start;
4043		this.pos = this.state = 0;
4044
4045		var self = this;
4046		function t(gotoEnd){
4047			return self.step(gotoEnd);
4048		}
4049
4050		t.elem = this.elem;
4051
4052		if ( t() && jQuery.timers.push(t) && !timerId ) {
4053			timerId = setInterval(function(){
4054				var timers = jQuery.timers;
4055
4056				for ( var i = 0; i < timers.length; i++ )
4057					if ( !timers[i]() )
4058						timers.splice(i--, 1);
4059
4060				if ( !timers.length ) {
4061					clearInterval( timerId );
4062					timerId = undefined;
4063				}
4064			}, 13);
4065		}
4066	},
4067
4068	// Simple 'show' function
4069	show: function(){
4070		// Remember where we started, so that we can go back to it later
4071		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
4072		this.options.show = true;
4073
4074		// Begin the animation
4075		// Make sure that we start at a small width/height to avoid any
4076		// flash of content
4077		this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
4078
4079		// Start by showing the element
4080		jQuery(this.elem).show();
4081	},
4082
4083	// Simple 'hide' function
4084	hide: function(){
4085		// Remember where we started, so that we can go back to it later
4086		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
4087		this.options.hide = true;
4088
4089		// Begin the animation
4090		this.custom(this.cur(), 0);
4091	},
4092
4093	// Each step of an animation
4094	step: function(gotoEnd){
4095		var t = now();
4096
4097		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
4098			this.now = this.end;
4099			this.pos = this.state = 1;
4100			this.update();
4101
4102			this.options.curAnim[ this.prop ] = true;
4103
4104			var done = true;
4105			for ( var i in this.options.curAnim )
4106				if ( this.options.curAnim[i] !== true )
4107					done = false;
4108
4109			if ( done ) {
4110				if ( this.options.display != null ) {
4111					// Reset the overflow
4112					this.elem.style.overflow = this.options.overflow;
4113
4114					// Reset the display
4115					this.elem.style.display = this.options.display;
4116					if ( jQuery.css(this.elem, "display") == "none" )
4117						this.elem.style.display = "block";
4118				}
4119
4120				// Hide the element if the "hide" operation was done
4121				if ( this.options.hide )
4122					jQuery(this.elem).hide();
4123
4124				// Reset the properties, if the item has been hidden or shown
4125				if ( this.options.hide || this.options.show )
4126					for ( var p in this.options.curAnim )
4127						jQuery.attr(this.elem.style, p, this.options.orig[p]);
4128
4129				// Execute the complete function
4130				this.options.complete.call( this.elem );
4131			}
4132
4133			return false;
4134		} else {
4135			var n = t - this.startTime;
4136			this.state = n / this.options.duration;
4137
4138			// Perform the easing function, defaults to swing
4139			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
4140			this.now = this.start + ((this.end - this.start) * this.pos);
4141
4142			// Perform the next step of the animation
4143			this.update();
4144		}
4145
4146		return true;
4147	}
4148
4149};
4150
4151jQuery.extend( jQuery.fx, {
4152	speeds:{
4153		slow: 600,
4154 		fast: 200,
4155 		// Default speed
4156 		_default: 400
4157	},
4158	step: {
4159
4160		opacity: function(fx){
4161			jQuery.attr(fx.elem.style, "opacity", fx.now);
4162		},
4163
4164		_default: function(fx){
4165			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
4166				fx.elem.style[ fx.prop ] = fx.now + fx.unit;
4167			else
4168				fx.elem[ fx.prop ] = fx.now;
4169		}
4170	}
4171});
4172if ( document.documentElement["getBoundingClientRect"] )
4173	jQuery.fn.offset = function() {
4174		if ( !this[0] ) return { top: 0, left: 0 };
4175		if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4176		var box  = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
4177			clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
4178			top  = box.top  + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop  || body.scrollTop ) - clientTop,
4179			left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
4180		return { top: top, left: left };
4181	};
4182else
4183	jQuery.fn.offset = function() {
4184		if ( !this[0] ) return { top: 0, left: 0 };
4185		if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4186		jQuery.offset.initialized || jQuery.offset.initialize();
4187
4188		var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
4189			doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
4190			body = doc.body, defaultView = doc.defaultView,
4191			prevComputedStyle = defaultView.getComputedStyle(elem, null),
4192			top = elem.offsetTop, left = elem.offsetLeft;
4193
4194		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
4195			computedStyle = defaultView.getComputedStyle(elem, null);
4196			top -= elem.scrollTop, left -= elem.scrollLeft;
4197			if ( elem === offsetParent ) {
4198				top += elem.offsetTop, left += elem.offsetLeft;
4199				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
4200					top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
4201					left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4202				prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
4203			}
4204			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
4205				top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
4206				left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4207			prevComputedStyle = computedStyle;
4208		}
4209
4210		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
4211			top  += body.offsetTop,
4212			left += body.offsetLeft;
4213
4214		if ( prevComputedStyle.position === "fixed" )
4215			top  += Math.max(docElem.scrollTop, body.scrollTop),
4216			left += Math.max(docElem.scrollLeft, body.scrollLeft);
4217
4218		return { top: top, left: left };
4219	};
4220
4221jQuery.offset = {
4222	initialize: function() {
4223		if ( this.initialized ) return;
4224		var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
4225			html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
4226
4227		rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
4228		for ( prop in rules ) container.style[prop] = rules[prop];
4229
4230		container.innerHTML = html;
4231		body.insertBefore(container, body.firstChild);
4232		innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
4233
4234		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
4235		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
4236
4237		innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
4238		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
4239
4240		body.style.marginTop = '1px';
4241		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
4242		body.style.marginTop = bodyMarginTop;
4243
4244		body.removeChild(container);
4245		this.initialized = true;
4246	},
4247
4248	bodyOffset: function(body) {
4249		jQuery.offset.initialized || jQuery.offset.initialize();
4250		var top = body.offsetTop, left = body.offsetLeft;
4251		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
4252			top  += parseInt( jQuery.curCSS(body, 'marginTop',  true), 10 ) || 0,
4253			left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
4254		return { top: top, left: left };
4255	}
4256};
4257
4258
4259jQuery.fn.extend({
4260	position: function() {
4261		var left = 0, top = 0, results;
4262
4263		if ( this[0] ) {
4264			// Get *real* offsetParent
4265			var offsetParent = this.offsetParent(),
4266
4267			// Get correct offsets
4268			offset       = this.offset(),
4269			parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
4270
4271			// Subtract element margins
4272			// note: when an element has margin: auto the offsetLeft and marginLeft
4273			// are the same in Safari causing offset.left to incorrectly be 0
4274			offset.top  -= num( this, 'marginTop'  );
4275			offset.left -= num( this, 'marginLeft' );
4276
4277			// Add offsetParent borders
4278			parentOffset.top  += num( offsetParent, 'borderTopWidth'  );
4279			parentOffset.left += num( offsetParent, 'borderLeftWidth' );
4280
4281			// Subtract the two offsets
4282			results = {
4283				top:  offset.top  - parentOffset.top,
4284				left: offset.left - parentOffset.left
4285			};
4286		}
4287
4288		return results;
4289	},
4290
4291	offsetParent: function() {
4292		var offsetParent = this[0].offsetParent || document.body;
4293		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
4294			offsetParent = offsetParent.offsetParent;
4295		return jQuery(offsetParent);
4296	}
4297});
4298
4299
4300// Create scrollLeft and scrollTop methods
4301jQuery.each( ['Left', 'Top'], function(i, name) {
4302	var method = 'scroll' + name;
4303
4304	jQuery.fn[ method ] = function(val) {
4305		if (!this[0]) return null;
4306
4307		return val !== undefined ?
4308
4309			// Set the scroll offset
4310			this.each(function() {
4311				this == window || this == document ?
4312					window.scrollTo(
4313						!i ? val : jQuery(window).scrollLeft(),
4314						 i ? val : jQuery(window).scrollTop()
4315					) :
4316					this[ method ] = val;
4317			}) :
4318
4319			// Return the scroll offset
4320			this[0] == window || this[0] == document ?
4321				self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
4322					jQuery.boxModel && document.documentElement[ method ] ||
4323					document.body[ method ] :
4324				this[0][ method ];
4325	};
4326});
4327// Create innerHeight, innerWidth, outerHeight and outerWidth methods
4328jQuery.each([ "Height", "Width" ], function(i, name){
4329
4330	var tl = i ? "Left"  : "Top",  // top or left
4331		br = i ? "Right" : "Bottom", // bottom or right
4332		lower = name.toLowerCase();
4333
4334	// innerHeight and innerWidth
4335	jQuery.fn["inner" + name] = function(){
4336		return this[0] ?
4337			jQuery.css( this[0], lower, false, "padding" ) :
4338			null;
4339	};
4340
4341	// outerHeight and outerWidth
4342	jQuery.fn["outer" + name] = function(margin) {
4343		return this[0] ?
4344			jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
4345			null;
4346	};
4347
4348	var type = name.toLowerCase();
4349
4350	jQuery.fn[ type ] = function( size ) {
4351		// Get window width or height
4352		return this[0] == window ?
4353			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
4354			document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
4355			document.body[ "client" + name ] :
4356
4357			// Get document width or height
4358			this[0] == document ?
4359				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
4360				Math.max(
4361					document.documentElement["client" + name],
4362					document.body["scroll" + name], document.documentElement["scroll" + name],
4363					document.body["offset" + name], document.documentElement["offset" + name]
4364				) :
4365
4366				// Get or set width or height on the element
4367				size === undefined ?
4368					// Get width or height on the element
4369					(this.length ? jQuery.css( this[0], type ) : null) :
4370
4371					// Set the width or height on the element (default to pixels if value is unitless)
4372					this.css( type, typeof size === "string" ? size : size + "px" );
4373	};
4374
4375});
4376})();
4377