PageSourceSearch

https://poliupg.ac.id/templates/poliupg_front/js/jquery-ui-1.9.2.custom.js

js poliupg.ac.id collected 2026-10-02 06:09:26 UTC 465,008 bytes, 14,879 lines download raw bytes

vendor: 9,870 bytes, lines 1-339
1/*! jQuery UI - v1.9.2 - 2013-06-13
2* http://jqueryui.com
3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
4* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
5
6(function( $, undefined ) {
7
8var uuid = 0,
9	runiqueId = /^ui-id-\d+$/;
10
11// prevent duplicate loading
12// this is only a problem because we proxy existing functions
13// and we don't want to double proxy them
14$.ui = $.ui || {};
15if ( $.ui.version ) {
16	return;
17}
18
19$.extend( $.ui, {
20	version: "1.9.2",
21
22	keyCode: {
23		BACKSPACE: 8,
24		COMMA: 188,
25		DELETE: 46,
26		DOWN: 40,
27		END: 35,
28		ENTER: 13,
29		ESCAPE: 27,
30		HOME: 36,
31		LEFT: 37,
32		NUMPAD_ADD: 107,
33		NUMPAD_DECIMAL: 110,
34		NUMPAD_DIVIDE: 111,
35		NUMPAD_ENTER: 108,
36		NUMPAD_MULTIPLY: 106,
37		NUMPAD_SUBTRACT: 109,
38		PAGE_DOWN: 34,
39		PAGE_UP: 33,
40		PERIOD: 190,
41		RIGHT: 39,
42		SPACE: 32,
43		TAB: 9,
44		UP: 38
45	}
46});
47
48// plugins
49$.fn.extend({
50	_focus: $.fn.focus,
51	focus: function( delay, fn ) {
52		return typeof delay === "number" ?
53			this.each(function() {
54				var elem = this;
55				setTimeout(function() {
56					$( elem ).focus();
57					if ( fn ) {
58						fn.call( elem );
59					}
60				}, delay );
61			}) :
62			this._focus.apply( this, arguments );
63	},
64
65	scrollParent: function() {
66		var scrollParent;
67		if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
68			scrollParent = this.parents().filter(function() {
69				return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
70			}).eq(0);
71		} else {
72			scrollParent = this.parents().filter(function() {
73				return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
74			}).eq(0);
75		}
76
77		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
78	},
79
80	zIndex: function( zIndex ) {
81		if ( zIndex !== undefined ) {
82			return this.css( "zIndex", zIndex );
83		}
84
85		if ( this.length ) {
86			var elem = $( this[ 0 ] ), position, value;
87			while ( elem.length && elem[ 0 ] !== document ) {
88				// Ignore z-index if position is set to a value where z-index is ignored by the browser
89				// This makes behavior of this function consistent across browsers
90				// WebKit always returns auto if the element is positioned
91				position = elem.css( "position" );
92				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
93					// IE returns 0 when zIndex is not specified
94					// other browsers return a string
95					// we ignore the case of nested elements with an explicit value of 0
96					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
97					value = parseInt( elem.css( "zIndex" ), 10 );
98					if ( !isNaN( value ) && value !== 0 ) {
99						return value;
100					}
101				}
102				elem = elem.parent();
103			}
104		}
105
106		return 0;
107	},
108
109	uniqueId: function() {
110		return this.each(function() {
111			if ( !this.id ) {
112				this.id = "ui-id-" + (++uuid);
113			}
114		});
115	},
116
117	removeUniqueId: function() {
118		return this.each(function() {
119			if ( runiqueId.test( this.id ) ) {
120				$( this ).removeAttr( "id" );
121			}
122		});
123	}
124});
125
126// selectors
127function focusable( element, isTabIndexNotNaN ) {
128	var map, mapName, img,
129		nodeName = element.nodeName.toLowerCase();
130	if ( "area" === nodeName ) {
131		map = element.parentNode;
132		mapName = map.name;
133		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
134			return false;
135		}
136		img = $( "img[usemap=#" + mapName + "]" )[0];
137		return !!img && visible( img );
138	}
139	return ( /input|select|textarea|button|object/.test( nodeName ) ?
140		!element.disabled :
141		"a" === nodeName ?
142			element.href || isTabIndexNotNaN :
143			isTabIndexNotNaN) &&
144		// the element and all of its ancestors must be visible
145		visible( element );
146}
147
148function visible( element ) {
149	return $.expr.filters.visible( element ) &&
150		!$( element ).parents().andSelf().filter(function() {
151			return $.css( this, "visibility" ) === "hidden";
152		}).length;
153}
154
155$.extend( $.expr[ ":" ], {
156	data: $.expr.createPseudo ?
157		$.expr.createPseudo(function( dataName ) {
158			return function( elem ) {
159				return !!$.data( elem, dataName );
160			};
161		}) :
162		// support: jQuery <1.8
163		function( elem, i, match ) {
164			return !!$.data( elem, match[ 3 ] );
165		},
166
167	focusable: function( element ) {
168		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
169	},
170
171	tabbable: function( element ) {
172		var tabIndex = $.attr( element, "tabindex" ),
173			isTabIndexNaN = isNaN( tabIndex );
174		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
175	}
176});
177
178// support
179$(function() {
180	var body = document.body,
181		div = body.appendChild( div = document.createElement( "div" ) );
182
183	// access offsetHeight before setting the style to prevent a layout bug
184	// in IE 9 which causes the element to continue to take up space even
185	// after it is removed from the DOM (#8026)
186	div.offsetHeight;
187
188	$.extend( div.style, {
189		minHeight: "100px",
190		height: "auto",
191		padding: 0,
192		borderWidth: 0
193	});
194
195	$.support.minHeight = div.offsetHeight === 100;
196	$.support.selectstart = "onselectstart" in div;
197
198	// set display to none to avoid a layout bug in IE
199	// http://dev.jquery.com/ticket/4014
200	body.removeChild( div ).style.display = "none";
201});
202
203// support: jQuery <1.8
204if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
205	$.each( [ "Width", "Height" ], function( i, name ) {
206		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
207			type = name.toLowerCase(),
208			orig = {
209				innerWidth: $.fn.innerWidth,
210				innerHeight: $.fn.innerHeight,
211				outerWidth: $.fn.outerWidth,
212				outerHeight: $.fn.outerHeight
213			};
214
215		function reduce( elem, size, border, margin ) {
216			$.each( side, function() {
217				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
218				if ( border ) {
219					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
220				}
221				if ( margin ) {
222					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
223				}
224			});
225			return size;
226		}
227
228		$.fn[ "inner" + name ] = function( size ) {
229			if ( size === undefined ) {
230				return orig[ "inner" + name ].call( this );
231			}
232
233			return this.each(function() {
234				$( this ).css( type, reduce( this, size ) + "px" );
235			});
236		};
237
238		$.fn[ "outer" + name] = function( size, margin ) {
239			if ( typeof size !== "number" ) {
240				return orig[ "outer" + name ].call( this, size );
241			}
242
243			return this.each(function() {
244				$( this).css( type, reduce( this, size, true, margin ) + "px" );
245			});
246		};
247	});
248}
249
250// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
251if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
252	$.fn.removeData = (function( removeData ) {
253		return function( key ) {
254			if ( arguments.length ) {
255				return removeData.call( this, $.camelCase( key ) );
256			} else {
257				return removeData.call( this );
258			}
259		};
260	})( $.fn.removeData );
261}
262
263
264
265
266
267// deprecated
268
269(function() {
270	var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
271	$.ui.ie = uaMatch.length ? true : false;
272	$.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
273})();
274
275$.fn.extend({
276	disableSelection: function() {
277		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
278			".ui-disableSelection", function( event ) {
279				event.preventDefault();
280			});
281	},
282
283	enableSelection: function() {
284		return this.unbind( ".ui-disableSelection" );
285	}
286});
287
288$.extend( $.ui, {
289	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
290	plugin: {
291		add: function( module, option, set ) {
292			var i,
293				proto = $.ui[ module ].prototype;
294			for ( i in set ) {
295				proto.plugins[ i ] = proto.plugins[ i ] || [];
296				proto.plugins[ i ].push( [ option, set[ i ] ] );
297			}
298		},
299		call: function( instance, name, args ) {
300			var i,
301				set = instance.plugins[ name ];
302			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
303				return;
304			}
305
306			for ( i = 0; i < set.length; i++ ) {
307				if ( instance.options[ set[ i ][ 0 ] ] ) {
308					set[ i ][ 1 ].apply( instance.element, args );
309				}
310			}
311		}
312	},
313
314	contains: $.contains,
315
316	// only used by resizable
317	hasScroll: function( el, a ) {
318
319		//If overflow is hidden, the element might have extra content, but the user wants to hide it
320		if ( $( el ).css( "overflow" ) === "hidden") {
321			return false;
322		}
323
324		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
325			has = false;
326
327		if ( el[ scroll ] > 0 ) {
328			return true;
329		}
330
331		// TODO: determine which cases actually cause this to happen
332		// if the element doesn't have the scroll set, see if it's possible to
333		// set the scroll
334		el[ scroll ] = 1;
335		has = ( el[ scroll ] > 0 );
336		el[ scroll ] = 0;
337		return has;
338	},
339
vendor: 15,569 bytes, lines 340-848
340	// these are odd functions, fix the API or move into individual plugins
341	isOverAxis: function( x, reference, size ) {
342		//Determines when x coordinate is over "b" element axis
343		return ( x > reference ) && ( x < ( reference + size ) );
344	},
345	isOver: function( y, x, top, left, height, width ) {
346		//Determines when x, y coordinates is over "b" element
347		return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
348	}
349});
350
351})( jQuery );
352(function( $, undefined ) {
353
354var uuid = 0,
355	slice = Array.prototype.slice,
356	_cleanData = $.cleanData;
357$.cleanData = function( elems ) {
358	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
359		try {
360			$( elem ).triggerHandler( "remove" );
361		// http://bugs.jquery.com/ticket/8235
362		} catch( e ) {}
363	}
364	_cleanData( elems );
365};
366
367$.widget = function( name, base, prototype ) {
368	var fullName, existingConstructor, constructor, basePrototype,
369		namespace = name.split( "." )[ 0 ];
370
371	name = name.split( "." )[ 1 ];
372	fullName = namespace + "-" + name;
373
374	if ( !prototype ) {
375		prototype = base;
376		base = $.Widget;
377	}
378
379	// create selector for plugin
380	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
381		return !!$.data( elem, fullName );
382	};
383
384	$[ namespace ] = $[ namespace ] || {};
385	existingConstructor = $[ namespace ][ name ];
386	constructor = $[ namespace ][ name ] = function( options, element ) {
387		// allow instantiation without "new" keyword
388		if ( !this._createWidget ) {
389			return new constructor( options, element );
390		}
391
392		// allow instantiation without initializing for simple inheritance
393		// must use "new" keyword (the code above always passes args)
394		if ( arguments.length ) {
395			this._createWidget( options, element );
396		}
397	};
398	// extend with the existing constructor to carry over any static properties
399	$.extend( constructor, existingConstructor, {
400		version: prototype.version,
401		// copy the object used to create the prototype in case we need to
402		// redefine the widget later
403		_proto: $.extend( {}, prototype ),
404		// track widgets that inherit from this widget in case this widget is
405		// redefined after a widget inherits from it
406		_childConstructors: []
407	});
408
409	basePrototype = new base();
410	// we need to make the options hash a property directly on the new instance
411	// otherwise we'll modify the options hash on the prototype that we're
412	// inheriting from
413	basePrototype.options = $.widget.extend( {}, basePrototype.options );
414	$.each( prototype, function( prop, value ) {
415		if ( $.isFunction( value ) ) {
416			prototype[ prop ] = (function() {
417				var _super = function() {
418						return base.prototype[ prop ].apply( this, arguments );
419					},
420					_superApply = function( args ) {
421						return base.prototype[ prop ].apply( this, args );
422					};
423				return function() {
424					var __super = this._super,
425						__superApply = this._superApply,
426						returnValue;
427
428					this._super = _super;
429					this._superApply = _superApply;
430
431					returnValue = value.apply( this, arguments );
432
433					this._super = __super;
434					this._superApply = __superApply;
435
436					return returnValue;
437				};
438			})();
439		}
440	});
441	constructor.prototype = $.widget.extend( basePrototype, {
442		// TODO: remove support for widgetEventPrefix
443		// always use the name + a colon as the prefix, e.g., draggable:start
444		// don't prefix for widgets that aren't DOM-based
445		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
446	}, prototype, {
447		constructor: constructor,
448		namespace: namespace,
449		widgetName: name,
450		// TODO remove widgetBaseClass, see #8155
451		widgetBaseClass: fullName,
452		widgetFullName: fullName
453	});
454
455	// If this widget is being redefined then we need to find all widgets that
456	// are inheriting from it and redefine all of them so that they inherit from
457	// the new version of this widget. We're essentially trying to replace one
458	// level in the prototype chain.
459	if ( existingConstructor ) {
460		$.each( existingConstructor._childConstructors, function( i, child ) {
461			var childPrototype = child.prototype;
462
463			// redefine the child widget using the same prototype that was
464			// originally used, but inherit from the new version of the base
465			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
466		});
467		// remove the list of existing child constructors from the old constructor
468		// so the old child constructors can be garbage collected
469		delete existingConstructor._childConstructors;
470	} else {
471		base._childConstructors.push( constructor );
472	}
473
474	$.widget.bridge( name, constructor );
475};
476
477$.widget.extend = function( target ) {
478	var input = slice.call( arguments, 1 ),
479		inputIndex = 0,
480		inputLength = input.length,
481		key,
482		value;
483	for ( ; inputIndex < inputLength; inputIndex++ ) {
484		for ( key in input[ inputIndex ] ) {
485			value = input[ inputIndex ][ key ];
486			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
487				// Clone objects
488				if ( $.isPlainObject( value ) ) {
489					target[ key ] = $.isPlainObject( target[ key ] ) ?
490						$.widget.extend( {}, target[ key ], value ) :
491						// Don't extend strings, arrays, etc. with objects
492						$.widget.extend( {}, value );
493				// Copy everything else by reference
494				} else {
495					target[ key ] = value;
496				}
497			}
498		}
499	}
500	return target;
501};
502
503$.widget.bridge = function( name, object ) {
504	var fullName = object.prototype.widgetFullName || name;
505	$.fn[ name ] = function( options ) {
506		var isMethodCall = typeof options === "string",
507			args = slice.call( arguments, 1 ),
508			returnValue = this;
509
510		// allow multiple hashes to be passed on init
511		options = !isMethodCall && args.length ?
512			$.widget.extend.apply( null, [ options ].concat(args) ) :
513			options;
514
515		if ( isMethodCall ) {
516			this.each(function() {
517				var methodValue,
518					instance = $.data( this, fullName );
519				if ( !instance ) {
520					return $.error( "cannot call methods on " + name + " prior to initialization; " +
521						"attempted to call method '" + options + "'" );
522				}
523				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
524					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
525				}
526				methodValue = instance[ options ].apply( instance, args );
527				if ( methodValue !== instance && methodValue !== undefined ) {
528					returnValue = methodValue && methodValue.jquery ?
529						returnValue.pushStack( methodValue.get() ) :
530						methodValue;
531					return false;
532				}
533			});
534		} else {
535			this.each(function() {
536				var instance = $.data( this, fullName );
537				if ( instance ) {
538					instance.option( options || {} )._init();
539				} else {
540					$.data( this, fullName, new object( options, this ) );
541				}
542			});
543		}
544
545		return returnValue;
546	};
547};
548
549$.Widget = function( /* options, element */ ) {};
550$.Widget._childConstructors = [];
551
552$.Widget.prototype = {
553	widgetName: "widget",
554	widgetEventPrefix: "",
555	defaultElement: "<div>",
556	options: {
557		disabled: false,
558
559		// callbacks
560		create: null
561	},
562	_createWidget: function( options, element ) {
563		element = $( element || this.defaultElement || this )[ 0 ];
564		this.element = $( element );
565		this.uuid = uuid++;
566		this.eventNamespace = "." + this.widgetName + this.uuid;
567		this.options = $.widget.extend( {},
568			this.options,
569			this._getCreateOptions(),
570			options );
571
572		this.bindings = $();
573		this.hoverable = $();
574		this.focusable = $();
575
576		if ( element !== this ) {
577			// 1.9 BC for #7810
578			// TODO remove dual storage
579			$.data( element, this.widgetName, this );
580			$.data( element, this.widgetFullName, this );
581			this._on( true, this.element, {
582				remove: function( event ) {
583					if ( event.target === element ) {
584						this.destroy();
585					}
586				}
587			});
588			this.document = $( element.style ?
589				// element within the document
590				element.ownerDocument :
591				// element is window or document
592				element.document || element );
593			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
594		}
595
596		this._create();
597		this._trigger( "create", null, this._getCreateEventData() );
598		this._init();
599	},
600	_getCreateOptions: $.noop,
601	_getCreateEventData: $.noop,
602	_create: $.noop,
603	_init: $.noop,
604
605	destroy: function() {
606		this._destroy();
607		// we can probably remove the unbind calls in 2.0
608		// all event bindings should go through this._on()
609		this.element
610			.unbind( this.eventNamespace )
611			// 1.9 BC for #7810
612			// TODO remove dual storage
613			.removeData( this.widgetName )
614			.removeData( this.widgetFullName )
615			// support: jquery <1.6.3
616			// http://bugs.jquery.com/ticket/9413
617			.removeData( $.camelCase( this.widgetFullName ) );
618		this.widget()
619			.unbind( this.eventNamespace )
620			.removeAttr( "aria-disabled" )
621			.removeClass(
622				this.widgetFullName + "-disabled " +
623				"ui-state-disabled" );
624
625		// clean up events and states
626		this.bindings.unbind( this.eventNamespace );
627		this.hoverable.removeClass( "ui-state-hover" );
628		this.focusable.removeClass( "ui-state-focus" );
629	},
630	_destroy: $.noop,
631
632	widget: function() {
633		return this.element;
634	},
635
636	option: function( key, value ) {
637		var options = key,
638			parts,
639			curOption,
640			i;
641
642		if ( arguments.length === 0 ) {
643			// don't return a reference to the internal hash
644			return $.widget.extend( {}, this.options );
645		}
646
647		if ( typeof key === "string" ) {
648			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
649			options = {};
650			parts = key.split( "." );
651			key = parts.shift();
652			if ( parts.length ) {
653				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
654				for ( i = 0; i < parts.length - 1; i++ ) {
655					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
656					curOption = curOption[ parts[ i ] ];
657				}
658				key = parts.pop();
659				if ( value === undefined ) {
660					return curOption[ key ] === undefined ? null : curOption[ key ];
661				}
662				curOption[ key ] = value;
663			} else {
664				if ( value === undefined ) {
665					return this.options[ key ] === undefined ? null : this.options[ key ];
666				}
667				options[ key ] = value;
668			}
669		}
670
671		this._setOptions( options );
672
673		return this;
674	},
675	_setOptions: function( options ) {
676		var key;
677
678		for ( key in options ) {
679			this._setOption( key, options[ key ] );
680		}
681
682		return this;
683	},
684	_setOption: function( key, value ) {
685		this.options[ key ] = value;
686
687		if ( key === "disabled" ) {
688			this.widget()
689				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
690				.attr( "aria-disabled", value );
691			this.hoverable.removeClass( "ui-state-hover" );
692			this.focusable.removeClass( "ui-state-focus" );
693		}
694
695		return this;
696	},
697
698	enable: function() {
699		return this._setOption( "disabled", false );
700	},
701	disable: function() {
702		return this._setOption( "disabled", true );
703	},
704
705	_on: function( suppressDisabledCheck, element, handlers ) {
706		var delegateElement,
707			instance = this;
708
709		// no suppressDisabledCheck flag, shuffle arguments
710		if ( typeof suppressDisabledCheck !== "boolean" ) {
711			handlers = element;
712			element = suppressDisabledCheck;
713			suppressDisabledCheck = false;
714		}
715
716		// no element argument, shuffle and use this.element
717		if ( !handlers ) {
718			handlers = element;
719			element = this.element;
720			delegateElement = this.widget();
721		} else {
722			// accept selectors, DOM elements
723			element = delegateElement = $( element );
724			this.bindings = this.bindings.add( element );
725		}
726
727		$.each( handlers, function( event, handler ) {
728			function handlerProxy() {
729				// allow widgets to customize the disabled handling
730				// - disabled as an array instead of boolean
731				// - disabled class as method for disabling individual parts
732				if ( !suppressDisabledCheck &&
733						( instance.options.disabled === true ||
734							$( this ).hasClass( "ui-state-disabled" ) ) ) {
735					return;
736				}
737				return ( typeof handler === "string" ? instance[ handler ] : handler )
738					.apply( instance, arguments );
739			}
740
741			// copy the guid so direct unbinding works
742			if ( typeof handler !== "string" ) {
743				handlerProxy.guid = handler.guid =
744					handler.guid || handlerProxy.guid || $.guid++;
745			}
746
747			var match = event.match( /^(\w+)\s*(.*)$/ ),
748				eventName = match[1] + instance.eventNamespace,
749				selector = match[2];
750			if ( selector ) {
751				delegateElement.delegate( selector, eventName, handlerProxy );
752			} else {
753				element.bind( eventName, handlerProxy );
754			}
755		});
756	},
757
758	_off: function( element, eventName ) {
759		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
760		element.unbind( eventName ).undelegate( eventName );
761	},
762
763	_delay: function( handler, delay ) {
764		function handlerProxy() {
765			return ( typeof handler === "string" ? instance[ handler ] : handler )
766				.apply( instance, arguments );
767		}
768		var instance = this;
769		return setTimeout( handlerProxy, delay || 0 );
770	},
771
772	_hoverable: function( element ) {
773		this.hoverable = this.hoverable.add( element );
774		this._on( element, {
775			mouseenter: function( event ) {
776				$( event.currentTarget ).addClass( "ui-state-hover" );
777			},
778			mouseleave: function( event ) {
779				$( event.currentTarget ).removeClass( "ui-state-hover" );
780			}
781		});
782	},
783
784	_focusable: function( element ) {
785		this.focusable = this.focusable.add( element );
786		this._on( element, {
787			focusin: function( event ) {
788				$( event.currentTarget ).addClass( "ui-state-focus" );
789			},
790			focusout: function( event ) {
791				$( event.currentTarget ).removeClass( "ui-state-focus" );
792			}
793		});
794	},
795
796	_trigger: function( type, event, data ) {
797		var prop, orig,
798			callback = this.options[ type ];
799
800		data = data || {};
801		event = $.Event( event );
802		event.type = ( type === this.widgetEventPrefix ?
803			type :
804			this.widgetEventPrefix + type ).toLowerCase();
805		// the original event may come from any element
806		// so we need to reset the target on the new event
807		event.target = this.element[ 0 ];
808
809		// copy original event properties over to the new event
810		orig = event.originalEvent;
811		if ( orig ) {
812			for ( prop in orig ) {
813				if ( !( prop in event ) ) {
814					event[ prop ] = orig[ prop ];
815				}
816			}
817		}
818
819		this.element.trigger( event, data );
820		return !( $.isFunction( callback ) &&
821			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
822			event.isDefaultPrevented() );
823	}
824};
825
826$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
827	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
828		if ( typeof options === "string" ) {
829			options = { effect: options };
830		}
831		var hasOptions,
832			effectName = !options ?
833				method :
834				options === true || typeof options === "number" ?
835					defaultEffect :
836					options.effect || defaultEffect;
837		options = options || {};
838		if ( typeof options === "number" ) {
839			options = { duration: options };
840		}
841		hasOptions = !$.isEmptyObject( options );
842		options.complete = callback;
843		if ( options.delay ) {
844			element.delay( options.delay );
845		}
846		if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
847			element[ method ]( options );
848		} else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,729 bytes, lines 849-1019
849			element[ effectName ]( options.duration, options.easing, callback );
850		} else {
851			element.queue(function( next ) {
852				$( this )[ method ]();
853				if ( callback ) {
854					callback.call( element[ 0 ] );
855				}
856				next();
857			});
858		}
859	};
860});
861
862// DEPRECATED
863if ( $.uiBackCompat !== false ) {
864	$.Widget.prototype._getCreateOptions = function() {
865		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
866	};
867}
868
869})( jQuery );
870(function( $, undefined ) {
871
872var mouseHandled = false;
873$( document ).mouseup( function( e ) {
874	mouseHandled = false;
875});
876
877$.widget("ui.mouse", {
878	version: "1.9.2",
879	options: {
880		cancel: 'input,textarea,button,select,option',
881		distance: 1,
882		delay: 0
883	},
884	_mouseInit: function() {
885		var that = this;
886
887		this.element
888			.bind('mousedown.'+this.widgetName, function(event) {
889				return that._mouseDown(event);
890			})
891			.bind('click.'+this.widgetName, function(event) {
892				if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
893					$.removeData(event.target, that.widgetName + '.preventClickEvent');
894					event.stopImmediatePropagation();
895					return false;
896				}
897			});
898
899		this.started = false;
900	},
901
902	// TODO: make sure destroying one instance of mouse doesn't mess with
903	// other instances of mouse
904	_mouseDestroy: function() {
905		this.element.unbind('.'+this.widgetName);
906		if ( this._mouseMoveDelegate ) {
907			$(document)
908				.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
909				.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
910		}
911	},
912
913	_mouseDown: function(event) {
914		// don't let more than one widget handle mouseStart
915		if( mouseHandled ) { return; }
916
917		// we may have missed mouseup (out of window)
918		(this._mouseStarted && this._mouseUp(event));
919
920		this._mouseDownEvent = event;
921
922		var that = this,
923			btnIsLeft = (event.which === 1),
924			// event.target.nodeName works around a bug in IE 8 with
925			// disabled inputs (#7620)
926			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
927		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
928			return true;
929		}
930
931		this.mouseDelayMet = !this.options.delay;
932		if (!this.mouseDelayMet) {
933			this._mouseDelayTimer = setTimeout(function() {
934				that.mouseDelayMet = true;
935			}, this.options.delay);
936		}
937
938		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
939			this._mouseStarted = (this._mouseStart(event) !== false);
940			if (!this._mouseStarted) {
941				event.preventDefault();
942				return true;
943			}
944		}
945
946		// Click event may never have fired (Gecko & Opera)
947		if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
948			$.removeData(event.target, this.widgetName + '.preventClickEvent');
949		}
950
951		// these delegates are required to keep context
952		this._mouseMoveDelegate = function(event) {
953			return that._mouseMove(event);
954		};
955		this._mouseUpDelegate = function(event) {
956			return that._mouseUp(event);
957		};
958		$(document)
959			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
960			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
961
962		event.preventDefault();
963
964		mouseHandled = true;
965		return true;
966	},
967
968	_mouseMove: function(event) {
969		// IE mouseup check - mouseup happened when mouse was out of window
970		if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
971			return this._mouseUp(event);
972		}
973
974		if (this._mouseStarted) {
975			this._mouseDrag(event);
976			return event.preventDefault();
977		}
978
979		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
980			this._mouseStarted =
981				(this._mouseStart(this._mouseDownEvent, event) !== false);
982			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
983		}
984
985		return !this._mouseStarted;
986	},
987
988	_mouseUp: function(event) {
989		$(document)
990			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
991			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
992
993		if (this._mouseStarted) {
994			this._mouseStarted = false;
995
996			if (event.target === this._mouseDownEvent.target) {
997				$.data(event.target, this.widgetName + '.preventClickEvent', true);
998			}
999
1000			this._mouseStop(event);
1001		}
1002
1003		return false;
1004	},
1005
1006	_mouseDistanceMet: function(event) {
1007		return (Math.max(
1008				Math.abs(this._mouseDownEvent.pageX - event.pageX),
1009				Math.abs(this._mouseDownEvent.pageY - event.pageY)
1010			) >= this.options.distance
1011		);
1012	},
1013
1014	_mouseDelayMet: function(event) {
1015		return this.mouseDelayMet;
1016	},
1017
1018	// These are placeholder methods, to be overriden by extending plugin
1019	_mouseStart: function(event) {},
1020	_mouseDrag: function(event) {},
1021	_mouseStop: function(event) {},
1022	_mouseCapture: function(event) { return true; }
1023});
1024
1025})(jQuery);
1026(function( $, undefined ) {
1027
1028$.ui = $.ui || {};
1029
1030var cachedScrollbarWidth,
1031	max = Math.max,
1032	abs = Math.abs,
1033	round = Math.round,
1034	rhorizontal = /left|center|right/,
1035	rvertical = /top|center|bottom/,
1036	roffset = /[\+\-]\d+%?/,
1037	rposition = /^\w+/,
1038	rpercent = /%$/,
1039	_position = $.fn.position;
1040
1041function getOffsets( offsets, width, height ) {
1042	return [
1043		parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1044		parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1045	];
1046}
1047function parseCss( element, property ) {
1048	return parseInt( $.css( element, property ), 10 ) || 0;
1049}
1050
1051$.position = {
1052	scrollbarWidth: function() {
1053		if ( cachedScrollbarWidth !== undefined ) {
1054			return cachedScrollbarWidth;
1055		}
1056		var w1, w2,
1057			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1058			innerDiv = div.children()[0];
1059
1060		$( "body" ).append( div );
1061		w1 = innerDiv.offsetWidth;
1062		div.css( "overflow", "scroll" );
1063
1064		w2 = innerDiv.offsetWidth;
1065
1066		if ( w1 === w2 ) {
1067			w2 = div[0].clientWidth;
1068		}
1069
1070		div.remove();
1071
1072		return (cachedScrollbarWidth = w1 - w2);
1073	},
1074	getScrollInfo: function( within ) {
1075		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
1076			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
1077			hasOverflowX = overflowX === "scroll" ||
1078				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1079			hasOverflowY = overflowY === "scroll" ||
1080				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1081		return {
1082			width: hasOverflowX ? $.position.scrollbarWidth() : 0,
1083			height: hasOverflowY ? $.position.scrollbarWidth() : 0
1084		};
1085	},
1086	getWithinInfo: function( element ) {
1087		var withinElement = $( element || window ),
1088			isWindow = $.isWindow( withinElement[0] );
1089		return {
1090			element: withinElement,
1091			isWindow: isWindow,
1092			offset: withinElement.offset() || { left: 0, top: 0 },
1093			scrollLeft: withinElement.scrollLeft(),
1094			scrollTop: withinElement.scrollTop(),
1095			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1096			height: isWindow ? withinElement.height() : withinElement.outerHeight()
1097		};
1098	}
1099};
1100
1101$.fn.position = function( options ) {
1102	if ( !options || !options.of ) {
1103		return _position.apply( this, arguments );
1104	}
1105
1106	// make a copy, we don't want to modify arguments
1107	options = $.extend( {}, options );
1108
1109	var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
1110		target = $( options.of ),
1111		within = $.position.getWithinInfo( options.within ),
1112		scrollInfo = $.position.getScrollInfo( within ),
1113		targetElem = target[0],
1114		collision = ( options.collision || "flip" ).split( " " ),
1115		offsets = {};
1116
1117	if ( targetElem.nodeType === 9 ) {
1118		targetWidth = target.width();
1119		targetHeight = target.height();
1120		targetOffset = { top: 0, left: 0 };
1121	} else if ( $.isWindow( targetElem ) ) {
1122		targetWidth = target.width();
1123		targetHeight = target.height();
1124		targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
1125	} else if ( targetElem.preventDefault ) {
1126		// force left top to allow flipping
1127		options.at = "left top";
1128		targetWidth = targetHeight = 0;
1129		targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
1130	} else {
1131		targetWidth = target.outerWidth();
1132		targetHeight = target.outerHeight();
1133		targetOffset = target.offset();
1134	}
1135	// clone to reuse original targetOffset later
1136	basePosition = $.extend( {}, targetOffset );
1137
1138	// force my and at to have valid horizontal and vertical positions
1139	// if a value is missing or invalid, it will be converted to center
1140	$.each( [ "my", "at" ], function() {
1141		var pos = ( options[ this ] || "" ).split( " " ),
1142			horizontalOffset,
1143			verticalOffset;
1144
1145		if ( pos.length === 1) {
1146			pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 11,271 bytes, lines 1147-1475
1147				pos.concat( [ "center" ] ) :
1148				rvertical.test( pos[ 0 ] ) ?
1149					[ "center" ].concat( pos ) :
1150					[ "center", "center" ];
1151		}
1152		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1153		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1154
1155		// calculate offsets
1156		horizontalOffset = roffset.exec( pos[ 0 ] );
1157		verticalOffset = roffset.exec( pos[ 1 ] );
1158		offsets[ this ] = [
1159			horizontalOffset ? horizontalOffset[ 0 ] : 0,
1160			verticalOffset ? verticalOffset[ 0 ] : 0
1161		];
1162
1163		// reduce to just the positions without the offsets
1164		options[ this ] = [
1165			rposition.exec( pos[ 0 ] )[ 0 ],
1166			rposition.exec( pos[ 1 ] )[ 0 ]
1167		];
1168	});
1169
1170	// normalize collision option
1171	if ( collision.length === 1 ) {
1172		collision[ 1 ] = collision[ 0 ];
1173	}
1174
1175	if ( options.at[ 0 ] === "right" ) {
1176		basePosition.left += targetWidth;
1177	} else if ( options.at[ 0 ] === "center" ) {
1178		basePosition.left += targetWidth / 2;
1179	}
1180
1181	if ( options.at[ 1 ] === "bottom" ) {
1182		basePosition.top += targetHeight;
1183	} else if ( options.at[ 1 ] === "center" ) {
1184		basePosition.top += targetHeight / 2;
1185	}
1186
1187	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1188	basePosition.left += atOffset[ 0 ];
1189	basePosition.top += atOffset[ 1 ];
1190
1191	return this.each(function() {
1192		var collisionPosition, using,
1193			elem = $( this ),
1194			elemWidth = elem.outerWidth(),
1195			elemHeight = elem.outerHeight(),
1196			marginLeft = parseCss( this, "marginLeft" ),
1197			marginTop = parseCss( this, "marginTop" ),
1198			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1199			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1200			position = $.extend( {}, basePosition ),
1201			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1202
1203		if ( options.my[ 0 ] === "right" ) {
1204			position.left -= elemWidth;
1205		} else if ( options.my[ 0 ] === "center" ) {
1206			position.left -= elemWidth / 2;
1207		}
1208
1209		if ( options.my[ 1 ] === "bottom" ) {
1210			position.top -= elemHeight;
1211		} else if ( options.my[ 1 ] === "center" ) {
1212			position.top -= elemHeight / 2;
1213		}
1214
1215		position.left += myOffset[ 0 ];
1216		position.top += myOffset[ 1 ];
1217
1218		// if the browser doesn't support fractions, then round for consistent results
1219		if ( !$.support.offsetFractions ) {
1220			position.left = round( position.left );
1221			position.top = round( position.top );
1222		}
1223
1224		collisionPosition = {
1225			marginLeft: marginLeft,
1226			marginTop: marginTop
1227		};
1228
1229		$.each( [ "left", "top" ], function( i, dir ) {
1230			if ( $.ui.position[ collision[ i ] ] ) {
1231				$.ui.position[ collision[ i ] ][ dir ]( position, {
1232					targetWidth: targetWidth,
1233					targetHeight: targetHeight,
1234					elemWidth: elemWidth,
1235					elemHeight: elemHeight,
1236					collisionPosition: collisionPosition,
1237					collisionWidth: collisionWidth,
1238					collisionHeight: collisionHeight,
1239					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1240					my: options.my,
1241					at: options.at,
1242					within: within,
1243					elem : elem
1244				});
1245			}
1246		});
1247
1248		if ( $.fn.bgiframe ) {
1249			elem.bgiframe();
1250		}
1251
1252		if ( options.using ) {
1253			// adds feedback as second argument to using callback, if present
1254			using = function( props ) {
1255				var left = targetOffset.left - position.left,
1256					right = left + targetWidth - elemWidth,
1257					top = targetOffset.top - position.top,
1258					bottom = top + targetHeight - elemHeight,
1259					feedback = {
1260						target: {
1261							element: target,
1262							left: targetOffset.left,
1263							top: targetOffset.top,
1264							width: targetWidth,
1265							height: targetHeight
1266						},
1267						element: {
1268							element: elem,
1269							left: position.left,
1270							top: position.top,
1271							width: elemWidth,
1272							height: elemHeight
1273						},
1274						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1275						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1276					};
1277				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1278					feedback.horizontal = "center";
1279				}
1280				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1281					feedback.vertical = "middle";
1282				}
1283				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1284					feedback.important = "horizontal";
1285				} else {
1286					feedback.important = "vertical";
1287				}
1288				options.using.call( this, props, feedback );
1289			};
1290		}
1291
1292		elem.offset( $.extend( position, { using: using } ) );
1293	});
1294};
1295
1296$.ui.position = {
1297	fit: {
1298		left: function( position, data ) {
1299			var within = data.within,
1300				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1301				outerWidth = within.width,
1302				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1303				overLeft = withinOffset - collisionPosLeft,
1304				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1305				newOverRight;
1306
1307			// element is wider than within
1308			if ( data.collisionWidth > outerWidth ) {
1309				// element is initially over the left side of within
1310				if ( overLeft > 0 && overRight <= 0 ) {
1311					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1312					position.left += overLeft - newOverRight;
1313				// element is initially over right side of within
1314				} else if ( overRight > 0 && overLeft <= 0 ) {
1315					position.left = withinOffset;
1316				// element is initially over both left and right sides of within
1317				} else {
1318					if ( overLeft > overRight ) {
1319						position.left = withinOffset + outerWidth - data.collisionWidth;
1320					} else {
1321						position.left = withinOffset;
1322					}
1323				}
1324			// too far left -> align with left edge
1325			} else if ( overLeft > 0 ) {
1326				position.left += overLeft;
1327			// too far right -> align with right edge
1328			} else if ( overRight > 0 ) {
1329				position.left -= overRight;
1330			// adjust based on position and margin
1331			} else {
1332				position.left = max( position.left - collisionPosLeft, position.left );
1333			}
1334		},
1335		top: function( position, data ) {
1336			var within = data.within,
1337				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1338				outerHeight = data.within.height,
1339				collisionPosTop = position.top - data.collisionPosition.marginTop,
1340				overTop = withinOffset - collisionPosTop,
1341				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1342				newOverBottom;
1343
1344			// element is taller than within
1345			if ( data.collisionHeight > outerHeight ) {
1346				// element is initially over the top of within
1347				if ( overTop > 0 && overBottom <= 0 ) {
1348					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1349					position.top += overTop - newOverBottom;
1350				// element is initially over bottom of within
1351				} else if ( overBottom > 0 && overTop <= 0 ) {
1352					position.top = withinOffset;
1353				// element is initially over both top and bottom of within
1354				} else {
1355					if ( overTop > overBottom ) {
1356						position.top = withinOffset + outerHeight - data.collisionHeight;
1357					} else {
1358						position.top = withinOffset;
1359					}
1360				}
1361			// too far up -> align with top
1362			} else if ( overTop > 0 ) {
1363				position.top += overTop;
1364			// too far down -> align with bottom edge
1365			} else if ( overBottom > 0 ) {
1366				position.top -= overBottom;
1367			// adjust based on position and margin
1368			} else {
1369				position.top = max( position.top - collisionPosTop, position.top );
1370			}
1371		}
1372	},
1373	flip: {
1374		left: function( position, data ) {
1375			var within = data.within,
1376				withinOffset = within.offset.left + within.scrollLeft,
1377				outerWidth = within.width,
1378				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1379				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1380				overLeft = collisionPosLeft - offsetLeft,
1381				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1382				myOffset = data.my[ 0 ] === "left" ?
1383					-data.elemWidth :
1384					data.my[ 0 ] === "right" ?
1385						data.elemWidth :
1386						0,
1387				atOffset = data.at[ 0 ] === "left" ?
1388					data.targetWidth :
1389					data.at[ 0 ] === "right" ?
1390						-data.targetWidth :
1391						0,
1392				offset = -2 * data.offset[ 0 ],
1393				newOverRight,
1394				newOverLeft;
1395
1396			if ( overLeft < 0 ) {
1397				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1398				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1399					position.left += myOffset + atOffset + offset;
1400				}
1401			}
1402			else if ( overRight > 0 ) {
1403				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1404				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1405					position.left += myOffset + atOffset + offset;
1406				}
1407			}
1408		},
1409		top: function( position, data ) {
1410			var within = data.within,
1411				withinOffset = within.offset.top + within.scrollTop,
1412				outerHeight = within.height,
1413				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1414				collisionPosTop = position.top - data.collisionPosition.marginTop,
1415				overTop = collisionPosTop - offsetTop,
1416				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1417				top = data.my[ 1 ] === "top",
1418				myOffset = top ?
1419					-data.elemHeight :
1420					data.my[ 1 ] === "bottom" ?
1421						data.elemHeight :
1422						0,
1423				atOffset = data.at[ 1 ] === "top" ?
1424					data.targetHeight :
1425					data.at[ 1 ] === "bottom" ?
1426						-data.targetHeight :
1427						0,
1428				offset = -2 * data.offset[ 1 ],
1429				newOverTop,
1430				newOverBottom;
1431			if ( overTop < 0 ) {
1432				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1433				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1434					position.top += myOffset + atOffset + offset;
1435				}
1436			}
1437			else if ( overBottom > 0 ) {
1438				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1439				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1440					position.top += myOffset + atOffset + offset;
1441				}
1442			}
1443		}
1444	},
1445	flipfit: {
1446		left: function() {
1447			$.ui.position.flip.left.apply( this, arguments );
1448			$.ui.position.fit.left.apply( this, arguments );
1449		},
1450		top: function() {
1451			$.ui.position.flip.top.apply( this, arguments );
1452			$.ui.position.fit.top.apply( this, arguments );
1453		}
1454	}
1455};
1456
1457// fraction support test
1458(function () {
1459	var testElement, testElementParent, testElementStyle, offsetLeft, i,
1460		body = document.getElementsByTagName( "body" )[ 0 ],
1461		div = document.createElement( "div" );
1462
1463	//Create a "fake body" for testing based on method used in jQuery.support
1464	testElement = document.createElement( body ? "div" : "body" );
1465	testElementStyle = {
1466		visibility: "hidden",
1467		width: 0,
1468		height: 0,
1469		border: 0,
1470		margin: 0,
1471		background: "none"
1472	};
1473	if ( body ) {
1474		$.extend( testElementStyle, {
1475			position: "absolute",
1476			left: "-1000px",
1477			top: "-1000px"
1478		});
1479	}
1480	for ( i in testElementStyle ) {
1481		testElement.style[ i ] = testElementStyle[ i ];
1482	}
1483	testElement.appendChild( div );
1484	testElementParent = body || document.documentElement;
1485	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1486
1487	div.style.cssText = "position: absolute; left: 10.7432222px;";
1488
1489	offsetLeft = $( div ).offset().left;
1490	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1491
1492	testElement.innerHTML = "";
1493	testElementParent.removeChild( testElement );
1494})();
1495
1496// DEPRECATED
1497if ( $.uiBackCompat !== false ) {
1498	// offset option
1499	(function( $ ) {
1500		var _position = $.fn.position;
1501		$.fn.position = function( options ) {
1502			if ( !options || !options.offset ) {
1503				return _position.call( this, options );
1504			}
1505			var offset = options.offset.split( " " ),
1506				at = options.at.split( " " );
1507			if ( offset.length === 1 ) {
1508				offset[ 1 ] = offset[ 0 ];
1509			}
1510			if ( /^\d/.test( offset[ 0 ] ) ) {
1511				offset[ 0 ] = "+" + offset[ 0 ];
1512			}
1513			if ( /^\d/.test( offset[ 1 ] ) ) {
1514				offset[ 1 ] = "+" + offset[ 1 ];
1515			}
1516			if ( at.length === 1 ) {
1517				if ( /left|center|right/.test( at[ 0 ] ) ) {
1518					at[ 1 ] = "center";
1519				} else {
1520					at[ 1 ] = at[ 0 ];
1521					at[ 0 ] = "center";
1522				}
1523			}
1524			return _position.call( this, $.extend( options, {
1525				at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
1526				offset: undefined
1527			} ) );
1528		};
1529	}( jQuery ) );
1530}
1531
1532}( jQuery ) );
1533(function( $, undefined ) {
1534
1535$.widget("ui.draggable", $.ui.mouse, {
1536	version: "1.9.2",
1537	widgetEventPrefix: "drag",
1538	options: {
1539		addClasses: true,
1540		appendTo: "parent",
1541		axis: false,
1542		connectToSortable: false,
1543		containment: false,
1544		cursor: "auto",
1545		cursorAt: false,
1546		grid: false,
1547		handle: false,
1548		helper: "original",
1549		iframeFix: false,
1550		opacity: false,
1551		refreshPositions: false,
1552		revert: false,
1553		revertDuration: 500,
1554		scope: "default",
1555		scroll: true,
1556		scrollSensitivity: 20,
1557		scrollSpeed: 20,
1558		snap: false,
1559		snapMode: "both",
1560		snapTolerance: 20,
1561		stack: false,
1562		zIndex: false
1563	},
1564	_create: function() {
1565
1566		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1567			this.element[0].style.position = 'relative';
1568
1569		(this.options.addClasses && this.element.addClass("ui-draggable"));
1570		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1571
1572		this._mouseInit();
1573
1574	},
1575
1576	_destroy: function() {
1577		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1578		this._mouseDestroy();
1579	},
1580
1581	_mouseCapture: function(event) {
1582
1583		var o = this.options;
1584
1585		// among others, prevent a drag on a resizable-handle
1586		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1587			return false;
1588
1589		//Quit if we're not on a valid handle
1590		this.handle = this._getHandle(event);
1591		if (!this.handle)
1592			return false;
1593
1594		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1595			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1596			.css({
1597				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1598				position: "absolute", opacity: "0.001", zIndex: 1000
1599			})
1600			.css($(this).offset())
1601			.appendTo("body");
1602		});
1603
1604		return true;
1605
1606	},
1607
1608	_mouseStart: function(event) {
1609
1610		var o = this.options;
1611
1612		//Create and append the visible helper
1613		this.helper = this._createHelper(event);
1614
1615		this.helper.addClass("ui-draggable-dragging");
1616
1617		//Cache the helper size
1618		this._cacheHelperProportions();
1619
1620		//If ddmanager is used for droppables, set the global draggable
1621		if($.ui.ddmanager)
1622			$.ui.ddmanager.current = this;
1623
1624		/*
1625		 * - Position generation -
1626		 * This block generates everything position related - it's the core of draggables.
1627		 */
1628
1629		//Cache the margins of the original element
1630		this._cacheMargins();
1631
1632		//Store the helper's css position
1633		this.cssPosition = this.helper.css("position");
1634		this.scrollParent = this.helper.scrollParent();
1635
1636		//The element's absolute position on the page minus margins
1637		this.offset = this.positionAbs = this.element.offset();
1638		this.offset = {
1639			top: this.offset.top - this.margins.top,
1640			left: this.offset.left - this.margins.left
1641		};
1642
1643		$.extend(this.offset, {
1644			click: { //Where the click happened, relative to the element
1645				left: event.pageX - this.offset.left,
1646				top: event.pageY - this.offset.top
1647			},
1648			parent: this._getParentOffset(),
1649			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1650		});
1651
1652		//Generate the original position
1653		this.originalPosition = this.position = this._generatePosition(event);
1654		this.originalPageX = event.pageX;
1655		this.originalPageY = event.pageY;
1656
1657		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1658		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1659
1660		//Set a containment if given in the options
1661		if(o.containment)
1662			this._setContainment();
1663
1664		//Trigger event + callbacks
1665		if(this._trigger("start", event) === false) {
1666			this._clear();
1667			return false;
1668		}
1669
1670		//Recache the helper size
1671		this._cacheHelperProportions();
1672
1673		//Prepare the droppable offsets
1674		if ($.ui.ddmanager && !o.dropBehaviour)
1675			$.ui.ddmanager.prepareOffsets(this, event);
1676
1677
1678		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1679
1680		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1681		if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1682
1683		return true;
1684	},
1685
1686	_mouseDrag: function(event, noPropagation) {
1687
1688		//Compute the helpers position
1689		this.position = this._generatePosition(event);
1690		this.positionAbs = this._convertPositionTo("absolute");
1691
1692		//Call plugins and callbacks and use the resulting position if something is returned
1693		if (!noPropagation) {
1694			var ui = this._uiHash();
1695			if(this._trigger('drag', event, ui) === false) {
1696				this._mouseUp({});
1697				return false;
1698			}
1699			this.position = ui.position;
1700		}
1701
1702		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1703		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1704		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1705
1706		return false;
1707	},
1708
1709	_mouseStop: function(event) {
1710
1711		//If we are using droppables, inform the manager about the drop
1712		var dropped = false;
1713		if ($.ui.ddmanager && !this.options.dropBehaviour)
1714			dropped = $.ui.ddmanager.drop(this, event);
1715
1716		//if a drop comes from outside (a sortable)
1717		if(this.dropped) {
1718			dropped = this.dropped;
1719			this.dropped = false;
1720		}
1721
1722		//if the original element is no longer in the DOM don't bother to continue (see #8269)
1723		var element = this.element[0], elementInDom = false;
1724		while ( element && (element = element.parentNode) ) {
1725			if (element == document ) {
1726				elementInDom = true;
1727			}
1728		}
1729		if ( !elementInDom && this.options.helper === "original" )
1730			return false;
1731
1732		if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1733			var that = this;
1734			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1735				if(that._trigger("stop", event) !== false) {
1736					that._clear();
1737				}
1738			});
1739		} else {
1740			if(this._trigger("stop", event) !== false) {
1741				this._clear();
1742			}
1743		}
1744
1745		return false;
1746	},
1747
1748	_mouseUp: function(event) {
1749		//Remove frame helpers
1750		$("div.ui-draggable-iframeFix").each(function() {
1751			this.parentNode.removeChild(this);
1752		});
1753
1754		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1755		if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1756
1757		return $.ui.mouse.prototype._mouseUp.call(this, event);
1758	},
1759
1760	cancel: function() {
1761
1762		if(this.helper.is(".ui-draggable-dragging")) {
1763			this._mouseUp({});
1764		} else {
1765			this._clear();
1766		}
1767
1768		return this;
1769
1770	},
1771
1772	_getHandle: function(event) {
1773
1774		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1775		$(this.options.handle, this.element)
1776			.find("*")
1777			.andSelf()
1778			.each(function() {
1779				if(this == event.target) handle = true;
1780			});
1781
1782		return handle;
1783
1784	},
1785
1786	_createHelper: function(event) {
1787
1788		var o = this.options;
1789		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1790
1791		if(!helper.parents('body').length)
1792			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1793
1794		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1795			helper.css("position", "absolute");
1796
1797		return helper;
1798
1799	},
1800
1801	_adjustOffsetFromHelper: function(obj) {
1802		if (typeof obj == 'string') {
1803			obj = obj.split(' ');
1804		}
1805		if ($.isArray(obj)) {
1806			obj = {left: +obj[0], top: +obj[1] || 0};
1807		}
1808		if ('left' in obj) {
1809			this.offset.click.left = obj.left + this.margins.left;
1810		}
1811		if ('right' in obj) {
1812			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1813		}
1814		if ('top' in obj) {
1815			this.offset.click.top = obj.top + this.margins.top;
1816		}
1817		if ('bottom' in obj) {
1818			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1819		}
1820	},
1821
1822	_getParentOffset: function() {
1823
1824		//Get the offsetParent and cache its position
1825		this.offsetParent = this.helper.offsetParent();
1826		var po = this.offsetParent.offset();
1827
1828		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1829		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1830		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1831		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1832		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1833			po.left += this.scrollParent.scrollLeft();
1834			po.top += this.scrollParent.scrollTop();
1835		}
1836
1837		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1838		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
1839			po = { top: 0, left: 0 };
1840
1841		return {
1842			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
184210) || 0),
1843			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1844		};
1845
1846	},
1847
1848	_getRelativeOffset: function() {
1849
1850		if(this.cssPosition == "relative") {
1851			var p = this.element.position();
1852			return {
1853				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1854				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1855			};
1856		} else {
1857			return { top: 0, left: 0 };
1858		}
1859
1860	},
1861
1862	_cacheMargins: function() {
1863		this.margins = {
1864			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1865			top: (parseInt(this.element.css("marginTop"),10) || 0),
1866			right: (parseInt(this.element.css("marginRight"),10) || 0),
1867			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1868		};
1869	},
1870
1871	_cacheHelperProportions: function() {
1872		this.helperProportions = {
1873			width: this.helper.outerWidth(),
1874			height: this.helper.outerHeight()
1875		};
1876	},
1877
1878	_setContainment: function() {
1879
1880		var o = this.options;
1881		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1882		if(o.containment == 'document' || o.containment == 'window') this.containment = [
1883			o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1884			o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1885			(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1886			(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1887		];
1888
1889		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1890			var c = $(o.containment);
1891			var ce = c[0]; if(!ce) return;
1892			var co = c.offset();
1893			var over = ($(ce).css("overflow") != 'hidden');
1894
1895			this.containment = [
1896				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1897				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1898				(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
1899				(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1900			];
1901			this.relative_container = c;
1902
1903		} else if(o.containment.constructor == Array) {
1904			this.containment = o.containment;
1905		}
1906
1907	},
1908
1909	_convertPositionTo: function(d, pos) {
1910
1911		if(!pos) pos = this.position;
1912		var mod = d == "absolute" ? 1 : -1;
1913		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1914
1915		return {
1916			top: (
1917				pos.top																	// The absolute mouse position
1918				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1919				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
1920				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1921			),
1922			left: (
1923				pos.left																// The absolute mouse position
1924				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1925				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
1926				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1927			)
1928		};
1929
1930	},
1931
1932	_generatePosition: function(event) {
1933
1934		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1935		var pageX = event.pageX;
1936		var pageY = event.pageY;
1937
1938		/*
1939		 * - Position constraining -
1940		 * Constrain the position to a mix of grid, containment.
1941		 */
1942
1943		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1944			var containment;
1945			if(this.containment) {
1946			if (this.relative_container){
1947				var co = this.relative_container.offset();
1948				containment = [ this.containment[0] + co.left,
1949					this.containment[1] + co.top,
1950					this.containment[2] + co.left,
1951					this.containment[3] + co.top ];
1952			}
1953			else {
1954				containment = this.containment;
1955			}
1956
1957				if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1958				if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1959				if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1960				if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1961			}
1962
1963			if(o.grid) {
1964				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1965				var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1966				pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1967
1968				var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1969				pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1970			}
1971
1972		}
1973
1974		return {
1975			top: (
1976				pageY																// The absolute mouse position
1977				- this.offset.click.top													// Click offset (relative to the element)
1978				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
1979				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
1980				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1981			),
1982			left: (
1983				pageX																// The absolute mouse position
1984				- this.offset.click.left												// Click offset (relative to the element)
1985				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
1986				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
1987				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1988			)
1989		};
1990
1991	},
1992
1993	_clear: function() {
1994		this.helper.removeClass("ui-draggable-dragging");
1995		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1996		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
1997		this.helper = null;
1998		this.cancelHelperRemoval = false;
1999	},
2000
2001	// From now on bulk stuff - mainly helpers
2002
2003	_trigger: function(type, event, ui) {
2004		ui = ui || this._uiHash();
2005		$.ui.plugin.call(this, type, [event, ui]);
2006		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
2007		return $.Widget.prototype._trigger.call(this, type, event, ui);
2008	},
2009
2010	plugins: {},
2011
2012	_uiHash: function(event) {
2013		return {
2014			helper: this.helper,
2015			position: this.position,
2016			originalPosition: this.originalPosition,
2017			offset: this.positionAbs
2018		};
2019	}
2020
2021});
2022
2023$.ui.plugin.add("draggable", "connectToSortable", {
2024	start: function(event, ui) {
2025
2026		var inst = $(this).data("draggable"), o = inst.options,
2027			uiSortable = $.extend({}, ui, { item: inst.element });
2028		inst.sortables = [];
2029		$(o.connectToSortable).each(function() {
2030			var sortable = $.data(this, 'sortable');
2031			if (sortable && !sortable.options.disabled) {
2032				inst.sortables.push({
2033					instance: sortable,
2034					shouldRevert: sortable.options.revert
2035				});
2036				sortable.refreshPositions();	// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
2037				sortable._trigger("activate", event, uiSortable);
2038			}
2039		});
2040
2041	},
2042	stop: function(event, ui) {
2043
2044		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2045		var inst = $(this).data("draggable"),
2046			uiSortable = $.extend({}, ui, { item: inst.element });
2047
2048		$.each(inst.sortables, function() {
2049			if(this.instance.isOver) {
2050
2051				this.instance.isOver = 0;
2052
2053				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
2054				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
2055
2056				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
2057				if(this.shouldRevert) this.instance.options.revert = true;
2058
2059				//Trigger the stop of the sortable
2060				this.instance._mouseStop(event);
2061
2062				this.instance.options.helper = this.instance.options._helper;
2063
2064				//If the helper has been the original item, restore properties in the sortable
2065				if(inst.options.helper == 'original')
2066					this.instance.currentItem.css({ top: 'auto', left: 'auto' });
2067
2068			} else {
2069				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
2070				this.instance._trigger("deactivate", event, uiSortable);
2071			}
2072
2073		});
2074
2075	},
2076	drag: function(event, ui) {
2077
2078		var inst = $(this).data("draggable"), that = this;
2079
2080		var checkPos = function(o) {
2081			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
2082			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
2083			var itemHeight = o.height, itemWidth = o.width;
2084			var itemTop = o.top, itemLeft = o.left;
2085
2086			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
2087		};
2088
2089		$.each(inst.sortables, function(i) {
2090
2091			var innermostIntersecting = false;
2092			var thisSortable = this;
2093			//Copy over some variables to allow calling the sortable's native _intersectsWith
2094			this.instance.positionAbs = inst.positionAbs;
2095			this.instance.helperProportions = inst.helperProportions;
2096			this.instance.offset.click = inst.offset.click;
2097
2098			if(this.instance._intersectsWith(this.instance.containerCache)) {
2099				innermostIntersecting = true;
2100				$.each(inst.sortables, function () {
2101					this.instance.positionAbs = inst.positionAbs;
2102					this.instance.helperProportions = inst.helperProportions;
2103					this.instance.offset.click = inst.offset.click;
2104					if  (this != thisSortable
2105						&& this.instance._intersectsWith(this.instance.containerCache)
2106						&& $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
2107						innermostIntersecting = false;
2108						return innermostIntersecting;
2109				});
2110			}
2111
2112
2113			if(innermostIntersecting) {
2114				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
2115				if(!this.instance.isOver) {
2116
2117					this.instance.isOver = 1;
2118					//Now we fake the start of dragging for the sortable instance,
2119					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
2120					//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
2121					this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
2122					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
2123					this.instance.options.helper = function() { return ui.helper[0]; };
2124
2125					event.target = this.instance.currentItem[0];
2126					this.instance._mouseCapture(event, true);
2127					this.instance._mouseStart(event, true, true);
2128
2129					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
2130					this.instance.offset.click.top = inst.offset.click.top;
2131					this.instance.offset.click.left = inst.offset.click.left;
2132					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
2133					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
2134
2135					inst._trigger("toSortable", event);
2136					inst.dropped = this.instance.element; //draggable revert needs that
2137					//hack so receive/update callbacks work (mostly)
2138					inst.currentItem = inst.element;
2139					this.instance.fromOutside = inst;
2140
2141				}
2142
2143				//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
2144				if(this.instance.currentItem) this.instance._mouseDrag(event);
2145
2146			} else {
2147
2148				//If it doesn't intersect with the sortable, and it intersected before,
2149				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
2150				if(this.instance.isOver) {
2151
2152					this.instance.isOver = 0;
2153					this.instance.cancelHelperRemoval = true;
2154
2155					//Prevent reverting on this forced stop
2156					this.instance.options.revert = false;
2157
2158					// The out event needs to be triggered independently
2159					this.instance._trigger('out', event, this.instance._uiHash(this.instance));
2160
2161					this.instance._mouseStop(event, true);
2162					this.instance.options.helper = this.instance.options._helper;
2163
2164					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
2165					this.instance.currentItem.remove();
2166					if(this.instance.placeholder) this.instance.placeholder.remove();
2167
2168					inst._trigger("fromSortable", event);
2169					inst.dropped = false; //draggable revert needs that
2170				}
2171
2172			};
2173
2174		});
2175
2176	}
2177});
2178
2179$.ui.plugin.add("draggable", "cursor", {
2180	start: function(event, ui) {
2181		var t = $('body'), o = $(this).data('draggable').options;
2182		if (t.css("cursor")) o._cursor = t.css("cursor");
2183		t.css("cursor", o.cursor);
2184	},
2185	stop: function(event, ui) {
2186		var o = $(this).data('draggable').options;
2187		if (o._cursor) $('body').css("cursor", o._cursor);
2188	}
2189});
2190
2191$.ui.plugin.add("draggable", "opacity", {
2192	start: function(event, ui) {
2193		var t = $(ui.helper), o = $(this).data('draggable').options;
2194		if(t.css("opacity")) o._opacity = t.css("opacity");
2195		t.css('opacity', o.opacity);
2196	},
2197	stop: function(event, ui) {
2198		var o = $(this).data('draggable').options;
2199		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
2200	}
2201});
2202
2203$.ui.plugin.add("draggable", "scroll", {
2204	start: function(event, ui) {
2205		var i = $(this).data("draggable");
2206		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
2207	},
2208	drag: function(event, ui) {
2209
2210		var i = $(this).data("draggable"), o = i.options, scrolled = false;
2211
2212		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
2213
2214			if(!o.axis || o.axis != 'x') {
2215				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
2216					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
2217				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
2218					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
2219			}
2220
2221			if(!o.axis || o.axis != 'y') {
2222				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
2223					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
2224				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
2225					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
2226			}
2227
2228		} else {
2229
2230			if(!o.axis || o.axis != 'x') {
2231				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
2232					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2233				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
2234					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2235			}
2236
2237			if(!o.axis || o.axis != 'y') {
2238				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
2239					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2240				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
2241					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2242			}
2243
2244		}
2245
2246		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
2247			$.ui.ddmanager.prepareOffsets(i, event);
2248
2249	}
2250});
2251
2252$.ui.plugin.add("draggable", "snap", {
2253	start: function(event, ui) {
2254
2255		var i = $(this).data("draggable"), o = i.options;
2256		i.snapElements = [];
2257
2258		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
2259			var $t = $(this); var $o = $t.offset();
2260			if(this != i.element[0]) i.snapElements.push({
2261				item: this,
2262				width: $t.outerWidth(), height: $t.outerHeight(),
2263				top: $o.top, left: $o.left
2264			});
2265		});
2266
2267	},
2268	drag: function(event, ui) {
2269
2270		var inst = $(this).data("draggable"), o = inst.options;
2271		var d = o.snapTolerance;
2272
2273		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2274			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2275
2276		for (var i = inst.snapElements.length - 1; i >= 0; i--){
2277
2278			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
2279				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
2280
2281			//Yes, I know, this is insane ;)
2282			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
2283				if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2284				inst.snapElements[i].snapping = false;
2285				continue;
2286			}
2287
2288			if(o.snapMode != 'inner') {
2289				var ts = Math.abs(t - y2) <= d;
2290				var bs = Math.abs(b - y1) <= d;
2291				var ls = Math.abs(l - x2) <= d;
2292				var rs = Math.abs(r - x1) <= d;
2293				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2294				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
2295				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
2296				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
2297			}
2298
2299			var first = (ts || bs || ls || rs);
2300
2301			if(o.snapMode != 'outer') {
2302				var ts = Math.abs(t - y1) <= d;
2303				var bs = Math.abs(b - y2) <= d;
2304				var ls = Math.abs(l - x1) <= d;
2305				var rs = Math.abs(r - x2) <= d;
2306				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
2307				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2308				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
2309				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
2310			}
2311
2312			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
2313				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2314			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2315
2316		};
2317
2318	}
2319});
2320
2321$.ui.plugin.add("draggable", "stack", {
2322	start: function(event, ui) {
2323
2324		var o = $(this).data("draggable").options;
2325
2326		var group = $.makeArray($(o.stack)).sort(function(a,b) {
2327			return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
2328		});
2329		if (!group.length) { return; }
2330
2331		var min = parseInt(group[0].style.zIndex) || 0;
2332		$(group).each(function(i) {
2333			this.style.zIndex = min + i;
2334		});
2335
2336		this[0].style.zIndex = min + group.length;
2337
2338	}
2339});
2340
2341$.ui.plugin.add("draggable", "zIndex", {
2342	start: function(event, ui) {
2343		var t = $(ui.helper), o = $(this).data("draggable").options;
2344		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
2345		t.css('zIndex', o.zIndex);
2346	},
2347	stop: function(event, ui) {
2348		var o = $(this).data("draggable").options;
2349		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
2350	}
2351});
2352
2353})(jQuery);
2354(function( $, undefined ) {
2355
2356$.widget("ui.droppable", {
2357	version: "1.9.2",
2358	widgetEventPrefix: "drop",
2359	options: {
2360		accept: '*',
2361		activeClass: false,
2362		addClasses: true,
2363		greedy: false,
2364		hoverClass: false,
2365		scope: 'default',
2366		tolerance: 'intersect'
2367	},
2368	_create: function() {
2369
2370		var o = this.options, accept = o.accept;
2371		this.isover = 0; this.isout = 1;
2372
2373		this.accept = $.isFunction(accept) ? accept : function(d) {
2374			return d.is(accept);
2375		};
2376
2377		//Store the droppable's proportions
2378		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
2379
2380		// Add the reference and positions to the manager
2381		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
2382		$.ui.ddmanager.droppables[o.scope].push(this);
2383
2384		(o.addClasses && this.element.addClass("ui-droppable"));
2385
2386	},
2387
2388	_destroy: function() {
2389		var drop = $.ui.ddmanager.droppables[this.options.scope];
2390		for ( var i = 0; i < drop.length; i++ )
2391			if ( drop[i] == this )
2392				drop.splice(i, 1);
2393
2394		this.element.removeClass("ui-droppable ui-droppable-disabled");
2395	},
2396
2397	_setOption: function(key, value) {
2398
2399		if(key == 'accept') {
2400			this.accept = $.isFunction(value) ? value : function(d) {
2401				return d.is(value);
2402			};
2403		}
2404		$.Widget.prototype._setOption.apply(this, arguments);
2405	},
2406
2407	_activate: function(event) {
2408		var draggable = $.ui.ddmanager.current;
2409		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
2410		(draggable && this._trigger('activate', event, this.ui(draggable)));
2411	},
2412
2413	_deactivate: function(event) {
2414		var draggable = $.ui.ddmanager.current;
2415		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2416		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
2417	},
2418
2419	_over: function(event) {
2420
2421		var draggable = $.ui.ddmanager.current;
2422		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2423
2424		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2425			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
2426			this._trigger('over', event, this.ui(draggable));
2427		}
2428
2429	},
2430
2431	_out: function(event) {
2432
2433		var draggable = $.ui.ddmanager.current;
2434		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2435
2436		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2437			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2438			this._trigger('out', event, this.ui(draggable));
2439		}
2440
2441	},
2442
2443	_drop: function(event,custom) {
2444
2445		var draggable = custom || $.ui.ddmanager.current;
2446		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
2447
2448		var childrenIntersection = false;
2449		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
2450			var inst = $.data(this, 'droppable');
2451			if(
2452				inst.options.greedy
2453				&& !inst.options.disabled
2454				&& inst.options.scope == draggable.options.scope
2455				&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
2456				&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2457			) { childrenIntersection = true; return false; }
2458		});
2459		if(childrenIntersection) return false;
2460
2461		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2462			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2463			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2464			this._trigger('drop', event, this.ui(draggable));
2465			return this.element;
2466		}
2467
2468		return false;
2469
2470	},
2471
2472	ui: function(c) {
2473		return {
2474			draggable: (c.currentItem || c.element),
2475			helper: c.helper,
2476			position: c.position,
2477			offset: c.positionAbs
2478		};
2479	}
2480
2481});
2482
2483$.ui.intersect = function(draggable, droppable, toleranceMode) {
2484
2485	if (!droppable.offset) return false;
2486
2487	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2488		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
2489	var l = droppable.offset.left, r = l + droppable.proportions.width,
2490		t = droppable.offset.top, b = t + droppable.proportions.height;
2491
2492	switch (toleranceMode) {
2493		case 'fit':
2494			return (l <= x1 && x2 <= r
2495				&& t <= y1 && y2 <= b);
2496			break;
2497		case 'intersect':
2498			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
2499				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
2500				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
2501				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2502			break;
2503		case 'pointer':
2504			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
2505				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
2506				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
2507			return isOver;
2508			break;
2509		case 'touch':
2510			return (
2511					(y1 >= t && y1 <= b) ||	// Top edge touching
2512					(y2 >= t && y2 <= b) ||	// Bottom edge touching
2513					(y1 < t && y2 > b)		// Surrounded vertically
2514				) && (
2515					(x1 >= l && x1 <= r) ||	// Left edge touching
2516					(x2 >= l && x2 <= r) ||	// Right edge touching
2517					(x1 < l && x2 > r)		// Surrounded horizontally
2518				);
2519			break;
2520		default:
2521			return false;
2522			break;
2523		}
2524
2525};
2526
2527/*
2528	This manager tracks offsets of draggables and droppables
2529*/
2530$.ui.ddmanager = {
2531	current: null,
2532	droppables: { 'default': [] },
2533	prepareOffsets: function(t, event) {
2534
2535		var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2536		var type = event ? event.type : null; // workaround for #2317
2537		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2538
2539		droppablesLoop: for (var i = 0; i < m.length; i++) {
2540
2541			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
2542			for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
2543			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue
2544
2545			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2546
2547			m[i].offset = m[i].element.offset();
2548			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2549
2550		}
2551
2552	},
2553	drop: function(draggable, event) {
2554
2555		var dropped = false;
2556		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2557
2558			if(!this.options) return;
2559			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2560				dropped = this._drop.call(this, event) || dropped;
2561
2562			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2563				this.isout = 1; this.isover = 0;
2564				this._deactivate.call(this, event);
2565			}
2566
2567		});
2568		return dropped;
2569
2570	},
2571	dragStart: function( draggable, event ) {
2572		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2573		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2574			if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2575		});
2576	},
2577	drag: function(draggable, event) {
2578
2579		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2580		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2581
2582		//Run through all droppables and check their positions based on specific tolerance options
2583		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2584
2585			if(this.options.disabled || this.greedyChild || !this.visible) return;
2586			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2587
2588			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2589			if(!c) return;
2590
2591			var parentInstance;
2592			if (this.options.greedy) {
2593				// find droppable parents with same scope
2594				var scope = this.options.scope;
2595				var parent = this.element.parents(':data(droppable)').filter(function () {
2596					return $.data(this, 'droppable').options.scope === scope;
2597				});
2598
2599				if (parent.length) {
2600					parentInstance = $.data(parent[0], 'droppable');
2601					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2602				}
2603			}
2604
2605			// we just moved into a greedy child
2606			if (parentInstance && c == 'isover') {
2607				parentInstance['isover'] = 0;
2608				parentInstance['isout'] = 1;
2609				parentInstance._out.call(parentInstance, event);
2610			}
2611
2612			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2613			this[c == "isover" ? "_over" : "_out"].call(this, event);
2614
2615			// we just moved out of a greedy child
2616			if (parentInstance && c == 'isout') {
2617				parentInstance['isout'] = 0;
2618				parentInstance['isover'] = 1;
2619				parentInstance._over.call(parentInstance, event);
2620			}
2621		});
2622
2623	},
2624	dragStop: function( draggable, event ) {
2625		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2626		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2627		if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2628	}
2629};
2630
2631})(jQuery);
2632(function( $, undefined ) {
2633
2634$.widget("ui.resizable", $.ui.mouse, {
2635	version: "1.9.2",
2636	widgetEventPrefix: "resize",
2637	options: {
2638		alsoResize: false,
2639		animate: false,
2640		animateDuration: "slow",
2641		animateEasing: "swing",
2642		aspectRatio: false,
2643		autoHide: false,
2644		containment: false,
2645		ghost: false,
2646		grid: false,
2647		handles: "e,s,se",
2648		helper: false,
2649		maxHeight: null,
2650		maxWidth: null,
2651		minHeight: 10,
2652		minWidth: 10,
2653		zIndex: 1000
2654	},
2655	_create: function() {
2656
2657		var that = this, o = this.options;
2658		this.element.addClass("ui-resizable");
2659
2660		$.extend(this, {
2661			_aspectRatio: !!(o.aspectRatio),
2662			aspectRatio: o.aspectRatio,
2663			originalElement: this.element,
2664			_proportionallyResizeElements: [],
2665			_helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2666		});
2667
2668		//Wrap the element if it cannot hold child nodes
2669		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2670
2671			//Create a wrapper element and set the wrapper to the new current internal element
2672			this.element.wrap(
2673				$('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2674					position: this.element.css('position'),
2675					width: this.element.outerWidth(),
2676					height: this.element.outerHeight(),
2677					top: this.element.css('top'),
2678					left: this.element.css('left')
2679				})
2680			);
2681
2682			//Overwrite the original this.element
2683			this.element = this.element.parent().data(
2684				"resizable", this.element.data('resizable')
2685			);
2686
2687			this.elementIsWrapper = true;
2688
2689			//Move margins to the wrapper
2690			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2691			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2692
2693			//Prevent Safari textarea resize
2694			this.originalResizeStyle = this.originalElement.css('resize');
2695			this.originalElement.css('resize', 'none');
2696
2697			//Push the actual element to our proportionallyResize internal array
2698			this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2699
2700			// avoid IE jump (hard set the margin)
2701			this.originalElement.css({ margin: this.originalElement.css('margin') });
2702
2703			// fix handlers offset
2704			this._proportionallyResize();
2705
2706		}
2707
2708		this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
2709		if(this.handles.constructor == String) {
2710
2711			if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2712			var n = this.handles.split(","); this.handles = {};
2713
2714			for(var i = 0; i < n.length; i++) {
2715
2716				var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2717				var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2718
2719				// Apply zIndex to all handles - see #7960
2720				axis.css({ zIndex: o.zIndex });
2721
2722				//TODO : What's going on here?
2723				if ('se' == handle) {
2724					axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2725				};
2726
2727				//Insert into internal handles object and append to element
2728				this.handles[handle] = '.ui-resizable-'+handle;
2729				this.element.append(axis);
2730			}
2731
2732		}
2733
2734		this._renderAxis = function(target) {
2735
2736			target = target || this.element;
2737
2738			for(var i in this.handles) {
2739
2740				if(this.handles[i].constructor == String)
2741					this.handles[i] = $(this.handles[i], this.element).show();
2742
2743				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2744				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2745
2746					var axis = $(this.handles[i], this.element), padWrapper = 0;
2747
2748					//Checking the correct pad and border
2749					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2750
2751					//The padding type i have to apply...
2752					var padPos = [ 'padding',
2753						/ne|nw|n/.test(i) ? 'Top' :
2754						/se|sw|s/.test(i) ? 'Bottom' :
2755						/^e$/.test(i) ? 'Right' : 'Left' ].join("");
2756
2757					target.css(padPos, padWrapper);
2758
2759					this._proportionallyResize();
2760
2761				}
2762
2763				//TODO: What's that good for? There's not anything to be executed left
2764				if(!$(this.handles[i]).length)
2765					continue;
2766
2767			}
2768		};
2769
2770		//TODO: make renderAxis a prototype function
2771		this._renderAxis(this.element);
2772
2773		this._handles = $('.ui-resizable-handle', this.element)
2774			.disableSelection();
2775
2776		//Matching axis name
2777		this._handles.mouseover(function() {
2778			if (!that.resizing) {
2779				if (this.className)
2780					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2781				//Axis, default = se
2782				that.axis = axis && axis[1] ? axis[1] : 'se';
2783			}
2784		});
2785
2786		//If we want to auto hide the elements
2787		if (o.autoHide) {
2788			this._handles.hide();
2789			$(this.element)
2790				.addClass("ui-resizable-autohide")
2791				.mouseenter(function() {
2792					if (o.disabled) return;
2793					$(this).removeClass("ui-resizable-autohide");
2794					that._handles.show();
2795				})
2796				.mouseleave(function(){
2797					if (o.disabled) return;
2798					if (!that.resizing) {
2799						$(this).addClass("ui-resizable-autohide");
2800						that._handles.hide();
2801					}
2802				});
2803		}
2804
2805		//Initialize the mouse interaction
2806		this._mouseInit();
2807
2808	},
2809
2810	_destroy: function() {
2811
2812		this._mouseDestroy();
2813
2814		var _destroy = function(exp) {
2815			$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2816				.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2817		};
2818
2819		//TODO: Unwrap at same DOM position
2820		if (this.elementIsWrapper) {
2821			_destroy(this.element);
2822			var wrapper = this.element;
2823			this.originalElement.css({
2824				position: wrapper.css('position'),
2825				width: wrapper.outerWidth(),
2826				height: wrapper.outerHeight(),
2827				top: wrapper.css('top'),
2828				left: wrapper.css('left')
2829			}).insertAfter( wrapper );
2830			wrapper.remove();
2831		}
2832
2833		this.originalElement.css('resize', this.originalResizeStyle);
2834		_destroy(this.originalElement);
2835
2836		return this;
2837	},
2838
2839	_mouseCapture: function(event) {
2840		var handle = false;
2841		for (var i in this.handles) {
2842			if ($(this.handles[i])[0] == event.target) {
2843				handle = true;
2844			}
2845		}
2846
2847		return !this.options.disabled && handle;
2848	},
2849
2850	_mouseStart: function(event) {
2851
2852		var o = this.options, iniPos = this.element.position(), el = this.element;
2853
2854		this.resizing = true;
2855		this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2856
2857		// bugfix for http://dev.jquery.com/ticket/1749
2858		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2859			el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2860		}
2861
2862		this._renderProxy();
2863
2864		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2865
2866		if (o.containment) {
2867			curleft += $(o.containment).scrollLeft() || 0;
2868			curtop += $(o.containment).scrollTop() || 0;
2869		}
2870
2871		//Store needed variables
2872		this.offset = this.helper.offset();
2873		this.position = { left: curleft, top: curtop };
2874		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2875		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2876		this.originalPosition = { left: curleft, top: curtop };
2877		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2878		this.originalMousePosition = { left: event.pageX, top: event.pageY };
2879
2880		//Aspect Ratio
2881		this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2882
2883		var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2884		$('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2885
2886		el.addClass("ui-resizable-resizing");
2887		this._propagate("start", event);
2888		return true;
2889	},
2890
2891	_mouseDrag: function(event) {
2892
2893		//Increase performance, avoid regex
2894		var el = this.helper, o = this.options, props = {},
2895			that = this, smp = this.originalMousePosition, a = this.axis;
2896
2897		var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2898		var trigger = this._change[a];
2899		if (!trigger) return false;
2900
2901		// Calculate the attrs that will be change
2902		var data = trigger.apply(this, [event, dx, dy]);
2903
2904		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2905		this._updateVirtualBoundaries(event.shiftKey);
2906		if (this._aspectRatio || event.shiftKey)
2907			data = this._updateRatio(data, event);
2908
2909		data = this._respectSize(data, event);
2910
2911		// plugins callbacks need to be called first
2912		this._propagate("resize", event);
2913
2914		el.css({
2915			top: this.position.top + "px", left: this.position.left + "px",
2916			width: this.size.width + "px", height: this.size.height + "px"
2917		});
2918
2919		if (!this._helper && this._proportionallyResizeElements.length)
2920			this._proportionallyResize();
2921
2922		this._updateCache(data);
2923
2924		// calling the user callback at the end
2925		this._trigger('resize', event, this.ui());
2926
2927		return false;
2928	},
2929
2930	_mouseStop: function(event) {
2931
2932		this.resizing = false;
2933		var o = this.options, that = this;
2934
2935		if(this._helper) {
2936			var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2937				soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2938				soffsetw = ista ? 0 : that.sizeDiff.width;
2939
2940			var s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) },
2941				left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
2942				top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
2943
2944			if (!o.animate)
2945				this.element.css($.extend(s, { top: top, left: left }));
2946
2947			that.helper.height(that.size.height);
2948			that.helper.width(that.size.width);
2949
2950			if (this._helper && !o.animate) this._proportionallyResize();
2951		}
2952
2953		$('body').css('cursor', 'auto');
2954
2955		this.element.removeClass("ui-resizable-resizing");
2956
2957		this._propagate("stop", event);
2958
2959		if (this._helper) this.helper.remove();
2960		return false;
2961
2962	},
2963
2964	_updateVirtualBoundaries: function(forceAspectRatio) {
2965		var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2966
2967		b = {
2968			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2969			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2970			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2971			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2972		};
2973
2974		if(this._aspectRatio || forceAspectRatio) {
2975			// We want to create an enclosing box whose aspect ration is the requested one
2976			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2977			pMinWidth = b.minHeight * this.aspectRatio;
2978			pMinHeight = b.minWidth / this.aspectRatio;
2979			pMaxWidth = b.maxHeight * this.aspectRatio;
2980			pMaxHeight = b.maxWidth / this.aspectRatio;
2981
2982			if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2983			if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2984			if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2985			if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2986		}
2987		this._vBoundaries = b;
2988	},
2989
2990	_updateCache: function(data) {
2991		var o = this.options;
2992		this.offset = this.helper.offset();
2993		if (isNumber(data.left)) this.position.left = data.left;
2994		if (isNumber(data.top)) this.position.top = data.top;
2995		if (isNumber(data.height)) this.size.height = data.height;
2996		if (isNumber(data.width)) this.size.width = data.width;
2997	},
2998
2999	_updateRatio: function(data, event) {
3000
3001		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
3002
3003		if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
3004		else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
3005
3006		if (a == 'sw') {
3007			data.left = cpos.left + (csize.width - data.width);
3008			data.top = null;
3009		}
3010		if (a == 'nw') {
3011			data.top = cpos.top + (csize.height - data.height);
3012			data.left = cpos.left + (csize.width - data.width);
3013		}
3014
3015		return data;
3016	},
3017
3018	_respectSize: function(data, event) {
3019
3020		var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
3021				ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3022					isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
3023
3024		if (isminw) data.width = o.minWidth;
3025		if (isminh) data.height = o.minHeight;
3026		if (ismaxw) data.width = o.maxWidth;
3027		if (ismaxh) data.height = o.maxHeight;
3028
3029		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
3030		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3031
3032		if (isminw && cw) data.left = dw - o.minWidth;
3033		if (ismaxw && cw) data.left = dw - o.maxWidth;
3034		if (isminh && ch)	data.top = dh - o.minHeight;
3035		if (ismaxh && ch)	data.top = dh - o.maxHeight;
3036
3037		// fixing jump error on top/left - bug #2330
3038		var isNotwh = !data.width && !data.height;
3039		if (isNotwh && !data.left && data.top) data.top = null;
3040		else if (isNotwh && !data.top && data.left) data.left = null;
3041
3042		return data;
3043	},
3044
3045	_proportionallyResize: function() {
3046
3047		var o = this.options;
3048		if (!this._proportionallyResizeElements.length) return;
3049		var element = this.helper || this.element;
3050
3051		for (var i=0; i < this._proportionallyResizeElements.length; i++) {
3052
3053			var prel = this._proportionallyResizeElements[i];
3054
3055			if (!this.borderDif) {
3056				var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
3057					p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
3058
3059				this.borderDif = $.map(b, function(v, i) {
3060					var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
3061					return border + padding;
3062				});
3063			}
3064
3065			prel.css({
3066				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
3067				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
3068			});
3069
3070		};
3071
3072	},
3073
3074	_renderProxy: function() {
3075
3076		var el = this.element, o = this.options;
3077		this.elementOffset = el.offset();
3078
3079		if(this._helper) {
3080
3081			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
3082
3083			// fix ie6 offset TODO: This seems broken
3084			var ie6offset = ($.ui.ie6 ? 1 : 0),
3085			pxyoffset = ( $.ui.ie6 ? 2 : -1 );
3086
3087			this.helper.addClass(this._helper).css({
3088				width: this.element.outerWidth() + pxyoffset,
3089				height: this.element.outerHeight() + pxyoffset,
3090				position: 'absolute',
3091				left: this.elementOffset.left - ie6offset +'px',
3092				top: this.elementOffset.top - ie6offset +'px',
3093				zIndex: ++o.zIndex //TODO: Don't modify option
3094			});
3095
3096			this.helper
3097				.appendTo("body")
3098				.disableSelection();
3099
3100		} else {
3101			this.helper = this.element;
3102		}
3103
3104	},
3105
3106	_change: {
3107		e: function(event, dx, dy) {
3108			return { width: this.originalSize.width + dx };
3109		},
3110		w: function(event, dx, dy) {
3111			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
3112			return { left: sp.left + dx, width: cs.width - dx };
3113		},
3114		n: function(event, dx, dy) {
3115			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
3116			return { top: sp.top + dy, height: cs.height - dy };
3117		},
3118		s: function(event, dx, dy) {
3119			return { height: this.originalSize.height + dy };
3120		},
3121		se: function(event, dx, dy) {
3122			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3123		},
3124		sw: function(event, dx, dy) {
3125			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3126		},
3127		ne: function(event, dx, dy) {
3128			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3129		},
3130		nw: function(event, dx, dy) {
3131			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3132		}
3133	},
3134
vendor: 4,218 bytes, lines 3135-3270
3135	_propagate: function(n, event) {
3136		$.ui.plugin.call(this, n, [event, this.ui()]);
3137		(n != "resize" && this._trigger(n, event, this.ui()));
3138	},
3139
3140	plugins: {},
3141
3142	ui: function() {
3143		return {
3144			originalElement: this.originalElement,
3145			element: this.element,
3146			helper: this.helper,
3147			position: this.position,
3148			size: this.size,
3149			originalSize: this.originalSize,
3150			originalPosition: this.originalPosition
3151		};
3152	}
3153
3154});
3155
3156/*
3157 * Resizable Extensions
3158 */
3159
3160$.ui.plugin.add("resizable", "alsoResize", {
3161
3162	start: function (event, ui) {
3163		var that = $(this).data("resizable"), o = that.options;
3164
3165		var _store = function (exp) {
3166			$(exp).each(function() {
3167				var el = $(this);
3168				el.data("resizable-alsoresize", {
3169					width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3170					left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
3171				});
3172			});
3173		};
3174
3175		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
3176			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3177			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3178		}else{
3179			_store(o.alsoResize);
3180		}
3181	},
3182
3183	resize: function (event, ui) {
3184		var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
3185
3186		var delta = {
3187			height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3188			top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3189		},
3190
3191		_alsoResize = function (exp, c) {
3192			$(exp).each(function() {
3193				var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
3194					css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
3195
3196				$.each(css, function (i, prop) {
3197					var sum = (start[prop]||0) + (delta[prop]||0);
3198					if (sum && sum >= 0)
3199						style[prop] = sum || null;
3200				});
3201
3202				el.css(style);
3203			});
3204		};
3205
3206		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
3207			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3208		}else{
3209			_alsoResize(o.alsoResize);
3210		}
3211	},
3212
3213	stop: function (event, ui) {
3214		$(this).removeData("resizable-alsoresize");
3215	}
3216});
3217
3218$.ui.plugin.add("resizable", "animate", {
3219
3220	stop: function(event, ui) {
3221		var that = $(this).data("resizable"), o = that.options;
3222
3223		var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3224					soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
3225						soffsetw = ista ? 0 : that.sizeDiff.width;
3226
3227		var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3228					left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
3229						top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
3230
3231		that.element.animate(
3232			$.extend(style, top && left ? { top: top, left: left } : {}), {
3233				duration: o.animateDuration,
3234				easing: o.animateEasing,
3235				step: function() {
3236
3237					var data = {
3238						width: parseInt(that.element.css('width'), 10),
3239						height: parseInt(that.element.css('height'), 10),
3240						top: parseInt(that.element.css('top'), 10),
3241						left: parseInt(that.element.css('left'), 10)
3242					};
3243
3244					if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
3245
3246					// propagating resize, and updating values for each animation step
3247					that._updateCache(data);
3248					that._propagate("resize", event);
3249
3250				}
3251			}
3252		);
3253	}
3254
3255});
3256
3257$.ui.plugin.add("resizable", "containment", {
3258
3259	start: function(event, ui) {
3260		var that = $(this).data("resizable"), o = that.options, el = that.element;
3261		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
3262		if (!ce) return;
3263
3264		that.containerElement = $(ce);
3265
3266		if (/document/.test(oc) || oc == document) {
3267			that.containerOffset = { left: 0, top: 0 };
3268			that.containerPosition = { left: 0, top: 0 };
3269
3270			that.parentData = {
3271				element: $(document), left: 0, top: 0,
3272				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3273			};
3274		}
3275
3276		// i'm a node, so compute top, left, right, bottom
3277		else {
3278			var element = $(ce), p = [];
3279			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3280
3281			that.containerOffset = element.offset();
3282			that.containerPosition = element.position();
3283			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3284
3285			var co = that.containerOffset, ch = that.containerSize.height,	cw = that.containerSize.width,
3286						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3287
3288			that.parentData = {
3289				element: ce, left: co.left, top: co.top, width: width, height: height
3290			};
3291		}
3292	},
3293
3294	resize: function(event, ui) {
3295		var that = $(this).data("resizable"), o = that.options,
3296				ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
3297				pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
3298
3299		if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
3300
3301		if (cp.left < (that._helper ? co.left : 0)) {
3302			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3303			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
3304			that.position.left = o.helper ? co.left : 0;
3305		}
3306
3307		if (cp.top < (that._helper ? co.top : 0)) {
3308			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3309			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
3310			that.position.top = that._helper ? co.top : 0;
3311		}
3312
3313		that.offset.left = that.parentData.left+that.position.left;
3314		that.offset.top = that.parentData.top+that.position.top;
3315
3316		var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
3317					hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3318
3319		var isParent = that.containerElement.get(0) == that.element.parent().get(0),
3320			isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
3321
3322		if(isParent && isOffsetRelative) woset -= that.parentData.left;
3323
3324		if (woset + that.size.width >= that.parentData.width) {
3325			that.size.width = that.parentData.width - woset;
3326			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
3327		}
3328
3329		if (hoset + that.size.height >= that.parentData.height) {
3330			that.size.height = that.parentData.height - hoset;
3331			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
3332		}
3333	},
3334
3335	stop: function(event, ui){
3336		var that = $(this).data("resizable"), o = that.options, cp = that.position,
3337				co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
3338
3339		var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
3340
3341		if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
3342			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3343
3344		if (that._helper && !o.animate && (/static/).test(ce.css('position')))
3345			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3346
3347	}
3348});
3349
3350$.ui.plugin.add("resizable", "ghost", {
3351
3352	start: function(event, ui) {
3353
3354		var that = $(this).data("resizable"), o = that.options, cs = that.size;
3355
3356		that.ghost = that.originalElement.clone();
3357		that.ghost
3358			.css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3359			.addClass('ui-resizable-ghost')
3360			.addClass(typeof o.ghost == 'string' ? o.ghost : '');
3361
3362		that.ghost.appendTo(that.helper);
3363
3364	},
3365
3366	resize: function(event, ui){
3367		var that = $(this).data("resizable"), o = that.options;
3368		if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.
3368size.width });
3369	},
3370
3371	stop: function(event, ui){
3372		var that = $(this).data("resizable"), o = that.options;
3373		if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
3374	}
3375
3376});
3377
3378$.ui.plugin.add("resizable", "grid", {
3379
3380	resize: function(event, ui) {
3381		var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
3382		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
3383		var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
3384
3385		if (/^(se|s|e)$/.test(a)) {
3386			that.size.width = os.width + ox;
3387			that.size.height = os.height + oy;
3388		}
3389		else if (/^(ne)$/.test(a)) {
3390			that.size.width = os.width + ox;
3391			that.size.height = os.height + oy;
3392			that.position.top = op.top - oy;
3393		}
3394		else if (/^(sw)$/.test(a)) {
3395			that.size.width = os.width + ox;
3396			that.size.height = os.height + oy;
3397			that.position.left = op.left - ox;
3398		}
3399		else {
3400			that.size.width = os.width + ox;
3401			that.size.height = os.height + oy;
3402			that.position.top = op.top - oy;
3403			that.position.left = op.left - ox;
3404		}
3405	}
3406
3407});
3408
3409var num = function(v) {
3410	return parseInt(v, 10) || 0;
3411};
3412
3413var isNumber = function(value) {
3414	return !isNaN(parseInt(value, 10));
3415};
3416
3417})(jQuery);
3418(function( $, undefined ) {
3419
3420$.widget("ui.selectable", $.ui.mouse, {
3421	version: "1.9.2",
3422	options: {
3423		appendTo: 'body',
3424		autoRefresh: true,
3425		distance: 0,
3426		filter: '*',
3427		tolerance: 'touch'
3428	},
3429	_create: function() {
3430		var that = this;
3431
3432		this.element.addClass("ui-selectable");
3433
3434		this.dragged = false;
3435
3436		// cache selectee children based on filter
3437		var selectees;
3438		this.refresh = function() {
3439			selectees = $(that.options.filter, that.element[0]);
3440			selectees.addClass("ui-selectee");
3441			selectees.each(function() {
3442				var $this = $(this);
3443				var pos = $this.offset();
3444				$.data(this, "selectable-item", {
3445					element: this,
3446					$element: $this,
3447					left: pos.left,
3448					top: pos.top,
3449					right: pos.left + $this.outerWidth(),
3450					bottom: pos.top + $this.outerHeight(),
3451					startselected: false,
3452					selected: $this.hasClass('ui-selected'),
3453					selecting: $this.hasClass('ui-selecting'),
3454					unselecting: $this.hasClass('ui-unselecting')
3455				});
3456			});
3457		};
3458		this.refresh();
3459
3460		this.selectees = selectees.addClass("ui-selectee");
3461
3462		this._mouseInit();
3463
3464		this.helper = $("<div class='ui-selectable-helper'></div>");
3465	},
3466
3467	_destroy: function() {
3468		this.selectees
3469			.removeClass("ui-selectee")
3470			.removeData("selectable-item");
3471		this.element
3472			.removeClass("ui-selectable ui-selectable-disabled");
3473		this._mouseDestroy();
3474	},
3475
3476	_mouseStart: function(event) {
3477		var that = this;
3478
3479		this.opos = [event.pageX, event.pageY];
3480
3481		if (this.options.disabled)
3482			return;
3483
3484		var options = this.options;
3485
3486		this.selectees = $(options.filter, this.element[0]);
3487
3488		this._trigger("start", event);
3489
3490		$(options.appendTo).append(this.helper);
3491		// position helper (lasso)
3492		this.helper.css({
3493			"left": event.clientX,
3494			"top": event.clientY,
3495			"width": 0,
3496			"height": 0
3497		});
3498
3499		if (options.autoRefresh) {
3500			this.refresh();
3501		}
3502
3503		this.selectees.filter('.ui-selected').each(function() {
3504			var selectee = $.data(this, "selectable-item");
3505			selectee.startselected = true;
3506			if (!event.metaKey && !event.ctrlKey) {
3507				selectee.$element.removeClass('ui-selected');
3508				selectee.selected = false;
3509				selectee.$element.addClass('ui-unselecting');
3510				selectee.unselecting = true;
3511				// selectable UNSELECTING callback
3512				that._trigger("unselecting", event, {
3513					unselecting: selectee.element
3514				});
3515			}
3516		});
3517
3518		$(event.target).parents().andSelf().each(function() {
3519			var selectee = $.data(this, "selectable-item");
3520			if (selectee) {
3521				var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
3522				selectee.$element
3523					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3524					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3525				selectee.unselecting = !doSelect;
3526				selectee.selecting = doSelect;
3527				selectee.selected = doSelect;
3528				// selectable (UN)SELECTING callback
3529				if (doSelect) {
3530					that._trigger("selecting", event, {
3531						selecting: selectee.element
3532					});
vendor: 4,501 bytes, lines 3533-3701
3533				} else {
3534					that._trigger("unselecting", event, {
3535						unselecting: selectee.element
3536					});
3537				}
3538				return false;
3539			}
3540		});
3541
3542	},
3543
3544	_mouseDrag: function(event) {
3545		var that = this;
3546		this.dragged = true;
3547
3548		if (this.options.disabled)
3549			return;
3550
3551		var options = this.options;
3552
3553		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3554		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3555		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3556		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3557
3558		this.selectees.each(function() {
3559			var selectee = $.data(this, "selectable-item");
3560			//prevent helper from being selected if appendTo: selectable
3561			if (!selectee || selectee.element == that.element[0])
3562				return;
3563			var hit = false;
3564			if (options.tolerance == 'touch') {
3565				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3566			} else if (options.tolerance == 'fit') {
3567				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3568			}
3569
3570			if (hit) {
3571				// SELECT
3572				if (selectee.selected) {
3573					selectee.$element.removeClass('ui-selected');
3574					selectee.selected = false;
3575				}
3576				if (selectee.unselecting) {
3577					selectee.$element.removeClass('ui-unselecting');
3578					selectee.unselecting = false;
3579				}
3580				if (!selectee.selecting) {
3581					selectee.$element.addClass('ui-selecting');
3582					selectee.selecting = true;
3583					// selectable SELECTING callback
3584					that._trigger("selecting", event, {
3585						selecting: selectee.element
3586					});
3587				}
3588			} else {
3589				// UNSELECT
3590				if (selectee.selecting) {
3591					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3592						selectee.$element.removeClass('ui-selecting');
3593						selectee.selecting = false;
3594						selectee.$element.addClass('ui-selected');
3595						selectee.selected = true;
3596					} else {
3597						selectee.$element.removeClass('ui-selecting');
3598						selectee.selecting = false;
3599						if (selectee.startselected) {
3600							selectee.$element.addClass('ui-unselecting');
3601							selectee.unselecting = true;
3602						}
3603						// selectable UNSELECTING callback
3604						that._trigger("unselecting", event, {
3605							unselecting: selectee.element
3606						});
3607					}
3608				}
3609				if (selectee.selected) {
3610					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3611						selectee.$element.removeClass('ui-selected');
3612						selectee.selected = false;
3613
3614						selectee.$element.addClass('ui-unselecting');
3615						selectee.unselecting = true;
3616						// selectable UNSELECTING callback
3617						that._trigger("unselecting", event, {
3618							unselecting: selectee.element
3619						});
3620					}
3621				}
3622			}
3623		});
3624
3625		return false;
3626	},
3627
3628	_mouseStop: function(event) {
3629		var that = this;
3630
3631		this.dragged = false;
3632
3633		var options = this.options;
3634
3635		$('.ui-unselecting', this.element[0]).each(function() {
3636			var selectee = $.data(this, "selectable-item");
3637			selectee.$element.removeClass('ui-unselecting');
3638			selectee.unselecting = false;
3639			selectee.startselected = false;
3640			that._trigger("unselected", event, {
3641				unselected: selectee.element
3642			});
3643		});
3644		$('.ui-selecting', this.element[0]).each(function() {
3645			var selectee = $.data(this, "selectable-item");
3646			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3647			selectee.selecting = false;
3648			selectee.selected = true;
3649			selectee.startselected = true;
3650			that._trigger("selected", event, {
3651				selected: selectee.element
3652			});
3653		});
3654		this._trigger("stop", event);
3655
3656		this.helper.remove();
3657
3658		return false;
3659	}
3660
3661});
3662
3663})(jQuery);
3664(function( $, undefined ) {
3665
3666$.widget("ui.sortable", $.ui.mouse, {
3667	version: "1.9.2",
3668	widgetEventPrefix: "sort",
3669	ready: false,
3670	options: {
3671		appendTo: "parent",
3672		axis: false,
3673		connectWith: false,
3674		containment: false,
3675		cursor: 'auto',
3676		cursorAt: false,
3677		dropOnEmpty: true,
3678		forcePlaceholderSize: false,
3679		forceHelperSize: false,
3680		grid: false,
3681		handle: false,
3682		helper: "original",
3683		items: '> *',
3684		opacity: false,
3685		placeholder: false,
3686		revert: false,
3687		scroll: true,
3688		scrollSensitivity: 20,
3689		scrollSpeed: 20,
3690		scope: "default",
3691		tolerance: "intersect",
3692		zIndex: 1000
3693	},
3694	_create: function() {
3695
3696		var o = this.options;
3697		this.containerCache = {};
3698		this.element.addClass("ui-sortable");
3699
3700		//Get the items
3701		this.refresh();
3702
3703		//Let's determine if the items are being displayed horizontally
3704		this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
3705
3706		//Let's determine the parent's offset
3707		this.offset = this.element.offset();
3708
3709		//Initialize mouse events for interaction
3710		this._mouseInit();
3711
3712		//We're ready to go
3713		this.ready = true
3714
3715	},
3716
3717	_destroy: function() {
3718		this.element
3719			.removeClass("ui-sortable ui-sortable-disabled");
3720		this._mouseDestroy();
3721
3722		for ( var i = this.items.length - 1; i >= 0; i-- )
3723			this.items[i].item.removeData(this.widgetName + "-item");
3724
3725		return this;
3726	},
3727
3728	_setOption: function(key, value){
3729		if ( key === "disabled" ) {
3730			this.options[ key ] = value;
3731
3732			this.widget().toggleClass( "ui-sortable-disabled", !!value );
3733		} else {
3734			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
3735			$.Widget.prototype._setOption.apply(this, arguments);
3736		}
3737	},
3738
3739	_mouseCapture: function(event, overrideHandle) {
3740		var that = this;
3741
3742		if (this.reverting) {
3743			return false;
3744		}
3745
3746		if(this.options.disabled || this.options.type == 'static') return false;
3747
3748		//We have to refresh the items data once first
3749		this._refreshItems(event);
3750
3751		//Find out if the clicked node (or one of its parents) is a actual item in this.items
3752		var currentItem = null, nodes = $(event.target).parents().each(function() {
3753			if($.data(this, that.widgetName + '-item') == that) {
3754				currentItem = $(this);
3755				return false;
3756			}
3757		});
3758		if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
3759
3760		if(!currentItem) return false;
3761		if(this.options.handle && !overrideHandle) {
3762			var validHandle = false;
3763
3764			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3765			if(!validHandle) return false;
3766		}
3767
3768		this.currentItem = currentItem;
3769		this._removeCurrentsFromItems();
3770		return true;
3771
3772	},
3773
3774	_mouseStart: function(event, overrideHandle, noActivation) {
3775
3776		var o = this.options;
3777		this.currentContainer = this;
3778
3779		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3780		this.refreshPositions();
3781
3782		//Create and append the visible helper
3783		this.helper = this._createHelper(event);
3784
3785		//Cache the helper size
3786		this._cacheHelperProportions();
3787
3788		/*
3789		 * - Position generation -
3790		 * This block generates everything position related - it's the core of draggables.
3791		 */
3792
3793		//Cache the margins of the original element
3794		this._cacheMargins();
3795
3796		//Get the next scrolling parent
3797		this.scrollParent = this.helper.scrollParent();
3798
3799		//The element's absolute position on the page minus margins
3800		this.offset = this.currentItem.offset();
3801		this.offset = {
3802			top: this.offset.top - this.margins.top,
3803			left: this.offset.left - this.margins.left
3804		};
3805
3806		$.extend(this.offset, {
3807			click: { //Where the click happened, relative to the element
3808				left: event.pageX - this.offset.left,
3809				top: event.pageY - this.offset.top
3810			},
3811			parent: this._getParentOffset(),
3812			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3813		});
3814
3815		// Only after we got the offset, we can change the helper's position to absolute
3816		// TODO: Still need to figure out a way to make relative sorting possible
3817		this.helper.css("position", "absolute");
3818		this.cssPosition = this.helper.css("position");
3819
3820		//Generate the original position
3821		this.originalPosition = this._generatePosition(event);
3822		this.originalPageX = event.pageX;
3823		this.originalPageY = event.pageY;
3824
3825		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3826		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3827
3828		//Cache the former DOM position
3829		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3830
3831		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
3832		if(this.helper[0] != this.currentItem[0]) {
3833			this.currentItem.hide();
3834		}
3835
3836		//Create the placeholder
3837		this._createPlaceholder();
3838
3839		//Set a containment if given in the options
3840		if(o.containment)
3841			this._setContainment();
3842
3843		if(o.cursor) { // cursor option
3844			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3845			$('body').css("cursor", o.cursor);
3846		}
3847
3848		if(o.opacity) { // opacity option
3849			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3850			this.helper.css("opacity", o.opacity);
3851		}
3852
3853		if(o.zIndex) { // zIndex option
3854			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3855			this.helper.css("zIndex", o.zIndex);
3856		}
3857
3858		//Prepare scrolling
3859		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3860			this.overflowOffset = this.scrollParent.offset();
3861
3862		//Call callbacks
3863		this._trigger("start", event, this._uiHash());
3864
3865		//Recache the helper size
3866		if(!this._preserveHelperProportions)
3867			this._cacheHelperProportions();
3868
3869
3870		//Post 'activate' events to possible containers
3871		if(!noActivation) {
3872			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
3873		}
3874
3875		//Prepare possible droppables
3876		if($.ui.ddmanager)
3877			$.ui.ddmanager.current = this;
3878
3879		if ($.ui.ddmanager && !o.dropBehaviour)
3880			$.ui.ddmanager.prepareOffsets(this, event);
3881
3882		this.dragging = true;
3883
3884		this.helper.addClass("ui-sortable-helper");
3885		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3886		return true;
3887
3888	},
3889
3890	_mouseDrag: function(event) {
3891
3892		//Compute the helpers position
3893		this.position = this._generatePosition(event);
3894		this.positionAbs = this._convertPositionTo("absolute");
3895
3896		if (!this.lastPositionAbs) {
3897			this.lastPositionAbs = this.positionAbs;
3898		}
3899
3900		//Do scrolling
3901		if(this.options.scroll) {
3902			var o = this.options, scrolled = false;
3903			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3904
3905				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3906					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3907				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3908					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3909
3910				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3911					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3912				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3913					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3914
3915			} else {
3916
3917				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3918					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3919				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3920					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3921
3922				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3923					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3924				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3925					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3926
3927			}
3928
3929			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3930				$.ui.ddmanager.prepareOffsets(this, event);
3931		}
3932
3933		//Regenerate the absolute position used for position checks
3934		this.positionAbs = this._convertPositionTo("absolute");
3935
3936		//Set the helper position
3937		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3938		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3939
3940		//Rearrange
3941		for (var i = this.items.length - 1; i >= 0; i--) {
3942
3943			//Cache variables and intersection, continue if no intersection
3944			var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3945			if (!intersection) continue;
3946
3947			// Only put the placeholder inside the current Container, skip all
3948			// items form other containers. This works because when moving
3949			// an item from one container to another the
3950			// currentContainer is switched before the placeholder is moved.
3951			//
3952			// Without this moving items in "sub-sortables" can cause the placeholder to jitter
3953			// beetween the outer and inner container.
3954			if (item.instance !== this.currentContainer) continue;
3955
3956			if (itemElement != this.currentItem[0] //cannot intersect with itself
3957				&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3958				&&	!$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3959				&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
3960				//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3961			) {
3962
3963				this.direction = intersection == 1 ? "down" : "up";
3964
3965				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3966					this._rearrange(event, item);
3967				} else {
3968					break;
3969				}
3970
3971				this._trigger("change", event, this._uiHash());
3972				break;
3973			}
3974		}
3975
3976		//Post events to containers
3977		this._contactContainers(event);
3978
3979		//Interconnect with droppables
3980		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3981
3982		//Call callbacks
3983		this._trigger('sort', event, this._uiHash());
3984
3985		this.lastPositionAbs = this.positionAbs;
3986		return false;
3987
3988	},
3989
3990	_mouseStop: function(event, noPropagation) {
3991
3992		if(!event) return;
3993
3994		//If we are using droppables, inform the manager about the drop
3995		if ($.ui.ddmanager && !this.options.dropBehaviour)
3996			$.ui.ddmanager.drop(this, event);
3997
3998		if(this.options.revert) {
3999			var that = this;
4000			var cur = this.placeholder.offset();
4001
4002			this.reverting = true;
4003
4004			$(this.helper).animate({
4005				left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
4006				top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
4007			}, parseInt(this.options.revert, 10) || 500, function() {
4008				that._clear(event);
4009			});
4010		} else {
4011			this._clear(event, noPropagation);
4012		}
4013
4014		return false;
4015
4016	},
4017
4018	cancel: function() {
4019
4020		if(this.dragging) {
4021
4022			this._mouseUp({ target: null });
4023
4024			if(this.options.helper == "original")
4025				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4026			else
4027				this.currentItem.show();
4028
4029			//Post deactivating events to containers
4030			for (var i = this.containers.length - 1; i >= 0; i--){
4031				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4032				if(this.containers[i].containerCache.over) {
4033					this.containers[i]._trigger("out", null, this._uiHash(this));
4034					this.containers[i].containerCache.over = 0;
4035				}
4036			}
4037
4038		}
4039
4040		if (this.placeholder) {
4041			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4042			if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4043			if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
4044
4045			$.extend(this, {
4046				helper: null,
4047				dragging: false,
4048				reverting: false,
4049				_noFinalSort: null
4050			});
4051
4052			if(this.domPosition.prev) {
4053				$(this.domPosition.prev).after(this.currentItem);
4054			} else {
4055				$(this.domPosition.parent).prepend(this.currentItem);
4056			}
4057		}
4058
4059		return this;
4060
4061	},
4062
4063	serialize: function(o) {
4064
4065		var items = this._getItemsAsjQuery(o && o.connected);
4066		var str = []; o = o || {};
4067
4068		$(items).each(function() {
4069			var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
4070			if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
4071		});
4072
4073		if(!str.length && o.key) {
4074			str.push(o.key + '=');
4075		}
4076
4077		return str.join('&');
4078
4079	},
4080
4081	toArray: function(o) {
4082
4083		var items = this._getItemsAsjQuery(o && o.connected);
4084		var ret = []; o = o || {};
4085
4086		items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
4087		return ret;
4088
4089	},
4090
4091	/* Be careful with the following core functions */
4092	_intersectsWith: function(item) {
4093
4094		var x1 = this.positionAbs.left,
4095			x2 = x1 + this.helperProportions.width,
4096			y1 = this.positionAbs.top,
4097			y2 = y1 + this.helperProportions.height;
4098
4099		var l = item.left,
4100			r = l + item.width,
4101			t = item.top,
4102			b = t + item.height;
4103
4104		var dyClick = this.offset.click.top,
4105			dxClick = this.offset.click.left;
4106
4107		var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
4108
4109		if(	   this.options.tolerance == "pointer"
4110			|| this.options.forcePointerForContainers
4111			|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
4112		) {
4113			return isOverElement;
4114		} else {
4115
4116			return (l < x1 + (this.helperProportions.width / 2) // Right Half
4117				&& x2 - (this.helperProportions.width / 2) < r // Left Half
4118				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
4119				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
4120
4121		}
4122	},
4123
4124	_intersectsWithPointer: function(item) {
4125
4126		var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4127			isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4128			isOverElement = isOverElementHeight && isOverElementWidth,
4129			verticalDirection = this._getDragVerticalDirection(),
4130			horizontalDirection = this._getDragHorizontalDirection();
4131
4132		if (!isOverElement)
4133			return false;
4134
4135		return this.floating ?
4136			( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
4137			: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
4138
4139	},
4140
4141	_intersectsWithSides: function(item) {
4142
4143		var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4144			isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4145			verticalDirection = this._getDragVerticalDirection(),
4146			horizontalDirection = this._getDragHorizontalDirection();
4147
4148		if (this.floating && horizontalDirection) {
4149			return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
4150		} else {
4151			return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
4152		}
4153
4154	},
4155
4156	_getDragVerticalDirection: function() {
4157		var delta = this.positionAbs.top - this.lastPositionAbs.top;
4158		return delta != 0 && (delta > 0 ? "down" : "up");
4159	},
4160
4161	_getDragHorizontalDirection: function() {
4162		var delta = this.positionAbs.left - this.lastPositionAbs.left;
4163		return delta != 0 && (delta > 0 ? "right" : "left");
4164	},
4165
4166	refresh: function(event) {
4167		this._refreshItems(event);
4168		this.refreshPositions();
4169		return this;
4170	},
4171
4172	_connectWith: function() {
4173		var options = this.options;
4174		return options.connectWith.constructor == String
4175			? [options.connectWith]
4176			: options.connectWith;
4177	},
4178
4179	_getItemsAsjQuery: function(connected) {
4180
4181		var items = [];
4182		var queries = [];
4183		var connectWith = this._connectWith();
4184
4185		if(connectWith && connected) {
4186			for (var i = connectWith.length - 1; i >= 0; i--){
4187				var cur = $(connectWith[i]);
4188				for (var j = cur.length - 1; j >= 0; j--){
4189					var inst = $.data(cur[j], this.widgetName);
4190					if(inst && inst != this && !inst.options.disabled) {
4191						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
4192					}
4193				};
4194			};
4195		}
4196
4197		queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
4198
4199		for (var i = queries.length - 1; i >= 0; i--){
4200			queries[i][0].each(function() {
4201				items.push(this);
4202			});
4203		};
4204
4205		return $(items);
4206
4207	},
4208
4209	_removeCurrentsFromItems: function() {
4210
4211		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4212
4213		this.items = $.grep(this.items, function (item) {
4214			for (var j=0; j < list.length; j++) {
4215				if(list[j] == item.item[0])
4216					return false;
4217			};
4218			return true;
4219		});
4220
4221	},
4222
4223	_refreshItems: function(event) {
4224
4225		this.items = [];
4226		this.containers = [this];
4227		var items = this.items;
4228		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
4229		var connectWith = this._connectWith();
4230
4231		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4232			for (var i = connectWith.length - 1; i >= 0; i--){
4233				var cur = $(connectWith[i]);
4234				for (var j = cur.length - 1; j >= 0; j--){
4235					var inst = $.data(cur[j], this.widgetName);
4236					if(inst && inst != this && !inst.options.disabled) {
4237						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4238						this.containers.push(inst);
4239					}
4240				};
4241			};
4242		}
4243
4244		for (var i = queries.length - 1; i >= 0; i--) {
4245			var targetData = queries[i][1];
4246			var _queries = queries[i][0];
4247
4248			for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4249				var item = $(_queries[j]);
4250
4251				item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
4252
4253				items.push({
4254					item: item,
4255					instance: targetData,
4256					width: 0, height: 0,
4257					left: 0, top: 0
4258				});
4259			};
4260		};
4261
4262	},
4263
4264	refreshPositions: function(fast) {
4265
4266		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4267		if(this.offsetParent && this.helper) {
4268			this.offset.parent = this._getParentOffset();
4269		}
4270
4271		for (var i = this.items.length - 1; i >= 0; i--){
4272			var item = this.items[i];
4273
4274			//We ignore calculating positions of all connected containers when we're not over them
4275			if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
4276				continue;
4277
4278			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4279
4280			if (!fast) {
4281				item.width = t.outerWidth();
4282				item.height = t.outerHeight();
4283			}
4284
4285			var p = t.offset();
4286			item.left = p.left;
4287			item.top = p.top;
4288		};
4289
4290		if(this.options.custom && this.options.custom.refreshContainers
4290) {
4291			this.options.custom.refreshContainers.call(this);
4292		} else {
4293			for (var i = this.containers.length - 1; i >= 0; i--){
4294				var p = this.containers[i].element.offset();
4295				this.containers[i].containerCache.left = p.left;
4296				this.containers[i].containerCache.top = p.top;
4297				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
4298				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4299			};
4300		}
4301
4302		return this;
4303	},
4304
4305	_createPlaceholder: function(that) {
4306		that = that || this;
4307		var o = that.options;
4308
4309		if(!o.placeholder || o.placeholder.constructor == String) {
4310			var className = o.placeholder;
4311			o.placeholder = {
4312				element: function() {
4313
4314					var el = $(document.createElement(that.currentItem[0].nodeName))
4315						.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4316						.removeClass("ui-sortable-helper")[0];
4317
4318					if(!className)
4319						el.style.visibility = "hidden";
4320
4321					return el;
4322				},
4323				update: function(container, p) {
4324
4325					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4326					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4327					if(className && !o.forcePlaceholderSize) return;
4328
4329					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
4330					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
4331					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
4332				}
4333			};
4334		}
4335
4336		//Create the placeholder
4337		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4338
4339		//Append it after the actual current item
4340		that.currentItem.after(that.placeholder);
4341
4342		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4343		o.placeholder.update(that, that.placeholder);
4344
4345	},
4346
4347	_contactContainers: function(event) {
4348
4349		// get innermost container that intersects with item
4350		var innermostContainer = null, innermostIndex = null;
4351
4352
4353		for (var i = this.containers.length - 1; i >= 0; i--){
4354
4355			// never consider a container that's located within the item itself
4356			if($.contains(this.currentItem[0], this.containers[i].element[0]))
4357				continue;
4358
4359			if(this._intersectsWith(this.containers[i].containerCache)) {
4360
4361				// if we've already found a container and it's more "inner" than this, then continue
4362				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
4363					continue;
4364
4365				innermostContainer = this.containers[i];
4366				innermostIndex = i;
4367
4368			} else {
4369				// container doesn't intersect. trigger "out" event if necessary
4370				if(this.containers[i].containerCache.over) {
4371					this.containers[i]._trigger("out", event, this._uiHash(this));
4372					this.containers[i].containerCache.over = 0;
4373				}
4374			}
4375
4376		}
4377
4378		// if no intersecting containers found, return
4379		if(!innermostContainer) return;
4380
4381		// move the item into the container if it's not there already
4382		if(this.containers.length === 1) {
4383			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4384			this.containers[innermostIndex].containerCache.over = 1;
4385		} else {
4386
4387			//When entering a new container, we will find the item with the least distance and append our item near it
4388			var dist = 10000; var itemWithLeastDistance = null;
4389			var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
4390			var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
4391			var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4392			for (var j = this.items.length - 1; j >= 0; j--) {
4393				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
4394				if(this.items[j].item[0] == this.currentItem[0]) continue;
4395				var cur = this.items[j].item.offset()[posProperty];
4396				var nearBottom = false;
4397				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4398					nearBottom = true;
4399					cur += this.items[j][sizeProperty];
4400				}
4401
4402				if(Math.abs(cur - base) < dist) {
4403					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4404					this.direction = nearBottom ? "up": "down";
4405				}
4406			}
4407
4408			if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
4409				return;
4410
4411			this.currentContainer = this.containers[innermostIndex];
4412			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4413			this._trigger("change", event, this._uiHash());
4414			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4415
4416			//Update the placeholder
4417			this.options.placeholder.update(this.currentContainer, this.placeholder);
4418
4419			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4420			this.containers[innermostIndex].containerCache.over = 1;
4421		}
4422
4423
4424	},
4425
4426	_createHelper: function(event) {
4427
4428		var o = this.options;
4429		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
4430
4431		if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
4432			$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4433
4434		if(helper[0] == this.currentItem[0])
4435			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left
4435: this.currentItem.css("left") };
4436
4437		if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
4438		if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
4439
4440		return helper;
4441
4442	},
4443
4444	_adjustOffsetFromHelper: function(obj) {
4445		if (typeof obj == 'string') {
4446			obj = obj.split(' ');
4447		}
4448		if ($.isArray(obj)) {
4449			obj = {left: +obj[0], top: +obj[1] || 0};
4450		}
4451		if ('left' in obj) {
4452			this.offset.click.left = obj.left + this.margins.left;
4453		}
4454		if ('right' in obj) {
4455			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4456		}
4457		if ('top' in obj) {
4458			this.offset.click.top = obj.top + this.margins.top;
4459		}
4460		if ('bottom' in obj) {
4461			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4462		}
4463	},
4464
4465	_getParentOffset: function() {
4466
4467
4468		//Get the offsetParent and cache its position
4469		this.offsetParent = this.helper.offsetParent();
4470		var po = this.offsetParent.offset();
4471
4472		// This is a special case where we need to modify a offset calculated on start, since the following happened:
4473		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4474		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4475		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4476		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4477			po.left += this.scrollParent.scrollLeft();
4478			po.top += this.scrollParent.scrollTop();
4479		}
4480
4481		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4482		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
4483			po = { top: 0, left: 0 };
4484
4485		return {
4486			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4487			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4488		};
4489
4490	},
4491
4492	_getRelativeOffset: function() {
4493
4494		if(this.cssPosition == "relative") {
4495			var p = this.currentItem.position();
4496			return {
4497				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4498				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4499			};
4500		} else {
4501			return { top: 0, left: 0 };
4502		}
4503
4504	},
4505
4506	_cacheMargins: function() {
4507		this.margins = {
4508			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4509			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4510		};
4511	},
4512
4513	_cacheHelperProportions: function() {
4514		this.helperProportions = {
4515			width: this.helper.outerWidth(),
4516			height: this.helper.outerHeight()
4517		};
4518	},
4519
4520	_setContainment: function() {
4521
4522		var o = this.options;
4523		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4524		if(o.containment == 'document' || o.containment == 'window') this.containment = [
4525			0 - this.offset.relative.left - this.offset.parent.left,
4526			0 - this.offset.relative.top - this.offset.parent.top,
4527			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4528			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4529		];
4530
4531		if(!(/^(document|window|parent)$/).test(o.containment)) {
4532			var ce = $(o.containment)[0];
4533			var co = $(o.containment).offset();
4534			var over = ($(ce).css("overflow") != 'hidden');
4535
4536			this.containment = [
4537				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4538				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4539				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
4540				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
454010) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4541			];
4542		}
4543
4544	},
4545
4546	_convertPositionTo: function(d, pos) {
4547
4548		if(!pos) pos = this.position;
4549		var mod = d == "absolute" ? 1 : -1;
4550		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4551
4552		return {
4553			top: (
4554				pos.top																	// The absolute mouse position
4555				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4556				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
4557				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4558			),
4559			left: (
4560				pos.left																// The absolute mouse position
4561				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4562				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
4563				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4564			)
4565		};
4566
4567	},
4568
4569	_generatePosition: function(event) {
4570
4571		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4572
4573		// This is another very weird special case that only happens for relative elements:
4574		// 1. If the css position is relative
4575		// 2. and the scroll parent is the document or similar to the offset parent
4576		// we have to refresh the relative offset during the scroll so there are no jumps
4577		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4578			this.offset.relative = this._getRelativeOffset();
4579		}
4580
4581		var pageX = event.pageX;
4582		var pageY = event.pageY;
4583
4584		/*
4585		 * - Position constraining -
4586		 * Constrain the position to a mix of grid, containment.
4587		 */
4588
4589		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4590
4591			if(this.containment) {
4592				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4593				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4594				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4595				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4596			}
4597
4598			if(o.grid) {
4599				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4600				pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
4601
4602				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4603				pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
4604			}
4605
4606		}
4607
4608		return {
4609			top: (
4610				pageY																// The absolute mouse position
4611				- this.offset.click.top													// Click offset (relative to the element)
4612				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
4613				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
4614				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4615			),
4616			left: (
4617				pageX																// The absolute mouse position
4618				- this.offset.click.left												// Click offset (relative to the element)
4619				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
4620				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
4621				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4622			)
4623		};
4624
4625	},
4626
4627	_rearrange: function(event, i, a, hardRefresh) {
4628
4629		a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
4630
4631		//Various things done here to improve the performance:
4632		// 1. we create a setTimeout, that calls refreshPositions
4633		// 2. on the instance, we have a counter variable, that get's higher after every append
4634		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4635		// 4. this lets only the last addition to the timeout stack through
4636		this.counter = this.counter ? ++this.counter : 1;
4637		var counter = this.counter;
4638
4639		this._delay(function() {
4640			if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4641		});
4642
4643	},
4644
4645	_clear: function(event, noPropagation) {
4646
4647		this.reverting = false;
4648		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
4649		// everything else normalized again
4650		var delayedTriggers = [];
4651
4652		// We first have to update the dom position of the actual currentItem
4653		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4654		if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4655		this._noFinalSort = null;
4656
4657		if(this.helper[0] == this.currentItem[0]) {
4658			for(var i in this._storedCSS) {
4659				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4660			}
4661			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4662		} else {
4663			this.currentItem.show();
4664		}
4665
4666		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4667		if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4668
4669		// Check if the items Container has Changed and trigger appropriate
4670		// events.
4671		if (this !== this.currentContainer) {
4672			if(!noPropagation) {
4673				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4674				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4675				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4676			}
4677		}
4678
4679
4680		//Post events to containers
4681		for (var i = this.containers.length - 1; i >= 0; i--){
4682			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4683			if(this.containers[i].containerCache.over) {
4684				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4685				this.containers[i].containerCache.over = 0;
4686			}
4687		}
4688
4689		//Do what was originally in plugins
4690		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4691		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4692		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4693
4694		this.dragging = false;
4695		if(this.cancelHelperRemoval) {
4696			if(!noPropagation) {
4697				this._trigger("beforeStop", event, this._uiHash());
4698				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4699				this._trigger("stop", event, this._uiHash());
4700			}
4701
4702			this.fromOutside = false;
4703			return false;
4704		}
4705
4706		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4707
4708		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4709		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4710
4711		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4712
4713		if(!noPropagation) {
4714			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4715			this._trigger("stop", event, this._uiHash());
4716		}
4717
4718		this.fromOutside = false;
4719		return true;
4720
4721	},
4722
4723	_trigger: function() {
4724		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4725			this.cancel();
4726		}
4727	},
4728
4729	_uiHash: function(_inst) {
4730		var inst = _inst || this;
4731		return {
4732			helper: inst.helper,
4733			placeholder: inst.placeholder || $([]),
4734			position: inst.position,
4735			originalPosition: inst.originalPosition,
4736			offset: inst.positionAbs,
4737			item: inst.currentItem,
4738			sender: _inst ? _inst.element : null
4739		};
4740	}
4741
4742});
4743
4744})(jQuery);
4745(function( $, undefined ) {
4746
4747var uid = 0,
4748	hideProps = {},
4749	showProps = {};
4750
4751hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
4752	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
4753showProps.height = showProps.paddingTop = showProps.paddingBottom =
4754	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
4755
4756$.widget( "ui.accordion", {
4757	version: "1.9.2",
4758	options: {
4759		active: 0,
4760		animate: {},
4761		collapsible: false,
4762		event: "click",
4763		header: "> li > :first-child,> :not(li):even",
4764		heightStyle: "auto",
4765		icons: {
4766			activeHeader: "ui-icon-triangle-1-s",
4767			header: "ui-icon-triangle-1-e"
4768		},
4769
4770		// callbacks
4771		activate: null,
4772		beforeActivate: null
4773	},
4774
4775	_create: function() {
vendor: 5,494 bytes, lines 4776-4975
4776		var accordionId = this.accordionId = "ui-accordion-" +
4777				(this.element.attr( "id" ) || ++uid),
4778			options = this.options;
4779
4780		this.prevShow = this.prevHide = $();
4781		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
4782
4783		this.headers = this.element.find( options.header )
4784			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
4785		this._hoverable( this.headers );
4786		this._focusable( this.headers );
4787
4788		this.headers.next()
4789			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
4790			.hide();
4791
4792		// don't allow collapsible: false and active: false / null
4793		if ( !options.collapsible && (options.active === false || options.active == null) ) {
4794			options.active = 0;
4795		}
4796		// handle negative values
4797		if ( options.active < 0 ) {
4798			options.active += this.headers.length;
4799		}
4800		this.active = this._findActive( options.active )
4801			.addClass( "ui-accordion-header-active ui-state-active" )
4802			.toggleClass( "ui-corner-all ui-corner-top" );
4803		this.active.next()
4804			.addClass( "ui-accordion-content-active" )
4805			.show();
4806
4807		this._createIcons();
4808		this.refresh();
4809
4810		// ARIA
4811		this.element.attr( "role", "tablist" );
4812
4813		this.headers
4814			.attr( "role", "tab" )
4815			.each(function( i ) {
4816				var header = $( this ),
4817					headerId = header.attr( "id" ),
4818					panel = header.next(),
4819					panelId = panel.attr( "id" );
4820				if ( !headerId ) {
4821					headerId = accordionId + "-header-" + i;
4822					header.attr( "id", headerId );
4823				}
4824				if ( !panelId ) {
4825					panelId = accordionId + "-panel-" + i;
4826					panel.attr( "id", panelId );
4827				}
4828				header.attr( "aria-controls", panelId );
4829				panel.attr( "aria-labelledby", headerId );
4830			})
4831			.next()
4832				.attr( "role", "tabpanel" );
4833
4834		this.headers
4835			.not( this.active )
4836			.attr({
4837				"aria-selected": "false",
4838				tabIndex: -1
4839			})
4840			.next()
4841				.attr({
4842					"aria-expanded": "false",
4843					"aria-hidden": "true"
4844				})
4845				.hide();
4846
4847		// make sure at least one header is in the tab order
4848		if ( !this.active.length ) {
4849			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4850		} else {
4851			this.active.attr({
4852				"aria-selected": "true",
4853				tabIndex: 0
4854			})
4855			.next()
4856				.attr({
4857					"aria-expanded": "true",
4858					"aria-hidden": "false"
4859				});
4860		}
4861
4862		this._on( this.headers, { keydown: "_keydown" });
4863		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
4864		this._setupEvents( options.event );
4865	},
4866
4867	_getCreateEventData: function() {
4868		return {
4869			header: this.active,
4870			content: !this.active.length ? $() : this.active.next()
4871		};
4872	},
4873
4874	_createIcons: function() {
4875		var icons = this.options.icons;
4876		if ( icons ) {
4877			$( "<span>" )
4878				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
4879				.prependTo( this.headers );
4880			this.active.children( ".ui-accordion-header-icon" )
4881				.removeClass( icons.header )
4882				.addClass( icons.activeHeader );
4883			this.headers.addClass( "ui-accordion-icons" );
4884		}
4885	},
4886
4887	_destroyIcons: function() {
4888		this.headers
4889			.removeClass( "ui-accordion-icons" )
4890			.children( ".ui-accordion-header-icon" )
4891				.remove();
4892	},
4893
4894	_destroy: function() {
4895		var contents;
4896
4897		// clean up main element
4898		this.element
4899			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
4900			.removeAttr( "role" );
4901
4902		// clean up headers
4903		this.headers
4904			.removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
4905			.removeAttr( "role" )
4906			.removeAttr( "aria-selected" )
4907			.removeAttr( "aria-controls" )
4908			.removeAttr( "tabIndex" )
4909			.each(function() {
4910				if ( /^ui-accordion/.test( this.id ) ) {
4911					this.removeAttribute( "id" );
4912				}
4913			});
4914		this._destroyIcons();
4915
4916		// clean up content panels
4917		contents = this.headers.next()
4918			.css( "display", "" )
4919			.removeAttr( "role" )
4920			.removeAttr( "aria-expanded" )
4921			.removeAttr( "aria-hidden" )
4922			.removeAttr( "aria-labelledby" )
4923			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
4924			.each(function() {
4925				if ( /^ui-accordion/.test( this.id ) ) {
4926					this.removeAttribute( "id" );
4927				}
4928			});
4929		if ( this.options.heightStyle !== "content" ) {
4930			contents.css( "height", "" );
4931		}
4932	},
4933
4934	_setOption: function( key, value ) {
4935		if ( key === "active" ) {
4936			// _activate() will handle invalid values and update this.options
4937			this._activate( value );
4938			return;
4939		}
4940
4941		if ( key === "event" ) {
4942			if ( this.options.event ) {
4943				this._off( this.headers, this.options.event );
4944			}
4945			this._setupEvents( value );
4946		}
4947
4948		this._super( key, value );
4949
4950		// setting collapsible: false while collapsed; open first panel
4951		if ( key === "collapsible" && !value && this.options.active === false ) {
4952			this._activate( 0 );
4953		}
4954
4955		if ( key === "icons" ) {
4956			this._destroyIcons();
4957			if ( value ) {
4958				this._createIcons();
4959			}
4960		}
4961
4962		// #5332 - opacity doesn't cascade to positioned elements in IE
4963		// so we need to add the disabled class to the headers and panels
4964		if ( key === "disabled" ) {
4965			this.headers.add( this.headers.next() )
4966				.toggleClass( "ui-state-disabled", !!value );
4967		}
4968	},
4969
4970	_keydown: function( event ) {
4971		if ( event.altKey || event.ctrlKey ) {
4972			return;
4973		}
4974
4975		var keyCode = $.ui.keyCode,
vendor: 4,490 bytes, lines 4976-5134
4976			length = this.headers.length,
4977			currentIndex = this.headers.index( event.target ),
4978			toFocus = false;
4979
4980		switch ( event.keyCode ) {
4981			case keyCode.RIGHT:
4982			case keyCode.DOWN:
4983				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4984				break;
4985			case keyCode.LEFT:
4986			case keyCode.UP:
4987				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4988				break;
4989			case keyCode.SPACE:
4990			case keyCode.ENTER:
4991				this._eventHandler( event );
4992				break;
4993			case keyCode.HOME:
4994				toFocus = this.headers[ 0 ];
4995				break;
4996			case keyCode.END:
4997				toFocus = this.headers[ length - 1 ];
4998				break;
4999		}
5000
5001		if ( toFocus ) {
5002			$( event.target ).attr( "tabIndex", -1 );
5003			$( toFocus ).attr( "tabIndex", 0 );
5004			toFocus.focus();
5005			event.preventDefault();
5006		}
5007	},
5008
5009	_panelKeyDown : function( event ) {
5010		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5011			$( event.currentTarget ).prev().focus();
5012		}
5013	},
5014
5015	refresh: function() {
5016		var maxHeight, overflow,
5017			heightStyle = this.options.heightStyle,
5018			parent = this.element.parent();
5019
5020
5021		if ( heightStyle === "fill" ) {
5022			// IE 6 treats height like minHeight, so we need to turn off overflow
5023			// in order to get a reliable height
5024			// we use the minHeight support test because we assume that only
5025			// browsers that don't support minHeight will treat height as minHeight
5026			if ( !$.support.minHeight ) {
5027				overflow = parent.css( "overflow" );
5028				parent.css( "overflow", "hidden");
5029			}
5030			maxHeight = parent.height();
5031			this.element.siblings( ":visible" ).each(function() {
5032				var elem = $( this ),
5033					position = elem.css( "position" );
5034
5035				if ( position === "absolute" || position === "fixed" ) {
5036					return;
5037				}
5038				maxHeight -= elem.outerHeight( true );
5039			});
5040			if ( overflow ) {
5041				parent.css( "overflow", overflow );
5042			}
5043
5044			this.headers.each(function() {
5045				maxHeight -= $( this ).outerHeight( true );
5046			});
5047
5048			this.headers.next()
5049				.each(function() {
5050					$( this ).height( Math.max( 0, maxHeight -
5051						$( this ).innerHeight() + $( this ).height() ) );
5052				})
5053				.css( "overflow", "auto" );
5054		} else if ( heightStyle === "auto" ) {
5055			maxHeight = 0;
5056			this.headers.next()
5057				.each(function() {
5058					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
5059				})
5060				.height( maxHeight );
5061		}
5062	},
5063
5064	_activate: function( index ) {
5065		var active = this._findActive( index )[ 0 ];
5066
5067		// trying to activate the already active panel
5068		if ( active === this.active[ 0 ] ) {
5069			return;
5070		}
5071
5072		// trying to collapse, simulate a click on the currently active header
5073		active = active || this.active[ 0 ];
5074
5075		this._eventHandler({
5076			target: active,
5077			currentTarget: active,
5078			preventDefault: $.noop
5079		});
5080	},
5081
5082	_findActive: function( selector ) {
5083		return typeof selector === "number" ? this.headers.eq( selector ) : $();
5084	},
5085
5086	_setupEvents: function( event ) {
5087		var events = {};
5088		if ( !event ) {
5089			return;
5090		}
5091		$.each( event.split(" "), function( index, eventName ) {
5092			events[ eventName ] = "_eventHandler";
5093		});
5094		this._on( this.headers, events );
5095	},
5096
5097	_eventHandler: function( event ) {
5098		var options = this.options,
5099			active = this.active,
5100			clicked = $( event.currentTarget ),
5101			clickedIsActive = clicked[ 0 ] === active[ 0 ],
5102			collapsing = clickedIsActive && options.collapsible,
5103			toShow = collapsing ? $() : clicked.next(),
5104			toHide = active.next(),
5105			eventData = {
5106				oldHeader: active,
5107				oldPanel: toHide,
5108				newHeader: collapsing ? $() : clicked,
5109				newPanel: toShow
5110			};
5111
5112		event.preventDefault();
5113
5114		if (
5115				// click on active header, but not collapsible
5116				( clickedIsActive && !options.collapsible ) ||
5117				// allow canceling activation
5118				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
5119			return;
5120		}
5121
5122		options.active = collapsing ? false : this.headers.index( clicked );
5123
5124		// when the call to ._toggle() comes after the class changes
5125		// it causes a very odd bug in IE 8 (see #6720)
5126		this.active = clickedIsActive ? $() : clicked;
5127		this._toggle( eventData );
5128
5129		// switch classes
5130		// corner classes on the previously active header stay after the animation
5131		active.removeClass( "ui-accordion-header-active ui-state-active" );
5132		if ( options.icons ) {
5133			active.children( ".ui-accordion-header-icon" )
5134				.removeClass( options.icons.activeHeader )
5135				.addClass( options.icons.header );
5136		}
5137
5138		if ( !clickedIsActive ) {
5139			clicked
5140				.removeClass( "ui-corner-all" )
5141				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
5142			if ( options.icons ) {
5143				clicked.children( ".ui-accordion-header-icon" )
5144					.removeClass( options.icons.header )
5145					.addClass( options.icons.activeHeader );
5146			}
5147
5148			clicked
5149				.next()
5150				.addClass( "ui-accordion-content-active" );
5151		}
5152	},
5153
5154	_toggle: function( data ) {
5155		var toShow = data.newPanel,
5156			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
5157
5158		// handle activating a panel during the animation for another activation
5159		this.prevShow.add( this.prevHide ).stop( true, true );
5160		this.prevShow = toShow;
5161		this.prevHide = toHide;
5162
5163		if ( this.options.animate ) {
5164			this._animate( toShow, toHide, data );
5165		} else {
5166			toHide.hide();
5167			toShow.show();
5168			this._toggleComplete( data );
5169		}
5170
5171		toHide.attr({
5172			"aria-expanded": "false",
5173			"aria-hidden": "true"
5174		});
5175		toHide.prev().attr( "aria-selected", "false" );
5176		// if we're switching panels, remove the old header from the tab order
5177		// if we're opening from collapsed state, remove the previous header from the tab order
5178		// if we're collapsing, then keep the collapsing header in the tab order
5179		if ( toShow.length && toHide.length ) {
5180			toHide.prev().attr( "tabIndex", -1 );
5181		} else if ( toShow.length ) {
5182			this.headers.filter(function() {
5183				return $( this ).attr( "tabIndex" ) === 0;
5184			})
5185			.attr( "tabIndex", -1 );
5186		}
5187
5188		toShow
5189			.attr({
5190				"aria-expanded": "true",
5191				"aria-hidden": "false"
5192			})
5193			.prev()
5194				.attr({
5195					"aria-selected": "true",
5196					tabIndex: 0
5197				});
5198	},
5199
5200	_animate: function( toShow, toHide, data ) {
5201		var total, easing, duration,
5202			that = this,
5203			adjust = 0,
5204			down = toShow.length &&
5205				( !toHide.length || ( toShow.index() < toHide.index() ) ),
5206			animate = this.options.animate || {},
5207			options = down && animate.down || animate,
5208			complete = function() {
5209				that._toggleComplete( data );
5210			};
5211
5212		if ( typeof options === "number" ) {
5213			duration = options;
5214		}
5215		if ( typeof options === "string" ) {
5216			easing = options;
5217		}
5218		// fall back from options to animation in case of partial down settings
5219		easing = easing || options.easing || animate.easing;
5220		duration = duration || options.duration || animate.duration;
5221
5222		if ( !toHide.length ) {
5223			return toShow.animate( showProps, duration, easing, complete );
5224		}
5225		if ( !toShow.length ) {
5226			return toHide.animate( hideProps, duration, easing, complete );
5227		}
5228
5229		total = toShow.show().outerHeight();
5230		toHide.animate( hideProps, {
5231			duration: duration,
5232			easing: easing,
5233			step: function( now, fx ) {
5234				fx.now = Math.round( now );
5235			}
5236		});
5237		toShow
5238			.hide()
5239			.animate( showProps, {
5240				duration: duration,
5241				easing: easing,
5242				complete: complete,
5243				step: function( now, fx ) {
5244					fx.now = Math.round( now );
5245					if ( fx.prop !== "height" ) {
5246						adjust += fx.now;
5247					} else if ( that.options.heightStyle !== "content" ) {
5248						fx.now = Math.round( total - toHide.outerHeight() - adjust );
5249						adjust = 0;
5250					}
5251				}
5252			});
5253	},
5254
5255	_toggleComplete: function( data ) {
5256		var toHide = data.oldPanel;
5257
5258		toHide
5259			.removeClass( "ui-accordion-content-active" )
5260			.prev()
5261				.removeClass( "ui-corner-top" )
5262				.addClass( "ui-corner-all" );
5263
5264		// Work around for rendering bug in IE (#5421)
5265		if ( toHide.length ) {
5266			toHide.parent()[0].className = toHide.parent()[0].className;
5267		}
5268
5269		this._trigger( "activate", null, data );
5270	}
5271});
5272
5273
5274
5275// DEPRECATED
5276if ( $.uiBackCompat !== false ) {
5277	// navigation options
5278	(function( $, prototype ) {
5279		$.extend( prototype.options, {
5280			navigation: false,
5281			navigationFilter: function() {
5282				return this.href.toLowerCase() === location.href.toLowerCase();
5283			}
5284		});
5285
5286		var _create = prototype._create;
5287		prototype._create = function() {
5288			if ( this.options.navigation ) {
5289				var that = this,
5290					headers = this.element.find( this.options.header ),
5291					content = headers.next(),
5292					current = headers.add( content )
5293						.find( "a" )
5294						.filter( this.options.navigationFilter )
5295						[ 0 ];
5296				if ( current ) {
5297					headers.add( content ).each( function( index ) {
5298						if ( $.contains( this, current ) ) {
5299							that.options.active = Math.floor( index / 2 );
5300							return false;
5301						}
5302					});
5303				}
5304			}
5305			_create.call( this );
5306		};
5307	}( jQuery, jQuery.ui.accordion.prototype ) );
5308
5309	// height options
5310	(function( $, prototype ) {
5311		$.extend( prototype.options, {
5312			heightStyle: null, // remove default so we fall back to old values
5313			autoHeight: true, // use heightStyle: "auto"
5314			clearStyle: false, // use heightStyle: "content"
5315			fillSpace: false // use heightStyle: "fill"
5316		});
5317
5318		var _create = prototype._create,
5319			_setOption = prototype._setOption;
5320
5321		$.extend( prototype, {
5322			_create: function() {
5323				this.options.heightStyle = this.options.heightStyle ||
5324					this._mergeHeightStyle();
5325
5326				_create.call( this );
5327			},
5328
5329			_setOption: function( key ) {
5330				if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
5331					this.options.heightStyle = this._mergeHeightStyle();
5332				}
5333				_setOption.apply( this, arguments );
5334			},
5335
5336			_mergeHeightStyle: function() {
5337				var options = this.options;
5338
5339				if ( options.fillSpace ) {
5340					return "fill";
5341				}
5342
5343				if ( options.clearStyle ) {
5344					return "content";
5345				}
5346
5347				if ( options.autoHeight ) {
5348					return "auto";
5349				}
5350			}
5351		});
5352	}( jQuery, jQuery.ui.accordion.prototype ) );
5353
5354	// icon options
5355	(function( $, prototype ) {
5356		$.extend( prototype.options.icons, {
5357			activeHeader: null, // remove default so we fall back to old values
5358			headerSelected: "ui-icon-triangle-1-s"
5359		});
5360
5361		var _createIcons = prototype._createIcons;
5362		prototype._createIcons = function() {
5363			if ( this.options.icons ) {
5364				this.options.icons.activeHeader = this.options.icons.activeHeader ||
5365					this.options.icons.headerSelected;
5366			}
5367			_createIcons.call( this );
5368		};
5369	}( jQuery, jQuery.ui.accordion.prototype ) );
5370
5371	// expanded active option, activate method
5372	(function( $, prototype ) {
5373		prototype.activate = prototype._activate;
5374
5375		var _findActive = prototype._findActive;
5376		prototype._findActive = function( index ) {
5377			if ( index === -1 ) {
5378				index = false;
5379			}
5380			if ( index && typeof index !== "number" ) {
5381				index = this.headers.index( this.headers.filter( index ) );
5382				if ( index === -1 ) {
5383					index = false;
5384				}
5385			}
5386			return _findActive.call( this, index );
5387		};
5388	}( jQuery, jQuery.ui.accordion.prototype ) );
5389
5390	// resize method
5391	jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
5392
5393	// change events
5394	(function( $, prototype ) {
5395		$.extend( prototype.options, {
5396			change: null,
5397			changestart: null
5398		});
5399
5400		var _trigger = prototype._trigger;
5401		prototype._trigger = function( type, event, data ) {
5402			var ret = _trigger.apply( this, arguments );
5403			if ( !ret ) {
5404				return false;
5405			}
5406
5407			if ( type === "beforeActivate" ) {
5408				ret = _trigger.call( this, "changestart", event, {
5409					oldHeader: data.oldHeader,
5410					oldContent: data.oldPanel,
5411					newHeader: data.newHeader,
5412					newContent: data.newPanel
5413				});
5414			} else if ( type === "activate" ) {
5415				ret = _trigger.call( this, "change", event, {
5416					oldHeader: data.oldHeader,
5417					oldContent: data.oldPanel,
5418					newHeader: data.newHeader,
5419					newContent: data.newPanel
5420				});
5421			}
5422			return ret;
5423		};
5424	}( jQuery, jQuery.ui.accordion.prototype ) );
5425
5426	// animated option
5427	// NOTE: this only provides support for "slide", "bounceslide", and easings
5428	// not the full $.ui.accordion.animations API
5429	(function( $, prototype ) {
5430		$.extend( prototype.options, {
5431			animate: null,
5432			animated: "slide"
5433		});
5434
5435		var _create = prototype._create;
5436		prototype._create = function() {
5437			var options = this.options;
5438			if ( options.animate === null ) {
5439				if ( !options.animated ) {
5440					options.animate = false;
5441				} else if ( options.animated === "slide" ) {
5442					options.animate = 300;
5443				} else if ( options.animated === "bounceslide" ) {
5444					options.animate = {
5445						duration: 200,
5446						down: {
5447							easing: "easeOutBounce",
5448							duration: 1000
5449						}
5450					};
5451				} else {
5452					options.animate = options.animated;
5453				}
5454			}
5455
5456			_create.call( this );
5457		};
5458	}( jQuery, jQuery.ui.accordion.prototype ) );
5459}
5460
5461})( jQuery );
5462(function( $, undefined ) {
5463
5464// used to prevent race conditions with remote data sources
5465var requestIndex = 0;
5466
5467$.widget( "ui.autocomplete", {
5468	version: "1.9.2",
5469	defaultElement: "<input>",
5470	options: {
5471		appendTo: "body",
5472		autoFocus: false,
5473		delay: 300,
5474		minLength: 1,
5475		position: {
5476			my: "left top",
5477			at: "left bottom",
5478			collision: "none"
5479		},
5480		source: null,
5481
5482		// callbacks
5483		change: null,
5484		close: null,
5485		focus: null,
5486		open: null,
5487		response: null,
5488		search: null,
5489		select: null
5490	},
5491
5492	pending: 0,
5493
5494	_create: function() {
5495		// Some browsers only repeat keydown events, not keypress events,
5496		// so we use the suppressKeyPress flag to determine if we've already
5497		// handled the keydown event. #7269
5498		// Unfortunately the code for & in keypress is the same as the up arrow,
5499		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5500		// events when we know the keydown event was used to modify the
5501		// search term. #7799
5502		var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
5503
5504		this.isMultiLine = this._isMultiLine();
5505		this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
5506		this.isNewMenu = true;
5507
5508		this.element
5509			.addClass( "ui-autocomplete-input" )
5510			.attr( "autocomplete", "off" );
5511
5512		this._on( this.element, {
5513			keydown: function( event ) {
5514				if ( this.element.prop( "readOnly" ) ) {
5515					suppressKeyPress = true;
5516					suppressInput = true;
5517					suppressKeyPressRepeat = true;
5518					return;
5519				}
5520
5521				suppressKeyPress = false;
5522				suppressInput = false;
5523				suppressKeyPressRepeat = false;
5524				var keyCode = $.ui.keyCode;
5525				switch( event.keyCode ) {
5526				case keyCode.PAGE_UP:
5527					suppressKeyPress = true;
5528					this._move( "previousPage", event );
5529					break;
5530				case keyCode.PAGE_DOWN:
5531					suppressKeyPress = true;
5532					this._move( "nextPage", event );
5533					break;
5534				case keyCode.UP:
5535					suppressKeyPress = true;
5536					this._keyEvent( "previous", event );
5537					break;
5538				case keyCode.DOWN:
5539					suppressKeyPress = true;
5540					this._keyEvent( "next", event );
5541					break;
5542				case keyCode.ENTER:
5543				case keyCode.NUMPAD_ENTER:
5544					// when menu is open and has focus
5545					if ( this.menu.active ) {
5546						// #6055 - Opera still allows the keypress to occur
5547						// which causes forms to submit
5548						suppressKeyPress = true;
5549						event.preventDefault();
5550						this.menu.select( event );
5551					}
5552					break;
5553				case keyCode.TAB:
5554					if ( this.menu.active ) {
5555						this.menu.select( event );
5556					}
5557					break;
5558				case keyCode.ESCAPE:
5559					if ( this.menu.element.is( ":visible" ) ) {
5560						this._value( this.term );
5561						this.close( event );
5562						// Different browsers have different default behavior for escape
5563						// Single press can mean undo or clear
5564						// Double press in IE means clear the whole form
5565						event.preventDefault();
5566					}
5567					break;
5568				default:
5569					suppressKeyPressRepeat = true;
5570					// search timeout should be triggered before the input value is changed
5571					this._searchTimeout( event );
5572					break;
5573				}
5574			},
5575			keypress: function( event ) {
5576				if ( suppressKeyPress ) {
5577					suppressKeyPress = false;
5578					event.preventDefault();
5579					return;
5580				}
5581				if ( suppressKeyPressRepeat ) {
5582					return;
5583				}
5584
5585				// replicate some key handlers to allow them to repeat in Firefox and Opera
5586				var keyCode = $.ui.keyCode;
5587				switch( event.keyCode ) {
5588				case keyCode.PAGE_UP:
5589					this._move( "previousPage", event );
5590					break;
5591				case keyCode.PAGE_DOWN:
5592					this._move( "nextPage", event );
5593					break;
5594				case keyCode.UP:
5595					this._keyEvent( "previous", event );
5596					break;
5597				case keyCode.DOWN:
5598					this._keyEvent( "next", event );
5599					break;
5600				}
5601			},
vendor: 23,199 bytes, lines 5602-6405
5602			input: function( event ) {
5603				if ( suppressInput ) {
5604					suppressInput = false;
5605					event.preventDefault();
5606					return;
5607				}
5608				this._searchTimeout( event );
5609			},
5610			focus: function() {
5611				this.selectedItem = null;
5612				this.previous = this._value();
5613			},
5614			blur: function( event ) {
5615				if ( this.cancelBlur ) {
5616					delete this.cancelBlur;
5617					return;
5618				}
5619
5620				clearTimeout( this.searching );
5621				this.close( event );
5622				this._change( event );
5623			}
5624		});
5625
5626		this._initSource();
5627		this.menu = $( "<ul>" )
5628			.addClass( "ui-autocomplete" )
5629			.appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
5630			.menu({
5631				// custom key handling for now
5632				input: $(),
5633				// disable ARIA support, the live region takes care of that
5634				role: null
5635			})
5636			.zIndex( this.element.zIndex() + 1 )
5637			.hide()
5638			.data( "menu" );
5639
5640		this._on( this.menu.element, {
5641			mousedown: function( event ) {
5642				// prevent moving focus out of the text field
5643				event.preventDefault();
5644
5645				// IE doesn't prevent moving focus even with event.preventDefault()
5646				// so we set a flag to know when we should ignore the blur event
5647				this.cancelBlur = true;
5648				this._delay(function() {
5649					delete this.cancelBlur;
5650				});
5651
5652				// clicking on the scrollbar causes focus to shift to the body
5653				// but we can't detect a mouseup or a click immediately afterward
5654				// so we have to track the next mousedown and close the menu if
5655				// the user clicks somewhere outside of the autocomplete
5656				var menuElement = this.menu.element[ 0 ];
5657				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
5658					this._delay(function() {
5659						var that = this;
5660						this.document.one( "mousedown", function( event ) {
5661							if ( event.target !== that.element[ 0 ] &&
5662									event.target !== menuElement &&
5663									!$.contains( menuElement, event.target ) ) {
5664								that.close();
5665							}
5666						});
5667					});
5668				}
5669			},
5670			menufocus: function( event, ui ) {
5671				// #7024 - Prevent accidental activation of menu items in Firefox
5672				if ( this.isNewMenu ) {
5673					this.isNewMenu = false;
5674					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5675						this.menu.blur();
5676
5677						this.document.one( "mousemove", function() {
5678							$( event.target ).trigger( event.originalEvent );
5679						});
5680
5681						return;
5682					}
5683				}
5684
5685				// back compat for _renderItem using item.autocomplete, via #7810
5686				// TODO remove the fallback, see #8156
5687				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
5688				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5689					// use value to match what will end up in the input, if it was a key event
5690					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5691						this._value( item.value );
5692					}
5693				} else {
5694					// Normally the input is populated with the item's value as the
5695					// menu is navigated, causing screen readers to notice a change and
5696					// announce the item. Since the focus event was canceled, this doesn't
5697					// happen, so we update the live region so that screen readers can
5698					// still notice the change and announce it.
5699					this.liveRegion.text( item.value );
5700				}
5701			},
5702			menuselect: function( event, ui ) {
5703				// back compat for _renderItem using item.autocomplete, via #7810
5704				// TODO remove the fallback, see #8156
5705				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
5706					previous = this.previous;
5707
5708				// only trigger when focus was lost (click on menu)
5709				if ( this.element[0] !== this.document[0].activeElement ) {
5710					this.element.focus();
5711					this.previous = previous;
5712					// #6109 - IE triggers two focus events and the second
5713					// is asynchronous, so we need to reset the previous
5714					// term synchronously and asynchronously :-(
5715					this._delay(function() {
5716						this.previous = previous;
5717						this.selectedItem = item;
5718					});
5719				}
5720
5721				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5722					this._value( item.value );
5723				}
5724				// reset the term after the select event
5725				// this allows custom select handling to work properly
5726				this.term = this._value();
5727
5728				this.close( event );
5729				this.selectedItem = item;
5730			}
5731		});
5732
5733		this.liveRegion = $( "<span>", {
5734				role: "status",
5735				"aria-live": "polite"
5736			})
5737			.addClass( "ui-helper-hidden-accessible" )
5738			.insertAfter( this.element );
5739
5740		if ( $.fn.bgiframe ) {
5741			this.menu.element.bgiframe();
5742		}
5743
5744		// turning off autocomplete prevents the browser from remembering the
5745		// value when navigating through history, so we re-enable autocomplete
5746		// if the page is unloaded before the widget is destroyed. #7790
5747		this._on( this.window, {
5748			beforeunload: function() {
5749				this.element.removeAttr( "autocomplete" );
5750			}
5751		});
5752	},
5753
5754	_destroy: function() {
5755		clearTimeout( this.searching );
5756		this.element
5757			.removeClass( "ui-autocomplete-input" )
5758			.removeAttr( "autocomplete" );
5759		this.menu.element.remove();
5760		this.liveRegion.remove();
5761	},
5762
5763	_setOption: function( key, value ) {
5764		this._super( key, value );
5765		if ( key === "source" ) {
5766			this._initSource();
5767		}
5768		if ( key === "appendTo" ) {
5769			this.menu.element.appendTo( this.document.find( value || "body" )[0] );
5770		}
5771		if ( key === "disabled" && value && this.xhr ) {
5772			this.xhr.abort();
5773		}
5774	},
5775
5776	_isMultiLine: function() {
5777		// Textareas are always multi-line
5778		if ( this.element.is( "textarea" ) ) {
5779			return true;
5780		}
5781		// Inputs are always single-line, even if inside a contentEditable element
5782		// IE also treats inputs as contentEditable
5783		if ( this.element.is( "input" ) ) {
5784			return false;
5785		}
5786		// All other element types are determined by whether or not they're contentEditable
5787		return this.element.prop( "isContentEditable" );
5788	},
5789
5790	_initSource: function() {
5791		var array, url,
5792			that = this;
5793		if ( $.isArray(this.options.source) ) {
5794			array = this.options.source;
5795			this.source = function( request, response ) {
5796				response( $.ui.autocomplete.filter( array, request.term ) );
5797			};
5798		} else if ( typeof this.options.source === "string" ) {
5799			url = this.options.source;
5800			this.source = function( request, response ) {
5801				if ( that.xhr ) {
5802					that.xhr.abort();
5803				}
5804				that.xhr = $.ajax({
5805					url: url,
5806					data: request,
5807					dataType: "json",
5808					success: function( data ) {
5809						response( data );
5810					},
5811					error: function() {
5812						response( [] );
5813					}
5814				});
5815			};
5816		} else {
5817			this.source = this.options.source;
5818		}
5819	},
5820
5821	_searchTimeout: function( event ) {
5822		clearTimeout( this.searching );
5823		this.searching = this._delay(function() {
5824			// only search if the value has changed
5825			if ( this.term !== this._value() ) {
5826				this.selectedItem = null;
5827				this.search( null, event );
5828			}
5829		}, this.options.delay );
5830	},
5831
5832	search: function( value, event ) {
5833		value = value != null ? value : this._value();
5834
5835		// always save the actual value, not the one passed as an argument
5836		this.term = this._value();
5837
5838		if ( value.length < this.options.minLength ) {
5839			return this.close( event );
5840		}
5841
5842		if ( this._trigger( "search", event ) === false ) {
5843			return;
5844		}
5845
5846		return this._search( value );
5847	},
5848
5849	_search: function( value ) {
5850		this.pending++;
5851		this.element.addClass( "ui-autocomplete-loading" );
5852		this.cancelSearch = false;
5853
5854		this.source( { term: value }, this._response() );
5855	},
5856
5857	_response: function() {
5858		var that = this,
5859			index = ++requestIndex;
5860
5861		return function( content ) {
5862			if ( index === requestIndex ) {
5863				that.__response( content );
5864			}
5865
5866			that.pending--;
5867			if ( !that.pending ) {
5868				that.element.removeClass( "ui-autocomplete-loading" );
5869			}
5870		};
5871	},
5872
5873	__response: function( content ) {
5874		if ( content ) {
5875			content = this._normalize( content );
5876		}
5877		this._trigger( "response", null, { content: content } );
5878		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
5879			this._suggest( content );
5880			this._trigger( "open" );
5881		} else {
5882			// use ._close() instead of .close() so we don't cancel future searches
5883			this._close();
5884		}
5885	},
5886
5887	close: function( event ) {
5888		this.cancelSearch = true;
5889		this._close( event );
5890	},
5891
5892	_close: function( event ) {
5893		if ( this.menu.element.is( ":visible" ) ) {
5894			this.menu.element.hide();
5895			this.menu.blur();
5896			this.isNewMenu = true;
5897			this._trigger( "close", event );
5898		}
5899	},
5900
5901	_change: function( event ) {
5902		if ( this.previous !== this._value() ) {
5903			this._trigger( "change", event, { item: this.selectedItem } );
5904		}
5905	},
5906
5907	_normalize: function( items ) {
5908		// assume all items have the right format when the first item is complete
5909		if ( items.length && items[0].label && items[0].value ) {
5910			return items;
5911		}
5912		return $.map( items, function( item ) {
5913			if ( typeof item === "string" ) {
5914				return {
5915					label: item,
5916					value: item
5917				};
5918			}
5919			return $.extend({
5920				label: item.label || item.value,
5921				value: item.value || item.label
5922			}, item );
5923		});
5924	},
5925
5926	_suggest: function( items ) {
5927		var ul = this.menu.element
5928			.empty()
5929			.zIndex( this.element.zIndex() + 1 );
5930		this._renderMenu( ul, items );
5931		this.menu.refresh();
5932
5933		// size and position menu
5934		ul.show();
5935		this._resizeMenu();
5936		ul.position( $.extend({
5937			of: this.element
5938		}, this.options.position ));
5939
5940		if ( this.options.autoFocus ) {
5941			this.menu.next();
5942		}
5943	},
5944
5945	_resizeMenu: function() {
5946		var ul = this.menu.element;
5947		ul.outerWidth( Math.max(
5948			// Firefox wraps long text (possibly a rounding bug)
5949			// so we add 1px to avoid the wrapping (#7513)
5950			ul.width( "" ).outerWidth() + 1,
5951			this.element.outerWidth()
5952		) );
5953	},
5954
5955	_renderMenu: function( ul, items ) {
5956		var that = this;
5957		$.each( items, function( index, item ) {
5958			that._renderItemData( ul, item );
5959		});
5960	},
5961
5962	_renderItemData: function( ul, item ) {
5963		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
5964	},
5965
5966	_renderItem: function( ul, item ) {
5967		return $( "<li>" )
5968			.append( $( "<a>" ).text( item.label ) )
5969			.appendTo( ul );
5970	},
5971
5972	_move: function( direction, event ) {
5973		if ( !this.menu.element.is( ":visible" ) ) {
5974			this.search( null, event );
5975			return;
5976		}
5977		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
5978				this.menu.isLastItem() && /^next/.test( direction ) ) {
5979			this._value( this.term );
5980			this.menu.blur();
5981			return;
5982		}
5983		this.menu[ direction ]( event );
5984	},
5985
5986	widget: function() {
5987		return this.menu.element;
5988	},
5989
5990	_value: function() {
5991		return this.valueMethod.apply( this.element, arguments );
5992	},
5993
5994	_keyEvent: function( keyEvent, event ) {
5995		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5996			this._move( keyEvent, event );
5997
5998			// prevents moving cursor to beginning/end of the text field in some browsers
5999			event.preventDefault();
6000		}
6001	}
6002});
6003
6004$.extend( $.ui.autocomplete, {
6005	escapeRegex: function( value ) {
6006		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
6007	},
6008	filter: function(array, term) {
6009		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6010		return $.grep( array, function(value) {
6011			return matcher.test( value.label || value.value || value );
6012		});
6013	}
6014});
6015
6016
6017// live region extension, adding a `messages` option
6018// NOTE: This is an experimental API. We are still investigating
6019// a full solution for string manipulation and internationalization.
6020$.widget( "ui.autocomplete", $.ui.autocomplete, {
6021	options: {
6022		messages: {
6023			noResults: "No search results.",
6024			results: function( amount ) {
6025				return amount + ( amount > 1 ? " results are" : " result is" ) +
6026					" available, use up and down arrow keys to navigate.";
6027			}
6028		}
6029	},
6030
6031	__response: function( content ) {
6032		var message;
6033		this._superApply( arguments );
6034		if ( this.options.disabled || this.cancelSearch ) {
6035			return;
6036		}
6037		if ( content && content.length ) {
6038			message = this.options.messages.results( content.length );
6039		} else {
6040			message = this.options.messages.noResults;
6041		}
6042		this.liveRegion.text( message );
6043	}
6044});
6045
6046
6047}( jQuery ));
6048(function( $, undefined ) {
6049
6050var lastActive, startXPos, startYPos, clickDragged,
6051	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6052	stateClasses = "ui-state-hover ui-state-active ",
6053	typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
6054	formResetHandler = function() {
6055		var buttons = $( this ).find( ":ui-button" );
6056		setTimeout(function() {
6057			buttons.button( "refresh" );
6058		}, 1 );
6059	},
6060	radioGroup = function( radio ) {
6061		var name = radio.name,
6062			form = radio.form,
6063			radios = $( [] );
6064		if ( name ) {
6065			if ( form ) {
6066				radios = $( form ).find( "[name='" + name + "']" );
6067			} else {
6068				radios = $( "[name='" + name + "']", radio.ownerDocument )
6069					.filter(function() {
6070						return !this.form;
6071					});
6072			}
6073		}
6074		return radios;
6075	};
6076
6077$.widget( "ui.button", {
6078	version: "1.9.2",
6079	defaultElement: "<button>",
6080	options: {
6081		disabled: null,
6082		text: true,
6083		label: null,
6084		icons: {
6085			primary: null,
6086			secondary: null
6087		}
6088	},
6089	_create: function() {
6090		this.element.closest( "form" )
6091			.unbind( "reset" + this.eventNamespace )
6092			.bind( "reset" + this.eventNamespace, formResetHandler );
6093
6094		if ( typeof this.options.disabled !== "boolean" ) {
6095			this.options.disabled = !!this.element.prop( "disabled" );
6096		} else {
6097			this.element.prop( "disabled", this.options.disabled );
6098		}
6099
6100		this._determineButtonType();
6101		this.hasTitle = !!this.buttonElement.attr( "title" );
6102
6103		var that = this,
6104			options = this.options,
6105			toggleButton = this.type === "checkbox" || this.type === "radio",
6106			activeClass = !toggleButton ? "ui-state-active" : "",
6107			focusClass = "ui-state-focus";
6108
6109		if ( options.label === null ) {
6110			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
6111		}
6112
6113		this._hoverable( this.buttonElement );
6114
6115		this.buttonElement
6116			.addClass( baseClasses )
6117			.attr( "role", "button" )
6118			.bind( "mouseenter" + this.eventNamespace, function() {
6119				if ( options.disabled ) {
6120					return;
6121				}
6122				if ( this === lastActive ) {
6123					$( this ).addClass( "ui-state-active" );
6124				}
6125			})
6126			.bind( "mouseleave" + this.eventNamespace, function() {
6127				if ( options.disabled ) {
6128					return;
6129				}
6130				$( this ).removeClass( activeClass );
6131			})
6132			.bind( "click" + this.eventNamespace, function( event ) {
6133				if ( options.disabled ) {
6134					event.preventDefault();
6135					event.stopImmediatePropagation();
6136				}
6137			});
6138
6139		this.element
6140			.bind( "focus" + this.eventNamespace, function() {
6141				// no need to check disabled, focus won't be triggered anyway
6142				that.buttonElement.addClass( focusClass );
6143			})
6144			.bind( "blur" + this.eventNamespace, function() {
6145				that.buttonElement.removeClass( focusClass );
6146			});
6147
6148		if ( toggleButton ) {
6149			this.element.bind( "change" + this.eventNamespace, function() {
6150				if ( clickDragged ) {
6151					return;
6152				}
6153				that.refresh();
6154			});
6155			// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6156			// prevents issue where button state changes but checkbox/radio checked state
6157			// does not in Firefox (see ticket #6970)
6158			this.buttonElement
6159				.bind( "mousedown" + this.eventNamespace, function( event ) {
6160					if ( options.disabled ) {
6161						return;
6162					}
6163					clickDragged = false;
6164					startXPos = event.pageX;
6165					startYPos = event.pageY;
6166				})
6167				.bind( "mouseup" + this.eventNamespace, function( event ) {
6168					if ( options.disabled ) {
6169						return;
6170					}
6171					if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
6172						clickDragged = true;
6173					}
6174			});
6175		}
6176
6177		if ( this.type === "checkbox" ) {
6178			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6179				if ( options.disabled || clickDragged ) {
6180					return false;
6181				}
6182				$( this ).toggleClass( "ui-state-active" );
6183				that.buttonElement.attr( "aria-pressed", that.element[0].checked );
6184			});
6185		} else if ( this.type === "radio" ) {
6186			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6187				if ( options.disabled || clickDragged ) {
6188					return false;
6189				}
6190				$( this ).addClass( "ui-state-active" );
6191				that.buttonElement.attr( "aria-pressed", "true" );
6192
6193				var radio = that.element[ 0 ];
6194				radioGroup( radio )
6195					.not( radio )
6196					.map(function() {
6197						return $( this ).button( "widget" )[ 0 ];
6198					})
6199					.removeClass( "ui-state-active" )
6200					.attr( "aria-pressed", "false" );
6201			});
6202		} else {
6203			this.buttonElement
6204				.bind( "mousedown" + this.eventNamespace, function() {
6205					if ( options.disabled ) {
6206						return false;
6207					}
6208					$( this ).addClass( "ui-state-active" );
6209					lastActive = this;
6210					that.document.one( "mouseup", function() {
6211						lastActive = null;
6212					});
6213				})
6214				.bind( "mouseup" + this.eventNamespace, function() {
6215					if ( options.disabled ) {
6216						return false;
6217					}
6218					$( this ).removeClass( "ui-state-active" );
6219				})
6220				.bind( "keydown" + this.eventNamespace, function(event) {
6221					if ( options.disabled ) {
6222						return false;
6223					}
6224					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
6225						$( this ).addClass( "ui-state-active" );
6226					}
6227				})
6228				.bind( "keyup" + this.eventNamespace, function() {
6229					$( this ).removeClass( "ui-state-active" );
6230				});
6231
6232			if ( this.buttonElement.is("a") ) {
6233				this.buttonElement.keyup(function(event) {
6234					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6235						// TODO pass through original event correctly (just as 2nd argument doesn't work)
6236						$( this ).click();
6237					}
6238				});
6239			}
6240		}
6241
6242		// TODO: pull out $.Widget's handling for the disabled option into
6243		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
6244		// be overridden by individual plugins
6245		this._setOption( "disabled", options.disabled );
6246		this._resetButton();
6247	},
6248
6249	_determineButtonType: function() {
6250		var ancestor, labelSelector, checked;
6251
6252		if ( this.element.is("[type=checkbox]") ) {
6253			this.type = "checkbox";
6254		} else if ( this.element.is("[type=radio]") ) {
6255			this.type = "radio";
6256		} else if ( this.element.is("input") ) {
6257			this.type = "input";
6258		} else {
6259			this.type = "button";
6260		}
6261
6262		if ( this.type === "checkbox" || this.type === "radio" ) {
6263			// we don't search against the document in case the element
6264			// is disconnected from the DOM
6265			ancestor = this.element.parents().last();
6266			labelSelector = "label[for='" + this.element.attr("id") + "']";
6267			this.buttonElement = ancestor.find( labelSelector );
6268			if ( !this.buttonElement.length ) {
6269				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
6270				this.buttonElement = ancestor.filter( labelSelector );
6271				if ( !this.buttonElement.length ) {
6272					this.buttonElement = ancestor.find( labelSelector );
6273				}
6274			}
6275			this.element.addClass( "ui-helper-hidden-accessible" );
6276
6277			checked = this.element.is( ":checked" );
6278			if ( checked ) {
6279				this.buttonElement.addClass( "ui-state-active" );
6280			}
6281			this.buttonElement.prop( "aria-pressed", checked );
6282		} else {
6283			this.buttonElement = this.element;
6284		}
6285	},
6286
6287	widget: function() {
6288		return this.buttonElement;
6289	},
6290
6291	_destroy: function() {
6292		this.element
6293			.removeClass( "ui-helper-hidden-accessible" );
6294		this.buttonElement
6295			.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
6296			.removeAttr( "role" )
6297			.removeAttr( "aria-pressed" )
6298			.html( this.buttonElement.find(".ui-button-text").html() );
6299
6300		if ( !this.hasTitle ) {
6301			this.buttonElement.removeAttr( "title" );
6302		}
6303	},
6304
6305	_setOption: function( key, value ) {
6306		this._super( key, value );
6307		if ( key === "disabled" ) {
6308			if ( value ) {
6309				this.element.prop( "disabled", true );
6310			} else {
6311				this.element.prop( "disabled", false );
6312			}
6313			return;
6314		}
6315		this._resetButton();
6316	},
6317
6318	refresh: function() {
6319		//See #8237 & #8828
6320		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
6321
6322		if ( isDisabled !== this.options.disabled ) {
6323			this._setOption( "disabled", isDisabled );
6324		}
6325		if ( this.type === "radio" ) {
6326			radioGroup( this.element[0] ).each(function() {
6327				if ( $( this ).is( ":checked" ) ) {
6328					$( this ).button( "widget" )
6329						.addClass( "ui-state-active" )
6330						.attr( "aria-pressed", "true" );
6331				} else {
6332					$( this ).button( "widget" )
6333						.removeClass( "ui-state-active" )
6334						.attr( "aria-pressed", "false" );
6335				}
6336			});
6337		} else if ( this.type === "checkbox" ) {
6338			if ( this.element.is( ":checked" ) ) {
6339				this.buttonElement
6340					.addClass( "ui-state-active" )
6341					.attr( "aria-pressed", "true" );
6342			} else {
6343				this.buttonElement
6344					.removeClass( "ui-state-active" )
6345					.attr( "aria-pressed", "false" );
6346			}
6347		}
6348	},
6349
6350	_resetButton: function() {
6351		if ( this.type === "input" ) {
6352			if ( this.options.label ) {
6353				this.element.val( this.options.label );
6354			}
6355			return;
6356		}
6357		var buttonElement = this.buttonElement.removeClass( typeClasses ),
6358			buttonText = $( "<span></span>", this.document[0] )
6359				.addClass( "ui-button-text" )
6360				.html( this.options.label )
6361				.appendTo( buttonElement.empty() )
6362				.text(),
6363			icons = this.options.icons,
6364			multipleIcons = icons.primary && icons.secondary,
6365			buttonClasses = [];
6366
6367		if ( icons.primary || icons.secondary ) {
6368			if ( this.options.text ) {
6369				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
6370			}
6371
6372			if ( icons.primary ) {
6373				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
6374			}
6375
6376			if ( icons.secondary ) {
6377				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
6378			}
6379
6380			if ( !this.options.text ) {
6381				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
6382
6383				if ( !this.hasTitle ) {
6384					buttonElement.attr( "title", $.trim( buttonText ) );
6385				}
6386			}
6387		} else {
6388			buttonClasses.push( "ui-button-text-only" );
6389		}
6390		buttonElement.addClass( buttonClasses.join( " " ) );
6391	}
6392});
6393
6394$.widget( "ui.buttonset", {
6395	version: "1.9.2",
6396	options: {
6397		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
6398	},
6399
6400	_create: function() {
6401		this.element.addClass( "ui-buttonset" );
6402	},
6403
6404	_init: function() {
6405		this.refresh();
vendor: 4,388 bytes, lines 6406-6502
6406	},
6407
6408	_setOption: function( key, value ) {
6409		if ( key === "disabled" ) {
6410			this.buttons.button( "option", key, value );
6411		}
6412
6413		this._super( key, value );
6414	},
6415
6416	refresh: function() {
6417		var rtl = this.element.css( "direction" ) === "rtl";
6418
6419		this.buttons = this.element.find( this.options.items )
6420			.filter( ":ui-button" )
6421				.button( "refresh" )
6422			.end()
6423			.not( ":ui-button" )
6424				.button()
6425			.end()
6426			.map(function() {
6427				return $( this ).button( "widget" )[ 0 ];
6428			})
6429				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
6430				.filter( ":first" )
6431					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
6432				.end()
6433				.filter( ":last" )
6434					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
6435				.end()
6436			.end();
6437	},
6438
6439	_destroy: function() {
6440		this.element.removeClass( "ui-buttonset" );
6441		this.buttons
6442			.map(function() {
6443				return $( this ).button( "widget" )[ 0 ];
6444			})
6445				.removeClass( "ui-corner-left ui-corner-right" )
6446			.end()
6447			.button( "destroy" );
6448	}
6449});
6450
6451}( jQuery ) );
6452(function( $, undefined ) {
6453
6454$.extend($.ui, { datepicker: { version: "1.9.2" } });
6455
6456var PROP_NAME = 'datepicker';
6457var dpuuid = new Date().getTime();
6458var instActive;
6459
6460/* Date picker manager.
6461   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
6462   Settings for (groups of) date pickers are maintained in an instance object,
6463   allowing multiple different settings on the same page. */
6464
6465function Datepicker() {
6466	this.debug = false; // Change this to true to start debugging
6467	this._curInst = null; // The current instance in use
6468	this._keyEvent = false; // If the last event was a key event
6469	this._disabledInputs = []; // List of date picker inputs that have been disabled
6470	this._datepickerShowing = false; // True if the popup picker is showing , false if not
6471	this._inDialog = false; // True if showing within a "dialog", false if not
6472	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
6473	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
6474	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
6475	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
6476	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
6477	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
6478	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
6479	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
6480	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
6481	this.regional = []; // Available regional settings, indexed by language code
6482	this.regional[''] = { // Default regional settings
6483		closeText: 'Done', // Display text for close link
6484		prevText: 'Prev', // Display text for previous month link
6485		nextText: 'Next', // Display text for next month link
6486		currentText: 'Today', // Display text for current month link
6487		monthNames: ['January','February','March','April','May','June',
6488			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
6489		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
6490		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
6491		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
6492		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
6493		weekHeader: 'Wk', // Column header for week of the year
6494		dateFormat: 'mm/dd/yy', // See format options on parseDate
6495		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
6496		isRTL: false, // True if right-to-left language, false if left-to-right
6497		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
6498		yearSuffix: '' // Additional text to append to the year in the month headers
6499	};
6500	this._defaults = { // Global defaults for all the date picker instances
6501		showOn: 'focus', // 'focus' for popup on focus,
6502			// 'button' for trigger button, or 'both' for either
vendor: 7,167 bytes, lines 6503-6650
6503		showAnim: 'fadeIn', // Name of jQuery animation for popup
6504		showOptions: {}, // Options for enhanced animations
6505		defaultDate: null, // Used when field is blank: actual date,
6506			// +/-number for offset from today, null for today
6507		appendText: '', // Display text following the input box, e.g. showing the format
6508		buttonText: '...', // Text for trigger button
6509		buttonImage: '', // URL for trigger button image
6510		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
6511		hideIfNoPrevNext: false, // True to hide next/previous month links
6512			// if not applicable, false to just disable them
6513		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
6514		gotoCurrent: false, // True if today link goes back to current selection instead
6515		changeMonth: false, // True if month can be selected directly, false if only prev/next
6516		changeYear: false, // True if year can be selected directly, false if only prev/next
6517		yearRange: 'c-10:c+10', // Range of years to display in drop-down,
6518			// either relative to today's year (-nn:+nn), relative to currently displayed year
6519			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
6520		showOtherMonths: false, // True to show dates in other months, false to leave blank
6521		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
6522		showWeek: false, // True to show week of the year, false to not show it
6523		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
6524			// takes a Date and returns the number of the week for it
6525		shortYearCutoff: '+10', // Short year values < this are in the current century,
6526			// > this are in the previous century,
6527			// string value starting with '+' for current year + value
6528		minDate: null, // The earliest selectable date, or null for no limit
6529		maxDate: null, // The latest selectable date, or null for no limit
6530		duration: 'fast', // Duration of display/closure
6531		beforeShowDay: null, // Function that takes a date and returns an array with
6532			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
6533			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
6534		beforeShow: null, // Function that takes an input field and
6535			// returns a set of custom settings for the date picker
6536		onSelect: null, // Define a callback function when a date is selected
6537		onChangeMonthYear: null, // Define a callback function when the month or year is changed
6538		onClose: null, // Define a callback function when the datepicker is closed
6539		numberOfMonths: 1, // Number of months to show at a time
6540		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
6541		stepMonths: 1, // Number of months to step back/forward
6542		stepBigMonths: 12, // Number of months to step back/forward for the big links
6543		altField: '', // Selector for an alternate field to store selected dates into
6544		altFormat: '', // The date format to use for the alternate field
6545		constrainInput: true, // The input is constrained by the current date format
6546		showButtonPanel: false, // True to show button panel, false to not show it
6547		autoSize: false, // True to size the input for the date format, false to leave as is
6548		disabled: false // The initial disabled state
6549	};
6550	$.extend(this._defaults, this.regional['']);
6551	this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
6552}
6553
6554$.extend(Datepicker.prototype, {
6555	/* Class name added to elements to indicate already configured with a date picker. */
6556	markerClassName: 'hasDatepicker',
6557
6558	//Keep track of the maximum number of rows displayed (see #7043)
6559	maxRows: 4,
6560
6561	/* Debug logging (if enabled). */
6562	log: function () {
6563		if (this.debug)
6564			console.log.apply('', arguments);
6565	},
6566
6567	// TODO rename to "widget" when switching to widget factory
6568	_widgetDatepicker: function() {
6569		return this.dpDiv;
6570	},
6571
6572	/* Override the default settings for all instances of the date picker.
6573	   @param  settings  object - the new settings to use as defaults (anonymous object)
6574	   @return the manager object */
6575	setDefaults: function(settings) {
6576		extendRemove(this._defaults, settings || {});
6577		return this;
6578	},
6579
6580	/* Attach the date picker to a jQuery selection.
6581	   @param  target    element - the target input field or division or span
6582	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
6583	_attachDatepicker: function(target, settings) {
6584		// check for settings on the control itself - in namespace 'date:'
6585		var inlineSettings = null;
6586		for (var attrName in this._defaults) {
6587			var attrValue = target.getAttribute('date:' + attrName);
6588			if (attrValue) {
6589				inlineSettings = inlineSettings || {};
6590				try {
6591					inlineSettings[attrName] = eval(attrValue);
6592				} catch (err) {
6593					inlineSettings[attrName] = attrValue;
6594				}
6595			}
6596		}
6597		var nodeName = target.nodeName.toLowerCase();
6598		var inline = (nodeName == 'div' || nodeName == 'span');
6599		if (!target.id) {
6600			this.uuid += 1;
6601			target.id = 'dp' + this.uuid;
6602		}
6603		var inst = this._newInst($(target), inline);
6604		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
6605		if (nodeName == 'input') {
6606			this._connectDatepicker(target, inst);
6607		} else if (inline) {
6608			this._inlineDatepicker(target, inst);
6609		}
6610	},
6611
6612	/* Create a new instance object. */
6613	_newInst: function(target, inline) {
6614		var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
6615		return {id: id, input: target, // associated target
6616			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
6617			drawMonth: 0, drawYear: 0, // month being drawn
6618			inline: inline, // is datepicker inline or not
6619			dpDiv: (!inline ? this.dpDiv : // presentation div
6620			bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
6621	},
6622
6623	/* Attach the date picker to an input field. */
6624	_connectDatepicker: function(target, inst) {
6625		var input = $(target);
6626		inst.append = $([]);
6627		inst.trigger = $([]);
6628		if (input.hasClass(this.markerClassName))
6629			return;
6630		this._attachments(input, inst);
6631		input.addClass(this.markerClassName).keydown(this._doKeyDown).
6632			keypress(this._doKeyPress).keyup(this._doKeyUp).
6633			bind("setData.datepicker", function(event, key, value) {
6634				inst.settings[key] = value;
6635			}).bind("getData.datepicker", function(event, key) {
6636				return this._get(inst, key);
6637			});
6638		this._autoSize(inst);
6639		$.data(target, PROP_NAME, inst);
6640		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
6641		if( inst.settings.disabled ) {
6642			this._disableDatepicker( target );
6643		}
6644	},
6645
6646	/* Make attachments based on settings. */
6647	_attachments: function(input, inst) {
6648		var appendText = this._get(inst, 'appendText');
6649		var isRTL = this._get(inst, 'isRTL');
6650		if (inst.append)
6651			inst.append.remove();
6652		if (appendText) {
6653			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
6654			input[isRTL ? 'before' : 'after'](inst.append);
6655		}
6656		input.unbind('focus', this._showDatepicker);
6657		if (inst.trigger)
6658			inst.trigger.remove();
6659		var showOn = this._get(inst, 'showOn');
6660		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
6661			input.focus(this._showDatepicker);
6662		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
6663			var buttonText = this._get(inst, 'buttonText');
6664			var buttonImage = this._get(inst, 'buttonImage');
6665			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
6666				$('<img/>').addClass(this._triggerClass).
6667					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
6668				$('<button type="button"></button>').addClass(this._triggerClass).
6669					html(buttonImage == '' ? buttonText : $('<img/>').attr(
6670					{ src:buttonImage, alt:buttonText, title:buttonText })));
6671			input[isRTL ? 'before' : 'after'](inst.trigger);
6672			inst.trigger.click(function() {
6673				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
6674					$.datepicker._hideDatepicker();
6675				else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
6676					$.datepicker._hideDatepicker();
6677					$.datepicker._showDatepicker(input[0]);
6678				} else
6679					$.datepicker._showDatepicker(input[0]);
6680				return false;
6681			});
6682		}
6683	},
6684
6685	/* Apply the maximum length for the date format. */
6686	_autoSize: function(inst) {
6687		if (this._get(inst, 'autoSize') && !inst.inline) {
6688			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
6689			var dateFormat = this._get(inst, 'dateFormat');
6690			if (dateFormat.match(/[DM]/)) {
6691				var findMax = function(names) {
6692					var max = 0;
6693					var maxI = 0;
6694					for (var i = 0; i < names.length; i++) {
6695						if (names[i].length > max) {
6696							max = names[i].length;
6697							maxI = i;
6698						}
6699					}
6700					return maxI;
6701				};
6702				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
6703					'monthNames' : 'monthNamesShort'))));
6704				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
6705					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
6706			}
6707			inst.input.attr('size', this._formatDate(inst, date).length);
6708		}
6709	},
6710
6711	/* Attach an inline date picker to a div. */
6712	_inlineDatepicker: function(target, inst) {
6713		var divSpan = $(target);
6714		if (divSpan.hasClass(this.markerClassName))
6715			return;
6716		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
6717			bind("setData.datepicker", function(event, key, value){
6718				inst.settings[key] = value;
6719			}).bind("getData.datepicker", function(event, key){
6720				return this._get(inst, key);
6721			});
6722		$.data(target, PROP_NAME, inst);
6723		this._setDate(inst, this._getDefaultDate(inst), true);
6724		this._updateDatepicker(inst);
6725		this._updateAlternate(inst);
6726		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
6727		if( inst.settings.disabled ) {
6728			this._disableDatepicker( target );
6729		}
6730		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
6731		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
6732		inst.dpDiv.css( "display", "block" );
6733	},
6734
6735	/* Pop-up the date picker in a "dialog" box.
6736	   @param  input     element - ignored
6737	   @param  date      string or Date - the initial date to display
6738	   @param  onSelect  function - the function to call when a date is selected
6739	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
6740	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
6741	                     event - with x/y coordinates or
6742	                     leave empty for default (screen centre)
6743	   @return the manager object */
6744	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
6745		var inst = this._dialogInst; // internal instance
6746		if (!inst) {
6747			this.uuid += 1;
6748			var id = 'dp' + this.uuid;
6749			this._dialogInput = $('<input type="text" id="' + id +
6750				'" style="position: absolute; top: -100px; width: 0px;"/>');
6751			this._dialogInput.keydown(this._doKeyDown);
6752			$('body').append(this._dialogInput);
6753			inst = this._dialogInst = this._newInst(this._dialogInput, false);
6754			inst.settings = {};
6755			$.data(this._dialogInput[0], PROP_NAME, inst);
6756		}
6757		extendRemove(inst.settings, settings || {});
6758		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
6759		this._dialogInput.val(date);
6760
6761		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
6762		if (!this._pos) {
6763			var browserWidth = document.documentElement.clientWidth;
6764			var browserHeight = document.documentElement.clientHeight;
6765			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
6766			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
6767			this._pos = // should use actual width/height below
6768				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
6769		}
6770
6771		// move input on screen for focus, but hidden behind dialog
6772		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
6773		inst.settings.onSelect = onSelect;
6774		this._inDialog = true;
6775		this.dpDiv.addClass(this._dialogClass);
6776		this._showDatepicker(this._dialogInput[0]);
6777		if ($.blockUI)
6778			$.blockUI(this.dpDiv);
6779		$.data(this._dialogInput[0], PROP_NAME, inst);
6780		return this;
6781	},
6782
6783	/* Detach a datepicker from its control.
6784	   @param  target    element - the target input field or division or span */
6785	_destroyDatepicker: function(target) {
6786		var $target = $(target);
6787		var inst = $.data(target, PROP_NAME);
6788		if (!$target.hasClass(this.markerClassName)) {
6789			return;
6790		}
6791		var nodeName = target.nodeName.toLowerCase();
6792		$.removeData(target, PROP_NAME);
6793		if (nodeName == 'input') {
6794			inst.append.remove();
6795			inst.trigger.remove();
6796			$target.removeClass(this.markerClassName).
6797				unbind('focus', this._showDatepicker).
6798				unbind('keydown', this._doKeyDown).
6799				unbind('keypress', this._doKeyPress).
6800				unbind('keyup', this._doKeyUp);
6801		} else if (nodeName == 'div' || nodeName == 'span')
6802			$target.removeClass(this.markerClassName).empty();
6803	},
6804
6805	/* Enable the date picker to a jQuery selection.
6806	   @param  target    element - the target input field or division or span */
6807	_enableDatepicker: function(target) {
6808		var $target = $(target);
6809		var inst = $.data(target, PROP_NAME);
6810		if (!$target.hasClass(this.markerClassName)) {
6811			return;
6812		}
6813		var nodeName = target.nodeName.toLowerCase();
6814		if (nodeName == 'input') {
6815			target.disabled = false;
6816			inst.trigger.filter('button').
6817				each(function() { this.disabled = false; }).end().
6818				filter('img').css({opacity: '1.0', cursor: ''});
6819		}
6820		else if (nodeName == 'div' || nodeName == 'span') {
6821			var inline = $target.children('.' + this._inlineClass);
6822			inline.children().removeClass('ui-state-disabled');
6823			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
6824				prop("disabled", false);
6825		}
6826		this._disabledInputs = $.map(this._disabledInputs,
6827			function(value) { return (value == target ? null : value); }); // delete entry
6828	},
6829
6830	/* Disable the date picker to a jQuery selection.
6831	   @param  target    element - the target input field or division or span */
6832	_disableDatepicker: function(target) {
6833		var $target = $(target);
6834		var inst = $.data(target, PROP_NAME);
6835		if (!$target.hasClass(this.markerClassName)) {
6836			return;
6837		}
6838		var nodeName = target.nodeName.toLowerCase();
6839		if (nodeName == 'input') {
6840			target.disabled = true;
6841			inst.trigger.filter('button').
6842				each(function() { this.disabled = true; }).end().
6843				filter('img').css({opacity: '0.5', cursor: 'default'});
6844		}
6845		else if (nodeName == 'div' || nodeName == 'span') {
6846			var inline = $target.children('.' + this._inlineClass);
6847			inline.children().addClass('ui-state-disabled');
6848			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
6849				prop("disabled", true);
6850		}
6851		this._disabledInputs = $.map(this._disabledInputs,
6852			function(value) { return (value == target ? null : value); }); // delete entry
6853		this._disabledInputs[this._disabledInputs.length] = target;
6854	},
6855
6856	/* Is the first field in a jQuery collection disabled as a datepicker?
6857	   @param  target    element - the target input field or division or span
6858	   @return boolean - true if disabled, false if enabled */
6859	_isDisabledDatepicker: function(target) {
6860		if (!target) {
6861			return false;
6862		}
6863		for (var i = 0; i < this._disabledInputs.length; i++) {
6864			if (this._disabledInputs[i] == target)
6865				return true;
6866		}
6867		return false;
6868	},
6869
6870	/* Retrieve the instance data for the target control.
6871	   @param  target  element - the target input field or division or span
6872	   @return  object - the associated instance data
6873	   @throws  error if a jQuery problem getting data */
6874	_getInst: function(target) {
6875		try {
6876			return $.data(target, PROP_NAME);
6877		}
6878		catch (err) {
6879			throw 'Missing instance data for this datepicker';
6880		}
6881	},
6882
6883	/* Update or retrieve the settings for a date picker attached to an input field or division.
6884	   @param  target  element - the target input field or division or span
6885	   @param  name    object - the new settings to update or
6886	                   string - the name of the setting to change or retrieve,
6887	                   when retrieving also 'all' for all instance settings or
6888	                   'defaults' for all global defaults
6889	   @param  value   any - the new value for the setting
6890	                   (omit if above is an object or to retrieve a value) */
6891	_optionDatepicker: function(target, name, value) {
6892		var inst = this._getInst(target);
6893		if (arguments.length == 2 && typeof name == 'string') {
6894			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
6895				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
6896				this._get(inst, name)) : null));
6897		}
6898		var settings = name || {};
6899		if (typeof name == 'string') {
6900			settings = {};
6901			settings[name] = value;
6902		}
6903		if (inst) {
6904			if (this._curInst == inst) {
6905				this._hideDatepicker();
6906			}
6907			var date = this._getDateDatepicker(target, true);
6908			var minDate = this._getMinMaxDate(inst, 'min');
6909			var maxDate = this._getMinMaxDate(inst, 'max');
6910			extendRemove(inst.settings, settings);
6911			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
6912			if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
6913				inst.settings.minDate = this._formatDate(inst, minDate);
6914			if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
6915				inst.settings.maxDate = this._formatDate(inst, maxDate);
6916			this._attachments($(target), inst);
6917			this._autoSize(inst);
6918			this._setDate(inst, date);
6919			this._updateAlternate(inst);
6920			this._updateDatepicker(inst);
6921		}
6922	},
6923
6924	// change method deprecated
6925	_changeDatepicker: function(target, name, value) {
6926		this._optionDatepicker(target, name, value);
6927	},
6928
6929	/* Redraw the date picker attached to an input field or division.
6930	   @param  target  element - the target input field or division or span */
6931	_refreshDatepicker: function(target) {
6932		var inst = this._getInst(target);
6933		if (inst) {
6934			this._updateDatepicker(inst);
6935		}
6936	},
6937
6938	/* Set the dates for a jQuery selection.
6939	   @param  target   element - the target input field or division or span
6940	   @param  date     Date - the new date */
6941	_setDateDatepicker: function(target, date) {
6942		var inst = this._getInst(target);
6943		if (inst) {
6944			this._setDate(inst, date);
6945			this._updateDatepicker(inst);
6946			this._updateAlternate(inst);
6947		}
6948	},
6949
6950	/* Get the date(s) for the first entry in a jQuery selection.
6951	   @param  target     element - the target input field or division or span
6952	   @param  noDefault  boolean - true if no default date is to be used
6953	   @return Date - the current date */
6954	_getDateDatepicker: function(target, noDefault) {
6955		var inst = this._getInst(target);
6956		if (inst && !inst.inline)
6957			this._setDateFromField(inst, noDefault);
6958		return (inst ? this._getDate(inst) : null);
6959	},
6960
6961	/* Handle keystrokes. */
6962	_doKeyDown: function(event) {
6963		var inst = $.datepicker._getInst(event.target);
6964		var handled = true;
6965		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
6966		inst._keyEvent = true;
6967		if ($.datepicker._datepickerShowing)
6968			switch (event.keyCode) {
6969				case 9: $.datepicker._hideDatepicker();
6970						handled = false;
6971						break; // hide on tab out
6972				case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
6973									$.datepicker._currentClass + ')', inst.dpDiv);
6974						if (sel[0])
6975							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
6976							var onSelect = $.datepicker._get(inst, 'onSelect');
6977							if (onSelect) {
6978								var dateStr = $.datepicker._formatDate(inst);
6979
6980								// trigger custom callback
6981								onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
6982							}
6983						else
6984							$.datepicker._hideDatepicker();
6985						return false; // don't submit the form
6986						break; // select the value on enter
6987				case 27: $.datepicker._hideDatepicker();
6988						break; // hide on escape
6989				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6990							-$.datepicker._get(inst, 'stepBigMonths') :
6991							-$.datepicker._get(inst, 'stepMonths')), 'M');
6992						break; // previous month/year on page up/+ ctrl
6993				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6994							+$.datepicker._get(inst, 'stepBigMonths') :
6995							+$.datepicker._get(inst, 'stepMonths')), 'M');
6996						break; // next month/year on page down/+ ctrl
6997				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
6998						handled = event.ctrlKey || event.metaKey;
6999						break; // clear on ctrl or command +end
7000				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
7001						handled = event.ctrlKey || event.metaKey;
7002						break; // current on ctrl or command +home
7003				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
7004						handled = event.ctrlKey || event.metaKey;
7005						// -1 day on ctrl or command +left
7006						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7007									-$.datepicker._get(inst, 'stepBigMonths') :
7008									-$.datepicker._get(inst, 'stepMonths')), 'M');
7009						// next month/year on alt +left on Mac
7010						break;
7011				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
7012						handled = event.ctrlKey || event.metaKey;
7013						break; // -1 week on ctrl or command +up
7014				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
7015						handled = event.ctrlKey || event.metaKey;
7016						// +1 day on ctrl or command +right
7017						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7018									+$.datepicker._get(inst, 'stepBigMonths') :
7019									+$.datepicker._get(inst, 'stepMonths')), 'M');
7020						// next month/year on alt +right
7021						break;
7022				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
7023						handled = event.ctrlKey || event.metaKey;
7024						break; // +1 week on ctrl or command +down
7025				default: handled = false;
7026			}
7027		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
7028			$.datepicker._showDatepicker(this);
7029		else {
7030			handled = false;
7031		}
7032		if (handled) {
7033			event.preventDefault();
7034			event.stopPropagation();
7035		}
7036	},
7037
7038	/* Filter entered characters - based on date format. */
7039	_doKeyPress: function(event) {
7040		var inst = $.datepicker._getInst(event.target);
7041		if ($.datepicker._get(inst, 'constrainInput')) {
7042			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
vendor: 27,447 bytes, lines 7043-7774
7043			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
7044			return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
7045		}
7046	},
7047
7048	/* Synchronise manual entry and field/alternate field. */
7049	_doKeyUp: function(event) {
7050		var inst = $.datepicker._getInst(event.target);
7051		if (inst.input.val() != inst.lastVal) {
7052			try {
7053				var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7054					(inst.input ? inst.input.val() : null),
7055					$.datepicker._getFormatConfig(inst));
7056				if (date) { // only if valid
7057					$.datepicker._setDateFromField(inst);
7058					$.datepicker._updateAlternate(inst);
7059					$.datepicker._updateDatepicker(inst);
7060				}
7061			}
7062			catch (err) {
7063				$.datepicker.log(err);
7064			}
7065		}
7066		return true;
7067	},
7068
7069	/* Pop-up the date picker for a given input field.
7070	   If false returned from beforeShow event handler do not show.
7071	   @param  input  element - the input field attached to the date picker or
7072	                  event - if triggered by focus */
7073	_showDatepicker: function(input) {
7074		input = input.target || input;
7075		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
7076			input = $('input', input.parentNode)[0];
7077		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
7078			return;
7079		var inst = $.datepicker._getInst(input);
7080		if ($.datepicker._curInst && $.datepicker._curInst != inst) {
7081			$.datepicker._curInst.dpDiv.stop(true, true);
7082			if ( inst && $.datepicker._datepickerShowing ) {
7083				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7084			}
7085		}
7086		var beforeShow = $.datepicker._get(inst, 'beforeShow');
7087		var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7088		if(beforeShowSettings === false){
7089			//false
7090			return;
7091		}
7092		extendRemove(inst.settings, beforeShowSettings);
7093		inst.lastVal = null;
7094		$.datepicker._lastInput = input;
7095		$.datepicker._setDateFromField(inst);
7096		if ($.datepicker._inDialog) // hide cursor
7097			input.value = '';
7098		if (!$.datepicker._pos) { // position below input
7099			$.datepicker._pos = $.datepicker._findPos(input);
7100			$.datepicker._pos[1] += input.offsetHeight; // add the height
7101		}
7102		var isFixed = false;
7103		$(input).parents().each(function() {
7104			isFixed |= $(this).css('position') == 'fixed';
7105			return !isFixed;
7106		});
7107		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7108		$.datepicker._pos = null;
7109		//to avoid flashes on Firefox
7110		inst.dpDiv.empty();
7111		// determine sizing offscreen
7112		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
7113		$.datepicker._updateDatepicker(inst);
7114		// fix width for dynamic number of date pickers
7115		// and adjust position before showing
7116		offset = $.datepicker._checkOffset(inst, offset, isFixed);
7117		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7118			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
7119			left: offset.left + 'px', top: offset.top + 'px'});
7120		if (!inst.inline) {
7121			var showAnim = $.datepicker._get(inst, 'showAnim');
7122			var duration = $.datepicker._get(inst, 'duration');
7123			var postProcess = function() {
7124				var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7125				if( !! cover.length ){
7126					var borders = $.datepicker._getBorders(inst.dpDiv);
7127					cover.css({left: -borders[0], top: -borders[1],
7128						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
7129				}
7130			};
7131			inst.dpDiv.zIndex($(input).zIndex()+1);
7132			$.datepicker._datepickerShowing = true;
7133
7134			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7135			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
7136				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7137			else
7138				inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
7139			if (!showAnim || !duration)
7140				postProcess();
7141			if (inst.input.is(':visible') && !inst.input.is(':disabled'))
7142				inst.input.focus();
7143			$.datepicker._curInst = inst;
7144		}
7145	},
7146
7147	/* Generate the date picker content. */
7148	_updateDatepicker: function(inst) {
7149		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7150		var borders = $.datepicker._getBorders(inst.dpDiv);
7151		instActive = inst; // for delegate hover events
7152		inst.dpDiv.empty().append(this._generateHTML(inst));
7153		this._attachHandlers(inst);
7154		var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7155		if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
7156			cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
7157		}
7158		inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
7159		var numMonths = this._getNumberOfMonths(inst);
7160		var cols = numMonths[1];
7161		var width = 17;
7162		inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
7163		if (cols > 1)
7164			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
7165		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
7166			'Class']('ui-datepicker-multi');
7167		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
7168			'Class']('ui-datepicker-rtl');
7169		if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
7170				// #6694 - don't focus the input if it's already focused
7171				// this breaks the change event in IE
7172				inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
7173			inst.input.focus();
7174		// deffered render of the years select (to avoid flashes on Firefox)
7175		if( inst.yearshtml ){
7176			var origyearshtml = inst.yearshtml;
7177			setTimeout(function(){
7178				//assure that inst.yearshtml didn't change.
7179				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7180					inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
7181				}
7182				origyearshtml = inst.yearshtml = null;
7183			}, 0);
7184		}
7185	},
7186
7187	/* Retrieve the size of left and top borders for an element.
7188	   @param  elem  (jQuery object) the element of interest
7189	   @return  (number[2]) the left and top borders */
7190	_getBorders: function(elem) {
7191		var convert = function(value) {
7192			return {thin: 1, medium: 2, thick: 3}[value] || value;
7193		};
7194		return [parseFloat(convert(elem.css('border-left-width'))),
7195			parseFloat(convert(elem.css('border-top-width')))];
7196	},
7197
7198	/* Check positioning to remain on screen. */
7199	_checkOffset: function(inst, offset, isFixed) {
7200		var dpWidth = inst.dpDiv.outerWidth();
7201		var dpHeight = inst.dpDiv.outerHeight();
7202		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
7203		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
7204		var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
7205		var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
7206
7207		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
7208		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
7209		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7210
7211		// now check if datepicker is showing outside window viewport - move to a better place if so.
7212		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7213			Math.abs(offset.left + dpWidth - viewWidth) : 0);
7214		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7215			Math.abs(dpHeight + inputHeight) : 0);
7216
7217		return offset;
7218	},
7219
7220	/* Find an object's position on the screen. */
7221	_findPos: function(obj) {
7222		var inst = this._getInst(obj);
7223		var isRTL = this._get(inst, 'isRTL');
7224		while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
7225			obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
7226		}
7227		var position = $(obj).offset();
7228		return [position.left, position.top];
7229	},
7230
7231	/* Hide the date picker from view.
7232	   @param  input  element - the input field attached to the date picker */
7233	_hideDatepicker: function(input) {
7234		var inst = this._curInst;
7235		if (!inst || (input && inst != $.data(input, PROP_NAME)))
7236			return;
7237		if (this._datepickerShowing) {
7238			var showAnim = this._get(inst, 'showAnim');
7239			var duration = this._get(inst, 'duration');
7240			var postProcess = function() {
7241				$.datepicker._tidyDialog(inst);
7242			};
7243
7244			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7245			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
7246				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7247			else
7248				inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
7249					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
7250			if (!showAnim)
7251				postProcess();
7252			this._datepickerShowing = false;
7253			var onClose = this._get(inst, 'onClose');
7254			if (onClose)
7255				onClose.apply((inst.input ? inst.input[0] : null),
7256					[(inst.input ? inst.input.val() : ''), inst]);
7257			this._lastInput = null;
7258			if (this._inDialog) {
7259				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
7260				if ($.blockUI) {
7261					$.unblockUI();
7262					$('body').append(this.dpDiv);
7263				}
7264			}
7265			this._inDialog = false;
7266		}
7267	},
7268
7269	/* Tidy up after a dialog display. */
7270	_tidyDialog: function(inst) {
7271		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
7272	},
7273
7274	/* Close date picker if clicked elsewhere. */
7275	_checkExternalClick: function(event) {
7276		if (!$.datepicker._curInst)
7277			return;
7278
7279		var $target = $(event.target),
7280			inst = $.datepicker._getInst($target[0]);
7281
7282		if ( ( ( $target[0].id != $.datepicker._mainDivId &&
7283				$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
7284				!$target.hasClass($.datepicker.markerClassName) &&
7285				!$target.closest("." + $.datepicker._triggerClass).length &&
7286				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
7287			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
7288			$.datepicker._hideDatepicker();
7289	},
7290
7291	/* Adjust one of the date sub-fields. */
7292	_adjustDate: function(id, offset, period) {
7293		var target = $(id);
7294		var inst = this._getInst(target[0]);
7295		if (this._isDisabledDatepicker(target[0])) {
7296			return;
7297		}
7298		this._adjustInstDate(inst, offset +
7299			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
7300			period);
7301		this._updateDatepicker(inst);
7302	},
7303
7304	/* Action for current link. */
7305	_gotoToday: function(id) {
7306		var target = $(id);
7307		var inst = this._getInst(target[0]);
7308		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
7309			inst.selectedDay = inst.currentDay;
7310			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
7311			inst.drawYear = inst.selectedYear = inst.currentYear;
7312		}
7313		else {
7314			var date = new Date();
7315			inst.selectedDay = date.getDate();
7316			inst.drawMonth = inst.selectedMonth = date.getMonth();
7317			inst.drawYear = inst.selectedYear = date.getFullYear();
7318		}
7319		this._notifyChange(inst);
7320		this._adjustDate(target);
7321	},
7322
7323	/* Action for selecting a new month/year. */
7324	_selectMonthYear: function(id, select, period) {
7325		var target = $(id);
7326		var inst = this._getInst(target[0]);
7327		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
7328		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
7329			parseInt(select.options[select.selectedIndex].value,10);
7330		this._notifyChange(inst);
7331		this._adjustDate(target);
7332	},
7333
7334	/* Action for selecting a day. */
7335	_selectDay: function(id, month, year, td) {
7336		var target = $(id);
7337		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
7338			return;
7339		}
7340		var inst = this._getInst(target[0]);
7341		inst.selectedDay = inst.currentDay = $('a', td).html();
7342		inst.selectedMonth = inst.currentMonth = month;
7343		inst.selectedYear = inst.currentYear = year;
7344		this._selectDate(id, this._formatDate(inst,
7345			inst.currentDay, inst.currentMonth, inst.currentYear));
7346	},
7347
7348	/* Erase the input field and hide the date picker. */
7349	_clearDate: function(id) {
7350		var target = $(id);
7351		var inst = this._getInst(target[0]);
7352		this._selectDate(target, '');
7353	},
7354
7355	/* Update the input field with the selected date. */
7356	_selectDate: function(id, dateStr) {
7357		var target = $(id);
7358		var inst = this._getInst(target[0]);
7359		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
7360		if (inst.input)
7361			inst.input.val(dateStr);
7362		this._updateAlternate(inst);
7363		var onSelect = this._get(inst, 'onSelect');
7364		if (onSelect)
7365			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
7366		else if (inst.input)
7367			inst.input.trigger('change'); // fire the change event
7368		if (inst.inline)
7369			this._updateDatepicker(inst);
7370		else {
7371			this._hideDatepicker();
7372			this._lastInput = inst.input[0];
7373			if (typeof(inst.input[0]) != 'object')
7374				inst.input.focus(); // restore focus
7375			this._lastInput = null;
7376		}
7377	},
7378
7379	/* Update any alternate field to synchronise with the main field. */
7380	_updateAlternate: function(inst) {
7381		var altField = this._get(inst, 'altField');
7382		if (altField) { // update alternate field too
7383			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
7384			var date = this._getDate(inst);
7385			var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
7386			$(altField).each(function() { $(this).val(dateStr); });
7387		}
7388	},
7389
7390	/* Set as beforeShowDay function to prevent selection of weekends.
7391	   @param  date  Date - the date to customise
7392	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
7393	noWeekends: function(date) {
7394		var day = date.getDay();
7395		return [(day > 0 && day < 6), ''];
7396	},
7397
7398	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
7399	   @param  date  Date - the date to get the week for
7400	   @return  number - the number of the week within the year that contains this date */
7401	iso8601Week: function(date) {
7402		var checkDate = new Date(date.getTime());
7403		// Find Thursday of this week starting on Monday
7404		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
7405		var time = checkDate.getTime();
7406		checkDate.setMonth(0); // Compare with Jan 1
7407		checkDate.setDate(1);
7408		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
7409	},
7410
7411	/* Parse a string value into a date object.
7412	   See formatDate below for the possible formats.
7413
7414	   @param  format    string - the expected format of the date
7415	   @param  value     string - the date in the above format
7416	   @param  settings  Object - attributes include:
7417	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
7418	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
7419	                     dayNames         string[7] - names of the days from Sunday (optional)
7420	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
7421	                     monthNames       string[12] - names of the months (optional)
7422	   @return  Date - the extracted date value or null if value is blank */
7423	parseDate: function (format, value, settings) {
7424		if (format == null || value == null)
7425			throw 'Invalid arguments';
7426		value = (typeof value == 'object' ? value.toString() : value + '');
7427		if (value == '')
7428			return null;
7429		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
7430		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
7431				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
7432		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
7433		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
7434		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
7435		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
7436		var year = -1;
7437		var month = -1;
7438		var day = -1;
7439		var doy = -1;
7440		var literal = false;
7441		// Check whether a format character is doubled
7442		var lookAhead = function(match) {
7443			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7444			if (matches)
7445				iFormat++;
7446			return matches;
7447		};
7448		// Extract a number from the string value
7449		var getNumber = function(match) {
7450			var isDoubled = lookAhead(match);
7451			var size = (match == '@' ? 14 : (match == '!' ? 20 :
7452				(match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
7453			var digits = new RegExp('^\\d{1,' + size + '}');
7454			var num = value.substring(iValue).match(digits);
7455			if (!num)
7456				throw 'Missing number at position ' + iValue;
7457			iValue += num[0].length;
7458			return parseInt(num[0], 10);
7459		};
7460		// Extract a name from the string value and convert to an index
7461		var getName = function(match, shortNames, longNames) {
7462			var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
7463				return [ [k, v] ];
7464			}).sort(function (a, b) {
7465				return -(a[1].length - b[1].length);
7466			});
7467			var index = -1;
7468			$.each(names, function (i, pair) {
7469				var name = pair[1];
7470				if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
7471					index = pair[0];
7472					iValue += name.length;
7473					return false;
7474				}
7475			});
7476			if (index != -1)
7477				return index + 1;
7478			else
7479				throw 'Unknown name at position ' + iValue;
7480		};
7481		// Confirm that a literal character matches the string value
7482		var checkLiteral = function() {
7483			if (value.charAt(iValue) != format.charAt(iFormat))
7484				throw 'Unexpected literal at position ' + iValue;
7485			iValue++;
7486		};
7487		var iValue = 0;
7488		for (var iFormat = 0; iFormat < format.length; iFormat++) {
7489			if (literal)
7490				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
7491					literal = false;
7492				else
7493					checkLiteral();
7494			else
7495				switch (format.charAt(iFormat)) {
7496					case 'd':
7497						day = getNumber('d');
7498						break;
7499					case 'D':
7500						getName('D', dayNamesShort, dayNames);
7501						break;
7502					case 'o':
7503						doy = getNumber('o');
7504						break;
7505					case 'm':
7506						month = getNumber('m');
7507						break;
7508					case 'M':
7509						month = getName('M', monthNamesShort, monthNames);
7510						break;
7511					case 'y':
7512						year = getNumber('y');
7513						break;
7514					case '@':
7515						var date = new Date(getNumber('@'));
7516						year = date.getFullYear();
7517						month = date.getMonth() + 1;
7518						day = date.getDate();
7519						break;
7520					case '!':
7521						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
7522						year = date.getFullYear();
7523						month = date.getMonth() + 1;
7524						day = date.getDate();
7525						break;
7526					case "'":
7527						if (lookAhead("'"))
7528							checkLiteral();
7529						else
7530							literal = true;
7531						break;
7532					default:
7533						checkLiteral();
7534				}
7535		}
7536		if (iValue < value.length){
7537			var extra = value.substr(iValue);
7538			if (!/^\s+/.test(extra)) {
7539				throw "Extra/unparsed characters found in date: " + extra;
7540			}
7541		}
7542		if (year == -1)
7543			year = new Date().getFullYear();
7544		else if (year < 100)
7545			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
7546				(year <= shortYearCutoff ? 0 : -100);
7547		if (doy > -1) {
7548			month = 1;
7549			day = doy;
7550			do {
7551				var dim = this._getDaysInMonth(year, month - 1);
7552				if (day <= dim)
7553					break;
7554				month++;
7555				day -= dim;
7556			} while (true);
7557		}
7558		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
7559		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
7560			throw 'Invalid date'; // E.g. 31/02/00
7561		return date;
7562	},
7563
7564	/* Standard date formats. */
7565	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
7566	COOKIE: 'D, dd M yy',
7567	ISO_8601: 'yy-mm-dd',
7568	RFC_822: 'D, d M y',
7569	RFC_850: 'DD, dd-M-y',
7570	RFC_1036: 'D, d M y',
7571	RFC_1123: 'D, d M yy',
7572	RFC_2822: 'D, d M yy',
7573	RSS: 'D, d M y', // RFC 822
7574	TICKS: '!',
7575	TIMESTAMP: '@',
7576	W3C: 'yy-mm-dd', // ISO 8601
7577
7578	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
7579		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
7580
7581	/* Format a date object into a string value.
7582	   The format can be combinations of the following:
7583	   d  - day of month (no leading zero)
7584	   dd - day of month (two digit)
7585	   o  - day of year (no leading zeros)
7586	   oo - day of year (three digit)
7587	   D  - day name short
7588	   DD - day name long
7589	   m  - month of year (no leading zero)
7590	   mm - month of year (two digit)
7591	   M  - month name short
7592	   MM - month name long
7593	   y  - year (two digit)
7594	   yy - year (four digit)
7595	   @ - Unix timestamp (ms since 01/01/1970)
7596	   ! - Windows ticks (100ns since 01/01/0001)
7597	   '...' - literal text
7598	   '' - single quote
7599
7600	   @param  format    string - the desired format of the date
7601	   @param  date      Date - the date value to format
7602	   @param  settings  Object - attributes include:
7603	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
7604	                     dayNames         string[7] - names of the days from Sunday (optional)
7605	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
7606	                     monthNames       string[12] - names of the months (optional)
7607	   @return  string - the date in the above format */
7608	formatDate: function (format, date, settings) {
7609		if (!date)
7610			return '';
7611		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
7612		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
7613		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
7614		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
7615		// Check whether a format character is doubled
7616		var lookAhead = function(match) {
7617			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7618			if (matches)
7619				iFormat++;
7620			return matches;
7621		};
7622		// Format a number, with leading zero if necessary
7623		var formatNumber = function(match, value, len) {
7624			var num = '' + value;
7625			if (lookAhead(match))
7626				while (num.length < len)
7627					num = '0' + num;
7628			return num;
7629		};
7630		// Format a name, short or long as requested
7631		var formatName = function(match, value, shortNames, longNames) {
7632			return (lookAhead(match) ? longNames[value] : shortNames[value]);
7633		};
7634		var output = '';
7635		var literal = false;
7636		if (date)
7637			for (var iFormat = 0; iFormat < format.length; iFormat++) {
7638				if (literal)
7639					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
7640						literal = false;
7641					else
7642						output += format.charAt(iFormat);
7643				else
7644					switch (format.charAt(iFormat)) {
7645						case 'd':
7646							output += formatNumber('d', date.getDate(), 2);
7647							break;
7648						case 'D':
7649							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
7650							break;
7651						case 'o':
7652							output += formatNumber('o',
7653								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
7654							break;
7655						case 'm':
7656							output += formatNumber('m', date.getMonth() + 1, 2);
7657							break;
7658						case 'M':
7659							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
7660							break;
7661						case 'y':
7662							output += (lookAhead('y') ? date.getFullYear() :
7663								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
7664							break;
7665						case '@':
7666							output += date.getTime();
7667							break;
7668						case '!':
7669							output += date.getTime() * 10000 + this._ticksTo1970;
7670							break;
7671						case "'":
7672							if (lookAhead("'"))
7673								output += "'";
7674							else
7675								literal = true;
7676							break;
7677						default:
7678							output += format.charAt(iFormat);
7679					}
7680			}
7681		return output;
7682	},
7683
7684	/* Extract all possible characters from the date format. */
7685	_possibleChars: function (format) {
7686		var chars = '';
7687		var literal = false;
7688		// Check whether a format character is doubled
7689		var lookAhead = function(match) {
7690			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7691			if (matches)
7692				iFormat++;
7693			return matches;
7694		};
7695		for (var iFormat = 0; iFormat < format.length; iFormat++)
7696			if (literal)
7697				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
7698					literal = false;
7699				else
7700					chars += format.charAt(iFormat);
7701			else
7702				switch (format.charAt(iFormat)) {
7703					case 'd': case 'm': case 'y': case '@':
7704						chars += '0123456789';
7705						break;
7706					case 'D': case 'M':
7707						return null; // Accept anything
7708					case "'":
7709						if (lookAhead("'"))
7710							chars += "'";
7711						else
7712							literal = true;
7713						break;
7714					default:
7715						chars += format.charAt(iFormat);
7716				}
7717		return chars;
7718	},
7719
7720	/* Get a setting value, defaulting if necessary. */
7721	_get: function(inst, name) {
7722		return inst.settings[name] !== undefined ?
7723			inst.settings[name] : this._defaults[name];
7724	},
7725
7726	/* Parse existing date and initialise date picker. */
7727	_setDateFromField: function(inst, noDefault) {
7728		if (inst.input.val() == inst.lastVal) {
7729			return;
7730		}
7731		var dateFormat = this._get(inst, 'dateFormat');
7732		var dates = inst.lastVal = inst.input ? inst.input.val() : null;
7733		var date, defaultDate;
7734		date = defaultDate = this._getDefaultDate(inst);
7735		var settings = this._getFormatConfig(inst);
7736		try {
7737			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
7738		} catch (event) {
7739			this.log(event);
7740			dates = (noDefault ? '' : dates);
7741		}
7742		inst.selectedDay = date.getDate();
7743		inst.drawMonth = inst.selectedMonth = date.getMonth();
7744		inst.drawYear = inst.selectedYear = date.getFullYear();
7745		inst.currentDay = (dates ? date.getDate() : 0);
7746		inst.currentMonth = (dates ? date.getMonth() : 0);
7747		inst.currentYear = (dates ? date.getFullYear() : 0);
7748		this._adjustInstDate(inst);
7749	},
7750
7751	/* Retrieve the default date shown on opening. */
7752	_getDefaultDate: function(inst) {
7753		return this._restrictMinMax(inst,
7754			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
7755	},
7756
7757	/* A date may be specified as an exact value or a relative one. */
7758	_determineDate: function(inst, date, defaultDate) {
7759		var offsetNumeric = function(offset) {
7760			var date = new Date();
7761			date.setDate(date.getDate() + offset);
7762			return date;
7763		};
7764		var offsetString = function(offset) {
7765			try {
7766				return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7767					offset, $.datepicker._getFormatConfig(inst));
7768			}
7769			catch (e) {
7770				// Ignore
7771			}
7772			var date = (offset.toLowerCase().match(/^c/) ?
7773				$.datepicker._getDate(inst) : null) || new Date();
7774			var year = date.getFullYear();
7775			var month = date.getMonth();
7776			var day = date.getDate();
7777			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
7778			var matches = pattern.exec(offset);
7779			while (matches) {
7780				switch (matches[2] || 'd') {
7781					case 'd' : case 'D' :
7782						day += parseInt(matches[1],10); break;
7783					case 'w' : case 'W' :
7784						day += parseInt(matches[1],10) * 7; break;
7785					case 'm' : case 'M' :
7786						month += parseInt(matches[1],10);
7787						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
7788						break;
7789					case 'y': case 'Y' :
7790						year += parseInt(matches[1],10);
7791						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
7792						break;
7793				}
7794				matches = pattern.exec(offset);
7795			}
7796			return new Date(year, month, day);
7797		};
7798		var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
7799			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
7800		newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
7801		if (newDate) {
7802			newDate.setHours(0);
7803			newDate.setMinutes(0);
7804			newDate.setSeconds(0);
7805			newDate.setMilliseconds(0);
7806		}
7807		return this._daylightSavingAdjust(newDate);
7808	},
7809
7810	/* Handle switch to/from daylight saving.
7811	   Hours may be non-zero on daylight saving cut-over:
7812	   > 12 when midnight changeover, but then cannot generate
7813	   midnight datetime, so jump to 1AM, otherwise reset.
7814	   @param  date  (Date) the date to check
7815	   @return  (Date) the corrected date */
7816	_daylightSavingAdjust: function(date) {
7817		if (!date) return null;
7818		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
7819		return date;
7820	},
7821
7822	/* Set the date(s) directly. */
7823	_setDate: function(inst, date, noChange) {
7824		var clear = !date;
7825		var origMonth = inst.selectedMonth;
7826		var origYear = inst.selectedYear;
7827		var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
7828		inst.selectedDay = inst.currentDay = newDate.getDate();
7829		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
7830		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
7831		if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
7832			this._notifyChange(inst);
7833		this._adjustInstDate(inst);
7834		if (inst.input) {
7835			inst.input.val(clear ? '' : this._formatDate(inst));
7836		}
7837	},
7838
7839	/* Retrieve the date(s) directly. */
7840	_getDate: function(inst) {
7841		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
7842			this._daylightSavingAdjust(new Date(
7843			inst.currentYear, inst.currentMonth, inst.currentDay)));
7844			return startDate;
7845	},
7846
7847	/* Attach the onxxx handlers.  These are declared statically so
7848	 * they work with static code transformers like Caja.
7849	 */
7850	_attachHandlers: function(inst) {
7851		var stepMonths = this._get(inst, 'stepMonths');
7852		var id = '#' + inst.id.replace( /\\\\/g, "\\" );
7853		inst.dpDiv.find('[data-handler]').map(function () {
7854			var handler = {
7855				prev: function () {
7856					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
7857				},
7858				next: function () {
7859					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
7860				},
7861				hide: function () {
7862					window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
7863				},
7864				today: function () {
7865					window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
7866				},
7867				selectDay: function () {
7868					window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
7869					return false;
7870				},
7871				selectMonth: function () {
7872					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
7873					return false;
7874				},
7875				selectYear: function () {
7876					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
7877					return false;
7878				}
7879			};
7880			$(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
7881		});
7882	},
7883
7884	/* Generate the HTML for the current state of the date picker. */
7885	_generateHTML: function(inst) {
7886		var today = new Date();
7887		today = this._daylightSavingAdjust(
7888			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
7889		var isRTL = this._get(inst, 'isRTL');
7890		var showButtonPanel = this._get(inst, 'showButtonPanel');
7891		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
7892		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
7893		var numMonths = this._getNumberOfMonths(inst);
7894		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
7895		var stepMonths = this._get(inst, 'stepMonths');
7896		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
7897		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
7898			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
7899		var minDate = this._getMinMaxDate(inst, 'min');
7900		var maxDate = this._getMinMaxDate(inst, 'max');
7901		var drawMonth = inst.drawMonth - showCurrentAtPos;
7902		var drawYear = inst.drawYear;
7903		if (drawMonth < 0) {
7904			drawMonth += 12;
7905			drawYear--;
7906		}
7907		if (maxDate) {
7908			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
7909				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
7910			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
7911			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
7912				drawMonth--;
7913				if (drawMonth < 0) {
7914					drawMonth = 11;
7915					drawYear--;
7916				}
7917			}
7918		}
7919		inst.drawMonth = drawMonth;
7920		inst.drawYear = drawYear;
7921		var prevText = this._get(inst, 'prevText');
7922		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
7923			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
7924			this._getFormatConfig(inst)));
7925		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
7926			'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
7927			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
7928			(hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
7929		var nextText = this._get(inst, 'nextText');
7930		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
7931			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
7932			this._getFormatConfig(inst)));
7933		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
7934			'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
7935			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
7936			(hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
7937		var currentText = this._get(inst, 'currentText');
7938		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
7939		currentText = (!navigationAsDateFormat ? currentText :
7940			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
7941		var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">' +
7942			this._get(inst, 'closeText') + '</button>' : '');
7943		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
7944			(this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click"' +
7945			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
7946		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
7947		firstDay = (isNaN(firstDay) ? 0 : firstDay);
7948		var showWeek = this._get(inst, 'showWeek');
7949		var dayNames = this._get(inst, 'dayNames');
7950		var dayNamesShort = this._get(inst, 'dayNamesShort');
7951		var dayNamesMin = this._get(inst, 'dayNamesMin');
7952		var monthNames = this._get(inst, 'monthNames');
7953		var monthNamesShort = this._get(inst, 'monthNamesShort');
7954		var beforeShowDay = this._get(inst, 'beforeShowDay');
7955		var showOtherMonths = this._get(inst, 'showOtherMonths');
7956		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
7957		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
7958		var defaultDate = this._getDefaultDate(inst);
7959		var html = '';
7960		for (var row = 0; row < numMonths[0]; row++) {
7961			var group = '';
7962			this.maxRows = 4;
7963			for (var col = 0; col < numMonths[1]; col++) {
7964				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
7965				var cornerClass = ' ui-corner-all';
7966				var calender = '';
7967				if (isMultiMonth) {
7968					calender += '<div class="ui-datepicker-group';
7969					if (numMonths[1] > 1)
7970						switch (col) {
7971							case 0: calender += ' ui-datepicker-group-first';
7972								cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
7973							case numMonths[1]-1: calender += ' ui-datepicker-group-last';
7974								cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
7975							default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
7976						}
7977					calender += '">';
7978				}
7979				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
7980					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
7981					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
7982					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
7983					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
7984					'</div><table class="ui-datepicker-calendar"><thead>' +
7985					'<tr>';
7986				var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
7987				for (var dow = 0; dow < 7; dow++) { // days of the week
7988					var day = (dow + firstDay) % 7;
7989					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
7989' +
7990						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
7991				}
7992				calender += thead + '</tr></thead><tbody>';
7993				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
7994				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
7995					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
7996				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
7997				var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
7998				var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
7999				this.maxRows = numRows;
8000				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8001				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8002					calender += '<tr>';
8003					var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
8004						this._get(inst, 'calculateWeek')(printDate) + '</td>');
8005					for (var dow = 0; dow < 7; dow++) { // create date picker days
8006						var daySettings = (beforeShowDay ?
8007							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
8008						var otherMonth = (printDate.getMonth() != drawMonth);
8009						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8010							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8011						tbody += '<td class="' +
8012							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
8013							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
8014							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
8015							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
8016							// or defaultDate is current printedDate and defaultDate is selectedDate
8017							' ' + this._dayOverClass : '') + // highlight selected day
8018							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
8019							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
8020							(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
8021							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
8022							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
8023							(unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
8024							(otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
8025							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
8026							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
8027							(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
8028							(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
8029							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
8030						printDate.setDate(printDate.getDate() + 1);
8031						printDate = this._daylightSavingAdjust(printDate);
8032					}
8033					calender += tbody + '</tr>';
8034				}
8035				drawMonth++;
8036				if (drawMonth > 11) {
8037					drawMonth = 0;
8038					drawYear++;
8039				}
8040				calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
8041							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
8042				group += calender;
8043			}
8044			html += group;
8045		}
8046		html += buttonPanel + ($.ui.ie6 && !inst.inline ?
8047			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
8048		inst._keyEvent = false;
8049		return html;
8050	},
8051
8052	/* Generate the month and year header. */
8053	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8054			secondary, monthNames, monthNamesShort) {
8055		var changeMonth = this._get(inst, 'changeMonth');
8056		var changeYear = this._get(inst, 'changeYear');
8057		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
8058		var html = '<div class="ui-datepicker-title">';
8059		var monthHtml = '';
8060		// month selection
8061		if (secondary || !changeMonth)
8062			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
8063		else {
8064			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
8065			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
8066			monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
8067			for (var month = 0; month < 12; month++) {
8068				if ((!inMinYear || month >= minDate.getMonth()) &&
8069						(!inMaxYear || month <= maxDate.getMonth()))
8070					monthHtml += '<option value="' + month + '"' +
8071						(month == drawMonth ? ' selected="selected"' : '') +
8072						'>' + monthNamesShort[month] + '</option>';
8073			}
8074			monthHtml += '</select>';
8075		}
8076		if (!showMonthAfterYear)
8077			html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
8078		// year selection
8079		if ( !inst.yearshtml ) {
8080			inst.yearshtml = '';
8081			if (secondary || !changeYear)
8082				html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
8083			else {
8084				// determine range of years to display
8085				var years = this._get(inst, 'yearRange').split(':');
8086				var thisYear = new Date().getFullYear();
8087				var determineYear = function(value) {
8088					var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8089						(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
8090						parseInt(value, 10)));
8091					return (isNaN(year) ? thisYear : year);
8092				};
8093				var year = determineYear(years[0]);
8094				var endYear = Math.max(year, determineYear(years[1] || ''));
8095				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8096				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8097				inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
8098				for (; year <= endYear; year++) {
8099					inst.yearshtml += '<option value="' + year + '"' +
8100						(year == drawYear ? ' selected="selected"' : '') +
8101						'>' + year + '</option>';
8102				}
8103				inst.yearshtml += '</select>';
8104
8105				html += inst.yearshtml;
8106				inst.yearshtml = null;
8107			}
8108		}
8109		html += this._get(inst, 'yearSuffix');
8110		if (showMonthAfterYear)
8111			html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
8112		html += '</div>'; // Close datepicker_header
8113		return html;
8114	},
8115
8116	/* Adjust one of the date sub-fields. */
8117	_adjustInstDate: function(inst, offset, period) {
8118		var year = inst.drawYear + (period == 'Y' ? offset : 0);
8119		var month = inst.drawMonth + (period == 'M' ? offset : 0);
8120		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
8121			(period == 'D' ? offset : 0);
8122		var date = this._restrictMinMax(inst,
8123			this._daylightSavingAdjust(new Date(year, month, day)));
8124		inst.selectedDay = date.getDate();
8125		inst.drawMonth = inst.selectedMonth = date.getMonth();
8126		inst.drawYear = inst.selectedYear = date.getFullYear();
8127		if (period == 'M' || period == 'Y')
8128			this._notifyChange(inst);
8129	},
8130
8131	/* Ensure a date is within any min/max bounds. */
8132	_restrictMinMax: function(inst, date) {
8133		var minDate = this._getMinMaxDate(inst, 'min');
8134		var maxDate = this._getMinMaxDate(inst, 'max');
8135		var newDate = (minDate && date < minDate ? minDate : date);
8136		newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
8137		return newDate;
8138	},
8139
8140	/* Notify change of month/year. */
8141	_notifyChange: function(inst) {
8142		var onChange = this._get(inst, 'onChangeMonthYear');
8143		if (onChange)
8144			onChange.apply((inst.input ? inst.input[0] : null),
8145				[inst.selectedYear, inst.selectedMonth + 1, inst]);
8146	},
8147
8148	/* Determine the number of months to show. */
8149	_getNumberOfMonths: function(inst) {
8150		var numMonths = this._get(inst, 'numberOfMonths');
8151		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
8152	},
8153
8154	/* Determine the current maximum date - ensure no time components are set. */
8155	_getMinMaxDate: function(inst, minMax) {
8156		return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
8157	},
8158
8159	/* Find the number of days in a given month. */
8160	_getDaysInMonth: function(year, month) {
8161		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8162	},
8163
8164	/* Find the day of the week of the first of a month. */
8165	_getFirstDayOfMonth: function(year, month) {
8166		return new Date(year, month, 1).getDay();
8167	},
8168
8169	/* Determines if we should allow a "next/prev" month display change. */
8170	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
8171		var numMonths = this._getNumberOfMonths(inst);
8172		var date = this._daylightSavingAdjust(new Date(curYear,
8173			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8174		if (offset < 0)
8175			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8176		return this._isInRange(inst, date);
8177	},
8178
8179	/* Is the given date in the accepted range? */
8180	_isInRange: function(inst, date) {
8181		var minDate = this._getMinMaxDate(inst, 'min');
8182		var maxDate = this._getMinMaxDate(inst, 'max');
8183		return ((!minDate || date.getTime() >= minDate.getTime()) &&
8184			(!maxDate || date.getTime() <= maxDate.getTime()));
8185	},
8186
8187	/* Provide the configuration settings for formatting/parsing. */
8188	_getFormatConfig: function(inst) {
8189		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
8190		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8191			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8192		return {shortYearCutoff: shortYearCutoff,
8193			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
8194			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
8195	},
8196
8197	/* Format the given date for display. */
8198	_formatDate: function(inst, day, month, year) {
8199		if (!day) {
8200			inst.currentDay = inst.selectedDay;
8201			inst.currentMonth = inst.selectedMonth;
8202			inst.currentYear = inst.selectedYear;
8203		}
8204		var date = (day ? (typeof day == 'object' ? day :
8205			this._daylightSavingAdjust(new Date(year, month, day))) :
8206			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8207		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
8208	}
8209});
8210
8211/*
8212 * Bind hover events for datepicker elements.
8213 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8214 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8215 */
8216function bindHover(dpDiv) {
8217	var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
8218	return dpDiv.delegate(selector, 'mouseout', function() {
8219			$(this).removeClass('ui-state-hover');
8220			if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
8221			if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
8222		})
8223		.delegate(selector, 'mouseover', function(){
8224			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
8225				$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
8226				$(this).addClass('ui-state-hover');
8227				if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
8228				if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
8229			}
8230		});
8231}
8232
8233/* jQuery extend now ignores nulls! */
8234function extendRemove(target, props) {
8235	$.extend(target, props);
8236	for (var name in props)
8237		if (props[name] == null || props[name] == undefined)
8238			target[name] = props[name];
8239	return target;
8240};
8241
8242/* Invoke the datepicker functionality.
8243   @param  options  string - a command, optionally followed by additional parameters or
8244	                Object - settings for attaching new datepicker functionality
8245   @return  jQuery object */
8246$.fn.datepicker = function(options){
8247
8248	/* Verify an empty collection wasn't passed - Fixes #6976 */
8249	if ( !this.length ) {
8250		return this;
8251	}
8252
8253	/* Initialise the date picker. */
8254	if (!$.datepicker.initialized) {
8255		$(document).mousedown($.datepicker._checkExternalClick).
8256			find(document.body).append($.datepicker.dpDiv);
8257		$.datepicker.initialized = true;
8258	}
8259
8260	var otherArgs = Array.prototype.slice.call(arguments, 1);
8261	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
8262		return $.datepicker['_' + options + 'Datepicker'].
8263			apply($.datepicker, [this[0]].concat(otherArgs));
8264	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
8265		return $.datepicker['_' + options + 'Datepicker'].
8266			apply($.datepicker, [this[0]].concat(otherArgs));
8267	return this.each(function() {
8268		typeof options == 'string' ?
8269			$.datepicker['_' + options + 'Datepicker'].
8270				apply($.datepicker, [this].concat(otherArgs)) :
8271			$.datepicker._attachDatepicker(this, options);
8272	});
8273};
8274
8275$.datepicker = new Datepicker(); // singleton instance
8276$.datepicker.initialized = false;
8277$.datepicker.uuid = new Date().getTime();
8278$.datepicker.version = "1.9.2";
8279
8280// Workaround for #4055
8281// Add another global to avoid noConflict issues with inline event handlers
8282window['DP_jQuery_' + dpuuid] = $;
8283
8284})(jQuery);
8285(function( $, undefined ) {
8286
8287var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
8288	sizeRelatedOptions = {
8289		buttons: true,
8290		height: true,
8291		maxHeight: true,
8292		maxWidth: true,
8293		minHeight: true,
8294		minWidth: true,
8295		width: true
8296	},
8297	resizableRelatedOptions = {
8298		maxHeight: true,
8299		maxWidth: true,
8300		minHeight: true,
8301		minWidth: true
8302	};
8303
8304$.widget("ui.dialog", {
8305	version: "1.9.2",
8306	options: {
8307		autoOpen: true,
8308		buttons: {},
8309		closeOnEscape: true,
8310		closeText: "close",
8311		dialogClass: "",
8312		draggable: true,
8313		hide: null,
8314		height: "auto",
8315		maxHeight: false,
8316		maxWidth: false,
8317		minHeight: 150,
8318		minWidth: 150,
8319		modal: false,
8320		position: {
8321			my: "center",
8322			at: "center",
8323			of: window,
8324			collision: "fit",
8325			// ensure that the titlebar is never outside the document
8326			using: function( pos ) {
8327				var topOffset = $( this ).css( pos ).offset().top;
8328				if ( topOffset < 0 ) {
8329					$( this ).css( "top", pos.top - topOffset );
8330				}
8331			}
8332		},
8333		resizable: true,
8334		show: null,
8335		stack: true,
8336		title: "",
8337		width: 300,
8338		zIndex: 1000
8339	},
8340
8341	_create: function() {
8342		this.originalTitle = this.element.attr( "title" );
8343		// #5742 - .attr() might return a DOMElement
8344		if ( typeof this.originalTitle !== "string" ) {
8345			this.originalTitle = "";
8346		}
8347		this.oldPosition = {
8348			parent: this.element.parent(),
8349			index: this.element.parent().children().index( this.element )
8350		};
8351		this.options.title = this.options.title || this.originalTitle;
8352		var that = this,
8353			options = this.options,
8354
8355			title = options.title || "&#160;",
8356			uiDialog,
8357			uiDialogTitlebar,
8358			uiDialogTitlebarClose,
8359			uiDialogTitle,
8360			uiDialogButtonPane;
8361
8362			uiDialog = ( this.uiDialog = $( "<div>" ) )
8363				.addClass( uiDialogClasses + options.dialogClass )
8364				.css({
8365					display: "none",
8366					outline: 0, // TODO: move to stylesheet
8367					zIndex: options.zIndex
8368				})
8369				// setting tabIndex makes the div focusable
8370				.attr( "tabIndex", -1)
8371				.keydown(function( event ) {
8372					if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8373							event.keyCode === $.ui.keyCode.ESCAPE ) {
8374						that.close( event );
8375						event.preventDefault();
8376					}
8377				})
8378				.mousedown(function( event ) {
8379					that.moveToTop( false, event );
8380				})
8381				.appendTo( "body" );
8382
8383			this.element
8384				.show()
8385				.removeAttr( "title" )
8386				.addClass( "ui-dialog-content ui-widget-content" )
8387				.appendTo( uiDialog );
8388
8389			uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
8390				.addClass( "ui-dialog-titlebar  ui-widget-header  " +
8391					"ui-corner-all  ui-helper-clearfix" )
8392				.bind( "mousedown", function() {
8393					// Dialog isn't getting focus when dragging (#8063)
8394					uiDialog.focus();
8395				})
8396				.prependTo( uiDialog );
8397
8398			uiDialogTitlebarClose = $( "<a href='#'></a>" )
8399				.addClass( "ui-dialog-titlebar-close  ui-corner-all" )
8400				.attr( "role", "button" )
8401				.click(function( event ) {
8402					event.preventDefault();
8403					that.close( event );
8404				})
8405				.appendTo( uiDialogTitlebar );
8406
8407			( this.uiDialogTitlebarCloseText = $( "<span>" ) )
8408				.addClass( "ui-icon ui-icon-closethick" )
8409				.text( options.closeText )
8410				.appendTo( uiDialogTitlebarClose );
8411
8412			uiDialogTitle = $( "<span>" )
8413				.uniqueId()
8414				.addClass( "ui-dialog-title" )
8415				.html( title )
8416				.prependTo( uiDialogTitlebar );
8417
8418			uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
8419				.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8420
8421			( this.uiButtonSet = $( "<div>" ) )
8422				.addClass( "ui-dialog-buttonset" )
8423				.appendTo( uiDialogButtonPane );
8424
8425		uiDialog.attr({
8426			role: "dialog",
8427			"aria-labelledby": uiDialogTitle.attr( "id" )
8428		});
8429
8430		uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection();
8431		this._hoverable( uiDialogTitlebarClose );
8432		this._focusable( uiDialogTitlebarClose );
8433
8434		if ( options.draggable && $.fn.draggable ) {
8435			this._makeDraggable();
8436		}
8437		if ( options.resizable && $.fn.resizable ) {
8438			this._makeResizable();
8439		}
8440
8441		this._createButtons( options.buttons );
8442		this._isOpen = false;
8443
8444		if ( $.fn.bgiframe ) {
8445			uiDialog.bgiframe();
8446		}
8447
8448		// prevent tabbing out of modal dialogs
8449		this._on( uiDialog, { keydown: function( event ) {
8450			if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
8451				return;
8452			}
8453
8454			var tabbables = $( ":tabbable", uiDialog ),
8455				first = tabbables.filter( ":first" ),
8456				last  = tabbables.filter( ":last" );
8457
8458			if ( event.target === last[0] && !event.shiftKey ) {
8459				first.focus( 1 );
8460				return false;
8461			} else if ( event.target === first[0] && event.shiftKey ) {
8462				last.focus( 1 );
8463				return false;
8464			}
8465		}});
8466	},
8467
8468	_init: function() {
8469		if ( this.options.autoOpen ) {
8470			this.open();
8471		}
8472	},
8473
8474	_destroy: function() {
8475		var next,
8476			oldPosition = this.oldPosition;
8477
8478		if ( this.overlay ) {
8479			this.overlay.destroy();
8480		}
8481		this.uiDialog.hide();
8482		this.element
8483			.removeClass( "ui-dialog-content ui-widget-content" )
8484			.hide()
8485			.appendTo( "body" );
8486		this.uiDialog.remove();
8487
8488		if ( this.originalTitle ) {
8489			this.element.attr( "title", this.originalTitle );
8490		}
8491
8492		next = oldPosition.parent.children().eq( oldPosition.index );
8493		// Don't try to place the dialog next to itself (#8613)
8494		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8495			next.before( this.element );
8496		} else {
8497			oldPosition.parent.append( this.element );
8498		}
8499	},
8500
8501	widget: function() {
8502		return this.uiDialog;
8503	},
8504
8505	close: function( event ) {
8506		var that = this,
8507			maxZ, thisZ;
8508
8509		if ( !this._isOpen ) {
8510			return;
8511		}
8512
8513		if ( false === this._trigger( "beforeClose", event ) ) {
8514			return;
8515		}
8516
8517		this._isOpen = false;
8518
8519		if ( this.overlay ) {
8520			this.overlay.destroy();
8521		}
8522
8523		if ( this.options.hide ) {
8524			this._hide( this.uiDialog, this.options.hide, function() {
8525				that._trigger( "close", event );
8526			});
8527		} else {
8528			this.uiDialog.hide();
8529			this._trigger( "close", event );
8530		}
8531
8532		$.ui.dialog.overlay.resize();
8533
8534		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
8535		if ( this.options.modal ) {
8536			maxZ = 0;
8537			$( ".ui-dialog" ).each(function() {
8538				if ( this !== that.uiDialog[0] ) {
8539					thisZ = $( this ).css( "z-index" );
8540					if ( !isNaN( thisZ ) ) {
8541						maxZ = Math.max( maxZ, thisZ );
8542					}
8543				}
8544			});
8545			$.ui.dialog.maxZ = maxZ;
8546		}
8547
8548		return this;
8549	},
8550
8551	isOpen: function() {
8552		return this._isOpen;
8553	},
8554
8555	// the force parameter allows us to move modal dialogs to their correct
8556	// position on open
8557	moveToTop: function( force, event ) {
8558		var options = this.options,
8559			saveScroll;
8560
8561		if ( ( options.modal && !force ) ||
8562				( !options.stack && !options.modal ) ) {
8563			return this._trigger( "focus", event );
8564		}
8565
8566		if ( options.zIndex > $.ui.dialog.maxZ ) {
8567			$.ui.dialog.maxZ = options.zIndex;
8568		}
8569		if ( this.overlay ) {
8570			$.ui.dialog.maxZ += 1;
8571			$.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
8572			this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
8573		}
8574
8575		// Save and then restore scroll
8576		// Opera 9.5+ resets when parent z-index is changed.
8577		// http://bugs.jqueryui.com/ticket/3193
8578		saveScroll = {
8579			scrollTop: this.element.scrollTop(),
8580			scrollLeft: this.element.scrollLeft()
8581		};
8582		$.ui.dialog.maxZ += 1;
8583		this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
8584		this.element.attr( saveScroll );
8585		this._trigger( "focus", event );
8586
8587		return this;
8588	},
8589
8590	open: function() {
8591		if ( this._isOpen ) {
8592			return;
8593		}
8594
8595		var hasFocus,
8596			options = this.options,
8597			uiDialog = this.uiDialog;
8598
8599		this._size();
8600		this._position( options.position );
8601		uiDialog.show( options.show );
8602		this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
8603		this.moveToTop( true );
8604
8605		// set focus to the first tabbable element in the content area or the first button
8606		// if there are no tabbable elements, set focus on the dialog itself
8607		hasFocus = this.element.find( ":tabbable" );
8608		if ( !hasFocus.length ) {
8609			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8610			if ( !hasFocus.length ) {
8611				hasFocus = uiDialog;
8612			}
8613		}
8614		hasFocus.eq( 0 ).focus();
8615
8616		this._isOpen = true;
8617		this._trigger( "open" );
8618
8619		return this;
8620	},
8621
8622	_createButtons: function( buttons ) {
8623		var that = this,
8624			hasButtons = false;
8625
8626		// if we already have a button pane, remove it
8627		this.uiDialogButtonPane.remove();
8628		this.uiButtonSet.empty();
8629
8630		if ( typeof buttons === "object" && buttons !== null ) {
8631			$.each( buttons, function() {
8632				return !(hasButtons = true);
8633			});
8634		}
8635		if ( hasButtons ) {
8636			$.each( buttons, function( name, props ) {
8637				var button, click;
8638				props = $.isFunction( props ) ?
8639					{ click: props, text: name } :
8640					props;
8641				// Default to a non-submitting button
8642				props = $.extend( { type: "button" }, props );
8643				// Change the context for the click callback to be the main element
8644				click = props.click;
8645				props.click = function() {
8646					click.apply( that.element[0], arguments );
8647				};
8648				button = $( "<button></button>", props )
8649					.appendTo( that.uiButtonSet );
8650				if ( $.fn.button ) {
8651					button.button();
8652				}
8653			});
8654			this.uiDialog.addClass( "ui-dialog-buttons" );
8655			this.uiDialogButtonPane.appendTo( this.uiDialog );
8656		} else {
8657			this.uiDialog.removeClass( "ui-dialog-buttons" );
8658		}
8659	},
8660
8661	_makeDraggable: function() {
8662		var that = this,
8663			options = this.options;
8664
8665		function filteredUi( ui ) {
8666			return {
8667				position: ui.position,
8668				offset: ui.offset
8669			};
8670		}
8671
8672		this.uiDialog.draggable({
8673			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8674			handle: ".ui-dialog-titlebar",
8675			containment: "document",
8676			start: function( event, ui ) {
8677				$( this )
8678					.addClass( "ui-dialog-dragging" );
8679				that._trigger( "dragStart", event, filteredUi( ui ) );
8680			},
8681			drag: function( event, ui ) {
8682				that._trigger( "drag", event, filteredUi( ui ) );
8683			},
8684			stop: function( event, ui ) {
8685				options.position = [
8686					ui.position.left - that.document.scrollLeft(),
8687					ui.position.top - that.document.scrollTop()
8688				];
8689				$( this )
8690					.removeClass( "ui-dialog-dragging" );
8691				that._trigger( "dragStop", event, filteredUi( ui ) );
8692				$.ui.dialog.overlay.resize();
8693			}
8694		});
8695	},
8696
8697	_makeResizable: function( handles ) {
8698		handles = (handles === undefined ? this.options.resizable : handles);
8699		var that = this,
8700			options = this.options,
8701			// .ui-resizable has position: relative defined in the stylesheet
8702			// but dialogs have to use absolute or fixed positioning
8703			position = this.uiDialog.css( "position" ),
8704			resizeHandles = typeof handles === 'string' ?
8705				handles	:
8706				"n,e,s,w,se,sw,ne,nw";
8707
8708		function filteredUi( ui ) {
8709			return {
8710				originalPosition: ui.originalPosition,
8711				originalSize: ui.originalSize,
8712				position: ui.position,
8713				size: ui.size
8714			};
8715		}
8716
8717		this.uiDialog.resizable({
8718			cancel: ".ui-dialog-content",
8719			containment: "document",
8720			alsoResize: this.element,
8721			maxWidth: options.maxWidth,
8722			maxHeight: options.maxHeight,
8723			minWidth: options.minWidth,
8724			minHeight: this._minHeight(),
8725			handles: resizeHandles,
8726			start: function( event, ui ) {
8727				$( this ).addClass( "ui-dialog-resizing" );
8728				that._trigger( "resizeStart", event, filteredUi( ui ) );
8729			},
8730			resize: function( event, ui ) {
8731				that._trigger( "resize", event, filteredUi( ui ) );
8732			},
8733			stop: function( event, ui ) {
8734				$( this ).removeClass( "ui-dialog-resizing" );
8735				options.height = $( this ).height();
8736				options.width = $( this ).width();
8737				that._trigger( "resizeStop", event, filteredUi( ui ) );
8738				$.ui.dialog.overlay.resize();
8739			}
8740		})
8741		.css( "position", position )
8742		.find( ".ui-resizable-se" )
8743			.addClass( "ui-icon ui-icon-grip-diagonal-se" );
8744	},
8745
8746	_minHeight: function() {
8747		var options = this.options;
8748
8749		if ( options.height === "auto" ) {
8750			return options.minHeight;
8751		} else {
8752			return Math.min( options.minHeight, options.height );
8753		}
8754	},
8755
8756	_position: function( position ) {
8757		var myAt = [],
8758			offset = [ 0, 0 ],
8759			isVisible;
8760
8761		if ( position ) {
8762			// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
8763	//		if (typeof position == 'string' || $.isArray(position)) {
8764	//			myAt = $.isArray(position) ? position : position.split(' ');
8765
8766			if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
8767				myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ];
8768				if ( myAt.length === 1 ) {
8769					myAt[ 1 ] = myAt[ 0 ];
8770				}
8771
8772				$.each( [ "left", "top" ], function( i, offsetPosition ) {
8773					if ( +myAt[ i ] === myAt[ i ] ) {
8774						offset[ i ] = myAt[ i ];
8775						myAt[ i ] = offsetPosition;
8776					}
8777				});
8778
8779				position = {
8780					my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
8781						myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
8782					at: myAt.join( " " )
8783				};
8784			}
8785
8786			position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
8787		} else {
8788			position = $.ui.dialog.prototype.options.position;
8789		}
8790
8791		// need to show the dialog to get the actual offset in the position plugin
8792		isVisible = this.uiDialog.is( ":visible" );
8793		if ( !isVisible ) {
8794			this.uiDialog.show();
8795		}
8796		this.uiDialog.position( position );
8797		if ( !isVisible ) {
8798			this.uiDialog.hide();
8799		}
8800	},
8801
8802	_setOptions: function( options ) {
8803		var that = this,
8804			resizableOptions = {},
8805			resize = false;
8806
8807		$.each( options, function( key, value ) {
8808			that._setOption( key, value );
8809
8810			if ( key in sizeRelatedOptions ) {
8811				resize = true;
8812			}
8813			if ( key in resizableRelatedOptions ) {
8814				resizableOptions[ key ] = value;
8815			}
8816		});
8817
8818		if ( resize ) {
8819			this._size();
8820		}
8821		if ( this.uiDialog.is( ":data(resizable)" ) ) {
8822			this.uiDialog.resizable( "option", resizableOptions );
8823		}
8824	},
8825
8826	_setOption: function( key, value ) {
8827		var isDraggable, isResizable,
8828			uiDialog = this.uiDialog;
8829
8830		switch ( key ) {
8831			case "buttons":
8832				this._createButtons( value );
8833				break;
8834			case "closeText":
8835				// ensure that we always pass a string
8836				this.uiDialogTitlebarCloseText.text( "" + value );
8837				break;
8838			case "dialogClass":
8839				uiDialog
8840					.removeClass( this.options.dialogClass )
8841					.addClass( uiDialogClasses + value );
8842				break;
8843			case "disabled":
8844				if ( value ) {
8845					uiDialog.addClass( "ui-dialog-disabled" );
8846				} else {
8847					uiDialog.removeClass( "ui-dialog-disabled" );
8848				}
8849				break;
8850			case "draggable":
8851				isDraggable = uiDialog.is( ":data(draggable)" );
8852				if ( isDraggable && !value ) {
8853					uiDialog.draggable( "destroy" );
8854				}
8855
8856				if ( !isDraggable && value ) {
8857					this._makeDraggable();
8858				}
8859				break;
8860			case "position":
8861				this._position( value );
8862				break;
8863			case "resizable":
8864				// currently resizable, becoming non-resizable
8865				isResizable = uiDialog.is( ":data(resizable)" );
8866				if ( isResizable && !value ) {
8867					uiDialog.resizable( "destroy" );
8868				}
8869
8870				// currently resizable, changing handles
8871				if ( isResizable && typeof value === "string" ) {
8872					uiDialog.resizable( "option", "handles", value );
8873				}
8874
8875				// currently non-resizable, becoming resizable
8876				if ( !isResizable && value !== false ) {
8877					this._makeResizable( value );
8878				}
8879				break;
8880			case "title":
8881				// convert whatever was passed in o a string, for html() to not throw up
8882				$( ".ui-dialog-title", this.uiDialogTitlebar )
8883					.html( "" + ( value || "&#160;" ) );
8884				break;
8885		}
8886
8887		this._super( key, value );
8888	},
8889
8890	_size: function() {
8891		/* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8892		 * divs will both have width and height set, so we need to reset them
8893		 */
8894		var nonContentHeight, minContentHeight, autoHeight,
8895			options = this.options,
8896			isVisible = this.uiDialog.is( ":visible" );
8897
8898		// reset content sizing
8899		this.element.show().css({
8900			width: "auto",
8901			minHeight: 0,
8902			height: 0
8903		});
8904
8905		if ( options.minWidth > options.width ) {
8906			options.width = options.minWidth;
8907		}
8908
8909		// reset wrapper sizing
8910		// determine the height of all the non-content elements
8911		nonContentHeight = this.uiDialog.css({
8912				height: "auto",
8913				width: options.width
8914			})
8915			.outerHeight();
8916		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8917
8918		if ( options.height === "auto" ) {
8919			// only needed for IE6 support
8920			if ( $.support.minHeight ) {
8921				this.element.css({
8922					minHeight: minContentHeight,
8923					height: "auto"
8924				});
8925			} else {
8926				this.uiDialog.show();
8927				autoHeight = this.element.css( "height", "auto" ).height();
8928				if ( !isVisible ) {
8929					this.uiDialog.hide();
8930				}
8931				this.element.height( Math.max( autoHeight, minContentHeight ) );
8932			}
8933		} else {
8934			this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
8935		}
8936
8937		if (this.uiDialog.is( ":data(resizable)" ) ) {
8938			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8939		}
8940	}
8941});
8942
8943$.extend($.ui.dialog, {
8944	uuid: 0,
8945	maxZ: 0,
8946
8947	getTitleId: function($el) {
8948		var id = $el.attr( "id" );
8949		if ( !id ) {
8950			this.uuid += 1;
8951			id = this.uuid;
8952		}
8953		return "ui-dialog-title-" + id;
8954	},
8955
8956	overlay: function( dialog ) {
8957		this.$el = $.ui.dialog.overlay.create( dialog );
8958	}
8959});
8960
8961$.extend( $.ui.dialog.overlay, {
8962	instances: [],
8963	// reuse old instances due to IE memory leak with alpha transparency (see #5185)
8964	oldInstances: [],
8965	maxZ: 0,
8966	events: $.map(
8967		"focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
8968		function( event ) {
8969			return event + ".dialog-overlay";
8970		}
8971	).join( " " ),
8972	create: function( dialog ) {
8973		if ( this.instances.length === 0 ) {
8974			// prevent use of anchors and inputs
8975			// we use a setTimeout in case the overlay is created from an
8976			// event that we're going to be cancelling (see #2804)
8977			setTimeout(function() {
8978				// handle $(el).dialog().dialog('close') (see #4065)
8979				if ( $.ui.dialog.overlay.instances.length ) {
8980					$( document ).bind( $.ui.dialog.overlay.events, function( event ) {
8981						// stop events if the z-index of the target is < the z-index of the overlay
8982						// we cannot return true when we don't want to cancel the event (#3523)
8983						if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
8984							return false;
8985						}
8986					});
8987				}
8988			}, 1 );
8989
8990			// handle window resize
8991			$( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
8992		}
8993
8994		var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
8995
8996		// allow closing by pressing the escape key
8997		$( document ).bind( "keydown.dialog-overlay", function( event ) {
8998			var instances = $.ui.dialog.overlay.instances;
8999			// only react to the event if we're the top overlay
9000			if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
9001				dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9002				event.keyCode === $.ui.keyCode.ESCAPE ) {
9003
9004				dialog.close( event );
9005				event.preventDefault();
9006			}
9007		});
9008
9009		$el.appendTo( document.body ).css({
9010			width: this.width(),
9011			height: this.height()
9012		});
9013
9014		if ( $.fn.bgiframe ) {
9015			$el.bgiframe();
9016		}
9017
9018		this.instances.push( $el );
9019		return $el;
9020	},
9021
9022	destroy: function( $el ) {
9023		var indexOf = $.inArray( $el, this.instances ),
9024			maxZ = 0;
9025
9026		if ( indexOf !== -1 ) {
9027			this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
9028		}
9029
9030		if ( this.instances.length === 0 ) {
9031			$( [ document, window ] ).unbind( ".dialog-overlay" );
9032		}
9033
9034		$el.height( 0 ).width( 0 ).remove();
9035
9036		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9037		$.each( this.instances, function() {
9038			maxZ = Math.max( maxZ, this.css( "z-index" ) );
9039		});
9040		this.maxZ = maxZ;
9041	},
9042
9043	height: function() {
9044		var scrollHeight,
9045			offsetHeight;
9046		// handle IE
9047		if ( $.ui.ie ) {
9048			scrollHeight = Math.max(
9049				document.documentElement.scrollHeight,
9050				document.body.scrollHeight
9051			);
9052			offsetHeight = Math.max(
9053				document.documentElement.offsetHeight,
9054				document.body.offsetHeight
9055			);
9056
9057			if ( scrollHeight < offsetHeight ) {
9058				return $( window ).height() + "px";
9059			} else {
9060				return scrollHeight + "px";
9061			}
9062		// handle "good" browsers
9063		} else {
9064			return $( document ).height() + "px";
9065		}
9066	},
9067
9068	width: function() {
9069		var scrollWidth,
9070			offsetWidth;
9071		// handle IE
9072		if ( $.ui.ie ) {
9073			scrollWidth = Math.max(
9074				document.documentElement.scrollWidth,
9075				document.body.scrollWidth
9076			);
9077			offsetWidth = Math.max(
9078				document.documentElement.offsetWidth,
9079				document.body.offsetWidth
9080			);
9081
9082			if ( scrollWidth < offsetWidth ) {
9083				return $( window ).width() + "px";
9084			} else {
9085				return scrollWidth + "px";
9086			}
9087		// handle "good" browsers
9088		} else {
9089			return $( document ).width() + "px";
9090		}
9091	},
9092
9093	resize: function() {
9094		/* If the dialog is draggable and the user drags it past the
9095		 * right edge of the window, the document becomes wider so we
9096		 * need to stretch the overlay. If the user then drags the
9097		 * dialog back to the left, the document will become narrower,
9098		 * so we need to shrink the overlay to the appropriate size.
9099		 * This is handled by shrinking the overlay before setting it
9100		 * to the full document size.
9101		 */
9102		var $overlays = $( [] );
9103		$.each( $.ui.dialog.overlay.instances, function() {
9104			$overlays = $overlays.add( this );
9105		});
9106
9107		$overlays.css({
9108			width: 0,
9109			height: 0
9110		}).css({
9111			width: $.ui.dialog.overlay.width(),
9112			height: $.ui.dialog.overlay.height()
9113		});
9114	}
9115});
9116
9117$.extend( $.ui.dialog.overlay.prototype, {
9118	destroy: function() {
9119		$.ui.dialog.overlay.destroy( this.$el );
9120	}
9121});
9122
9123}( jQuery ) );
9124(function( $, undefined ) {
9125
9126var mouseHandled = false;
9127
9128$.widget( "ui.menu", {
9129	version: "1.9.2",
9130	defaultElement: "<ul>",
9131	delay: 300,
9132	options: {
9133		icons: {
9134			submenu: "ui-icon-carat-1-e"
9135		},
9136		menus: "ul",
9137		position: {
9138			my: "left top",
9139			at: "right top"
9140		},
9141		role: "menu",
9142
9143		// callbacks
9144		blur: null,
9145		focus: null,
9146		select: null
9147	},
9148
9149	_create: function() {
9150		this.activeMenu = this.element;
9151		this.element
9152			.uniqueId()
9153			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9154			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
9155			.attr({
9156				role: this.options.role,
9157				tabIndex: 0
9158			})
9159			// need to catch all clicks on disabled menu
9160			// not possible through _on
9161			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
9162				if ( this.options.disabled ) {
9163					event.preventDefault();
9164				}
9165			}, this ));
9166
9167		if ( this.options.disabled ) {
9168			this.element
9169				.addClass( "ui-state-disabled" )
9170				.attr( "aria-disabled", "true" );
9171		}
9172
9173		this._on({
9174			// Prevent focus from sticking to links inside menu after clicking
9175			// them (focus should always stay on UL during navigation).
9176			"mousedown .ui-menu-item > a": function( event ) {
9177				event.preventDefault();
9178			},
9179			"click .ui-state-disabled > a": function( event ) {
9180				event.preventDefault();
9181			},
9182			"click .ui-menu-item:has(a)": function( event ) {
9183				var target = $( event.target ).closest( ".ui-menu-item" );
9184				if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
9185					mouseHandled = true;
9186
9187					this.select( event );
9188					// Open submenu on click
9189					if ( target.has( ".ui-menu" ).length ) {
9190						this.expand( event );
9191					} else if ( !this.element.is( ":focus" ) ) {
9192						// Redirect focus to the menu
9193						this.element.trigger( "focus", [ true ] );
9194
9195						// If the active item is on the top level, let it stay active.
9196						// Otherwise, blur the active item since it is no longer visible.
9197						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
9198							clearTimeout( this.timer );
9199						}
9200					}
9201				}
9202			},
9203			"mouseenter .ui-menu-item": function( event ) {
9204				var target = $( event.currentTarget );
9205				// Remove ui-state-active class from siblings of the newly focused menu item
9206				// to avoid a jump caused by adjacent elements both having a class with a border
9207				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
9208				this.focus( event, target );
9209			},
9210			mouseleave: "collapseAll",
9211			"mouseleave .ui-menu": "collapseAll",
9212			focus: function( event, keepActiveItem ) {
9213				// If there's already an active item, keep it active
9214				// If not, activate the first item
9215				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
9216
9217				if ( !keepActiveItem ) {
9218					this.focus( event, item );
9219				}
9220			},
9221			blur: function( event ) {
9222				this._delay(function() {
9223					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
9224						this.collapseAll( event );
9225					}
9226				});
9227			},
9228			keydown: "_keydown"
9229		});
9230
9231		this.refresh();
vendor: 69,658 bytes, lines 9232-11793
9232
9233		// Clicks outside of a menu collapse any open menus
9234		this._on( this.document, {
9235			click: function( event ) {
9236				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
9237					this.collapseAll( event );
9238				}
9239
9240				// Reset the mouseHandled flag
9241				mouseHandled = false;
9242			}
9243		});
9244	},
9245
9246	_destroy: function() {
9247		// Destroy (sub)menus
9248		this.element
9249			.removeAttr( "aria-activedescendant" )
9250			.find( ".ui-menu" ).andSelf()
9251				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
9252				.removeAttr( "role" )
9253				.removeAttr( "tabIndex" )
9254				.removeAttr( "aria-labelledby" )
9255				.removeAttr( "aria-expanded" )
9256				.removeAttr( "aria-hidden" )
9257				.removeAttr( "aria-disabled" )
9258				.removeUniqueId()
9259				.show();
9260
9261		// Destroy menu items
9262		this.element.find( ".ui-menu-item" )
9263			.removeClass( "ui-menu-item" )
9264			.removeAttr( "role" )
9265			.removeAttr( "aria-disabled" )
9266			.children( "a" )
9267				.removeUniqueId()
9268				.removeClass( "ui-corner-all ui-state-hover" )
9269				.removeAttr( "tabIndex" )
9270				.removeAttr( "role" )
9271				.removeAttr( "aria-haspopup" )
9272				.children().each( function() {
9273					var elem = $( this );
9274					if ( elem.data( "ui-menu-submenu-carat" ) ) {
9275						elem.remove();
9276					}
9277				});
9278
9279		// Destroy menu dividers
9280		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
9281	},
9282
9283	_keydown: function( event ) {
9284		var match, prev, character, skip, regex,
9285			preventDefault = true;
9286
9287		function escape( value ) {
9288			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
9289		}
9290
9291		switch ( event.keyCode ) {
9292		case $.ui.keyCode.PAGE_UP:
9293			this.previousPage( event );
9294			break;
9295		case $.ui.keyCode.PAGE_DOWN:
9296			this.nextPage( event );
9297			break;
9298		case $.ui.keyCode.HOME:
9299			this._move( "first", "first", event );
9300			break;
9301		case $.ui.keyCode.END:
9302			this._move( "last", "last", event );
9303			break;
9304		case $.ui.keyCode.UP:
9305			this.previous( event );
9306			break;
9307		case $.ui.keyCode.DOWN:
9308			this.next( event );
9309			break;
9310		case $.ui.keyCode.LEFT:
9311			this.collapse( event );
9312			break;
9313		case $.ui.keyCode.RIGHT:
9314			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
9315				this.expand( event );
9316			}
9317			break;
9318		case $.ui.keyCode.ENTER:
9319		case $.ui.keyCode.SPACE:
9320			this._activate( event );
9321			break;
9322		case $.ui.keyCode.ESCAPE:
9323			this.collapse( event );
9324			break;
9325		default:
9326			preventDefault = false;
9327			prev = this.previousFilter || "";
9328			character = String.fromCharCode( event.keyCode );
9329			skip = false;
9330
9331			clearTimeout( this.filterTimer );
9332
9333			if ( character === prev ) {
9334				skip = true;
9335			} else {
9336				character = prev + character;
9337			}
9338
9339			regex = new RegExp( "^" + escape( character ), "i" );
9340			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9341				return regex.test( $( this ).children( "a" ).text() );
9342			});
9343			match = skip && match.index( this.active.next() ) !== -1 ?
9344				this.active.nextAll( ".ui-menu-item" ) :
9345				match;
9346
9347			// If no matches on the current filter, reset to the last character pressed
9348			// to move down the menu to the first item that starts with that character
9349			if ( !match.length ) {
9350				character = String.fromCharCode( event.keyCode );
9351				regex = new RegExp( "^" + escape( character ), "i" );
9352				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9353					return regex.test( $( this ).children( "a" ).text() );
9354				});
9355			}
9356
9357			if ( match.length ) {
9358				this.focus( event, match );
9359				if ( match.length > 1 ) {
9360					this.previousFilter = character;
9361					this.filterTimer = this._delay(function() {
9362						delete this.previousFilter;
9363					}, 1000 );
9364				} else {
9365					delete this.previousFilter;
9366				}
9367			} else {
9368				delete this.previousFilter;
9369			}
9370		}
9371
9372		if ( preventDefault ) {
9373			event.preventDefault();
9374		}
9375	},
9376
9377	_activate: function( event ) {
9378		if ( !this.active.is( ".ui-state-disabled" ) ) {
9379			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
9380				this.expand( event );
9381			} else {
9382				this.select( event );
9383			}
9384		}
9385	},
9386
9387	refresh: function() {
9388		var menus,
9389			icon = this.options.icons.submenu,
9390			submenus = this.element.find( this.options.menus );
9391
9392		// Initialize nested menus
9393		submenus.filter( ":not(.ui-menu)" )
9394			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9395			.hide()
9396			.attr({
9397				role: this.options.role,
9398				"aria-hidden": "true",
9399				"aria-expanded": "false"
9400			})
9401			.each(function() {
9402				var menu = $( this ),
9403					item = menu.prev( "a" ),
9404					submenuCarat = $( "<span>" )
9405						.addClass( "ui-menu-icon ui-icon " + icon )
9406						.data( "ui-menu-submenu-carat", true );
9407
9408				item
9409					.attr( "aria-haspopup", "true" )
9410					.prepend( submenuCarat );
9411				menu.attr( "aria-labelledby", item.attr( "id" ) );
9412			});
9413
9414		menus = submenus.add( this.element );
9415
9416		// Don't refresh list items that are already adapted
9417		menus.children( ":not(.ui-menu-item):has(a)" )
9418			.addClass( "ui-menu-item" )
9419			.attr( "role", "presentation" )
9420			.children( "a" )
9421				.uniqueId()
9422				.addClass( "ui-corner-all" )
9423				.attr({
9424					tabIndex: -1,
9425					role: this._itemRole()
9426				});
9427
9428		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
9429		menus.children( ":not(.ui-menu-item)" ).each(function() {
9430			var item = $( this );
9431			// hyphen, em dash, en dash
9432			if ( !/[^\-—–\s]/.test( item.text() ) ) {
9433				item.addClass( "ui-widget-content ui-menu-divider" );
9434			}
9435		});
9436
9437		// Add aria-disabled attribute to any disabled menu item
9438		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
9439
9440		// If the active item has been removed, blur the menu
9441		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
9442			this.blur();
9443		}
9444	},
9445
9446	_itemRole: function() {
9447		return {
9448			menu: "menuitem",
9449			listbox: "option"
9450		}[ this.options.role ];
9451	},
9452
9453	focus: function( event, item ) {
9454		var nested, focused;
9455		this.blur( event, event && event.type === "focus" );
9456
9457		this._scrollIntoView( item );
9458
9459		this.active = item.first();
9460		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
9461		// Only update aria-activedescendant if there's a role
9462		// otherwise we assume focus is managed elsewhere
9463		if ( this.options.role ) {
9464			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
9465		}
9466
9467		// Highlight active parent menu item, if any
9468		this.active
9469			.parent()
9470			.closest( ".ui-menu-item" )
9471			.children( "a:first" )
9472			.addClass( "ui-state-active" );
9473
9474		if ( event && event.type === "keydown" ) {
9475			this._close();
9476		} else {
9477			this.timer = this._delay(function() {
9478				this._close();
9479			}, this.delay );
9480		}
9481
9482		nested = item.children( ".ui-menu" );
9483		if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
9484			this._startOpening(nested);
9485		}
9486		this.activeMenu = item.parent();
9487
9488		this._trigger( "focus", event, { item: item } );
9489	},
9490
9491	_scrollIntoView: function( item ) {
9492		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
9493		if ( this._hasScroll() ) {
9494			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
9495			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
9496			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
9497			scroll = this.activeMenu.scrollTop();
9498			elementHeight = this.activeMenu.height();
9499			itemHeight = item.height();
9500
9501			if ( offset < 0 ) {
9502				this.activeMenu.scrollTop( scroll + offset );
9503			} else if ( offset + itemHeight > elementHeight ) {
9504				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
9505			}
9506		}
9507	},
9508
9509	blur: function( event, fromFocus ) {
9510		if ( !fromFocus ) {
9511			clearTimeout( this.timer );
9512		}
9513
9514		if ( !this.active ) {
9515			return;
9516		}
9517
9518		this.active.children( "a" ).removeClass( "ui-state-focus" );
9519		this.active = null;
9520
9521		this._trigger( "blur", event, { item: this.active } );
9522	},
9523
9524	_startOpening: function( submenu ) {
9525		clearTimeout( this.timer );
9526
9527		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
9528		// shift in the submenu position when mousing over the carat icon
9529		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
9530			return;
9531		}
9532
9533		this.timer = this._delay(function() {
9534			this._close();
9535			this._open( submenu );
9536		}, this.delay );
9537	},
9538
9539	_open: function( submenu ) {
9540		var position = $.extend({
9541			of: this.active
9542		}, this.options.position );
9543
9544		clearTimeout( this.timer );
9545		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
9546			.hide()
9547			.attr( "aria-hidden", "true" );
9548
9549		submenu
9550			.show()
9551			.removeAttr( "aria-hidden" )
9552			.attr( "aria-expanded", "true" )
9553			.position( position );
9554	},
9555
9556	collapseAll: function( event, all ) {
9557		clearTimeout( this.timer );
9558		this.timer = this._delay(function() {
9559			// If we were passed an event, look for the submenu that contains the event
9560			var currentMenu = all ? this.element :
9561				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
9562
9563			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
9564			if ( !currentMenu.length ) {
9565				currentMenu = this.element;
9566			}
9567
9568			this._close( currentMenu );
9569
9570			this.blur( event );
9571			this.activeMenu = currentMenu;
9572		}, this.delay );
9573	},
9574
9575	// With no arguments, closes the currently active menu - if nothing is active
9576	// it closes all menus.  If passed an argument, it will search for menus BELOW
9577	_close: function( startMenu ) {
9578		if ( !startMenu ) {
9579			startMenu = this.active ? this.active.parent() : this.element;
9580		}
9581
9582		startMenu
9583			.find( ".ui-menu" )
9584				.hide()
9585				.attr( "aria-hidden", "true" )
9586				.attr( "aria-expanded", "false" )
9587			.end()
9588			.find( "a.ui-state-active" )
9589				.removeClass( "ui-state-active" );
9590	},
9591
9592	collapse: function( event ) {
9593		var newItem = this.active &&
9594			this.active.parent().closest( ".ui-menu-item", this.element );
9595		if ( newItem && newItem.length ) {
9596			this._close();
9597			this.focus( event, newItem );
9598		}
9599	},
9600
9601	expand: function( event ) {
9602		var newItem = this.active &&
9603			this.active
9604				.children( ".ui-menu " )
9605				.children( ".ui-menu-item" )
9606				.first();
9607
9608		if ( newItem && newItem.length ) {
9609			this._open( newItem.parent() );
9610
9611			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
9612			this._delay(function() {
9613				this.focus( event, newItem );
9614			});
9615		}
9616	},
9617
9618	next: function( event ) {
9619		this._move( "next", "first", event );
9620	},
9621
9622	previous: function( event ) {
9623		this._move( "prev", "last", event );
9624	},
9625
9626	isFirstItem: function() {
9627		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
9628	},
9629
9630	isLastItem: function() {
9631		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
9632	},
9633
9634	_move: function( direction, filter, event ) {
9635		var next;
9636		if ( this.active ) {
9637			if ( direction === "first" || direction === "last" ) {
9638				next = this.active
9639					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
9640					.eq( -1 );
9641			} else {
9642				next = this.active
9643					[ direction + "All" ]( ".ui-menu-item" )
9644					.eq( 0 );
9645			}
9646		}
9647		if ( !next || !next.length || !this.active ) {
9648			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
9649		}
9650
9651		this.focus( event, next );
9652	},
9653
9654	nextPage: function( event ) {
9655		var item, base, height;
9656
9657		if ( !this.active ) {
9658			this.next( event );
9659			return;
9660		}
9661		if ( this.isLastItem() ) {
9662			return;
9663		}
9664		if ( this._hasScroll() ) {
9665			base = this.active.offset().top;
9666			height = this.element.height();
9667			this.active.nextAll( ".ui-menu-item" ).each(function() {
9668				item = $( this );
9669				return item.offset().top - base - height < 0;
9670			});
9671
9672			this.focus( event, item );
9673		} else {
9674			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
9675				[ !this.active ? "first" : "last" ]() );
9676		}
9677	},
9678
9679	previousPage: function( event ) {
9680		var item, base, height;
9681		if ( !this.active ) {
9682			this.next( event );
9683			return;
9684		}
9685		if ( this.isFirstItem() ) {
9686			return;
9687		}
9688		if ( this._hasScroll() ) {
9689			base = this.active.offset().top;
9690			height = this.element.height();
9691			this.active.prevAll( ".ui-menu-item" ).each(function() {
9692				item = $( this );
9693				return item.offset().top - base + height > 0;
9694			});
9695
9696			this.focus( event, item );
9697		} else {
9698			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
9699		}
9700	},
9701
9702	_hasScroll: function() {
9703		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
9704	},
9705
9706	select: function( event ) {
9707		// TODO: It should never be possible to not have an active item at this
9708		// point, but the tests don't trigger mouseenter before click.
9709		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
9710		var ui = { item: this.active };
9711		if ( !this.active.has( ".ui-menu" ).length ) {
9712			this.collapseAll( event, true );
9713		}
9714		this._trigger( "select", event, ui );
9715	}
9716});
9717
9718}( jQuery ));
9719(function( $, undefined ) {
9720
9721$.widget( "ui.progressbar", {
9722	version: "1.9.2",
9723	options: {
9724		value: 0,
9725		max: 100
9726	},
9727
9728	min: 0,
9729
9730	_create: function() {
9731		this.element
9732			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
9733			.attr({
9734				role: "progressbar",
9735				"aria-valuemin": this.min,
9736				"aria-valuemax": this.options.max,
9737				"aria-valuenow": this._value()
9738			});
9739
9740		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
9741			.appendTo( this.element );
9742
9743		this.oldValue = this._value();
9744		this._refreshValue();
9745	},
9746
9747	_destroy: function() {
9748		this.element
9749			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
9750			.removeAttr( "role" )
9751			.removeAttr( "aria-valuemin" )
9752			.removeAttr( "aria-valuemax" )
9753			.removeAttr( "aria-valuenow" );
9754
9755		this.valueDiv.remove();
9756	},
9757
9758	value: function( newValue ) {
9759		if ( newValue === undefined ) {
9760			return this._value();
9761		}
9762
9763		this._setOption( "value", newValue );
9764		return this;
9765	},
9766
9767	_setOption: function( key, value ) {
9768		if ( key === "value" ) {
9769			this.options.value = value;
9770			this._refreshValue();
9771			if ( this._value() === this.options.max ) {
9772				this._trigger( "complete" );
9773			}
9774		}
9775
9776		this._super( key, value );
9777	},
9778
9779	_value: function() {
9780		var val = this.options.value;
9781		// normalize invalid value
9782		if ( typeof val !== "number" ) {
9783			val = 0;
9784		}
9785		return Math.min( this.options.max, Math.max( this.min, val ) );
9786	},
9787
9788	_percentage: function() {
9789		return 100 * this._value() / this.options.max;
9790	},
9791
9792	_refreshValue: function() {
9793		var value = this.value(),
9794			percentage = this._percentage();
9795
9796		if ( this.oldValue !== value ) {
9797			this.oldValue = value;
9798			this._trigger( "change" );
9799		}
9800
9801		this.valueDiv
9802			.toggle( value > this.min )
9803			.toggleClass( "ui-corner-right", value === this.options.max )
9804			.width( percentage.toFixed(0) + "%" );
9805		this.element.attr( "aria-valuenow", value );
9806	}
9807});
9808
9809})( jQuery );
9810(function( $, undefined ) {
9811
9812// number of pages in a slider
9813// (how many times can you page up/down to go through the whole range)
9814var numPages = 5;
9815
9816$.widget( "ui.slider", $.ui.mouse, {
9817	version: "1.9.2",
9818	widgetEventPrefix: "slide",
9819
9820	options: {
9821		animate: false,
9822		distance: 0,
9823		max: 100,
9824		min: 0,
9825		orientation: "horizontal",
9826		range: false,
9827		step: 1,
9828		value: 0,
9829		values: null
9830	},
9831
9832	_create: function() {
9833		var i, handleCount,
9834			o = this.options,
9835			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
9836			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
9837			handles = [];
9838
9839		this._keySliding = false;
9840		this._mouseSliding = false;
9841		this._animateOff = true;
9842		this._handleIndex = null;
9843		this._detectOrientation();
9844		this._mouseInit();
9845
9846		this.element
9847			.addClass( "ui-slider" +
9848				" ui-slider-" + this.orientation +
9849				" ui-widget" +
9850				" ui-widget-content" +
9851				" ui-corner-all" +
9852				( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
9853
9854		this.range = $([]);
9855
9856		if ( o.range ) {
9857			if ( o.range === true ) {
9858				if ( !o.values ) {
9859					o.values = [ this._valueMin(), this._valueMin() ];
9860				}
9861				if ( o.values.length && o.values.length !== 2 ) {
9862					o.values = [ o.values[0], o.values[0] ];
9863				}
9864			}
9865
9866			this.range = $( "<div></div>" )
9867				.appendTo( this.element )
9868				.addClass( "ui-slider-range" +
9869				// note: this isn't the most fittingly semantic framework class for this element,
9870				// but worked best visually with a variety of themes
9871				" ui-widget-header" +
9872				( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
9873		}
9874
9875		handleCount = ( o.values && o.values.length ) || 1;
9876
9877		for ( i = existingHandles.length; i < handleCount; i++ ) {
9878			handles.push( handle );
9879		}
9880
9881		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
9882
9883		this.handle = this.handles.eq( 0 );
9884
9885		this.handles.add( this.range ).filter( "a" )
9886			.click(function( event ) {
9887				event.preventDefault();
9888			})
9889			.mouseenter(function() {
9890				if ( !o.disabled ) {
9891					$( this ).addClass( "ui-state-hover" );
9892				}
9893			})
9894			.mouseleave(function() {
9895				$( this ).removeClass( "ui-state-hover" );
9896			})
9897			.focus(function() {
9898				if ( !o.disabled ) {
9899					$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
9900					$( this ).addClass( "ui-state-focus" );
9901				} else {
9902					$( this ).blur();
9903				}
9904			})
9905			.blur(function() {
9906				$( this ).removeClass( "ui-state-focus" );
9907			});
9908
9909		this.handles.each(function( i ) {
9910			$( this ).data( "ui-slider-handle-index", i );
9911		});
9912
9913		this._on( this.handles, {
9914			keydown: function( event ) {
9915				var allowed, curVal, newVal, step,
9916					index = $( event.target ).data( "ui-slider-handle-index" );
9917
9918				switch ( event.keyCode ) {
9919					case $.ui.keyCode.HOME:
9920					case $.ui.keyCode.END:
9921					case $.ui.keyCode.PAGE_UP:
9922					case $.ui.keyCode.PAGE_DOWN:
9923					case $.ui.keyCode.UP:
9924					case $.ui.keyCode.RIGHT:
9925					case $.ui.keyCode.DOWN:
9926					case $.ui.keyCode.LEFT:
9927						event.preventDefault();
9928						if ( !this._keySliding ) {
9929							this._keySliding = true;
9930							$( event.target ).addClass( "ui-state-active" );
9931							allowed = this._start( event, index );
9932							if ( allowed === false ) {
9933								return;
9934							}
9935						}
9936						break;
9937				}
9938
9939				step = this.options.step;
9940				if ( this.options.values && this.options.values.length ) {
9941					curVal = newVal = this.values( index );
9942				} else {
9943					curVal = newVal = this.value();
9944				}
9945
9946				switch ( event.keyCode ) {
9947					case $.ui.keyCode.HOME:
9948						newVal = this._valueMin();
9949						break;
9950					case $.ui.keyCode.END:
9951						newVal = this._valueMax();
9952						break;
9953					case $.ui.keyCode.PAGE_UP:
9954						newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
9955						break;
9956					case $.ui.keyCode.PAGE_DOWN:
9957						newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
9958						break;
9959					case $.ui.keyCode.UP:
9960					case $.ui.keyCode.RIGHT:
9961						if ( curVal === this._valueMax() ) {
9962							return;
9963						}
9964						newVal = this._trimAlignValue( curVal + step );
9965						break;
9966					case $.ui.keyCode.DOWN:
9967					case $.ui.keyCode.LEFT:
9968						if ( curVal === this._valueMin() ) {
9969							return;
9970						}
9971						newVal = this._trimAlignValue( curVal - step );
9972						break;
9973				}
9974
9975				this._slide( event, index, newVal );
9976			},
9977			keyup: function( event ) {
9978				var index = $( event.target ).data( "ui-slider-handle-index" );
9979
9980				if ( this._keySliding ) {
9981					this._keySliding = false;
9982					this._stop( event, index );
9983					this._change( event, index );
9984					$( event.target ).removeClass( "ui-state-active" );
9985				}
9986			}
9987		});
9988
9989		this._refreshValue();
9990
9991		this._animateOff = false;
9992	},
9993
9994	_destroy: function() {
9995		this.handles.remove();
9996		this.range.remove();
9997
9998		this.element
9999			.removeClass( "ui-slider" +
10000				" ui-slider-horizontal" +
10001				" ui-slider-vertical" +
10002				" ui-slider-disabled" +
10003				" ui-widget" +
10004				" ui-widget-content" +
10005				" ui-corner-all" );
10006
10007		this._mouseDestroy();
10008	},
10009
10010	_mouseCapture: function( event ) {
10011		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
10012			that = this,
10013			o = this.options;
10014
10015		if ( o.disabled ) {
10016			return false;
10017		}
10018
10019		this.elementSize = {
10020			width: this.element.outerWidth(),
10021			height: this.element.outerHeight()
10022		};
10023		this.elementOffset = this.element.offset();
10024
10025		position = { x: event.pageX, y: event.pageY };
10026		normValue = this._normValueFromMouse( position );
10027		distance = this._valueMax() - this._valueMin() + 1;
10028		this.handles.each(function( i ) {
10029			var thisDistance = Math.abs( normValue - that.values(i) );
10030			if ( distance > thisDistance ) {
10031				distance = thisDistance;
10032				closestHandle = $( this );
10033				index = i;
10034			}
10035		});
10036
10037		// workaround for bug #3736 (if both handles of a range are at 0,
10038		// the first is always used as the one with least distance,
10039		// and moving it is obviously prevented by preventing negative ranges)
10040		if( o.range === true && this.values(1) === o.min ) {
10041			index += 1;
10042			closestHandle = $( this.handles[index] );
10043		}
10044
10045		allowed = this._start( event, index );
10046		if ( allowed === false ) {
10047			return false;
10048		}
10049		this._mouseSliding = true;
10050
10051		this._handleIndex = index;
10052
10053		closestHandle
10054			.addClass( "ui-state-active" )
10055			.focus();
10056
10057		offset = closestHandle.offset();
10058		mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
10059		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10060			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10061			top: event.pageY - offset.top -
10062				( closestHandle.height() / 2 ) -
10063				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10064				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10065				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10066		};
10067
10068		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10069			this._slide( event, index, normValue );
10070		}
10071		this._animateOff = true;
10072		return true;
10073	},
10074
10075	_mouseStart: function() {
10076		return true;
10077	},
10078
10079	_mouseDrag: function( event ) {
10080		var position = { x: event.pageX, y: event.pageY },
10081			normValue = this._normValueFromMouse( position );
10082
10083		this._slide( event, this._handleIndex, normValue );
10084
10085		return false;
10086	},
10087
10088	_mouseStop: function( event ) {
10089		this.handles.removeClass( "ui-state-active" );
10090		this._mouseSliding = false;
10091
10092		this._stop( event, this._handleIndex );
10093		this._change( event, this._handleIndex );
10094
10095		this._handleIndex = null;
10096		this._clickOffset = null;
10097		this._animateOff = false;
10098
10099		return false;
10100	},
10101
10102	_detectOrientation: function() {
10103		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10104	},
10105
10106	_normValueFromMouse: function( position ) {
10107		var pixelTotal,
10108			pixelMouse,
10109			percentMouse,
10110			valueTotal,
10111			valueMouse;
10112
10113		if ( this.orientation === "horizontal" ) {
10114			pixelTotal = this.elementSize.width;
10115			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10116		} else {
10117			pixelTotal = this.elementSize.height;
10118			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10119		}
10120
10121		percentMouse = ( pixelMouse / pixelTotal );
10122		if ( percentMouse > 1 ) {
10123			percentMouse = 1;
10124		}
10125		if ( percentMouse < 0 ) {
10126			percentMouse = 0;
10127		}
10128		if ( this.orientation === "vertical" ) {
10129			percentMouse = 1 - percentMouse;
10130		}
10131
10132		valueTotal = this._valueMax() - this._valueMin();
10133		valueMouse = this._valueMin() + percentMouse * valueTotal;
10134
10135		return this._trimAlignValue( valueMouse );
10136	},
10137
10138	_start: function( event, index ) {
10139		var uiHash = {
10140			handle: this.handles[ index ],
10141			value: this.value()
10142		};
10143		if ( this.options.values && this.options.values.length ) {
10144			uiHash.value = this.values( index );
10145			uiHash.values = this.values();
10146		}
10147		return this._trigger( "start", event, uiHash );
10148	},
10149
10150	_slide: function( event, index, newVal ) {
10151		var otherVal,
10152			newValues,
10153			allowed;
10154
10155		if ( this.options.values && this.options.values.length ) {
10156			otherVal = this.values( index ? 0 : 1 );
10157
10158			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
10159					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10160				) {
10161				newVal = otherVal;
10162			}
10163
10164			if ( newVal !== this.values( index ) ) {
10165				newValues = this.values();
10166				newValues[ index ] = newVal;
10167				// A slide can be canceled by returning false from the slide callback
10168				allowed = this._trigger( "slide", event, {
10169					handle: this.handles[ index ],
10170					value: newVal,
10171					values: newValues
10172				} );
10173				otherVal = this.values( index ? 0 : 1 );
10174				if ( allowed !== false ) {
10175					this.values( index, newVal, true );
10176				}
10177			}
10178		} else {
10179			if ( newVal !== this.value() ) {
10180				// A slide can be canceled by returning false from the slide callback
10181				allowed = this._trigger( "slide", event, {
10182					handle: this.handles[ index ],
10183					value: newVal
10184				} );
10185				if ( allowed !== false ) {
10186					this.value( newVal );
10187				}
10188			}
10189		}
10190	},
10191
10192	_stop: function( event, index ) {
10193		var uiHash = {
10194			handle: this.handles[ index ],
10195			value: this.value()
10196		};
10197		if ( this.options.values && this.options.values.length ) {
10198			uiHash.value = this.values( index );
10199			uiHash.values = this.values();
10200		}
10201
10202		this._trigger( "stop", event, uiHash );
10203	},
10204
10205	_change: function( event, index ) {
10206		if ( !this._keySliding && !this._mouseSliding ) {
10207			var uiHash = {
10208				handle: this.handles[ index ],
10209				value: this.value()
10210			};
10211			if ( this.options.values && this.options.values.length ) {
10212				uiHash.value = this.values( index );
10213				uiHash.values = this.values();
10214			}
10215
10216			this._trigger( "change", event, uiHash );
10217		}
10218	},
10219
10220	value: function( newValue ) {
10221		if ( arguments.length ) {
10222			this.options.value = this._trimAlignValue( newValue );
10223			this._refreshValue();
10224			this._change( null, 0 );
10225			return;
10226		}
10227
10228		return this._value();
10229	},
10230
10231	values: function( index, newValue ) {
10232		var vals,
10233			newValues,
10234			i;
10235
10236		if ( arguments.length > 1 ) {
10237			this.options.values[ index ] = this._trimAlignValue( newValue );
10238			this._refreshValue();
10239			this._change( null, index );
10240			return;
10241		}
10242
10243		if ( arguments.length ) {
10244			if ( $.isArray( arguments[ 0 ] ) ) {
10245				vals = this.options.values;
10246				newValues = arguments[ 0 ];
10247				for ( i = 0; i < vals.length; i += 1 ) {
10248					vals[ i ] = this._trimAlignValue( newValues[ i ] );
10249					this._change( null, i );
10250				}
10251				this._refreshValue();
10252			} else {
10253				if ( this.options.values && this.options.values.length ) {
10254					return this._values( index );
10255				} else {
10256					return this.value();
10257				}
10258			}
10259		} else {
10260			return this._values();
10261		}
10262	},
10263
10264	_setOption: function( key, value ) {
10265		var i,
10266			valsLength = 0;
10267
10268		if ( $.isArray( this.options.values ) ) {
10269			valsLength = this.options.values.length;
10270		}
10271
10272		$.Widget.prototype._setOption.apply( this, arguments );
10273
10274		switch ( key ) {
10275			case "disabled":
10276				if ( value ) {
10277					this.handles.filter( ".ui-state-focus" ).blur();
10278					this.handles.removeClass( "ui-state-hover" );
10279					this.handles.prop( "disabled", true );
10280					this.element.addClass( "ui-disabled" );
10281				} else {
10282					this.handles.prop( "disabled", false );
10283					this.element.removeClass( "ui-disabled" );
10284				}
10285				break;
10286			case "orientation":
10287				this._detectOrientation();
10288				this.element
10289					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
10290					.addClass( "ui-slider-" + this.orientation );
10291				this._refreshValue();
10292				break;
10293			case "value":
10294				this._animateOff = true;
10295				this._refreshValue();
10296				this._change( null, 0 );
10297				this._animateOff = false;
10298				break;
10299			case "values":
10300				this._animateOff = true;
10301				this._refreshValue();
10302				for ( i = 0; i < valsLength; i += 1 ) {
10303					this._change( null, i );
10304				}
10305				this._animateOff = false;
10306				break;
10307			case "min":
10308			case "max":
10309				this._animateOff = true;
10310				this._refreshValue();
10311				this._animateOff = false;
10312				break;
10313		}
10314	},
10315
10316	//internal value getter
10317	// _value() returns value trimmed by min and max, aligned by step
10318	_value: function() {
10319		var val = this.options.value;
10320		val = this._trimAlignValue( val );
10321
10322		return val;
10323	},
10324
10325	//internal values getter
10326	// _values() returns array of values trimmed by min and max, aligned by step
10327	// _values( index ) returns single value trimmed by min and max, aligned by step
10328	_values: function( index ) {
10329		var val,
10330			vals,
10331			i;
10332
10333		if ( arguments.length ) {
10334			val = this.options.values[ index ];
10335			val = this._trimAlignValue( val );
10336
10337			return val;
10338		} else {
10339			// .slice() creates a copy of the array
10340			// this copy gets trimmed by min and max and then returned
10341			vals = this.options.values.slice();
10342			for ( i = 0; i < vals.length; i+= 1) {
10343				vals[ i ] = this._trimAlignValue( vals[ i ] );
10344			}
10345
10346			return vals;
10347		}
10348	},
10349
10350	// returns the step-aligned value that val is closest to, between (inclusive) min and max
10351	_trimAlignValue: function( val ) {
10352		if ( val <= this._valueMin() ) {
10353			return this._valueMin();
10354		}
10355		if ( val >= this._valueMax() ) {
10356			return this._valueMax();
10357		}
10358		var step = ( this.options.step > 0 ) ? this.options.step : 1,
10359			valModStep = (val - this._valueMin()) % step,
10360			alignValue = val - valModStep;
10361
10362		if ( Math.abs(valModStep) * 2 >= step ) {
10363			alignValue += ( valModStep > 0 ) ? step : ( -step );
10364		}
10365
10366		// Since JavaScript has problems with large floats, round
10367		// the final value to 5 digits after the decimal point (see #4124)
10368		return parseFloat( alignValue.toFixed(5) );
10369	},
10370
10371	_valueMin: function() {
10372		return this.options.min;
10373	},
10374
10375	_valueMax: function() {
10376		return this.options.max;
10377	},
10378
10379	_refreshValue: function() {
10380		var lastValPercent, valPercent, value, valueMin, valueMax,
10381			oRange = this.options.range,
10382			o = this.options,
10383			that = this,
10384			animate = ( !this._animateOff ) ? o.animate : false,
10385			_set = {};
10386
10387		if ( this.options.values && this.options.values.length ) {
10388			this.handles.each(function( i ) {
10389				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
10390				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10391				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10392				if ( that.options.range === true ) {
10393					if ( that.orientation === "horizontal" ) {
10394						if ( i === 0 ) {
10395							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10396						}
10397						if ( i === 1 ) {
10398							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10399						}
10400					} else {
10401						if ( i === 0 ) {
10402							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10403						}
10404						if ( i === 1 ) {
10405							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10406						}
10407					}
10408				}
10409				lastValPercent = valPercent;
10410			});
10411		} else {
10412			value = this.value();
10413			valueMin = this._valueMin();
10414			valueMax = this._valueMax();
10415			valPercent = ( valueMax !== valueMin ) ?
10416					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10417					0;
10418			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10419			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10420
10421			if ( oRange === "min" && this.orientation === "horizontal" ) {
10422				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10423			}
10424			if ( oRange === "max" && this.orientation === "horizontal" ) {
10425				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10426			}
10427			if ( oRange === "min" && this.orientation === "vertical" ) {
10428				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10429			}
10430			if ( oRange === "max" && this.orientation === "vertical" ) {
10431				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10432			}
10433		}
10434	}
10435
10436});
10437
10438}(jQuery));
10439(function( $ ) {
10440
10441function modifier( fn ) {
10442	return function() {
10443		var previous = this.element.val();
10444		fn.apply( this, arguments );
10445		this._refresh();
10446		if ( previous !== this.element.val() ) {
10447			this._trigger( "change" );
10448		}
10449	};
10450}
10451
10452$.widget( "ui.spinner", {
10453	version: "1.9.2",
10454	defaultElement: "<input>",
10455	widgetEventPrefix: "spin",
10456	options: {
10457		culture: null,
10458		icons: {
10459			down: "ui-icon-triangle-1-s",
10460			up: "ui-icon-triangle-1-n"
10461		},
10462		incremental: true,
10463		max: null,
10464		min: null,
10465		numberFormat: null,
10466		page: 10,
10467		step: 1,
10468
10469		change: null,
10470		spin: null,
10471		start: null,
10472		stop: null
10473	},
10474
10475	_create: function() {
10476		// handle string values that need to be parsed
10477		this._setOption( "max", this.options.max );
10478		this._setOption( "min", this.options.min );
10479		this._setOption( "step", this.options.step );
10480
10481		// format the value, but don't constrain
10482		this._value( this.element.val(), true );
10483
10484		this._draw();
10485		this._on( this._events );
10486		this._refresh();
10487
10488		// turning off autocomplete prevents the browser from remembering the
10489		// value when navigating through history, so we re-enable autocomplete
10490		// if the page is unloaded before the widget is destroyed. #7790
10491		this._on( this.window, {
10492			beforeunload: function() {
10493				this.element.removeAttr( "autocomplete" );
10494			}
10495		});
10496	},
10497
10498	_getCreateOptions: function() {
10499		var options = {},
10500			element = this.element;
10501
10502		$.each( [ "min", "max", "step" ], function( i, option ) {
10503			var value = element.attr( option );
10504			if ( value !== undefined && value.length ) {
10505				options[ option ] = value;
10506			}
10507		});
10508
10509		return options;
10510	},
10511
10512	_events: {
10513		keydown: function( event ) {
10514			if ( this._start( event ) && this._keydown( event ) ) {
10515				event.preventDefault();
10516			}
10517		},
10518		keyup: "_stop",
10519		focus: function() {
10520			this.previous = this.element.val();
10521		},
10522		blur: function( event ) {
10523			if ( this.cancelBlur ) {
10524				delete this.cancelBlur;
10525				return;
10526			}
10527
10528			this._refresh();
10529			if ( this.previous !== this.element.val() ) {
10530				this._trigger( "change", event );
10531			}
10532		},
10533		mousewheel: function( event, delta ) {
10534			if ( !delta ) {
10535				return;
10536			}
10537			if ( !this.spinning && !this._start( event ) ) {
10538				return false;
10539			}
10540
10541			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
10542			clearTimeout( this.mousewheelTimer );
10543			this.mousewheelTimer = this._delay(function() {
10544				if ( this.spinning ) {
10545					this._stop( event );
10546				}
10547			}, 100 );
10548			event.preventDefault();
10549		},
10550		"mousedown .ui-spinner-button": function( event ) {
10551			var previous;
10552
10553			// We never want the buttons to have focus; whenever the user is
10554			// interacting with the spinner, the focus should be on the input.
10555			// If the input is focused then this.previous is properly set from
10556			// when the input first received focus. If the input is not focused
10557			// then we need to set this.previous based on the value before spinning.
10558			previous = this.element[0] === this.document[0].activeElement ?
10559				this.previous : this.element.val();
10560			function checkFocus() {
10561				var isActive = this.element[0] === this.document[0].activeElement;
10562				if ( !isActive ) {
10563					this.element.focus();
10564					this.previous = previous;
10565					// support: IE
10566					// IE sets focus asynchronously, so we need to check if focus
10567					// moved off of the input because the user clicked on the button.
10568					this._delay(function() {
10569						this.previous = previous;
10570					});
10571				}
10572			}
10573
10574			// ensure focus is on (or stays on) the text field
10575			event.preventDefault();
10576			checkFocus.call( this );
10577
10578			// support: IE
10579			// IE doesn't prevent moving focus even with event.preventDefault()
10580			// so we set a flag to know when we should ignore the blur event
10581			// and check (again) if focus moved off of the input.
10582			this.cancelBlur = true;
10583			this._delay(function() {
10584				delete this.cancelBlur;
10585				checkFocus.call( this );
10586			});
10587
10588			if ( this._start( event ) === false ) {
10589				return;
10590			}
10591
10592			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
10593		},
10594		"mouseup .ui-spinner-button": "_stop",
10595		"mouseenter .ui-spinner-button": function( event ) {
10596			// button will add ui-state-active if mouse was down while mouseleave and kept down
10597			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
10598				return;
10599			}
10600
10601			if ( this._start( event ) === false ) {
10602				return false;
10603			}
10604			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
10605		},
10606		// TODO: do we really want to consider this a stop?
10607		// shouldn't we just stop the repeater and wait until mouseup before
10608		// we trigger the stop event?
10609		"mouseleave .ui-spinner-button": "_stop"
10610	},
10611
10612	_draw: function() {
10613		var uiSpinner = this.uiSpinner = this.element
10614			.addClass( "ui-spinner-input" )
10615			.attr( "autocomplete", "off" )
10616			.wrap( this._uiSpinnerHtml() )
10617			.parent()
10618				// add buttons
10619				.append( this._buttonHtml() );
10620
10621		this.element.attr( "role", "spinbutton" );
10622
10623		// button bindings
10624		this.buttons = uiSpinner.find( ".ui-spinner-button" )
10625			.attr( "tabIndex", -1 )
10626			.button()
10627			.removeClass( "ui-corner-all" );
10628
10629		// IE 6 doesn't understand height: 50% for the buttons
10630		// unless the wrapper has an explicit height
10631		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
10632				uiSpinner.height() > 0 ) {
10633			uiSpinner.height( uiSpinner.height() );
10634		}
10635
10636		// disable spinner if element was already disabled
10637		if ( this.options.disabled ) {
10638			this.disable();
10639		}
10640	},
10641
10642	_keydown: function( event ) {
10643		var options = this.options,
10644			keyCode = $.ui.keyCode;
10645
10646		switch ( event.keyCode ) {
10647		case keyCode.UP:
10648			this._repeat( null, 1, event );
10649			return true;
10650		case keyCode.DOWN:
10651			this._repeat( null, -1, event );
10652			return true;
10653		case keyCode.PAGE_UP:
10654			this._repeat( null, options.page, event );
10655			return true;
10656		case keyCode.PAGE_DOWN:
10657			this._repeat( null, -options.page, event );
10658			return true;
10659		}
10660
10661		return false;
10662	},
10663
10664	_uiSpinnerHtml: function() {
10665		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
10666	},
10667
10668	_buttonHtml: function() {
10669		return "" +
10670			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
10671				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
10672			"</a>" +
10673			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
10674				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
10675			"</a>";
10676	},
10677
10678	_start: function( event ) {
10679		if ( !this.spinning && this._trigger( "start", event ) === false ) {
10680			return false;
10681		}
10682
10683		if ( !this.counter ) {
10684			this.counter = 1;
10685		}
10686		this.spinning = true;
10687		return true;
10688	},
10689
10690	_repeat: function( i, steps, event ) {
10691		i = i || 500;
10692
10693		clearTimeout( this.timer );
10694		this.timer = this._delay(function() {
10695			this._repeat( 40, steps, event );
10696		}, i );
10697
10698		this._spin( steps * this.options.step, event );
10699	},
10700
10701	_spin: function( step, event ) {
10702		var value = this.value() || 0;
10703
10704		if ( !this.counter ) {
10705			this.counter = 1;
10706		}
10707
10708		value = this._adjustValue( value + step * this._increment( this.counter ) );
10709
10710		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
10711			this._value( value );
10712			this.counter++;
10713		}
10714	},
10715
10716	_increment: function( i ) {
10717		var incremental = this.options.incremental;
10718
10719		if ( incremental ) {
10720			return $.isFunction( incremental ) ?
10721				incremental( i ) :
10722				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
10723		}
10724
10725		return 1;
10726	},
10727
10728	_precision: function() {
10729		var precision = this._precisionOf( this.options.step );
10730		if ( this.options.min !== null ) {
10731			precision = Math.max( precision, this._precisionOf( this.options.min ) );
10732		}
10733		return precision;
10734	},
10735
10736	_precisionOf: function( num ) {
10737		var str = num.toString(),
10738			decimal = str.indexOf( "." );
10739		return decimal === -1 ? 0 : str.length - decimal - 1;
10740	},
10741
10742	_adjustValue: function( value ) {
10743		var base, aboveMin,
10744			options = this.options;
10745
10746		// make sure we're at a valid step
10747		// - find out where we are relative to the base (min or 0)
10748		base = options.min !== null ? options.min : 0;
10749		aboveMin = value - base;
10750		// - round to the nearest step
10751		aboveMin = Math.round(aboveMin / options.step) * options.step;
10752		// - rounding is based on 0, so adjust back to our base
10753		value = base + aboveMin;
10754
10755		// fix precision from bad JS floating point math
10756		value = parseFloat( value.toFixed( this._precision() ) );
10757
10758		// clamp the value
10759		if ( options.max !== null && value > options.max) {
10760			return options.max;
10761		}
10762		if ( options.min !== null && value < options.min ) {
10763			return options.min;
10764		}
10765
10766		return value;
10767	},
10768
10769	_stop: function( event ) {
10770		if ( !this.spinning ) {
10771			return;
10772		}
10773
10774		clearTimeout( this.timer );
10775		clearTimeout( this.mousewheelTimer );
10776		this.counter = 0;
10777		this.spinning = false;
10778		this._trigger( "stop", event );
10779	},
10780
10781	_setOption: function( key, value ) {
10782		if ( key === "culture" || key === "numberFormat" ) {
10783			var prevValue = this._parse( this.element.val() );
10784			this.options[ key ] = value;
10785			this.element.val( this._format( prevValue ) );
10786			return;
10787		}
10788
10789		if ( key === "max" || key === "min" || key === "step" ) {
10790			if ( typeof value === "string" ) {
10791				value = this._parse( value );
10792			}
10793		}
10794
10795		this._super( key, value );
10796
10797		if ( key === "disabled" ) {
10798			if ( value ) {
10799				this.element.prop( "disabled", true );
10800				this.buttons.button( "disable" );
10801			} else {
10802				this.element.prop( "disabled", false );
10803				this.buttons.button( "enable" );
10804			}
10805		}
10806	},
10807
10808	_setOptions: modifier(function( options ) {
10809		this._super( options );
10810		this._value( this.element.val() );
10811	}),
10812
10813	_parse: function( val ) {
10814		if ( typeof val === "string" && val !== "" ) {
10815			val = window.Globalize && this.options.numberFormat ?
10816				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
10817		}
10818		return val === "" || isNaN( val ) ? null : val;
10819	},
10820
10821	_format: function( value ) {
10822		if ( value === "" ) {
10823			return "";
10824		}
10825		return window.Globalize && this.options.numberFormat ?
10826			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
10827			value;
10828	},
10829
10830	_refresh: function() {
10831		this.element.attr({
10832			"aria-valuemin": this.options.min,
10833			"aria-valuemax": this.options.max,
10834			// TODO: what should we do with values that can't be parsed?
10835			"aria-valuenow": this._parse( this.element.val() )
10836		});
10837	},
10838
10839	// update the value without triggering change
10840	_value: function( value, allowAny ) {
10841		var parsed;
10842		if ( value !== "" ) {
10843			parsed = this._parse( value );
10844			if ( parsed !== null ) {
10845				if ( !allowAny ) {
10846					parsed = this._adjustValue( parsed );
10847				}
10848				value = this._format( parsed );
10849			}
10850		}
10851		this.element.val( value );
10852		this._refresh();
10853	},
10854
10855	_destroy: function() {
10856		this.element
10857			.removeClass( "ui-spinner-input" )
10858			.prop( "disabled", false )
10859			.removeAttr( "autocomplete" )
10860			.removeAttr( "role" )
10861			.removeAttr( "aria-valuemin" )
10862			.removeAttr( "aria-valuemax" )
10863			.removeAttr( "aria-valuenow" );
10864		this.uiSpinner.replaceWith( this.element );
10865	},
10866
10867	stepUp: modifier(function( steps ) {
10868		this._stepUp( steps );
10869	}),
10870	_stepUp: function( steps ) {
10871		this._spin( (steps || 1) * this.options.step );
10872	},
10873
10874	stepDown: modifier(function( steps ) {
10875		this._stepDown( steps );
10876	}),
10877	_stepDown: function( steps ) {
10878		this._spin( (steps || 1) * -this.options.step );
10879	},
10880
10881	pageUp: modifier(function( pages ) {
10882		this._stepUp( (pages || 1) * this.options.page );
10883	}),
10884
10885	pageDown: modifier(function( pages ) {
10886		this._stepDown( (pages || 1) * this.options.page );
10887	}),
10888
10889	value: function( newVal ) {
10890		if ( !arguments.length ) {
10891			return this._parse( this.element.val() );
10892		}
10893		modifier( this._value ).call( this, newVal );
10894	},
10895
10896	widget: function() {
10897		return this.uiSpinner;
10898	}
10899});
10900
10901}( jQuery ) );
10902(function( $, undefined ) {
10903
10904var tabId = 0,
10905	rhash = /#.*$/;
10906
10907function getNextTabId() {
10908	return ++tabId;
10909}
10910
10911function isLocal( anchor ) {
10912	return anchor.hash.length > 1 &&
10913		anchor.href.replace( rhash, "" ) ===
10914			location.href.replace( rhash, "" )
10915				// support: Safari 5.1
10916				// Safari 5.1 doesn't encode spaces in window.location
10917				// but it does encode spaces from anchors (#8777)
10918				.replace( /\s/g, "%20" );
10919}
10920
10921$.widget( "ui.tabs", {
10922	version: "1.9.2",
10923	delay: 300,
10924	options: {
10925		active: null,
10926		collapsible: false,
10927		event: "click",
10928		heightStyle: "content",
10929		hide: null,
10930		show: null,
10931
10932		// callbacks
10933		activate: null,
10934		beforeActivate: null,
10935		beforeLoad: null,
10936		load: null
10937	},
10938
10939	_create: function() {
10940		var that = this,
10941			options = this.options,
10942			active = options.active,
10943			locationHash = location.hash.substring( 1 );
10944
10945		this.running = false;
10946
10947		this.element
10948			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
10949			.toggleClass( "ui-tabs-collapsible", options.collapsible )
10950			// Prevent users from focusing disabled tabs via click
10951			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
10952				if ( $( this ).is( ".ui-state-disabled" ) ) {
10953					event.preventDefault();
10954				}
10955			})
10956			// support: IE <9
10957			// Preventing the default action in mousedown doesn't prevent IE
10958			// from focusing the element, so if the anchor gets focused, blur.
10959			// We don't have to worry about focusing the previously focused
10960			// element since clicking on a non-focusable element should focus
10961			// the body anyway.
10962			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
10963				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
10964					this.blur();
10965				}
10966			});
10967
10968		this._processTabs();
10969
10970		if ( active === null ) {
10971			// check the fragment identifier in the URL
10972			if ( locationHash ) {
10973				this.tabs.each(function( i, tab ) {
10974					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
10975						active = i;
10976						return false;
10977					}
10978				});
10979			}
10980
10981			// check for a tab marked active via a class
10982			if ( active === null ) {
10983				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
10984			}
10985
10986			// no active tab, set to false
10987			if ( active === null || active === -1 ) {
10988				active = this.tabs.length ? 0 : false;
10989			}
10990		}
10991
10992		// handle numbers: negative, out of range
10993		if ( active !== false ) {
10994			active = this.tabs.index( this.tabs.eq( active ) );
10995			if ( active === -1 ) {
10996				active = options.collapsible ? false : 0;
10997			}
10998		}
10999		options.active = active;
11000
11001		// don't allow collapsible: false and active: false
11002		if ( !options.collapsible && options.active === false && this.anchors.length ) {
11003			options.active = 0;
11004		}
11005
11006		// Take disabling tabs via class attribute from HTML
11007		// into account and update option properly.
11008		if ( $.isArray( options.disabled ) ) {
11009			options.disabled = $.unique( options.disabled.concat(
11010				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
11011					return that.tabs.index( li );
11012				})
11013			) ).sort();
11014		}
11015
11016		// check for length avoids error when initializing empty list
11017		if ( this.options.active !== false && this.anchors.length ) {
11018			this.active = this._findActive( this.options.active );
11019		} else {
11020			this.active = $();
11021		}
11022
11023		this._refresh();
11024
11025		if ( this.active.length ) {
11026			this.load( options.active );
11027		}
11028	},
11029
11030	_getCreateEventData: function() {
11031		return {
11032			tab: this.active,
11033			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
11034		};
11035	},
11036
11037	_tabKeydown: function( event ) {
11038		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
11039			selectedIndex = this.tabs.index( focusedTab ),
11040			goingForward = true;
11041
11042		if ( this._handlePageNav( event ) ) {
11043			return;
11044		}
11045
11046		switch ( event.keyCode ) {
11047			case $.ui.keyCode.RIGHT:
11048			case $.ui.keyCode.DOWN:
11049				selectedIndex++;
11050				break;
11051			case $.ui.keyCode.UP:
11052			case $.ui.keyCode.LEFT:
11053				goingForward = false;
11054				selectedIndex--;
11055				break;
11056			case $.ui.keyCode.END:
11057				selectedIndex = this.anchors.length - 1;
11058				break;
11059			case $.ui.keyCode.HOME:
11060				selectedIndex = 0;
11061				break;
11062			case $.ui.keyCode.SPACE:
11063				// Activate only, no collapsing
11064				event.preventDefault();
11065				clearTimeout( this.activating );
11066				this._activate( selectedIndex );
11067				return;
11068			case $.ui.keyCode.ENTER:
11069				// Toggle (cancel delayed activation, allow collapsing)
11070				event.preventDefault();
11071				clearTimeout( this.activating );
11072				// Determine if we should collapse or activate
11073				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
11074				return;
11075			default:
11076				return;
11077		}
11078
11079		// Focus the appropriate tab, based on which key was pressed
11080		event.preventDefault();
11081		clearTimeout( this.activating );
11082		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
11083
11084		// Navigating with control key will prevent automatic activation
11085		if ( !event.ctrlKey ) {
11086			// Update aria-selected immediately so that AT think the tab is already selected.
11087			// Otherwise AT may confuse the user by stating that they need to activate the tab,
11088			// but the tab will already be activated by the time the announcement finishes.
11089			focusedTab.attr( "aria-selected", "false" );
11090			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
11091
11092			this.activating = this._delay(function() {
11093				this.option( "active", selectedIndex );
11094			}, this.delay );
11095		}
11096	},
11097
11098	_panelKeydown: function( event ) {
11099		if ( this._handlePageNav( event ) ) {
11100			return;
11101		}
11102
11103		// Ctrl+up moves focus to the current tab
11104		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
11105			event.preventDefault();
11106			this.active.focus();
11107		}
11108	},
11109
11110	// Alt+page up/down moves focus to the previous/next tab (and activates)
11111	_handlePageNav: function( event ) {
11112		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
11113			this._activate( this._focusNextTab( this.options.active - 1, false ) );
11114			return true;
11115		}
11116		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
11117			this._activate( this._focusNextTab( this.options.active + 1, true ) );
11118			return true;
11119		}
11120	},
11121
11122	_findNextTab: function( index, goingForward ) {
11123		var lastTabIndex = this.tabs.length - 1;
11124
11125		function constrain() {
11126			if ( index > lastTabIndex ) {
11127				index = 0;
11128			}
11129			if ( index < 0 ) {
11130				index = lastTabIndex;
11131			}
11132			return index;
11133		}
11134
11135		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
11136			index = goingForward ? index + 1 : index - 1;
11137		}
11138
11139		return index;
11140	},
11141
11142	_focusNextTab: function( index, goingForward ) {
11143		index = this._findNextTab( index, goingForward );
11144		this.tabs.eq( index ).focus();
11145		return index;
11146	},
11147
11148	_setOption: function( key, value ) {
11149		if ( key === "active" ) {
11150			// _activate() will handle invalid values and update this.options
11151			this._activate( value );
11152			return;
11153		}
11154
11155		if ( key === "disabled" ) {
11156			// don't use the widget factory's disabled handling
11157			this._setupDisabled( value );
11158			return;
11159		}
11160
11161		this._super( key, value);
11162
11163		if ( key === "collapsible" ) {
11164			this.element.toggleClass( "ui-tabs-collapsible", value );
11165			// Setting collapsible: false while collapsed; open first panel
11166			if ( !value && this.options.active === false ) {
11167				this._activate( 0 );
11168			}
11169		}
11170
11171		if ( key === "event" ) {
11172			this._setupEvents( value );
11173		}
11174
11175		if ( key === "heightStyle" ) {
11176			this._setupHeightStyle( value );
11177		}
11178	},
11179
11180	_tabId: function( tab ) {
11181		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
11182	},
11183
11184	_sanitizeSelector: function( hash ) {
11185		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
11186	},
11187
11188	refresh: function() {
11189		var options = this.options,
11190			lis = this.tablist.children( ":has(a[href])" );
11191
11192		// get disabled tabs from class attribute from HTML
11193		// this will get converted to a boolean if needed in _refresh()
11194		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
11195			return lis.index( tab );
11196		});
11197
11198		this._processTabs();
11199
11200		// was collapsed or no tabs
11201		if ( options.active === false || !this.anchors.length ) {
11202			options.active = false;
11203			this.active = $();
11204		// was active, but active tab is gone
11205		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
11206			// all remaining tabs are disabled
11207			if ( this.tabs.length === options.disabled.length ) {
11208				options.active = false;
11209				this.active = $();
11210			// activate previous tab
11211			} else {
11212				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
11213			}
11214		// was active, active tab still exists
11215		} else {
11216			// make sure active index is correct
11217			options.active = this.tabs.index( this.active );
11218		}
11219
11220		this._refresh();
11221	},
11222
11223	_refresh: function() {
11224		this._setupDisabled( this.options.disabled );
11225		this._setupEvents( this.options.event );
11226		this._setupHeightStyle( this.options.heightStyle );
11227
11228		this.tabs.not( this.active ).attr({
11229			"aria-selected": "false",
11230			tabIndex: -1
11231		});
11232		this.panels.not( this._getPanelForTab( this.active ) )
11233			.hide()
11234			.attr({
11235				"aria-expanded": "false",
11236				"aria-hidden": "true"
11237			});
11238
11239		// Make sure one tab is in the tab order
11240		if ( !this.active.length ) {
11241			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
11242		} else {
11243			this.active
11244				.addClass( "ui-tabs-active ui-state-active" )
11245				.attr({
11246					"aria-selected": "true",
11247					tabIndex: 0
11248				});
11249			this._getPanelForTab( this.active )
11250				.show()
11251				.attr({
11252					"aria-expanded": "true",
11253					"aria-hidden": "false"
11254				});
11255		}
11256	},
11257
11258	_processTabs: function() {
11259		var that = this;
11260
11261		this.tablist = this._getList()
11262			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11263			.attr( "role", "tablist" );
11264
11265		this.tabs = this.tablist.find( "> li:has(a[href])" )
11266			.addClass( "ui-state-default ui-corner-top" )
11267			.attr({
11268				role: "tab",
11269				tabIndex: -1
11270			});
11271
11272		this.anchors = this.tabs.map(function() {
11273				return $( "a", this )[ 0 ];
11274			})
11275			.addClass( "ui-tabs-anchor" )
11276			.attr({
11277				role: "presentation",
11278				tabIndex: -1
11279			});
11280
11281		this.panels = $();
11282
11283		this.anchors.each(function( i, anchor ) {
11284			var selector, panel, panelId,
11285				anchorId = $( anchor ).uniqueId().attr( "id" ),
11286				tab = $( anchor ).closest( "li" ),
11287				originalAriaControls = tab.attr( "aria-controls" );
11288
11289			// inline tab
11290			if ( isLocal( anchor ) ) {
11291				selector = anchor.hash;
11292				panel = that.element.find( that._sanitizeSelector( selector ) );
11293			// remote tab
11294			} else {
11295				panelId = that._tabId( tab );
11296				selector = "#" + panelId;
11297				panel = that.element.find( selector );
11298				if ( !panel.length ) {
11299					panel = that._createPanel( panelId );
11300					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
11301				}
11302				panel.attr( "aria-live", "polite" );
11303			}
11304
11305			if ( panel.length) {
11306				that.panels = that.panels.add( panel );
11307			}
11308			if ( originalAriaControls ) {
11309				tab.data( "ui-tabs-aria-controls", originalAriaControls );
11310			}
11311			tab.attr({
11312				"aria-controls": selector.substring( 1 ),
11313				"aria-labelledby": anchorId
11314			});
11315			panel.attr( "aria-labelledby", anchorId );
11316		});
11317
11318		this.panels
11319			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11320			.attr( "role", "tabpanel" );
11321	},
11322
11323	// allow overriding how to find the list for rare usage scenarios (#7715)
11324	_getList: function() {
11325		return this.element.find( "ol,ul" ).eq( 0 );
11326	},
11327
11328	_createPanel: function( id ) {
11329		return $( "<div>" )
11330			.attr( "id", id )
11331			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11332			.data( "ui-tabs-destroy", true );
11333	},
11334
11335	_setupDisabled: function( disabled ) {
11336		if ( $.isArray( disabled ) ) {
11337			if ( !disabled.length ) {
11338				disabled = false;
11339			} else if ( disabled.length === this.anchors.length ) {
11340				disabled = true;
11341			}
11342		}
11343
11344		// disable tabs
11345		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
11346			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
11347				$( li )
11348					.addClass( "ui-state-disabled" )
11349					.attr( "aria-disabled", "true" );
11350			} else {
11351				$( li )
11352					.removeClass( "ui-state-disabled" )
11353					.removeAttr( "aria-disabled" );
11354			}
11355		}
11356
11357		this.options.disabled = disabled;
11358	},
11359
11360	_setupEvents: function( event ) {
11361		var events = {
11362			click: function( event ) {
11363				event.preventDefault();
11364			}
11365		};
11366		if ( event ) {
11367			$.each( event.split(" "), function( index, eventName ) {
11368				events[ eventName ] = "_eventHandler";
11369			});
11370		}
11371
11372		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
11373		this._on( this.anchors, events );
11374		this._on( this.tabs, { keydown: "_tabKeydown" } );
11375		this._on( this.panels, { keydown: "_panelKeydown" } );
11376
11377		this._focusable( this.tabs );
11378		this._hoverable( this.tabs );
11379	},
11380
11381	_setupHeightStyle: function( heightStyle ) {
11382		var maxHeight, overflow,
11383			parent = this.element.parent();
11384
11385		if ( heightStyle === "fill" ) {
11386			// IE 6 treats height like minHeight, so we need to turn off overflow
11387			// in order to get a reliable height
11388			// we use the minHeight support test because we assume that only
11389			// browsers that don't support minHeight will treat height as minHeight
11390			if ( !$.support.minHeight ) {
11391				overflow = parent.css( "overflow" );
11392				parent.css( "overflow", "hidden");
11393			}
11394			maxHeight = parent.height();
11395			this.element.siblings( ":visible" ).each(function() {
11396				var elem = $( this ),
11397					position = elem.css( "position" );
11398
11399				if ( position === "absolute" || position === "fixed" ) {
11400					return;
11401				}
11402				maxHeight -= elem.outerHeight( true );
11403			});
11404			if ( overflow ) {
11405				parent.css( "overflow", overflow );
11406			}
11407
11408			this.element.children().not( this.panels ).each(function() {
11409				maxHeight -= $( this ).outerHeight( true );
11410			});
11411
11412			this.panels.each(function() {
11413				$( this ).height( Math.max( 0, maxHeight -
11414					$( this ).innerHeight() + $( this ).height() ) );
11415			})
11416			.css( "overflow", "auto" );
11417		} else if ( heightStyle === "auto" ) {
11418			maxHeight = 0;
11419			this.panels.each(function() {
11420				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
11421			}).height( maxHeight );
11422		}
11423	},
11424
11425	_eventHandler: function( event ) {
11426		var options = this.options,
11427			active = this.active,
11428			anchor = $( event.currentTarget ),
11429			tab = anchor.closest( "li" ),
11430			clickedIsActive = tab[ 0 ] === active[ 0 ],
11431			collapsing = clickedIsActive && options.collapsible,
11432			toShow = collapsing ? $() : this._getPanelForTab( tab ),
11433			toHide = !active.length ? $() : this._getPanelForTab( active ),
11434			eventData = {
11435				oldTab: active,
11436				oldPanel: toHide,
11437				newTab: collapsing ? $() : tab,
11438				newPanel: toShow
11439			};
11440
11441		event.preventDefault();
11442
11443		if ( tab.hasClass( "ui-state-disabled" ) ||
11444				// tab is already loading
11445				tab.hasClass( "ui-tabs-loading" ) ||
11446				// can't switch durning an animation
11447				this.running ||
11448				// click on active header, but not collapsible
11449				( clickedIsActive && !options.collapsible ) ||
11450				// allow canceling activation
11451				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
11452			return;
11453		}
11454
11455		options.active = collapsing ? false : this.tabs.index( tab );
11456
11457		this.active = clickedIsActive ? $() : tab;
11458		if ( this.xhr ) {
11459			this.xhr.abort();
11460		}
11461
11462		if ( !toHide.length && !toShow.length ) {
11463			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
11464		}
11465
11466		if ( toShow.length ) {
11467			this.load( this.tabs.index( tab ), event );
11468		}
11469		this._toggle( event, eventData );
11470	},
11471
11472	// handles show/hide for selecting tabs
11473	_toggle: function( event, eventData ) {
11474		var that = this,
11475			toShow = eventData.newPanel,
11476			toHide = eventData.oldPanel;
11477
11478		this.running = true;
11479
11480		function complete() {
11481			that.running = false;
11482			that._trigger( "activate", event, eventData );
11483		}
11484
11485		function show() {
11486			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
11487
11488			if ( toShow.length && that.options.show ) {
11489				that._show( toShow, that.options.show, complete );
11490			} else {
11491				toShow.show();
11492				complete();
11493			}
11494		}
11495
11496		// start out by hiding, then showing, then completing
11497		if ( toHide.length && this.options.hide ) {
11498			this._hide( toHide, this.options.hide, function() {
11499				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
11500				show();
11501			});
11502		} else {
11503			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
11504			toHide.hide();
11505			show();
11506		}
11507
11508		toHide.attr({
11509			"aria-expanded": "false",
11510			"aria-hidden": "true"
11511		});
11512		eventData.oldTab.attr( "aria-selected", "false" );
11513		// If we're switching tabs, remove the old tab from the tab order.
11514		// If we're opening from collapsed state, remove the previous tab from the tab order.
11515		// If we're collapsing, then keep the collapsing tab in the tab order.
11516		if ( toShow.length && toHide.length ) {
11517			eventData.oldTab.attr( "tabIndex", -1 );
11518		} else if ( toShow.length ) {
11519			this.tabs.filter(function() {
11520				return $( this ).attr( "tabIndex" ) === 0;
11521			})
11522			.attr( "tabIndex", -1 );
11523		}
11524
11525		toShow.attr({
11526			"aria-expanded": "true",
11527			"aria-hidden": "false"
11528		});
11529		eventData.newTab.attr({
11530			"aria-selected": "true",
11531			tabIndex: 0
11532		});
11533	},
11534
11535	_activate: function( index ) {
11536		var anchor,
11537			active = this._findActive( index );
11538
11539		// trying to activate the already active panel
11540		if ( active[ 0 ] === this.active[ 0 ] ) {
11541			return;
11542		}
11543
11544		// trying to collapse, simulate a click on the current active header
11545		if ( !active.length ) {
11546			active = this.active;
11547		}
11548
11549		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
11550		this._eventHandler({
11551			target: anchor,
11552			currentTarget: anchor,
11553			preventDefault: $.noop
11554		});
11555	},
11556
11557	_findActive: function( index ) {
11558		return index === false ? $() : this.tabs.eq( index );
11559	},
11560
11561	_getIndex: function( index ) {
11562		// meta-function to give users option to provide a href string instead of a numerical index.
11563		if ( typeof index === "string" ) {
11564			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
11565		}
11566
11567		return index;
11568	},
11569
11570	_destroy: function() {
11571		if ( this.xhr ) {
11572			this.xhr.abort();
11573		}
11574
11575		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
11576
11577		this.tablist
11578			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11579			.removeAttr( "role" );
11580
11581		this.anchors
11582			.removeClass( "ui-tabs-anchor" )
11583			.removeAttr( "role" )
11584			.removeAttr( "tabIndex" )
11585			.removeData( "href.tabs" )
11586			.removeData( "load.tabs" )
11587			.removeUniqueId();
11588
11589		this.tabs.add( this.panels ).each(function() {
11590			if ( $.data( this, "ui-tabs-destroy" ) ) {
11591				$( this ).remove();
11592			} else {
11593				$( this )
11594					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
11595						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
11596					.removeAttr( "tabIndex" )
11597					.removeAttr( "aria-live" )
11598					.removeAttr( "aria-busy" )
11599					.removeAttr( "aria-selected" )
11600					.removeAttr( "aria-labelledby" )
11601					.removeAttr( "aria-hidden" )
11602					.removeAttr( "aria-expanded" )
11603					.removeAttr( "role" );
11604			}
11605		});
11606
11607		this.tabs.each(function() {
11608			var li = $( this ),
11609				prev = li.data( "ui-tabs-aria-controls" );
11610			if ( prev ) {
11611				li.attr( "aria-controls", prev );
11612			} else {
11613				li.removeAttr( "aria-controls" );
11614			}
11615		});
11616
11617		this.panels.show();
11618
11619		if ( this.options.heightStyle !== "content" ) {
11620			this.panels.css( "height", "" );
11621		}
11622	},
11623
11624	enable: function( index ) {
11625		var disabled = this.options.disabled;
11626		if ( disabled === false ) {
11627			return;
11628		}
11629
11630		if ( index === undefined ) {
11631			disabled = false;
11632		} else {
11633			index = this._getIndex( index );
11634			if ( $.isArray( disabled ) ) {
11635				disabled = $.map( disabled, function( num ) {
11636					return num !== index ? num : null;
11637				});
11638			} else {
11639				disabled = $.map( this.tabs, function( li, num ) {
11640					return num !== index ? num : null;
11641				});
11642			}
11643		}
11644		this._setupDisabled( disabled );
11645	},
11646
11647	disable: function( index ) {
11648		var disabled = this.options.disabled;
11649		if ( disabled === true ) {
11650			return;
11651		}
11652
11653		if ( index === undefined ) {
11654			disabled = true;
11655		} else {
11656			index = this._getIndex( index );
11657			if ( $.inArray( index, disabled ) !== -1 ) {
11658				return;
11659			}
11660			if ( $.isArray( disabled ) ) {
11661				disabled = $.merge( [ index ], disabled ).sort();
11662			} else {
11663				disabled = [ index ];
11664			}
11665		}
11666		this._setupDisabled( disabled );
11667	},
11668
11669	load: function( index, event ) {
11670		index = this._getIndex( index );
11671		var that = this,
11672			tab = this.tabs.eq( index ),
11673			anchor = tab.find( ".ui-tabs-anchor" ),
11674			panel = this._getPanelForTab( tab ),
11675			eventData = {
11676				tab: tab,
11677				panel: panel
11678			};
11679
11680		// not remote
11681		if ( isLocal( anchor[ 0 ] ) ) {
11682			return;
11683		}
11684
11685		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
11686
11687		// support: jQuery <1.8
11688		// jQuery <1.8 returns false if the request is canceled in beforeSend,
11689		// but as of 1.8, $.ajax() always returns a jqXHR object.
11690		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
11691			tab.addClass( "ui-tabs-loading" );
11692			panel.attr( "aria-busy", "true" );
11693
11694			this.xhr
11695				.success(function( response ) {
11696					// support: jQuery <1.8
11697					// http://bugs.jquery.com/ticket/11778
11698					setTimeout(function() {
11699						panel.html( response );
11700						that._trigger( "load", event, eventData );
11701					}, 1 );
11702				})
11703				.complete(function( jqXHR, status ) {
11704					// support: jQuery <1.8
11705					// http://bugs.jquery.com/ticket/11778
11706					setTimeout(function() {
11707						if ( status === "abort" ) {
11708							that.panels.stop( false, true );
11709						}
11710
11711						tab.removeClass( "ui-tabs-loading" );
11712						panel.removeAttr( "aria-busy" );
11713
11714						if ( jqXHR === that.xhr ) {
11715							delete that.xhr;
11716						}
11717					}, 1 );
11718				});
11719		}
11720	},
11721
11722	// TODO: Remove this function in 1.10 when ajaxOptions is removed
11723	_ajaxSettings: function( anchor, event, eventData ) {
11724		var that = this;
11725		return {
11726			url: anchor.attr( "href" ),
11727			beforeSend: function( jqXHR, settings ) {
11728				return that._trigger( "beforeLoad", event,
11729					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
11730			}
11731		};
11732	},
11733
11734	_getPanelForTab: function( tab ) {
11735		var id = $( tab ).attr( "aria-controls" );
11736		return this.element.find( this._sanitizeSelector( "#" + id ) );
11737	}
11738});
11739
11740// DEPRECATED
11741if ( $.uiBackCompat !== false ) {
11742
11743	// helper method for a lot of the back compat extensions
11744	$.ui.tabs.prototype._ui = function( tab, panel ) {
11745		return {
11746			tab: tab,
11747			panel: panel,
11748			index: this.anchors.index( tab )
11749		};
11750	};
11751
11752	// url method
11753	$.widget( "ui.tabs", $.ui.tabs, {
11754		url: function( index, url ) {
11755			this.anchors.eq( index ).attr( "href", url );
11756		}
11757	});
11758
11759	// TODO: Remove _ajaxSettings() method when removing this extension
11760	// ajaxOptions and cache options
11761	$.widget( "ui.tabs", $.ui.tabs, {
11762		options: {
11763			ajaxOptions: null,
11764			cache: false
11765		},
11766
11767		_create: function() {
11768			this._super();
11769
11770			var that = this;
11771
11772			this._on({ tabsbeforeload: function( event, ui ) {
11773				// tab is already cached
11774				if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
11775					event.preventDefault();
11776					return;
11777				}
11778
11779				ui.jqXHR.success(function() {
11780					if ( that.options.cache ) {
11781						$.data( ui.tab[ 0 ], "cache.tabs", true );
11782					}
11783				});
11784			}});
11785		},
11786
11787		_ajaxSettings: function( anchor, event, ui ) {
11788			var ajaxOptions = this.options.ajaxOptions;
11789			return $.extend( {}, ajaxOptions, {
11790				error: function( xhr, status ) {
11791					try {
11792						// Passing index avoid a race condition when this method is
11793						// called after the user has selected another tab.
11794						// Pass the anchor that initiated this request allows
11795						// loadError to manipulate the tab content panel via $(a.hash)
11796						ajaxOptions.error(
11797							xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
11798					}
11799					catch ( error ) {}
11800				}
11801			}, this._superApply( arguments ) );
11802		},
11803
11804		_setOption: function( key, value ) {
11805			// reset cache if switching from cached to not cached
11806			if ( key === "cache" && value === false ) {
11807				this.anchors.removeData( "cache.tabs" );
11808			}
11809			this._super( key, value );
11810		},
11811
11812		_destroy: function() {
11813			this.anchors.removeData( "cache.tabs" );
11814			this._super();
11815		},
11816
11817		url: function( index ){
11818			this.anchors.eq( index ).removeData( "cache.tabs" );
11819			this._superApply( arguments );
11820		}
11821	});
11822
11823	// abort method
11824	$.widget( "ui.tabs", $.ui.tabs, {
11825		abort: function() {
11826			if ( this.xhr ) {
11827				this.xhr.abort();
11828			}
11829		}
11830	});
11831
11832	// spinner
11833	$.widget( "ui.tabs", $.ui.tabs, {
11834		options: {
11835			spinner: "<em>Loading&#8230;</em>"
11836		},
11837		_create: function() {
11838			this._super();
11839			this._on({
11840				tabsbeforeload: function( event, ui ) {
11841					// Don't react to nested tabs or tabs that don't use a spinner
11842					if ( event.target !== this.element[ 0 ] ||
11843							!this.options.spinner ) {
11844						return;
11845					}
11846
11847					var span = ui.tab.find( "span" ),
11848						html = span.html();
11849					span.html( this.options.spinner );
11850					ui.jqXHR.complete(function() {
11851						span.html( html );
11852					});
11853				}
11854			});
11855		}
11856	});
11857
11858	// enable/disable events
11859	$.widget( "ui.tabs", $.ui.tabs, {
11860		options: {
11861			enable: null,
11862			disable: null
11863		},
11864
11865		enable: function( index ) {
11866			var options = this.options,
11867				trigger;
11868
11869			if ( index && options.disabled === true ||
11870					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
11871				trigger = true;
11872			}
11873
11874			this._superApply( arguments );
11875
11876			if ( trigger ) {
11877				this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11878			}
11879		},
11880
11881		disable: function( index ) {
11882			var options = this.options,
11883				trigger;
11884
11885			if ( index && options.disabled === false ||
11886					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
11887				trigger = true;
11888			}
11889
11890			this._superApply( arguments );
11891
11892			if ( trigger ) {
11893				this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11894			}
11895		}
11896	});
11897
11898	// add/remove methods and events
11899	$.widget( "ui.tabs", $.ui.tabs, {
11900		options: {
11901			add: null,
11902			remove: null,
11903			tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
11904		},
11905
11906		add: function( url, label, index ) {
11907			if ( index === undefined ) {
11908				index = this.anchors.length;
11909			}
11910
11911			var doInsertAfter, panel,
11912				options = this.options,
11913				li = $( options.tabTemplate
11914					.replace( /#\{href\}/g, url )
11915					.replace( /#\{label\}/g, label ) ),
11916				id = !url.indexOf( "#" ) ?
11917					url.replace( "#", "" ) :
11918					this._tabId( li );
11919
11920			li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
11921			li.attr( "aria-controls", id );
11922
11923			doInsertAfter = index >= this.tabs.length;
11924
11925			// try to find an existing element before creating a new one
11926			panel = this.element.find( "#" + id );
11927			if ( !panel.length ) {
11928				panel = this._createPanel( id );
11929				if ( doInsertAfter ) {
11930					if ( index > 0 ) {
11931						panel.insertAfter( this.panels.eq( -1 ) );
11932					} else {
11933						panel.appendTo( this.element );
11934					}
11935				} else {
11936					panel.insertBefore( this.panels[ index ] );
11937				}
11938			}
11939			panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
11940
11941			if ( doInsertAfter ) {
11942				li.appendTo( this.tablist );
11943			} else {
11944				li.insertBefore( this.tabs[ index ] );
11945			}
11946
11947			options.disabled = $.map( options.disabled, function( n ) {
11948				return n >= index ? ++n : n;
11949			});
11950
11951			this.refresh();
11952			if ( this.tabs.length === 1 && options.active === false ) {
11953				this.option( "active", 0 );
11954			}
11955
11956			this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11957			return this;
11958		},
11959
11960		remove: function( index ) {
11961			index = this._getIndex( index );
11962			var options = this.options,
11963				tab = this.tabs.eq( index ).remove(),
11964				panel = this._getPanelForTab( tab ).remove();
11965
11966			// If selected tab was removed focus tab to the right or
11967			// in case the last tab was removed the tab to the left.
11968			// We check for more than 2 tabs, because if there are only 2,
11969			// then when we remove this tab, there will only be one tab left
11970			// so we don't need to detect which tab to activate.
11971			if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
11972				this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
11973			}
11974
11975			options.disabled = $.map(
11976				$.grep( options.disabled, function( n ) {
11977					return n !== index;
11978				}),
11979				function( n ) {
11980					return n >= index ? --n : n;
11981				});
11982
11983			this.refresh();
11984
11985			this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
11986			return this;
11987		}
11988	});
11989
11990	// length method
11991	$.widget( "ui.tabs", $.ui.tabs, {
11992		length: function() {
11993			return this.anchors.length;
11994		}
11995	});
11996
11997	// panel ids (idPrefix option + title attribute)
11998	$.widget( "ui.tabs", $.ui.tabs, {
11999		options: {
12000			idPrefix: "ui-tabs-"
12001		},
12002
12003		_tabId: function( tab ) {
12004			var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
12005			a = a[0];
12006			return $( a ).closest( "li" ).attr( "aria-controls" ) ||
12007				a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
12008				this.options.idPrefix + getNextTabId();
12009		}
12010	});
12011
12012	// _createPanel method
12013	$.widget( "ui.tabs", $.ui.tabs, {
12014		options: {
12015			panelTemplate: "<div></div>"
12016		},
12017
12018		_createPanel: function( id ) {
12019			return $( this.options.panelTemplate )
12020				.attr( "id", id )
12021				.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
12022				.data( "ui-tabs-destroy", true );
12023		}
12024	});
12025
12026	// selected option
12027	$.widget( "ui.tabs", $.ui.tabs, {
12028		_create: function() {
12029			var options = this.options;
12030			if ( options.active === null && options.selected !== undefined ) {
12031				options.active = options.selected === -1 ? false : options.selected;
12032			}
12033			this._super();
12034			options.selected = options.active;
12035			if ( options.selected === false ) {
12036				options.selected = -1;
12037			}
12038		},
12039
12040		_setOption: function( key, value ) {
12041			if ( key !== "selected" ) {
12042				return this._super( key, value );
12043			}
12044
12045			var options = this.options;
12046			this._super( "active", value === -1 ? false : value );
12047			options.selected = options.active;
12048			if ( options.selected === false ) {
12049				options.selected = -1;
12050			}
12051		},
12052
12053		_eventHandler: function() {
12054			this._superApply( arguments );
12055			this.options.selected = this.options.active;
12056			if ( this.options.selected === false ) {
12057				this.options.selected = -1;
12058			}
12059		}
12060	});
12061
12062	// show and select event
12063	$.widget( "ui.tabs", $.ui.tabs, {
12064		options: {
12065			show: null,
12066			select: null
12067		},
12068		_create: function() {
12069			this._super();
12070			if ( this.options.active !== false ) {
12071				this._trigger( "show", null, this._ui(
12072					this.active.find( ".ui-tabs-anchor" )[ 0 ],
12073					this._getPanelForTab( this.active )[ 0 ] ) );
12074			}
12075		},
12076		_trigger: function( type, event, data ) {
12077			var tab, panel,
12078				ret = this._superApply( arguments );
12079
12080			if ( !ret ) {
12081				return false;
12082			}
12083
12084			if ( type === "beforeActivate" ) {
12085				tab = data.newTab.length ? data.newTab : data.oldTab;
12086				panel = data.newPanel.length ? data.newPanel : data.oldPanel;
12087				ret = this._super( "select", event, {
12088					tab: tab.find( ".ui-tabs-anchor" )[ 0],
12089					panel: panel[ 0 ],
12090					index: tab.closest( "li" ).index()
12091				});
12092			} else if ( type === "activate" && data.newTab.length ) {
12093				ret = this._super( "show", event, {
12094					tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
12095					panel: data.newPanel[ 0 ],
12096					index: data.newTab.closest( "li" ).index()
12097				});
12098			}
12099			return ret;
12100		}
12101	});
12102
12103	// select method
12104	$.widget( "ui.tabs", $.ui.tabs, {
12105		select: function( index ) {
12106			index = this._getIndex( index );
12107			if ( index === -1 ) {
12108				if ( this.options.collapsible && this.options.selected !== -1 ) {
12109					index = this.options.selected;
12110				} else {
12111					return;
12112				}
12113			}
12114			this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
12115		}
12116	});
12117
12118	// cookie option
12119	(function() {
12120
12121	var listId = 0;
12122
12123	$.widget( "ui.tabs", $.ui.tabs, {
12124		options: {
12125			cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
12126		},
12127		_create: function() {
12128			var options = this.options,
12129				active;
12130			if ( options.active == null && options.cookie ) {
12131				active = parseInt( this._cookie(), 10 );
12132				if ( active === -1 ) {
12133					active = false;
12134				}
12135				options.active = active;
12136			}
12137			this._super();
12138		},
12139		_cookie: function( active ) {
12140			var cookie = [ this.cookie ||
12141				( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
12142			if ( arguments.length ) {
12143				cookie.push( active === false ? -1 : active );
12144				cookie.push( this.options.cookie );
12145			}
12146			return $.cookie.apply( null, cookie );
12147		},
12148		_refresh: function() {
12149			this._super();
12150			if ( this.options.cookie ) {
12151				this._cookie( this.options.active, this.options.cookie );
12152			}
12153		},
12154		_eventHandler: function() {
12155			this._superApply( arguments );
12156			if ( this.options.cookie ) {
12157				this._cookie( this.options.active, this.options.cookie );
12158			}
12159		},
12160		_destroy: function() {
12161			this._super();
12162			if ( this.options.cookie ) {
12163				this._cookie( null, this.options.cookie );
12164			}
12165		}
12166	});
12167
12168	})();
12169
12170	// load event
12171	$.widget( "ui.tabs", $.ui.tabs, {
12172		_trigger: function( type, event, data ) {
12173			var _data = $.extend( {}, data );
12174			if ( type === "load" ) {
12175				_data.panel = _data.panel[ 0 ];
12176				_data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
12177			}
12178			return this._super( type, event, _data );
12179		}
12180	});
12181
12182	// fx option
12183	// The new animation options (show, hide) conflict with the old show callback.
12184	// The old fx option wins over show/hide anyway (always favor back-compat).
12185	// If a user wants to use the new animation API, they must give up the old API.
12186	$.widget( "ui.tabs", $.ui.tabs, {
12187		options: {
12188			fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
12189		},
12190
12191		_getFx: function() {
12192			var hide, show,
12193				fx = this.options.fx;
12194
12195			if ( fx ) {
12196				if ( $.isArray( fx ) ) {
12197					hide = fx[ 0 ];
12198					show = fx[ 1 ];
12199				} else {
12200					hide = show = fx;
12201				}
12202			}
12203
12204			return fx ? { show: show, hide: hide } : null;
12205		},
12206
12207		_toggle: function( event, eventData ) {
12208			var that = this,
12209				toShow = eventData.newPanel,
12210				toHide = eventData.oldPanel,
12211				fx = this._getFx();
vendor: 68,909 bytes, lines 12212-14868
12212
12213			if ( !fx ) {
12214				return this._super( event, eventData );
12215			}
12216
12217			that.running = true;
12218
12219			function complete() {
12220				that.running = false;
12221				that._trigger( "activate", event, eventData );
12222			}
12223
12224			function show() {
12225				eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
12226
12227				if ( toShow.length && fx.show ) {
12228					toShow
12229						.animate( fx.show, fx.show.duration, function() {
12230							complete();
12231						});
12232				} else {
12233					toShow.show();
12234					complete();
12235				}
12236			}
12237
12238			// start out by hiding, then showing, then completing
12239			if ( toHide.length && fx.hide ) {
12240				toHide.animate( fx.hide, fx.hide.duration, function() {
12241					eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12242					show();
12243				});
12244			} else {
12245				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12246				toHide.hide();
12247				show();
12248			}
12249		}
12250	});
12251}
12252
12253})( jQuery );
12254(function( $ ) {
12255
12256var increments = 0;
12257
12258function addDescribedBy( elem, id ) {
12259	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
12260	describedby.push( id );
12261	elem
12262		.data( "ui-tooltip-id", id )
12263		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
12264}
12265
12266function removeDescribedBy( elem ) {
12267	var id = elem.data( "ui-tooltip-id" ),
12268		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
12269		index = $.inArray( id, describedby );
12270	if ( index !== -1 ) {
12271		describedby.splice( index, 1 );
12272	}
12273
12274	elem.removeData( "ui-tooltip-id" );
12275	describedby = $.trim( describedby.join( " " ) );
12276	if ( describedby ) {
12277		elem.attr( "aria-describedby", describedby );
12278	} else {
12279		elem.removeAttr( "aria-describedby" );
12280	}
12281}
12282
12283$.widget( "ui.tooltip", {
12284	version: "1.9.2",
12285	options: {
12286		content: function() {
12287			return $( this ).attr( "title" );
12288		},
12289		hide: true,
12290		// Disabled elements have inconsistent behavior across browsers (#8661)
12291		items: "[title]:not([disabled])",
12292		position: {
12293			my: "left top+15",
12294			at: "left bottom",
12295			collision: "flipfit flip"
12296		},
12297		show: true,
12298		tooltipClass: null,
12299		track: false,
12300
12301		// callbacks
12302		close: null,
12303		open: null
12304	},
12305
12306	_create: function() {
12307		this._on({
12308			mouseover: "open",
12309			focusin: "open"
12310		});
12311
12312		// IDs of generated tooltips, needed for destroy
12313		this.tooltips = {};
12314		// IDs of parent tooltips where we removed the title attribute
12315		this.parents = {};
12316
12317		if ( this.options.disabled ) {
12318			this._disable();
12319		}
12320	},
12321
12322	_setOption: function( key, value ) {
12323		var that = this;
12324
12325		if ( key === "disabled" ) {
12326			this[ value ? "_disable" : "_enable" ]();
12327			this.options[ key ] = value;
12328			// disable element style changes
12329			return;
12330		}
12331
12332		this._super( key, value );
12333
12334		if ( key === "content" ) {
12335			$.each( this.tooltips, function( id, element ) {
12336				that._updateContent( element );
12337			});
12338		}
12339	},
12340
12341	_disable: function() {
12342		var that = this;
12343
12344		// close open tooltips
12345		$.each( this.tooltips, function( id, element ) {
12346			var event = $.Event( "blur" );
12347			event.target = event.currentTarget = element[0];
12348			that.close( event, true );
12349		});
12350
12351		// remove title attributes to prevent native tooltips
12352		this.element.find( this.options.items ).andSelf().each(function() {
12353			var element = $( this );
12354			if ( element.is( "[title]" ) ) {
12355				element
12356					.data( "ui-tooltip-title", element.attr( "title" ) )
12357					.attr( "title", "" );
12358			}
12359		});
12360	},
12361
12362	_enable: function() {
12363		// restore title attributes
12364		this.element.find( this.options.items ).andSelf().each(function() {
12365			var element = $( this );
12366			if ( element.data( "ui-tooltip-title" ) ) {
12367				element.attr( "title", element.data( "ui-tooltip-title" ) );
12368			}
12369		});
12370	},
12371
12372	open: function( event ) {
12373		var that = this,
12374			target = $( event ? event.target : this.element )
12375				// we need closest here due to mouseover bubbling,
12376				// but always pointing at the same event target
12377				.closest( this.options.items );
12378
12379		// No element to show a tooltip for or the tooltip is already open
12380		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
12381			return;
12382		}
12383
12384		if ( target.attr( "title" ) ) {
12385			target.data( "ui-tooltip-title", target.attr( "title" ) );
12386		}
12387
12388		target.data( "ui-tooltip-open", true );
12389
12390		// kill parent tooltips, custom or native, for hover
12391		if ( event && event.type === "mouseover" ) {
12392			target.parents().each(function() {
12393				var parent = $( this ),
12394					blurEvent;
12395				if ( parent.data( "ui-tooltip-open" ) ) {
12396					blurEvent = $.Event( "blur" );
12397					blurEvent.target = blurEvent.currentTarget = this;
12398					that.close( blurEvent, true );
12399				}
12400				if ( parent.attr( "title" ) ) {
12401					parent.uniqueId();
12402					that.parents[ this.id ] = {
12403						element: this,
12404						title: parent.attr( "title" )
12405					};
12406					parent.attr( "title", "" );
12407				}
12408			});
12409		}
12410
12411		this._updateContent( target, event );
12412	},
12413
12414	_updateContent: function( target, event ) {
12415		var content,
12416			contentOption = this.options.content,
12417			that = this,
12418			eventType = event ? event.type : null;
12419
12420		if ( typeof contentOption === "string" ) {
12421			return this._open( event, target, contentOption );
12422		}
12423
12424		content = contentOption.call( target[0], function( response ) {
12425			// ignore async response if tooltip was closed already
12426			if ( !target.data( "ui-tooltip-open" ) ) {
12427				return;
12428			}
12429			// IE may instantly serve a cached response for ajax requests
12430			// delay this call to _open so the other call to _open runs first
12431			that._delay(function() {
12432				// jQuery creates a special event for focusin when it doesn't
12433				// exist natively. To improve performance, the native event
12434				// object is reused and the type is changed. Therefore, we can't
12435				// rely on the type being correct after the event finished
12436				// bubbling, so we set it back to the previous value. (#8740)
12437				if ( event ) {
12438					event.type = eventType;
12439				}
12440				this._open( event, target, response );
12441			});
12442		});
12443		if ( content ) {
12444			this._open( event, target, content );
12445		}
12446	},
12447
12448	_open: function( event, target, content ) {
12449		var tooltip, events, delayedShow,
12450			positionOption = $.extend( {}, this.options.position );
12451
12452		if ( !content ) {
12453			return;
12454		}
12455
12456		// Content can be updated multiple times. If the tooltip already
12457		// exists, then just update the content and bail.
12458		tooltip = this._find( target );
12459		if ( tooltip.length ) {
12460			tooltip.find( ".ui-tooltip-content" ).html( content );
12461			return;
12462		}
12463
12464		// if we have a title, clear it to prevent the native tooltip
12465		// we have to check first to avoid defining a title if none exists
12466		// (we don't want to cause an element to start matching [title])
12467		//
12468		// We use removeAttr only for key events, to allow IE to export the correct
12469		// accessible attributes. For mouse events, set to empty string to avoid
12470		// native tooltip showing up (happens only when removing inside mouseover).
12471		if ( target.is( "[title]" ) ) {
12472			if ( event && event.type === "mouseover" ) {
12473				target.attr( "title", "" );
12474			} else {
12475				target.removeAttr( "title" );
12476			}
12477		}
12478
12479		tooltip = this._tooltip( target );
12480		addDescribedBy( target, tooltip.attr( "id" ) );
12481		tooltip.find( ".ui-tooltip-content" ).html( content );
12482
12483		function position( event ) {
12484			positionOption.of = event;
12485			if ( tooltip.is( ":hidden" ) ) {
12486				return;
12487			}
12488			tooltip.position( positionOption );
12489		}
12490		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
12491			this._on( this.document, {
12492				mousemove: position
12493			});
12494			// trigger once to override element-relative positioning
12495			position( event );
12496		} else {
12497			tooltip.position( $.extend({
12498				of: target
12499			}, this.options.position ) );
12500		}
12501
12502		tooltip.hide();
12503
12504		this._show( tooltip, this.options.show );
12505		// Handle tracking tooltips that are shown with a delay (#8644). As soon
12506		// as the tooltip is visible, position the tooltip using the most recent
12507		// event.
12508		if ( this.options.show && this.options.show.delay ) {
12509			delayedShow = setInterval(function() {
12510				if ( tooltip.is( ":visible" ) ) {
12511					position( positionOption.of );
12512					clearInterval( delayedShow );
12513				}
12514			}, $.fx.interval );
12515		}
12516
12517		this._trigger( "open", event, { tooltip: tooltip } );
12518
12519		events = {
12520			keyup: function( event ) {
12521				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
12522					var fakeEvent = $.Event(event);
12523					fakeEvent.currentTarget = target[0];
12524					this.close( fakeEvent, true );
12525				}
12526			},
12527			remove: function() {
12528				this._removeTooltip( tooltip );
12529			}
12530		};
12531		if ( !event || event.type === "mouseover" ) {
12532			events.mouseleave = "close";
12533		}
12534		if ( !event || event.type === "focusin" ) {
12535			events.focusout = "close";
12536		}
12537		this._on( true, target, events );
12538	},
12539
12540	close: function( event ) {
12541		var that = this,
12542			target = $( event ? event.currentTarget : this.element ),
12543			tooltip = this._find( target );
12544
12545		// disabling closes the tooltip, so we need to track when we're closing
12546		// to avoid an infinite loop in case the tooltip becomes disabled on close
12547		if ( this.closing ) {
12548			return;
12549		}
12550
12551		// only set title if we had one before (see comment in _open())
12552		if ( target.data( "ui-tooltip-title" ) ) {
12553			target.attr( "title", target.data( "ui-tooltip-title" ) );
12554		}
12555
12556		removeDescribedBy( target );
12557
12558		tooltip.stop( true );
12559		this._hide( tooltip, this.options.hide, function() {
12560			that._removeTooltip( $( this ) );
12561		});
12562
12563		target.removeData( "ui-tooltip-open" );
12564		this._off( target, "mouseleave focusout keyup" );
12565		// Remove 'remove' binding only on delegated targets
12566		if ( target[0] !== this.element[0] ) {
12567			this._off( target, "remove" );
12568		}
12569		this._off( this.document, "mousemove" );
12570
12571		if ( event && event.type === "mouseleave" ) {
12572			$.each( this.parents, function( id, parent ) {
12573				$( parent.element ).attr( "title", parent.title );
12574				delete that.parents[ id ];
12575			});
12576		}
12577
12578		this.closing = true;
12579		this._trigger( "close", event, { tooltip: tooltip } );
12580		this.closing = false;
12581	},
12582
12583	_tooltip: function( element ) {
12584		var id = "ui-tooltip-" + increments++,
12585			tooltip = $( "<div>" )
12586				.attr({
12587					id: id,
12588					role: "tooltip"
12589				})
12590				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
12591					( this.options.tooltipClass || "" ) );
12592		$( "<div>" )
12593			.addClass( "ui-tooltip-content" )
12594			.appendTo( tooltip );
12595		tooltip.appendTo( this.document[0].body );
12596		if ( $.fn.bgiframe ) {
12597			tooltip.bgiframe();
12598		}
12599		this.tooltips[ id ] = element;
12600		return tooltip;
12601	},
12602
12603	_find: function( target ) {
12604		var id = target.data( "ui-tooltip-id" );
12605		return id ? $( "#" + id ) : $();
12606	},
12607
12608	_removeTooltip: function( tooltip ) {
12609		tooltip.remove();
12610		delete this.tooltips[ tooltip.attr( "id" ) ];
12611	},
12612
12613	_destroy: function() {
12614		var that = this;
12615
12616		// close open tooltips
12617		$.each( this.tooltips, function( id, element ) {
12618			// Delegate to close method to handle common cleanup
12619			var event = $.Event( "blur" );
12620			event.target = event.currentTarget = element[0];
12621			that.close( event, true );
12622
12623			// Remove immediately; destroying an open tooltip doesn't use the
12624			// hide animation
12625			$( "#" + id ).remove();
12626
12627			// Restore the title
12628			if ( element.data( "ui-tooltip-title" ) ) {
12629				element.attr( "title", element.data( "ui-tooltip-title" ) );
12630				element.removeData( "ui-tooltip-title" );
12631			}
12632		});
12633	}
12634});
12635
12636}( jQuery ) );
12637;(jQuery.effects || (function($, undefined) {
12638
12639var backCompat = $.uiBackCompat !== false,
12640	// prefix used for storing data on .data()
12641	dataSpace = "ui-effects-";
12642
12643$.effects = {
12644	effect: {}
12645};
12646
12647/*!
12648 * jQuery Color Animations v2.0.0
12649 * http://jquery.com/
12650 *
12651 * Copyright 2012 jQuery Foundation and other contributors
12652 * Released under the MIT license.
12653 * http://jquery.org/license
12654 *
12655 * Date: Mon Aug 13 13:41:02 2012 -0500
12656 */
12657(function( jQuery, undefined ) {
12658
12659	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),
12660
12661	// plusequals test for += 100 -= 100
12662	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
12663	// a set of RE's that can match strings and generate color tuples.
12664	stringParsers = [{
12665			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
12666			parse: function( execResult ) {
12667				return [
12668					execResult[ 1 ],
12669					execResult[ 2 ],
12670					execResult[ 3 ],
12671					execResult[ 4 ]
12672				];
12673			}
12674		}, {
12675			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
12676			parse: function( execResult ) {
12677				return [
12678					execResult[ 1 ] * 2.55,
12679					execResult[ 2 ] * 2.55,
12680					execResult[ 3 ] * 2.55,
12681					execResult[ 4 ]
12682				];
12683			}
12684		}, {
12685			// this regex ignores A-F because it's compared against an already lowercased string
12686			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
12687			parse: function( execResult ) {
12688				return [
12689					parseInt( execResult[ 1 ], 16 ),
12690					parseInt( execResult[ 2 ], 16 ),
12691					parseInt( execResult[ 3 ], 16 )
12692				];
12693			}
12694		}, {
12695			// this regex ignores A-F because it's compared against an already lowercased string
12696			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
12697			parse: function( execResult ) {
12698				return [
12699					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
12700					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
12701					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
12702				];
12703			}
12704		}, {
12705			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
12706			space: "hsla",
12707			parse: function( execResult ) {
12708				return [
12709					execResult[ 1 ],
12710					execResult[ 2 ] / 100,
12711					execResult[ 3 ] / 100,
12712					execResult[ 4 ]
12713				];
12714			}
12715		}],
12716
12717	// jQuery.Color( )
12718	color = jQuery.Color = function( color, green, blue, alpha ) {
12719		return new jQuery.Color.fn.parse( color, green, blue, alpha );
12720	},
12721	spaces = {
12722		rgba: {
12723			props: {
12724				red: {
12725					idx: 0,
12726					type: "byte"
12727				},
12728				green: {
12729					idx: 1,
12730					type: "byte"
12731				},
12732				blue: {
12733					idx: 2,
12734					type: "byte"
12735				}
12736			}
12737		},
12738
12739		hsla: {
12740			props: {
12741				hue: {
12742					idx: 0,
12743					type: "degrees"
12744				},
12745				saturation: {
12746					idx: 1,
12747					type: "percent"
12748				},
12749				lightness: {
12750					idx: 2,
12751					type: "percent"
12752				}
12753			}
12754		}
12755	},
12756	propTypes = {
12757		"byte": {
12758			floor: true,
12759			max: 255
12760		},
12761		"percent": {
12762			max: 1
12763		},
12764		"degrees": {
12765			mod: 360,
12766			floor: true
12767		}
12768	},
12769	support = color.support = {},
12770
12771	// element for support tests
12772	supportElem = jQuery( "<p>" )[ 0 ],
12773
12774	// colors = jQuery.Color.names
12775	colors,
12776
12777	// local aliases of functions called often
12778	each = jQuery.each;
12779
12780// determine rgba support immediately
12781supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
12782support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
12783
12784// define cache name and alpha properties
12785// for rgba and hsla spaces
12786each( spaces, function( spaceName, space ) {
12787	space.cache = "_" + spaceName;
12788	space.props.alpha = {
12789		idx: 3,
12790		type: "percent",
12791		def: 1
12792	};
12793});
12794
12795function clamp( value, prop, allowEmpty ) {
12796	var type = propTypes[ prop.type ] || {};
12797
12798	if ( value == null ) {
12799		return (allowEmpty || !prop.def) ? null : prop.def;
12800	}
12801
12802	// ~~ is an short way of doing floor for positive numbers
12803	value = type.floor ? ~~value : parseFloat( value );
12804
12805	// IE will pass in empty strings as value for alpha,
12806	// which will hit this case
12807	if ( isNaN( value ) ) {
12808		return prop.def;
12809	}
12810
12811	if ( type.mod ) {
12812		// we add mod before modding to make sure that negatives values
12813		// get converted properly: -10 -> 350
12814		return (value + type.mod) % type.mod;
12815	}
12816
12817	// for now all property types without mod have min and max
12818	return 0 > value ? 0 : type.max < value ? type.max : value;
12819}
12820
12821function stringParse( string ) {
12822	var inst = color(),
12823		rgba = inst._rgba = [];
12824
12825	string = string.toLowerCase();
12826
12827	each( stringParsers, function( i, parser ) {
12828		var parsed,
12829			match = parser.re.exec( string ),
12830			values = match && parser.parse( match ),
12831			spaceName = parser.space || "rgba";
12832
12833		if ( values ) {
12834			parsed = inst[ spaceName ]( values );
12835
12836			// if this was an rgba parse the assignment might happen twice
12837			// oh well....
12838			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
12839			rgba = inst._rgba = parsed._rgba;
12840
12841			// exit each( stringParsers ) here because we matched
12842			return false;
12843		}
12844	});
12845
12846	// Found a stringParser that handled it
12847	if ( rgba.length ) {
12848
12849		// if this came from a parsed string, force "transparent" when alpha is 0
12850		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
12851		if ( rgba.join() === "0,0,0,0" ) {
12852			jQuery.extend( rgba, colors.transparent );
12853		}
12854		return inst;
12855	}
12856
12857	// named colors
12858	return colors[ string ];
12859}
12860
12861color.fn = jQuery.extend( color.prototype, {
12862	parse: function( red, green, blue, alpha ) {
12863		if ( red === undefined ) {
12864			this._rgba = [ null, null, null, null ];
12865			return this;
12866		}
12867		if ( red.jquery || red.nodeType ) {
12868			red = jQuery( red ).css( green );
12869			green = undefined;
12870		}
12871
12872		var inst = this,
12873			type = jQuery.type( red ),
12874			rgba = this._rgba = [];
12875
12876		// more than 1 argument specified - assume ( red, green, blue, alpha )
12877		if ( green !== undefined ) {
12878			red = [ red, green, blue, alpha ];
12879			type = "array";
12880		}
12881
12882		if ( type === "string" ) {
12883			return this.parse( stringParse( red ) || colors._default );
12884		}
12885
12886		if ( type === "array" ) {
12887			each( spaces.rgba.props, function( key, prop ) {
12888				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
12889			});
12890			return this;
12891		}
12892
12893		if ( type === "object" ) {
12894			if ( red instanceof color ) {
12895				each( spaces, function( spaceName, space ) {
12896					if ( red[ space.cache ] ) {
12897						inst[ space.cache ] = red[ space.cache ].slice();
12898					}
12899				});
12900			} else {
12901				each( spaces, function( spaceName, space ) {
12902					var cache = space.cache;
12903					each( space.props, function( key, prop ) {
12904
12905						// if the cache doesn't exist, and we know how to convert
12906						if ( !inst[ cache ] && space.to ) {
12907
12908							// if the value was null, we don't need to copy it
12909							// if the key was alpha, we don't need to copy it either
12910							if ( key === "alpha" || red[ key ] == null ) {
12911								return;
12912							}
12913							inst[ cache ] = space.to( inst._rgba );
12914						}
12915
12916						// this is the only case where we allow nulls for ALL properties.
12917						// call clamp with alwaysAllowEmpty
12918						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
12919					});
12920
12921					// everything defined but alpha?
12922					if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
12923						// use the default of 1
12924						inst[ cache ][ 3 ] = 1;
12925						if ( space.from ) {
12926							inst._rgba = space.from( inst[ cache ] );
12927						}
12928					}
12929				});
12930			}
12931			return this;
12932		}
12933	},
12934	is: function( compare ) {
12935		var is = color( compare ),
12936			same = true,
12937			inst = this;
12938
12939		each( spaces, function( _, space ) {
12940			var localCache,
12941				isCache = is[ space.cache ];
12942			if (isCache) {
12943				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
12944				each( space.props, function( _, prop ) {
12945					if ( isCache[ prop.idx ] != null ) {
12946						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
12947						return same;
12948					}
12949				});
12950			}
12951			return same;
12952		});
12953		return same;
12954	},
12955	_space: function() {
12956		var used = [],
12957			inst = this;
12958		each( spaces, function( spaceName, space ) {
12959			if ( inst[ space.cache ] ) {
12960				used.push( spaceName );
12961			}
12962		});
12963		return used.pop();
12964	},
12965	transition: function( other, distance ) {
12966		var end = color( other ),
12967			spaceName = end._space(),
12968			space = spaces[ spaceName ],
12969			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
12970			start = startColor[ space.cache ] || space.to( startColor._rgba ),
12971			result = start.slice();
12972
12973		end = end[ space.cache ];
12974		each( space.props, function( key, prop ) {
12975			var index = prop.idx,
12976				startValue = start[ index ],
12977				endValue = end[ index ],
12978				type = propTypes[ prop.type ] || {};
12979
12980			// if null, don't override start value
12981			if ( endValue === null ) {
12982				return;
12983			}
12984			// if null - use end
12985			if ( startValue === null ) {
12986				result[ index ] = endValue;
12987			} else {
12988				if ( type.mod ) {
12989					if ( endValue - startValue > type.mod / 2 ) {
12990						startValue += type.mod;
12991					} else if ( startValue - endValue > type.mod / 2 ) {
12992						startValue -= type.mod;
12993					}
12994				}
12995				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
12996			}
12997		});
12998		return this[ spaceName ]( result );
12999	},
13000	blend: function( opaque ) {
13001		// if we are already opaque - return ourself
13002		if ( this._rgba[ 3 ] === 1 ) {
13003			return this;
13004		}
13005
13006		var rgb = this._rgba.slice(),
13007			a = rgb.pop(),
13008			blend = color( opaque )._rgba;
13009
13010		return color( jQuery.map( rgb, function( v, i ) {
13011			return ( 1 - a ) * blend[ i ] + a * v;
13012		}));
13013	},
13014	toRgbaString: function() {
13015		var prefix = "rgba(",
13016			rgba = jQuery.map( this._rgba, function( v, i ) {
13017				return v == null ? ( i > 2 ? 1 : 0 ) : v;
13018			});
13019
13020		if ( rgba[ 3 ] === 1 ) {
13021			rgba.pop();
13022			prefix = "rgb(";
13023		}
13024
13025		return prefix + rgba.join() + ")";
13026	},
13027	toHslaString: function() {
13028		var prefix = "hsla(",
13029			hsla = jQuery.map( this.hsla(), function( v, i ) {
13030				if ( v == null ) {
13031					v = i > 2 ? 1 : 0;
13032				}
13033
13034				// catch 1 and 2
13035				if ( i && i < 3 ) {
13036					v = Math.round( v * 100 ) + "%";
13037				}
13038				return v;
13039			});
13040
13041		if ( hsla[ 3 ] === 1 ) {
13042			hsla.pop();
13043			prefix = "hsl(";
13044		}
13045		return prefix + hsla.join() + ")";
13046	},
13047	toHexString: function( includeAlpha ) {
13048		var rgba = this._rgba.slice(),
13049			alpha = rgba.pop();
13050
13051		if ( includeAlpha ) {
13052			rgba.push( ~~( alpha * 255 ) );
13053		}
13054
13055		return "#" + jQuery.map( rgba, function( v ) {
13056
13057			// default to 0 when nulls exist
13058			v = ( v || 0 ).toString( 16 );
13059			return v.length === 1 ? "0" + v : v;
13060		}).join("");
13061	},
13062	toString: function() {
13063		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
13064	}
13065});
13066color.fn.parse.prototype = color.fn;
13067
13068// hsla conversions adapted from:
13069// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
13070
13071function hue2rgb( p, q, h ) {
13072	h = ( h + 1 ) % 1;
13073	if ( h * 6 < 1 ) {
13074		return p + (q - p) * h * 6;
13075	}
13076	if ( h * 2 < 1) {
13077		return q;
13078	}
13079	if ( h * 3 < 2 ) {
13080		return p + (q - p) * ((2/3) - h) * 6;
13081	}
13082	return p;
13083}
13084
13085spaces.hsla.to = function ( rgba ) {
13086	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
13087		return [ null, null, null, rgba[ 3 ] ];
13088	}
13089	var r = rgba[ 0 ] / 255,
13090		g = rgba[ 1 ] / 255,
13091		b = rgba[ 2 ] / 255,
13092		a = rgba[ 3 ],
13093		max = Math.max( r, g, b ),
13094		min = Math.min( r, g, b ),
13095		diff = max - min,
13096		add = max + min,
13097		l = add * 0.5,
13098		h, s;
13099
13100	if ( min === max ) {
13101		h = 0;
13102	} else if ( r === max ) {
13103		h = ( 60 * ( g - b ) / diff ) + 360;
13104	} else if ( g === max ) {
13105		h = ( 60 * ( b - r ) / diff ) + 120;
13106	} else {
13107		h = ( 60 * ( r - g ) / diff ) + 240;
13108	}
13109
13110	if ( l === 0 || l === 1 ) {
13111		s = l;
13112	} else if ( l <= 0.5 ) {
13113		s = diff / add;
13114	} else {
13115		s = diff / ( 2 - add );
13116	}
13117	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
13118};
13119
13120spaces.hsla.from = function ( hsla ) {
13121	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
13122		return [ null, null, null, hsla[ 3 ] ];
13123	}
13124	var h = hsla[ 0 ] / 360,
13125		s = hsla[ 1 ],
13126		l = hsla[ 2 ],
13127		a = hsla[ 3 ],
13128		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
13129		p = 2 * l - q;
13130
13131	return [
13132		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
13133		Math.round( hue2rgb( p, q, h ) * 255 ),
13134		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
13135		a
13136	];
13137};
13138
13139
13140each( spaces, function( spaceName, space ) {
13141	var props = space.props,
13142		cache = space.cache,
13143		to = space.to,
13144		from = space.from;
13145
13146	// makes rgba() and hsla()
13147	color.fn[ spaceName ] = function( value ) {
13148
13149		// generate a cache for this space if it doesn't exist
13150		if ( to && !this[ cache ] ) {
13151			this[ cache ] = to( this._rgba );
13152		}
13153		if ( value === undefined ) {
13154			return this[ cache ].slice();
13155		}
13156
13157		var ret,
13158			type = jQuery.type( value ),
13159			arr = ( type === "array" || type === "object" ) ? value : arguments,
13160			local = this[ cache ].slice();
13161
13162		each( props, function( key, prop ) {
13163			var val = arr[ type === "object" ? key : prop.idx ];
13164			if ( val == null ) {
13165				val = local[ prop.idx ];
13166			}
13167			local[ prop.idx ] = clamp( val, prop );
13168		});
13169
13170		if ( from ) {
13171			ret = color( from( local ) );
13172			ret[ cache ] = local;
13173			return ret;
13174		} else {
13175			return color( local );
13176		}
13177	};
13178
13179	// makes red() green() blue() alpha() hue() saturation() lightness()
13180	each( props, function( key, prop ) {
13181		// alpha is included in more than one space
13182		if ( color.fn[ key ] ) {
13183			return;
13184		}
13185		color.fn[ key ] = function( value ) {
13186			var vtype = jQuery.type( value ),
13187				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
13188				local = this[ fn ](),
13189				cur = local[ prop.idx ],
13190				match;
13191
13192			if ( vtype === "undefined" ) {
13193				return cur;
13194			}
13195
13196			if ( vtype === "function" ) {
13197				value = value.call( this, cur );
13198				vtype = jQuery.type( value );
13199			}
13200			if ( value == null && prop.empty ) {
13201				return this;
13202			}
13203			if ( vtype === "string" ) {
13204				match = rplusequals.exec( value );
13205				if ( match ) {
13206					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
13207				}
13208			}
13209			local[ prop.idx ] = value;
13210			return this[ fn ]( local );
13211		};
13212	});
13213});
13214
13215// add .fx.step functions
13216each( stepHooks, function( i, hook ) {
13217	jQuery.cssHooks[ hook ] = {
13218		set: function( elem, value ) {
13219			var parsed, curElem,
13220				backgroundColor = "";
13221
13222			if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {
13223				value = color( parsed || value );
13224				if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
13225					curElem = hook === "backgroundColor" ? elem.parentNode : elem;
13226					while (
13227						(backgroundColor === "" || backgroundColor === "transparent") &&
13228						curElem && curElem.style
13229					) {
13230						try {
13231							backgroundColor = jQuery.css( curElem, "backgroundColor" );
13232							curElem = curElem.parentNode;
13233						} catch ( e ) {
13234						}
13235					}
13236
13237					value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
13238						backgroundColor :
13239						"_default" );
13240				}
13241
13242				value = value.toRgbaString();
13243			}
13244			try {
13245				elem.style[ hook ] = value;
13246			} catch( error ) {
13247				// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
13248			}
13249		}
13250	};
13251	jQuery.fx.step[ hook ] = function( fx ) {
13252		if ( !fx.colorInit ) {
13253			fx.start = color( fx.elem, hook );
13254			fx.end = color( fx.end );
13255			fx.colorInit = true;
13256		}
13257		jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
13258	};
13259});
13260
13261jQuery.cssHooks.borderColor = {
13262	expand: function( value ) {
13263		var expanded = {};
13264
13265		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
13266			expanded[ "border" + part + "Color" ] = value;
13267		});
13268		return expanded;
13269	}
13270};
13271
13272// Basic color names only.
13273// Usage of any of the other color names requires adding yourself or including
13274// jquery.color.svg-names.js.
13275colors = jQuery.Color.names = {
13276	// 4.1. Basic color keywords
13277	aqua: "#00ffff",
13278	black: "#000000",
13279	blue: "#0000ff",
13280	fuchsia: "#ff00ff",
13281	gray: "#808080",
13282	green: "#008000",
13283	lime: "#00ff00",
13284	maroon: "#800000",
13285	navy: "#000080",
13286	olive: "#808000",
13287	purple: "#800080",
13288	red: "#ff0000",
13289	silver: "#c0c0c0",
13290	teal: "#008080",
13291	white: "#ffffff",
13292	yellow: "#ffff00",
13293
13294	// 4.2.3. "transparent" color keyword
13295	transparent: [ null, null, null, 0 ],
13296
13297	_default: "#ffffff"
13298};
13299
13300})( jQuery );
13301
13302
13303
13304/******************************************************************************/
13305/****************************** CLASS ANIMATIONS ******************************/
13306/******************************************************************************/
13307(function() {
13308
13309var classAnimationActions = [ "add", "remove", "toggle" ],
13310	shorthandStyles = {
13311		border: 1,
13312		borderBottom: 1,
13313		borderColor: 1,
13314		borderLeft: 1,
13315		borderRight: 1,
13316		borderTop: 1,
13317		borderWidth: 1,
13318		margin: 1,
13319		padding: 1
13320	};
13321
13322$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
13323	$.fx.step[ prop ] = function( fx ) {
13324		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
13325			jQuery.style( fx.elem, prop, fx.end );
13326			fx.setAttr = true;
13327		}
13328	};
13329});
13330
13331function getElementStyles() {
13332	var style = this.ownerDocument.defaultView ?
13333			this.ownerDocument.defaultView.getComputedStyle( this, null ) :
13334			this.currentStyle,
13335		newStyle = {},
13336		key,
13337		len;
13338
13339	// webkit enumerates style porperties
13340	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
13341		len = style.length;
13342		while ( len-- ) {
13343			key = style[ len ];
13344			if ( typeof style[ key ] === "string" ) {
13345				newStyle[ $.camelCase( key ) ] = style[ key ];
13346			}
13347		}
13348	} else {
13349		for ( key in style ) {
13350			if ( typeof style[ key ] === "string" ) {
13351				newStyle[ key ] = style[ key ];
13352			}
13353		}
13354	}
13355
13356	return newStyle;
13357}
13358
13359
13360function styleDifference( oldStyle, newStyle ) {
13361	var diff = {},
13362		name, value;
13363
13364	for ( name in newStyle ) {
13365		value = newStyle[ name ];
13366		if ( oldStyle[ name ] !== value ) {
13367			if ( !shorthandStyles[ name ] ) {
13368				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
13369					diff[ name ] = value;
13370				}
13371			}
13372		}
13373	}
13374
13375	return diff;
13376}
13377
13378$.effects.animateClass = function( value, duration, easing, callback ) {
13379	var o = $.speed( duration, easing, callback );
13380
13381	return this.queue( function() {
13382		var animated = $( this ),
13383			baseClass = animated.attr( "class" ) || "",
13384			applyClassChange,
13385			allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;
13386
13387		// map the animated objects to store the original styles.
13388		allAnimations = allAnimations.map(function() {
13389			var el = $( this );
13390			return {
13391				el: el,
13392				start: getElementStyles.call( this )
13393			};
13394		});
13395
13396		// apply class change
13397		applyClassChange = function() {
13398			$.each( classAnimationActions, function(i, action) {
13399				if ( value[ action ] ) {
13400					animated[ action + "Class" ]( value[ action ] );
13401				}
13402			});
13403		};
13404		applyClassChange();
13405
13406		// map all animated objects again - calculate new styles and diff
13407		allAnimations = allAnimations.map(function() {
13408			this.end = getElementStyles.call( this.el[ 0 ] );
13409			this.diff = styleDifference( this.start, this.end );
13410			return this;
13411		});
13412
13413		// apply original class
13414		animated.attr( "class", baseClass );
13415
13416		// map all animated objects again - this time collecting a promise
13417		allAnimations = allAnimations.map(function() {
13418			var styleInfo = this,
13419				dfd = $.Deferred(),
13420				opts = jQuery.extend({}, o, {
13421					queue: false,
13422					complete: function() {
13423						dfd.resolve( styleInfo );
13424					}
13425				});
13426
13427			this.el.animate( this.diff, opts );
13428			return dfd.promise();
13429		});
13430
13431		// once all animations have completed:
13432		$.when.apply( $, allAnimations.get() ).done(function() {
13433
13434			// set the final class
13435			applyClassChange();
13436
13437			// for each animated element,
13438			// clear all css properties that were animated
13439			$.each( arguments, function() {
13440				var el = this.el;
13441				$.each( this.diff, function(key) {
13442					el.css( key, '' );
13443				});
13444			});
13445
13446			// this is guarnteed to be there if you use jQuery.speed()
13447			// it also handles dequeuing the next anim...
13448			o.complete.call( animated[ 0 ] );
13449		});
13450	});
13451};
13452
13453$.fn.extend({
13454	_addClass: $.fn.addClass,
13455	addClass: function( classNames, speed, easing, callback ) {
13456		return speed ?
13457			$.effects.animateClass.call( this,
13458				{ add: classNames }, speed, easing, callback ) :
13459			this._addClass( classNames );
13460	},
13461
13462	_removeClass: $.fn.removeClass,
13463	removeClass: function( classNames, speed, easing, callback ) {
13464		return speed ?
13465			$.effects.animateClass.call( this,
13466				{ remove: classNames }, speed, easing, callback ) :
13467			this._removeClass( classNames );
13468	},
13469
13470	_toggleClass: $.fn.toggleClass,
13471	toggleClass: function( classNames, force, speed, easing, callback ) {
13472		if ( typeof force === "boolean" || force === undefined ) {
13473			if ( !speed ) {
13474				// without speed parameter
13475				return this._toggleClass( classNames, force );
13476			} else {
13477				return $.effects.animateClass.call( this,
13478					(force ? { add: classNames } : { remove: classNames }),
13479					speed, easing, callback );
13480			}
13481		} else {
13482			// without force parameter
13483			return $.effects.animateClass.call( this,
13484				{ toggle: classNames }, force, speed, easing );
13485		}
13486	},
13487
13488	switchClass: function( remove, add, speed, easing, callback) {
13489		return $.effects.animateClass.call( this, {
13490			add: add,
13491			remove: remove
13492		}, speed, easing, callback );
13493	}
13494});
13495
13496})();
13497
13498/******************************************************************************/
13499/*********************************** EFFECTS **********************************/
13500/******************************************************************************/
13501
13502(function() {
13503
13504$.extend( $.effects, {
13505	version: "1.9.2",
13506
13507	// Saves a set of properties in a data storage
13508	save: function( element, set ) {
13509		for( var i=0; i < set.length; i++ ) {
13510			if ( set[ i ] !== null ) {
13511				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
13512			}
13513		}
13514	},
13515
13516	// Restores a set of previously saved properties from a data storage
13517	restore: function( element, set ) {
13518		var val, i;
13519		for( i=0; i < set.length; i++ ) {
13520			if ( set[ i ] !== null ) {
13521				val = element.data( dataSpace + set[ i ] );
13522				// support: jQuery 1.6.2
13523				// http://bugs.jquery.com/ticket/9917
13524				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
13525				// We can't differentiate between "" and 0 here, so we just assume
13526				// empty string since it's likely to be a more common value...
13527				if ( val === undefined ) {
13528					val = "";
13529				}
13530				element.css( set[ i ], val );
13531			}
13532		}
13533	},
13534
13535	setMode: function( el, mode ) {
13536		if (mode === "toggle") {
13537			mode = el.is( ":hidden" ) ? "show" : "hide";
13538		}
13539		return mode;
13540	},
13541
13542	// Translates a [top,left] array into a baseline value
13543	// this should be a little more flexible in the future to handle a string & hash
13544	getBaseline: function( origin, original ) {
13545		var y, x;
13546		switch ( origin[ 0 ] ) {
13547			case "top": y = 0; break;
13548			case "middle": y = 0.5; break;
13549			case "bottom": y = 1; break;
13550			default: y = origin[ 0 ] / original.height;
13551		}
13552		switch ( origin[ 1 ] ) {
13553			case "left": x = 0; break;
13554			case "center": x = 0.5; break;
13555			case "right": x = 1; break;
13556			default: x = origin[ 1 ] / original.width;
13557		}
13558		return {
13559			x: x,
13560			y: y
13561		};
13562	},
13563
13564	// Wraps the element around a wrapper that copies position properties
13565	createWrapper: function( element ) {
13566
13567		// if the element is already wrapped, return it
13568		if ( element.parent().is( ".ui-effects-wrapper" )) {
13569			return element.parent();
13570		}
13571
13572		// wrap the element
13573		var props = {
13574				width: element.outerWidth(true),
13575				height: element.outerHeight(true),
13576				"float": element.css( "float" )
13577			},
13578			wrapper = $( "<div></div>" )
13579				.addClass( "ui-effects-wrapper" )
13580				.css({
13581					fontSize: "100%",
13582					background: "transparent",
13583					border: "none",
13584					margin: 0,
13585					padding: 0
13586				}),
13587			// Store the size in case width/height are defined in % - Fixes #5245
13588			size = {
13589				width: element.width(),
13590				height: element.height()
13591			},
13592			active = document.activeElement;
13593
13594		// support: Firefox
13595		// Firefox incorrectly exposes anonymous content
13596		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
13597		try {
13598			active.id;
13599		} catch( e ) {
13600			active = document.body;
13601		}
13602
13603		element.wrap( wrapper );
13604
13605		// Fixes #7595 - Elements lose focus when wrapped.
13606		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13607			$( active ).focus();
13608		}
13609
13610		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
13611
13612		// transfer positioning properties to the wrapper
13613		if ( element.css( "position" ) === "static" ) {
13614			wrapper.css({ position: "relative" });
13615			element.css({ position: "relative" });
13616		} else {
13617			$.extend( props, {
13618				position: element.css( "position" ),
13619				zIndex: element.css( "z-index" )
13620			});
13621			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
13622				props[ pos ] = element.css( pos );
13623				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
13624					props[ pos ] = "auto";
13625				}
13626			});
13627			element.css({
13628				position: "relative",
13629				top: 0,
13630				left: 0,
13631				right: "auto",
13632				bottom: "auto"
13633			});
13634		}
13635		element.css(size);
13636
13637		return wrapper.css( props ).show();
13638	},
13639
13640	removeWrapper: function( element ) {
13641		var active = document.activeElement;
13642
13643		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
13644			element.parent().replaceWith( element );
13645
13646			// Fixes #7595 - Elements lose focus when wrapped.
13647			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13648				$( active ).focus();
13649			}
13650		}
13651
13652
13653		return element;
13654	},
13655
13656	setTransition: function( element, list, factor, value ) {
13657		value = value || {};
13658		$.each( list, function( i, x ) {
13659			var unit = element.cssUnit( x );
13660			if ( unit[ 0 ] > 0 ) {
13661				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
13662			}
13663		});
13664		return value;
13665	}
13666});
13667
13668// return an effect options object for the given parameters:
13669function _normalizeArguments( effect, options, speed, callback ) {
13670
13671	// allow passing all options as the first parameter
13672	if ( $.isPlainObject( effect ) ) {
13673		options = effect;
13674		effect = effect.effect;
13675	}
13676
13677	// convert to an object
13678	effect = { effect: effect };
13679
13680	// catch (effect, null, ...)
13681	if ( options == null ) {
13682		options = {};
13683	}
13684
13685	// catch (effect, callback)
13686	if ( $.isFunction( options ) ) {
13687		callback = options;
13688		speed = null;
13689		options = {};
13690	}
13691
13692	// catch (effect, speed, ?)
13693	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
13694		callback = speed;
13695		speed = options;
13696		options = {};
13697	}
13698
13699	// catch (effect, options, callback)
13700	if ( $.isFunction( speed ) ) {
13701		callback = speed;
13702		speed = null;
13703	}
13704
13705	// add options to effect
13706	if ( options ) {
13707		$.extend( effect, options );
13708	}
13709
13710	speed = speed || options.duration;
13711	effect.duration = $.fx.off ? 0 :
13712		typeof speed === "number" ? speed :
13713		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
13714		$.fx.speeds._default;
13715
13716	effect.complete = callback || options.complete;
13717
13718	return effect;
13719}
13720
13721function standardSpeed( speed ) {
13722	// valid standard speeds
13723	if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
13724		return true;
13725	}
13726
13727	// invalid strings - treat as "normal" speed
13728	if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
13729		// TODO: remove in 2.0 (#7115)
13730		if ( backCompat && $.effects[ speed ] ) {
13731			return false;
13732		}
13733		return true;
13734	}
13735
13736	return false;
13737}
13738
13739$.fn.extend({
13740	effect: function( /* effect, options, speed, callback */ ) {
13741		var args = _normalizeArguments.apply( this, arguments ),
13742			mode = args.mode,
13743			queue = args.queue,
13744			effectMethod = $.effects.effect[ args.effect ],
13745
13746			// DEPRECATED: remove in 2.0 (#7115)
13747			oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
13748
13749		if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
13750			// delegate to the original method (e.g., .show()) if possible
13751			if ( mode ) {
13752				return this[ mode ]( args.duration, args.complete );
13753			} else {
13754				return this.each( function() {
13755					if ( args.complete ) {
13756						args.complete.call( this );
13757					}
13758				});
13759			}
13760		}
13761
13762		function run( next ) {
13763			var elem = $( this ),
13764				complete = args.complete,
13765				mode = args.mode;
13766
13767			function done() {
13768				if ( $.isFunction( complete ) ) {
13769					complete.call( elem[0] );
13770				}
13771				if ( $.isFunction( next ) ) {
13772					next();
13773				}
13774			}
13775
13776			// if the element is hiddden and mode is hide,
13777			// or element is visible and mode is show
13778			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
13779				done();
13780			} else {
13781				effectMethod.call( elem[0], args, done );
13782			}
13783		}
13784
13785		// TODO: remove this check in 2.0, effectMethod will always be true
13786		if ( effectMethod ) {
13787			return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
13788		} else {
13789			// DEPRECATED: remove in 2.0 (#7115)
13790			return oldEffectMethod.call(this, {
13791				options: args,
13792				duration: args.duration,
13793				callback: args.complete,
13794				mode: args.mode
13795			});
13796		}
13797	},
13798
13799	_show: $.fn.show,
13800	show: function( speed ) {
13801		if ( standardSpeed( speed ) ) {
13802			return this._show.apply( this, arguments );
13803		} else {
13804			var args = _normalizeArguments.apply( this, arguments );
13805			args.mode = "show";
13806			return this.effect.call( this, args );
13807		}
13808	},
13809
13810	_hide: $.fn.hide,
13811	hide: function( speed ) {
13812		if ( standardSpeed( speed ) ) {
13813			return this._hide.apply( this, arguments );
13814		} else {
13815			var args = _normalizeArguments.apply( this, arguments );
13816			args.mode = "hide";
13817			return this.effect.call( this, args );
13818		}
13819	},
13820
13821	// jQuery core overloads toggle and creates _toggle
13822	__toggle: $.fn.toggle,
13823	toggle: function( speed ) {
13824		if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
13825			return this.__toggle.apply( this, arguments );
13826		} else {
13827			var args = _normalizeArguments.apply( this, arguments );
13828			args.mode = "toggle";
13829			return this.effect.call( this, args );
13830		}
13831	},
13832
13833	// helper functions
13834	cssUnit: function(key) {
13835		var style = this.css( key ),
13836			val = [];
13837
13838		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
13839			if ( style.indexOf( unit ) > 0 ) {
13840				val = [ parseFloat( style ), unit ];
13841			}
13842		});
13843		return val;
13844	}
13845});
13846
13847})();
13848
13849/******************************************************************************/
13850/*********************************** EASING ***********************************/
13851/******************************************************************************/
13852
13853(function() {
13854
13855// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
13856
13857var baseEasings = {};
13858
13859$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
13860	baseEasings[ name ] = function( p ) {
13861		return Math.pow( p, i + 2 );
13862	};
13863});
13864
13865$.extend( baseEasings, {
13866	Sine: function ( p ) {
13867		return 1 - Math.cos( p * Math.PI / 2 );
13868	},
13869	Circ: function ( p ) {
13870		return 1 - Math.sqrt( 1 - p * p );
13871	},
13872	Elastic: function( p ) {
13873		return p === 0 || p === 1 ? p :
13874			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
13875	},
13876	Back: function( p ) {
13877		return p * p * ( 3 * p - 2 );
13878	},
13879	Bounce: function ( p ) {
13880		var pow2,
13881			bounce = 4;
13882
13883		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
13884		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
13885	}
13886});
13887
13888$.each( baseEasings, function( name, easeIn ) {
13889	$.easing[ "easeIn" + name ] = easeIn;
13890	$.easing[ "easeOut" + name ] = function( p ) {
13891		return 1 - easeIn( 1 - p );
13892	};
13893	$.easing[ "easeInOut" + name ] = function( p ) {
13894		return p < 0.5 ?
13895			easeIn( p * 2 ) / 2 :
13896			1 - easeIn( p * -2 + 2 ) / 2;
13897	};
13898});
13899
13900})();
13901
13902})(jQuery));
13903(function( $, undefined ) {
13904
13905var rvertical = /up|down|vertical/,
13906	rpositivemotion = /up|left|vertical|horizontal/;
13907
13908$.effects.effect.blind = function( o, done ) {
13909	// Create element
13910	var el = $( this ),
13911		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13912		mode = $.effects.setMode( el, o.mode || "hide" ),
13913		direction = o.direction || "up",
13914		vertical = rvertical.test( direction ),
13915		ref = vertical ? "height" : "width",
13916		ref2 = vertical ? "top" : "left",
13917		motion = rpositivemotion.test( direction ),
13918		animation = {},
13919		show = mode === "show",
13920		wrapper, distance, margin;
13921
13922	// if already wrapped, the wrapper's properties are my property. #6245
13923	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
13924		$.effects.save( el.parent(), props );
13925	} else {
13926		$.effects.save( el, props );
13927	}
13928	el.show();
13929	wrapper = $.effects.createWrapper( el ).css({
13930		overflow: "hidden"
13931	});
13932
13933	distance = wrapper[ ref ]();
13934	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
13935
13936	animation[ ref ] = show ? distance : 0;
13937	if ( !motion ) {
13938		el
13939			.css( vertical ? "bottom" : "right", 0 )
13940			.css( vertical ? "top" : "left", "auto" )
13941			.css({ position: "absolute" });
13942
13943		animation[ ref2 ] = show ? margin : distance + margin;
13944	}
13945
13946	// start at 0 if we are showing
13947	if ( show ) {
13948		wrapper.css( ref, 0 );
13949		if ( ! motion ) {
13950			wrapper.css( ref2, margin + distance );
13951		}
13952	}
13953
13954	// Animate
13955	wrapper.animate( animation, {
13956		duration: o.duration,
13957		easing: o.easing,
13958		queue: false,
13959		complete: function() {
13960			if ( mode === "hide" ) {
13961				el.hide();
13962			}
13963			$.effects.restore( el, props );
13964			$.effects.removeWrapper( el );
13965			done();
13966		}
13967	});
13968
13969};
13970
13971})(jQuery);
13972(function( $, undefined ) {
13973
13974$.effects.effect.bounce = function( o, done ) {
13975	var el = $( this ),
13976		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13977
13978		// defaults:
13979		mode = $.effects.setMode( el, o.mode || "effect" ),
13980		hide = mode === "hide",
13981		show = mode === "show",
13982		direction = o.direction || "up",
13983		distance = o.distance,
13984		times = o.times || 5,
13985
13986		// number of internal animations
13987		anims = times * 2 + ( show || hide ? 1 : 0 ),
13988		speed = o.duration / anims,
13989		easing = o.easing,
13990
13991		// utility:
13992		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
13993		motion = ( direction === "up" || direction === "left" ),
13994		i,
13995		upAnim,
13996		downAnim,
13997
13998		// we will need to re-assemble the queue to stack our animations in place
13999		queue = el.queue(),
14000		queuelen = queue.length;
14001
14002	// Avoid touching opacity to prevent clearType and PNG issues in IE
14003	if ( show || hide ) {
14004		props.push( "opacity" );
14005	}
14006
14007	$.effects.save( el, props );
14008	el.show();
14009	$.effects.createWrapper( el ); // Create Wrapper
14010
14011	// default distance for the BIGGEST bounce is the outer Distance / 3
14012	if ( !distance ) {
14013		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
14014	}
14015
14016	if ( show ) {
14017		downAnim = { opacity: 1 };
14018		downAnim[ ref ] = 0;
14019
14020		// if we are showing, force opacity 0 and set the initial position
14021		// then do the "first" animation
14022		el.css( "opacity", 0 )
14023			.css( ref, motion ? -distance * 2 : distance * 2 )
14024			.animate( downAnim, speed, easing );
14025	}
14026
14027	// start at the smallest distance if we are hiding
14028	if ( hide ) {
14029		distance = distance / Math.pow( 2, times - 1 );
14030	}
14031
14032	downAnim = {};
14033	downAnim[ ref ] = 0;
14034	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
14035	for ( i = 0; i < times; i++ ) {
14036		upAnim = {};
14037		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14038
14039		el.animate( upAnim, speed, easing )
14040			.animate( downAnim, speed, easing );
14041
14042		distance = hide ? distance * 2 : distance / 2;
14043	}
14044
14045	// Last Bounce when Hiding
14046	if ( hide ) {
14047		upAnim = { opacity: 0 };
14048		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14049
14050		el.animate( upAnim, speed, easing );
14051	}
14052
14053	el.queue(function() {
14054		if ( hide ) {
14055			el.hide();
14056		}
14057		$.effects.restore( el, props );
14058		$.effects.removeWrapper( el );
14059		done();
14060	});
14061
14062	// inject all the animations we just queued to be first in line (after "inprogress")
14063	if ( queuelen > 1) {
14064		queue.splice.apply( queue,
14065			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14066	}
14067	el.dequeue();
14068
14069};
14070
14071})(jQuery);
14072(function( $, undefined ) {
14073
14074$.effects.effect.clip = function( o, done ) {
14075	// Create element
14076	var el = $( this ),
14077		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14078		mode = $.effects.setMode( el, o.mode || "hide" ),
14079		show = mode === "show",
14080		direction = o.direction || "vertical",
14081		vert = direction === "vertical",
14082		size = vert ? "height" : "width",
14083		position = vert ? "top" : "left",
14084		animation = {},
14085		wrapper, animate, distance;
14086
14087	// Save & Show
14088	$.effects.save( el, props );
14089	el.show();
14090
14091	// Create Wrapper
14092	wrapper = $.effects.createWrapper( el ).css({
14093		overflow: "hidden"
14094	});
14095	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
14096	distance = animate[ size ]();
14097
14098	// Shift
14099	if ( show ) {
14100		animate.css( size, 0 );
14101		animate.css( position, distance / 2 );
14102	}
14103
14104	// Create Animation Object:
14105	animation[ size ] = show ? distance : 0;
14106	animation[ position ] = show ? 0 : distance / 2;
14107
14108	// Animate
14109	animate.animate( animation, {
14110		queue: false,
14111		duration: o.duration,
14112		easing: o.easing,
14113		complete: function() {
14114			if ( !show ) {
14115				el.hide();
14116			}
14117			$.effects.restore( el, props );
14118			$.effects.removeWrapper( el );
14119			done();
14120		}
14121	});
14122
14123};
14124
14125})(jQuery);
14126(function( $, undefined ) {
14127
14128$.effects.effect.drop = function( o, done ) {
14129
14130	var el = $( this ),
14131		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
14132		mode = $.effects.setMode( el, o.mode || "hide" ),
14133		show = mode === "show",
14134		direction = o.direction || "left",
14135		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14136		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
14137		animation = {
14138			opacity: show ? 1 : 0
14139		},
14140		distance;
14141
14142	// Adjust
14143	$.effects.save( el, props );
14144	el.show();
14145	$.effects.createWrapper( el );
14146
14147	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
14148
14149	if ( show ) {
14150		el
14151			.css( "opacity", 0 )
14152			.css( ref, motion === "pos" ? -distance : distance );
14153	}
14154
14155	// Animation
14156	animation[ ref ] = ( show ?
14157		( motion === "pos" ? "+=" : "-=" ) :
14158		( motion === "pos" ? "-=" : "+=" ) ) +
14159		distance;
14160
14161	// Animate
14162	el.animate( animation, {
14163		queue: false,
14164		duration: o.duration,
14165		easing: o.easing,
14166		complete: function() {
14167			if ( mode === "hide" ) {
14168				el.hide();
14169			}
14170			$.effects.restore( el, props );
14171			$.effects.removeWrapper( el );
14172			done();
14173		}
14174	});
14175};
14176
14177})(jQuery);
14178(function( $, undefined ) {
14179
14180$.effects.effect.explode = function( o, done ) {
14181
14182	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
14183		cells = rows,
14184		el = $( this ),
14185		mode = $.effects.setMode( el, o.mode || "hide" ),
14186		show = mode === "show",
14187
14188		// show and then visibility:hidden the element before calculating offset
14189		offset = el.show().css( "visibility", "hidden" ).offset(),
14190
14191		// width and height of a piece
14192		width = Math.ceil( el.outerWidth() / cells ),
14193		height = Math.ceil( el.outerHeight() / rows ),
14194		pieces = [],
14195
14196		// loop
14197		i, j, left, top, mx, my;
14198
14199	// children animate complete:
14200	function childComplete() {
14201		pieces.push( this );
14202		if ( pieces.length === rows * cells ) {
14203			animComplete();
14204		}
14205	}
14206
14207	// clone the element for each row and cell.
14208	for( i = 0; i < rows ; i++ ) { // ===>
14209		top = offset.top + i * height;
14210		my = i - ( rows - 1 ) / 2 ;
14211
14212		for( j = 0; j < cells ; j++ ) { // |||
14213			left = offset.left + j * width;
14214			mx = j - ( cells - 1 ) / 2 ;
14215
14216			// Create a clone of the now hidden main element that will be absolute positioned
14217			// within a wrapper div off the -left and -top equal to size of our pieces
14218			el
14219				.clone()
14220				.appendTo( "body" )
14221				.wrap( "<div></div>" )
14222				.css({
14223					position: "absolute",
14224					visibility: "visible",
14225					left: -j * width,
14226					top: -i * height
14227				})
14228
14229			// select the wrapper - make it overflow: hidden and absolute positioned based on
14230			// where the original was located +left and +top equal to the size of pieces
14231				.parent()
14232				.addClass( "ui-effects-explode" )
14233				.css({
14234					position: "absolute",
14235					overflow: "hidden",
14236					width: width,
14237					height: height,
14238					left: left + ( show ? mx * width : 0 ),
14239					top: top + ( show ? my * height : 0 ),
14240					opacity: show ? 0 : 1
14241				}).animate({
14242					left: left + ( show ? 0 : mx * width ),
14243					top: top + ( show ? 0 : my * height ),
14244					opacity: show ? 1 : 0
14245				}, o.duration || 500, o.easing, childComplete );
14246		}
14247	}
14248
14249	function animComplete() {
14250		el.css({
14251			visibility: "visible"
14252		});
14253		$( pieces ).remove();
14254		if ( !show ) {
14255			el.hide();
14256		}
14257		done();
14258	}
14259};
14260
14261})(jQuery);
14262(function( $, undefined ) {
14263
14264$.effects.effect.fade = function( o, done ) {
14265	var el = $( this ),
14266		mode = $.effects.setMode( el, o.mode || "toggle" );
14267
14268	el.animate({
14269		opacity: mode
14270	}, {
14271		queue: false,
14272		duration: o.duration,
14273		easing: o.easing,
14274		complete: done
14275	});
14276};
14277
14278})( jQuery );
14279(function( $, undefined ) {
14280
14281$.effects.effect.fold = function( o, done ) {
14282
14283	// Create element
14284	var el = $( this ),
14285		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14286		mode = $.effects.setMode( el, o.mode || "hide" ),
14287		show = mode === "show",
14288		hide = mode === "hide",
14289		size = o.size || 15,
14290		percent = /([0-9]+)%/.exec( size ),
14291		horizFirst = !!o.horizFirst,
14292		widthFirst = show !== horizFirst,
14293		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
14294		duration = o.duration / 2,
14295		wrapper, distance,
14296		animation1 = {},
14297		animation2 = {};
14298
14299	$.effects.save( el, props );
14300	el.show();
14301
14302	// Create Wrapper
14303	wrapper = $.effects.createWrapper( el ).css({
14304		overflow: "hidden"
14305	});
14306	distance = widthFirst ?
14307		[ wrapper.width(), wrapper.height() ] :
14308		[ wrapper.height(), wrapper.width() ];
14309
14310	if ( percent ) {
14311		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
14312	}
14313	if ( show ) {
14314		wrapper.css( horizFirst ? {
14315			height: 0,
14316			width: size
14317		} : {
14318			height: size,
14319			width: 0
14320		});
14321	}
14322
14323	// Animation
14324	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
14325	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
14326
14327	// Animate
14328	wrapper
14329		.animate( animation1, duration, o.easing )
14330		.animate( animation2, duration, o.easing, function() {
14331			if ( hide ) {
14332				el.hide();
14333			}
14334			$.effects.restore( el, props );
14335			$.effects.removeWrapper( el );
14336			done();
14337		});
14338
14339};
14340
14341})(jQuery);
14342(function( $, undefined ) {
14343
14344$.effects.effect.highlight = function( o, done ) {
14345	var elem = $( this ),
14346		props = [ "backgroundImage", "backgroundColor", "opacity" ],
14347		mode = $.effects.setMode( elem, o.mode || "show" ),
14348		animation = {
14349			backgroundColor: elem.css( "backgroundColor" )
14350		};
14351
14352	if (mode === "hide") {
14353		animation.opacity = 0;
14354	}
14355
14356	$.effects.save( elem, props );
14357
14358	elem
14359		.show()
14360		.css({
14361			backgroundImage: "none",
14362			backgroundColor: o.color || "#ffff99"
14363		})
14364		.animate( animation, {
14365			queue: false,
14366			duration: o.duration,
14367			easing: o.easing,
14368			complete: function() {
14369				if ( mode === "hide" ) {
14370					elem.hide();
14371				}
14372				$.effects.restore( elem, props );
14373				done();
14374			}
14375		});
14376};
14377
14378})(jQuery);
14379(function( $, undefined ) {
14380
14381$.effects.effect.pulsate = function( o, done ) {
14382	var elem = $( this ),
14383		mode = $.effects.setMode( elem, o.mode || "show" ),
14384		show = mode === "show",
14385		hide = mode === "hide",
14386		showhide = ( show || mode === "hide" ),
14387
14388		// showing or hiding leaves of the "last" animation
14389		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
14390		duration = o.duration / anims,
14391		animateTo = 0,
14392		queue = elem.queue(),
14393		queuelen = queue.length,
14394		i;
14395
14396	if ( show || !elem.is(":visible")) {
14397		elem.css( "opacity", 0 ).show();
14398		animateTo = 1;
14399	}
14400
14401	// anims - 1 opacity "toggles"
14402	for ( i = 1; i < anims; i++ ) {
14403		elem.animate({
14404			opacity: animateTo
14405		}, duration, o.easing );
14406		animateTo = 1 - animateTo;
14407	}
14408
14409	elem.animate({
14410		opacity: animateTo
14411	}, duration, o.easing);
14412
14413	elem.queue(function() {
14414		if ( hide ) {
14415			elem.hide();
14416		}
14417		done();
14418	});
14419
14420	// We just queued up "anims" animations, we need to put them next in the queue
14421	if ( queuelen > 1 ) {
14422		queue.splice.apply( queue,
14423			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14424	}
14425	elem.dequeue();
14426};
14427
14428})(jQuery);
14429(function( $, undefined ) {
14430
14431$.effects.effect.puff = function( o, done ) {
14432	var elem = $( this ),
14433		mode = $.effects.setMode( elem, o.mode || "hide" ),
14434		hide = mode === "hide",
14435		percent = parseInt( o.percent, 10 ) || 150,
14436		factor = percent / 100,
14437		original = {
14438			height: elem.height(),
14439			width: elem.width(),
14440			outerHeight: elem.outerHeight(),
14441			outerWidth: elem.outerWidth()
14442		};
14443
14444	$.extend( o, {
14445		effect: "scale",
14446		queue: false,
14447		fade: true,
14448		mode: mode,
14449		complete: done,
14450		percent: hide ? percent : 100,
14451		from: hide ?
14452			original :
14453			{
14454				height: original.height * factor,
14455				width: original.width * factor,
14456				outerHeight: original.outerHeight * factor,
14457				outerWidth: original.outerWidth * factor
14458			}
14459	});
14460
14461	elem.effect( o );
14462};
14463
14464$.effects.effect.scale = function( o, done ) {
14465
14466	// Create element
14467	var el = $( this ),
14468		options = $.extend( true, {}, o ),
14469		mode = $.effects.setMode( el, o.mode || "effect" ),
14470		percent = parseInt( o.percent, 10 ) ||
14471			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
14472		direction = o.direction || "both",
14473		origin = o.origin,
14474		original = {
14475			height: el.height(),
14476			width: el.width(),
14477			outerHeight: el.outerHeight(),
14478			outerWidth: el.outerWidth()
14479		},
14480		factor = {
14481			y: direction !== "horizontal" ? (percent / 100) : 1,
14482			x: direction !== "vertical" ? (percent / 100) : 1
14483		};
14484
14485	// We are going to pass this effect to the size effect:
14486	options.effect = "size";
14487	options.queue = false;
14488	options.complete = done;
14489
14490	// Set default origin and restore for show/hide
14491	if ( mode !== "effect" ) {
14492		options.origin = origin || ["middle","center"];
14493		options.restore = true;
14494	}
14495
14496	options.from = o.from || ( mode === "show" ? {
14497		height: 0,
14498		width: 0,
14499		outerHeight: 0,
14500		outerWidth: 0
14501	} : original );
14502	options.to = {
14503		height: original.height * factor.y,
14504		width: original.width * factor.x,
14505		outerHeight: original.outerHeight * factor.y,
14506		outerWidth: original.outerWidth * factor.x
14507	};
14508
14509	// Fade option to support puff
14510	if ( options.fade ) {
14511		if ( mode === "show" ) {
14512			options.from.opacity = 0;
14513			options.to.opacity = 1;
14514		}
14515		if ( mode === "hide" ) {
14516			options.from.opacity = 1;
14517			options.to.opacity = 0;
14518		}
14519	}
14520
14521	// Animate
14522	el.effect( options );
14523
14524};
14525
14526$.effects.effect.size = function( o, done ) {
14527
14528	// Create element
14529	var original, baseline, factor,
14530		el = $( this ),
14531		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
14532
14533		// Always restore
14534		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
14535
14536		// Copy for children
14537		props2 = [ "width", "height", "overflow" ],
14538		cProps = [ "fontSize" ],
14539		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
14540		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
14541
14542		// Set options
14543		mode = $.effects.setMode( el, o.mode || "effect" ),
14544		restore = o.restore || mode !== "effect",
14545		scale = o.scale || "both",
14546		origin = o.origin || [ "middle", "center" ],
14547		position = el.css( "position" ),
14548		props = restore ? props0 : props1,
14549		zero = {
14550			height: 0,
14551			width: 0,
14552			outerHeight: 0,
14553			outerWidth: 0
14554		};
14555
14556	if ( mode === "show" ) {
14557		el.show();
14558	}
14559	original = {
14560		height: el.height(),
14561		width: el.width(),
14562		outerHeight: el.outerHeight(),
14563		outerWidth: el.outerWidth()
14564	};
14565
14566	if ( o.mode === "toggle" && mode === "show" ) {
14567		el.from = o.to || zero;
14568		el.to = o.from || original;
14569	} else {
14570		el.from = o.from || ( mode === "show" ? zero : original );
14571		el.to = o.to || ( mode === "hide" ? zero : original );
14572	}
14573
14574	// Set scaling factor
14575	factor = {
14576		from: {
14577			y: el.from.height / original.height,
14578			x: el.from.width / original.width
14579		},
14580		to: {
14581			y: el.to.height / original.height,
14582			x: el.to.width / original.width
14583		}
14584	};
14585
14586	// Scale the css box
14587	if ( scale === "box" || scale === "both" ) {
14588
14589		// Vertical props scaling
14590		if ( factor.from.y !== factor.to.y ) {
14591			props = props.concat( vProps );
14592			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
14593			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
14594		}
14595
14596		// Horizontal props scaling
14597		if ( factor.from.x !== factor.to.x ) {
14598			props = props.concat( hProps );
14599			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
14600			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
14601		}
14602	}
14603
14604	// Scale the content
14605	if ( scale === "content" || scale === "both" ) {
14606
14607		// Vertical props scaling
14608		if ( factor.from.y !== factor.to.y ) {
14609			props = props.concat( cProps ).concat( props2 );
14610			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
14611			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
14612		}
14613	}
14614
14615	$.effects.save( el, props );
14616	el.show();
14617	$.effects.createWrapper( el );
14618	el.css( "overflow", "hidden" ).css( el.from );
14619
14620	// Adjust
14621	if (origin) { // Calculate baseline shifts
14622		baseline = $.effects.getBaseline( origin, original );
14623		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
14624		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
14625		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
14626		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
14627	}
14628	el.css( el.from ); // set top & left
14629
14630	// Animate
14631	if ( scale === "content" || scale === "both" ) { // Scale the children
14632
14633		// Add margins/font-size
14634		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
14635		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
14636		props2 = props0.concat(vProps).concat(hProps);
14637
14638		el.find( "*[width]" ).each( function(){
14639			var child = $( this ),
14640				c_original = {
14641					height: child.height(),
14642					width: child.width(),
14643					outerHeight: child.outerHeight(),
14644					outerWidth: child.outerWidth()
14645				};
14646			if (restore) {
14647				$.effects.save(child, props2);
14648			}
14649
14650			child.from = {
14651				height: c_original.height * factor.from.y,
14652				width: c_original.width * factor.from.x,
14653				outerHeight: c_original.outerHeight * factor.from.y,
14654				outerWidth: c_original.outerWidth * factor.from.x
14655			};
14656			child.to = {
14657				height: c_original.height * factor.to.y,
14658				width: c_original.width * factor.to.x,
14659				outerHeight: c_original.height * factor.to.y,
14660				outerWidth: c_original.width * factor.to.x
14661			};
14662
14663			// Vertical props scaling
14664			if ( factor.from.y !== factor.to.y ) {
14665				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
14666				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
14667			}
14668
14669			// Horizontal props scaling
14670			if ( factor.from.x !== factor.to.x ) {
14671				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
14672				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
14673			}
14674
14675			// Animate children
14676			child.css( child.from );
14677			child.animate( child.to, o.duration, o.easing, function() {
14678
14679				// Restore children
14680				if ( restore ) {
14681					$.effects.restore( child, props2 );
14682				}
14683			});
14684		});
14685	}
14686
14687	// Animate
14688	el.animate( el.to, {
14689		queue: false,
14690		duration: o.duration,
14691		easing: o.easing,
14692		complete: function() {
14693			if ( el.to.opacity === 0 ) {
14694				el.css( "opacity", el.from.opacity );
14695			}
14696			if( mode === "hide" ) {
14697				el.hide();
14698			}
14699			$.effects.restore( el, props );
14700			if ( !restore ) {
14701
14702				// we need to calculate our new positioning based on the scaling
14703				if ( position === "static" ) {
14704					el.css({
14705						position: "relative",
14706						top: el.to.top,
14707						left: el.to.left
14708					});
14709				} else {
14710					$.each([ "top", "left" ], function( idx, pos ) {
14711						el.css( pos, function( _, str ) {
14712							var val = parseInt( str, 10 ),
14713								toRef = idx ? el.to.left : el.to.top;
14714
14715							// if original was "auto", recalculate the new value from wrapper
14716							if ( str === "auto" ) {
14717								return toRef + "px";
14718							}
14719
14720							return val + toRef + "px";
14721						});
14722					});
14723				}
14724			}
14725
14726			$.effects.removeWrapper( el );
14727			done();
14728		}
14729	});
14730
14731};
14732
14733})(jQuery);
14734(function( $, undefined ) {
14735
14736$.effects.effect.shake = function( o, done ) {
14737
14738	var el = $( this ),
14739		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14740		mode = $.effects.setMode( el, o.mode || "effect" ),
14741		direction = o.direction || "left",
14742		distance = o.distance || 20,
14743		times = o.times || 3,
14744		anims = times * 2 + 1,
14745		speed = Math.round(o.duration/anims),
14746		ref = (direction === "up" || direction === "down") ? "top" : "left",
14747		positiveMotion = (direction === "up" || direction === "left"),
14748		animation = {},
14749		animation1 = {},
14750		animation2 = {},
14751		i,
14752
14753		// we will need to re-assemble the queue to stack our animations in place
14754		queue = el.queue(),
14755		queuelen = queue.length;
14756
14757	$.effects.save( el, props );
14758	el.show();
14759	$.effects.createWrapper( el );
14760
14761	// Animation
14762	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
14763	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
14764	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
14765
14766	// Animate
14767	el.animate( animation, speed, o.easing );
14768
14769	// Shakes
14770	for ( i = 1; i < times; i++ ) {
14771		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
14772	}
14773	el
14774		.animate( animation1, speed, o.easing )
14775		.animate( animation, speed / 2, o.easing )
14776		.queue(function() {
14777			if ( mode === "hide" ) {
14778				el.hide();
14779			}
14780			$.effects.restore( el, props );
14781			$.effects.removeWrapper( el );
14782			done();
14783		});
14784
14785	// inject all the animations we just queued to be first in line (after "inprogress")
14786	if ( queuelen > 1) {
14787		queue.splice.apply( queue,
14788			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14789	}
14790	el.dequeue();
14791
14792};
14793
14794})(jQuery);
14795(function( $, undefined ) {
14796
14797$.effects.effect.slide = function( o, done ) {
14798
14799	// Create element
14800	var el = $( this ),
14801		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
14802		mode = $.effects.setMode( el, o.mode || "show" ),
14803		show = mode === "show",
14804		direction = o.direction || "left",
14805		ref = (direction === "up" || direction === "down") ? "top" : "left",
14806		positiveMotion = (direction === "up" || direction === "left"),
14807		distance,
14808		animation = {};
14809
14810	// Adjust
14811	$.effects.save( el, props );
14812	el.show();
14813	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
14814
14815	$.effects.createWrapper( el ).css({
14816		overflow: "hidden"
14817	});
14818
14819	if ( show ) {
14820		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
14821	}
14822
14823	// Animation
14824	animation[ ref ] = ( show ?
14825		( positiveMotion ? "+=" : "-=") :
14826		( positiveMotion ? "-=" : "+=")) +
14827		distance;
14828
14829	// Animate
14830	el.animate( animation, {
14831		queue: false,
14832		duration: o.duration,
14833		easing: o.easing,
14834		complete: function() {
14835			if ( mode === "hide" ) {
14836				el.hide();
14837			}
14838			$.effects.restore( el, props );
14839			$.effects.removeWrapper( el );
14840			done();
14841		}
14842	});
14843};
14844
14845})(jQuery);
14846(function( $, undefined ) {
14847
14848$.effects.effect.transfer = function( o, done ) {
14849	var elem = $( this ),
14850		target = $( o.to ),
14851		targetFixed = target.css( "position" ) === "fixed",
14852		body = $("body"),
14853		fixTop = targetFixed ? body.scrollTop() : 0,
14854		fixLeft = targetFixed ? body.scrollLeft() : 0,
14855		endPosition = target.offset(),
14856		animation = {
14857			top: endPosition.top - fixTop ,
14858			left: endPosition.left - fixLeft ,
14859			height: target.innerHeight(),
14860			width: target.innerWidth()
14861		},
14862		startPosition = elem.offset(),
14863		transfer = $( '<div class="ui-effects-transfer"></div>' )
14864			.appendTo( document.body )
14865			.addClass( o.className )
14866			.css({
14867				top: startPosition.top - fixTop ,
14868				left: startPosition.left - fixLeft ,
14869				height: elem.innerHeight(),
14870				width: elem.innerWidth(),
14871				position: targetFixed ? "fixed" : "absolute"
14872			})
14873			.animate( animation, o.duration, o.easing, function() {
14874				transfer.remove();
14875				done();
14876			});
14877};
14878
14879})(jQuery);

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