PageSourceSearch

https://themagicuniverse.com/wp-content/themes/listingpro/assets/js/jquery-ui.js?ver=7.1

js themagicuniverse.com collected 2026-10-06 22:18:05 UTC 501,434 bytes, 17,970 lines download raw bytes

1/*! jQuery UI - v1.12.1 - 2017-10-14
2* http://jqueryui.com
3* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer
vendor: 46,668 bytes, lines 3-1721
3.js
4* Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6(function( factory ) {
7	if ( typeof define === "function" && define.amd ) {
8
9		// AMD. Register as an anonymous module.
10		define([ "jquery" ], factory );
11	} else {
12
13		// Browser globals
14		factory( jQuery );
15	}
16}(function( $ ) {
17
18$.ui = $.ui || {};
19
20var version = $.ui.version = "1.12.1";
21
22
23/*!
24 * jQuery UI Widget 1.12.1
25 * http://jqueryui.com
26 *
27 * Copyright jQuery Foundation and other contributors
28 * Released under the MIT license.
29 * http://jquery.org/license
30 */
31
32//>>label: Widget
33//>>group: Core
34//>>description: Provides a factory for creating stateful widgets with a common API.
35//>>docs: http://api.jqueryui.com/jQuery.widget/
36//>>demos: http://jqueryui.com/widget/
37
38
39
40var widgetUuid = 0;
41var widgetSlice = Array.prototype.slice;
42
43$.cleanData = ( function( orig ) {
44	return function( elems ) {
45		var events, elem, i;
46		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
47			try {
48
49				// Only trigger remove when necessary to save time
50				events = $._data( elem, "events" );
51				if ( events && events.remove ) {
52					$( elem ).triggerHandler( "remove" );
53				}
54
55			// Http://bugs.jquery.com/ticket/8235
56			} catch ( e ) {}
57		}
58		orig( elems );
59	};
60} )( $.cleanData );
61
62$.widget = function( name, base, prototype ) {
63	var existingConstructor, constructor, basePrototype;
64
65	// ProxiedPrototype allows the provided prototype to remain unmodified
66	// so that it can be used as a mixin for multiple widgets (#8876)
67	var proxiedPrototype = {};
68
69	var namespace = name.split( "." )[ 0 ];
70	name = name.split( "." )[ 1 ];
71	var fullName = namespace + "-" + name;
72
73	if ( !prototype ) {
74		prototype = base;
75		base = $.Widget;
76	}
77
78	if ( $.isArray( prototype ) ) {
79		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
80	}
81
82	// Create selector for plugin
83	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
84		return !!$.data( elem, fullName );
85	};
86
87	$[ namespace ] = $[ namespace ] || {};
88	existingConstructor = $[ namespace ][ name ];
89	constructor = $[ namespace ][ name ] = function( options, element ) {
90
91		// Allow instantiation without "new" keyword
92		if ( !this._createWidget ) {
93			return new constructor( options, element );
94		}
95
96		// Allow instantiation without initializing for simple inheritance
97		// must use "new" keyword (the code above always passes args)
98		if ( arguments.length ) {
99			this._createWidget( options, element );
100		}
101	};
102
103	// Extend with the existing constructor to carry over any static properties
104	$.extend( constructor, existingConstructor, {
105		version: prototype.version,
106
107		// Copy the object used to create the prototype in case we need to
108		// redefine the widget later
109		_proto: $.extend( {}, prototype ),
110
111		// Track widgets that inherit from this widget in case this widget is
112		// redefined after a widget inherits from it
113		_childConstructors: []
114	} );
115
116	basePrototype = new base();
117
118	// We need to make the options hash a property directly on the new instance
119	// otherwise we'll modify the options hash on the prototype that we're
120	// inheriting from
121	basePrototype.options = $.widget.extend( {}, basePrototype.options );
122	$.each( prototype, function( prop, value ) {
123		if ( !$.isFunction( value ) ) {
124			proxiedPrototype[ prop ] = value;
125			return;
126		}
127		proxiedPrototype[ prop ] = ( function() {
128			function _super() {
129				return base.prototype[ prop ].apply( this, arguments );
130			}
131
132			function _superApply( args ) {
133				return base.prototype[ prop ].apply( this, args );
134			}
135
136			return function() {
137				var __super = this._super;
138				var __superApply = this._superApply;
139				var returnValue;
140
141				this._super = _super;
142				this._superApply = _superApply;
143
144				returnValue = value.apply( this, arguments );
145
146				this._super = __super;
147				this._superApply = __superApply;
148
149				return returnValue;
150			};
151		} )();
152	} );
153	constructor.prototype = $.widget.extend( basePrototype, {
154
155		// TODO: remove support for widgetEventPrefix
156		// always use the name + a colon as the prefix, e.g., draggable:start
157		// don't prefix for widgets that aren't DOM-based
158		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
159	}, proxiedPrototype, {
160		constructor: constructor,
161		namespace: namespace,
162		widgetName: name,
163		widgetFullName: fullName
164	} );
165
166	// If this widget is being redefined then we need to find all widgets that
167	// are inheriting from it and redefine all of them so that they inherit from
168	// the new version of this widget. We're essentially trying to replace one
169	// level in the prototype chain.
170	if ( existingConstructor ) {
171		$.each( existingConstructor._childConstructors, function( i, child ) {
172			var childPrototype = child.prototype;
173
174			// Redefine the child widget using the same prototype that was
175			// originally used, but inherit from the new version of the base
176			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
177				child._proto );
178		} );
179
180		// Remove the list of existing child constructors from the old constructor
181		// so the old child constructors can be garbage collected
182		delete existingConstructor._childConstructors;
183	} else {
184		base._childConstructors.push( constructor );
185	}
186
187	$.widget.bridge( name, constructor );
188
189	return constructor;
190};
191
192$.widget.extend = function( target ) {
193	var input = widgetSlice.call( arguments, 1 );
194	var inputIndex = 0;
195	var inputLength = input.length;
196	var key;
197	var value;
198
199	for ( ; inputIndex < inputLength; inputIndex++ ) {
200		for ( key in input[ inputIndex ] ) {
201			value = input[ inputIndex ][ key ];
202			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
203
204				// Clone objects
205				if ( $.isPlainObject( value ) ) {
206					target[ key ] = $.isPlainObject( target[ key ] ) ?
207						$.widget.extend( {}, target[ key ], value ) :
208
209						// Don't extend strings, arrays, etc. with objects
210						$.widget.extend( {}, value );
211
212				// Copy everything else by reference
213				} else {
214					target[ key ] = value;
215				}
216			}
217		}
218	}
219	return target;
220};
221
222$.widget.bridge = function( name, object ) {
223	var fullName = object.prototype.widgetFullName || name;
224	$.fn[ name ] = function( options ) {
225		var isMethodCall = typeof options === "string";
226		var args = widgetSlice.call( arguments, 1 );
227		var returnValue = this;
228
229		if ( isMethodCall ) {
230
231			// If this is an empty collection, we need to have the instance method
232			// return undefined instead of the jQuery instance
233			if ( !this.length && options === "instance" ) {
234				returnValue = undefined;
235			} else {
236				this.each( function() {
237					var methodValue;
238					var instance = $.data( this, fullName );
239
240					if ( options === "instance" ) {
241						returnValue = instance;
242						return false;
243					}
244
245					if ( !instance ) {
246						return $.error( "cannot call methods on " + name +
247							" prior to initialization; " +
248							"attempted to call method '" + options + "'" );
249					}
250
251					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
252						return $.error( "no such method '" + options + "' for " + name +
253							" widget instance" );
254					}
255
256					methodValue = instance[ options ].apply( instance, args );
257
258					if ( methodValue !== instance && methodValue !== undefined ) {
259						returnValue = methodValue && methodValue.jquery ?
260							returnValue.pushStack( methodValue.get() ) :
261							methodValue;
262						return false;
263					}
264				} );
265			}
266		} else {
267
268			// Allow multiple hashes to be passed on init
269			if ( args.length ) {
270				options = $.widget.extend.apply( null, [ options ].concat( args ) );
271			}
272
273			this.each( function() {
274				var instance = $.data( this, fullName );
275				if ( instance ) {
276					instance.option( options || {} );
277					if ( instance._init ) {
278						instance._init();
279					}
280				} else {
281					$.data( this, fullName, new object( options, this ) );
282				}
283			} );
284		}
285
286		return returnValue;
287	};
288};
289
290$.Widget = function( /* options, element */ ) {};
291$.Widget._childConstructors = [];
292
293$.Widget.prototype = {
294	widgetName: "widget",
295	widgetEventPrefix: "",
296	defaultElement: "<div>",
297
298	options: {
299		classes: {},
300		disabled: false,
301
302		// Callbacks
303		create: null
304	},
305
306	_createWidget: function( options, element ) {
307		element = $( element || this.defaultElement || this )[ 0 ];
308		this.element = $( element );
309		this.uuid = widgetUuid++;
310		this.eventNamespace = "." + this.widgetName + this.uuid;
311
312		this.bindings = $();
313		this.hoverable = $();
314		this.focusable = $();
315		this.classesElementLookup = {};
316
317		if ( element !== this ) {
318			$.data( element, this.widgetFullName, this );
319			this._on( true, this.element, {
320				remove: function( event ) {
321					if ( event.target === element ) {
322						this.destroy();
323					}
324				}
325			} );
326			this.document = $( element.style ?
327
328				// Element within the document
329				element.ownerDocument :
330
331				// Element is window or document
332				element.document || element );
333			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
334		}
335
336		this.options = $.widget.extend( {},
337			this.options,
338			this._getCreateOptions(),
339			options );
340
341		this._create();
342
343		if ( this.options.disabled ) {
344			this._setOptionDisabled( this.options.disabled );
345		}
346
347		this._trigger( "create", null, this._getCreateEventData() );
348		this._init();
349	},
350
351	_getCreateOptions: function() {
352		return {};
353	},
354
355	_getCreateEventData: $.noop,
356
357	_create: $.noop,
358
359	_init: $.noop,
360
361	destroy: function() {
362		var that = this;
363
364		this._destroy();
365		$.each( this.classesElementLookup, function( key, value ) {
366			that._removeClass( value, key );
367		} );
368
369		// We can probably remove the unbind calls in 2.0
370		// all event bindings should go through this._on()
371		this.element
372			.off( this.eventNamespace )
373			.removeData( this.widgetFullName );
374		this.widget()
375			.off( this.eventNamespace )
376			.removeAttr( "aria-disabled" );
377
378		// Clean up events and states
379		this.bindings.off( this.eventNamespace );
380	},
381
382	_destroy: $.noop,
383
384	widget: function() {
385		return this.element;
386	},
387
388	option: function( key, value ) {
389		var options = key;
390		var parts;
391		var curOption;
392		var i;
393
394		if ( arguments.length === 0 ) {
395
396			// Don't return a reference to the internal hash
397			return $.widget.extend( {}, this.options );
398		}
399
400		if ( typeof key === "string" ) {
401
402			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
403			options = {};
404			parts = key.split( "." );
405			key = parts.shift();
406			if ( parts.length ) {
407				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
408				for ( i = 0; i < parts.length - 1; i++ ) {
409					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
410					curOption = curOption[ parts[ i ] ];
411				}
412				key = parts.pop();
413				if ( arguments.length === 1 ) {
414					return curOption[ key ] === undefined ? null : curOption[ key ];
415				}
416				curOption[ key ] = value;
417			} else {
418				if ( arguments.length === 1 ) {
419					return this.options[ key ] === undefined ? null : this.options[ key ];
420				}
421				options[ key ] = value;
422			}
423		}
424
425		this._setOptions( options );
426
427		return this;
428	},
429
430	_setOptions: function( options ) {
431		var key;
432
433		for ( key in options ) {
434			this._setOption( key, options[ key ] );
435		}
436
437		return this;
438	},
439
440	_setOption: function( key, value ) {
441		if ( key === "classes" ) {
442			this._setOptionClasses( value );
443		}
444
445		this.options[ key ] = value;
446
447		if ( key === "disabled" ) {
448			this._setOptionDisabled( value );
449		}
450
451		return this;
452	},
453
454	_setOptionClasses: function( value ) {
455		var classKey, elements, currentElements;
456
457		for ( classKey in value ) {
458			currentElements = this.classesElementLookup[ classKey ];
459			if ( value[ classKey ] === this.options.classes[ classKey ] ||
460					!currentElements ||
461					!currentElements.length ) {
462				continue;
463			}
464
465			// We are doing this to create a new jQuery object because the _removeClass() call
466			// on the next line is going to destroy the reference to the current elements being
467			// tracked. We need to save a copy of this collection so that we can add the new classes
468			// below.
469			elements = $( currentElements.get() );
470			this._removeClass( currentElements, classKey );
471
472			// We don't use _addClass() here, because that uses this.options.classes
473			// for generating the string of classes. We want to use the value passed in from
474			// _setOption(), this is the new value of the classes option which was passed to
475			// _setOption(). We pass this value directly to _classes().
476			elements.addClass( this._classes( {
477				element: elements,
478				keys: classKey,
479				classes: value,
480				add: true
481			} ) );
482		}
483	},
484
485	_setOptionDisabled: function( value ) {
486		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
487
488		// If the widget is becoming disabled, then nothing is interactive
489		if ( value ) {
490			this._removeClass( this.hoverable, null, "ui-state-hover" );
491			this._removeClass( this.focusable, null, "ui-state-focus" );
492		}
493	},
494
495	enable: function() {
496		return this._setOptions( { disabled: false } );
497	},
498
499	disable: function() {
500		return this._setOptions( { disabled: true } );
501	},
502
503	_classes: function( options ) {
504		var full = [];
505		var that = this;
506
507		options = $.extend( {
508			element: this.element,
509			classes: this.options.classes || {}
510		}, options );
511
512		function processClassString( classes, checkOption ) {
513			var current, i;
514			for ( i = 0; i < classes.length; i++ ) {
515				current = that.classesElementLookup[ classes[ i ] ] || $();
516				if ( options.add ) {
517					current = $( $.unique( current.get().concat( options.element.get() ) ) );
518				} else {
519					current = $( current.not( options.element ).get() );
520				}
521				that.classesElementLookup[ classes[ i ] ] = current;
522				full.push( classes[ i ] );
523				if ( checkOption && options.classes[ classes[ i ] ] ) {
524					full.push( options.classes[ classes[ i ] ] );
525				}
526			}
527		}
528
529		this._on( options.element, {
530			"remove": "_untrackClassesElement"
531		} );
532
533		if ( options.keys ) {
534			processClassString( options.keys.match( /\S+/g ) || [], true );
535		}
536		if ( options.extra ) {
537			processClassString( options.extra.match( /\S+/g ) || [] );
538		}
539
540		return full.join( " " );
541	},
542
543	_untrackClassesElement: function( event ) {
544		var that = this;
545		$.each( that.classesElementLookup, function( key, value ) {
546			if ( $.inArray( event.target, value ) !== -1 ) {
547				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
548			}
549		} );
550	},
551
552	_removeClass: function( element, keys, extra ) {
553		return this._toggleClass( element, keys, extra, false );
554	},
555
556	_addClass: function( element, keys, extra ) {
557		return this._toggleClass( element, keys, extra, true );
558	},
559
560	_toggleClass: function( element, keys, extra, add ) {
561		add = ( typeof add === "boolean" ) ? add : extra;
562		var shift = ( typeof element === "string" || element === null ),
563			options = {
564				extra: shift ? keys : extra,
565				keys: shift ? element : keys,
566				element: shift ? this.element : element,
567				add: add
568			};
569		options.element.toggleClass( this._classes( options ), add );
570		return this;
571	},
572
573	_on: function( suppressDisabledCheck, element, handlers ) {
574		var delegateElement;
575		var instance = this;
576
577		// No suppressDisabledCheck flag, shuffle arguments
578		if ( typeof suppressDisabledCheck !== "boolean" ) {
579			handlers = element;
580			element = suppressDisabledCheck;
581			suppressDisabledCheck = false;
582		}
583
584		// No element argument, shuffle and use this.element
585		if ( !handlers ) {
586			handlers = element;
587			element = this.element;
588			delegateElement = this.widget();
589		} else {
590			element = delegateElement = $( element );
591			this.bindings = this.bindings.add( element );
592		}
593
594		$.each( handlers, function( event, handler ) {
595			function handlerProxy() {
596
597				// Allow widgets to customize the disabled handling
598				// - disabled as an array instead of boolean
599				// - disabled class as method for disabling individual parts
600				if ( !suppressDisabledCheck &&
601						( instance.options.disabled === true ||
602						$( this ).hasClass( "ui-state-disabled" ) ) ) {
603					return;
604				}
605				return ( typeof handler === "string" ? instance[ handler ] : handler )
606					.apply( instance, arguments );
607			}
608
609			// Copy the guid so direct unbinding works
610			if ( typeof handler !== "string" ) {
611				handlerProxy.guid = handler.guid =
612					handler.guid || handlerProxy.guid || $.guid++;
613			}
614
615			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
616			var eventName = match[ 1 ] + instance.eventNamespace;
617			var selector = match[ 2 ];
618
619			if ( selector ) {
620				delegateElement.on( eventName, selector, handlerProxy );
621			} else {
622				element.on( eventName, handlerProxy );
623			}
624		} );
625	},
626
627	_off: function( element, eventName ) {
628		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
629			this.eventNamespace;
630		element.off( eventName ).off( eventName );
631
632		// Clear the stack to avoid memory leaks (#10056)
633		this.bindings = $( this.bindings.not( element ).get() );
634		this.focusable = $( this.focusable.not( element ).get() );
635		this.hoverable = $( this.hoverable.not( element ).get() );
636	},
637
638	_delay: function( handler, delay ) {
639		function handlerProxy() {
640			return ( typeof handler === "string" ? instance[ handler ] : handler )
641				.apply( instance, arguments );
642		}
643		var instance = this;
644		return setTimeout( handlerProxy, delay || 0 );
645	},
646
647	_hoverable: function( element ) {
648		this.hoverable = this.hoverable.add( element );
649		this._on( element, {
650			mouseenter: function( event ) {
651				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
652			},
653			mouseleave: function( event ) {
654				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
655			}
656		} );
657	},
658
659	_focusable: function( element ) {
660		this.focusable = this.focusable.add( element );
661		this._on( element, {
662			focusin: function( event ) {
663				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
664			},
665			focusout: function( event ) {
666				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
667			}
668		} );
669	},
670
671	_trigger: function( type, event, data ) {
672		var prop, orig;
673		var callback = this.options[ type ];
674
675		data = data || {};
676		event = $.Event( event );
677		event.type = ( type === this.widgetEventPrefix ?
678			type :
679			this.widgetEventPrefix + type ).toLowerCase();
680
681		// The original event may come from any element
682		// so we need to reset the target on the new event
683		event.target = this.element[ 0 ];
684
685		// Copy original event properties over to the new event
686		orig = event.originalEvent;
687		if ( orig ) {
688			for ( prop in orig ) {
689				if ( !( prop in event ) ) {
690					event[ prop ] = orig[ prop ];
691				}
692			}
693		}
694
695		this.element.trigger( event, data );
696		return !( $.isFunction( callback ) &&
697			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
698			event.isDefaultPrevented() );
699	}
700};
701
702$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
703	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
704		if ( typeof options === "string" ) {
705			options = { effect: options };
706		}
707
708		var hasOptions;
709		var effectName = !options ?
710			method :
711			options === true || typeof options === "number" ?
712				defaultEffect :
713				options.effect || defaultEffect;
714
715		options = options || {};
716		if ( typeof options === "number" ) {
717			options = { duration: options };
718		}
719
720		hasOptions = !$.isEmptyObject( options );
721		options.complete = callback;
722
723		if ( options.delay ) {
724			element.delay( options.delay );
725		}
726
727		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
728			element[ method ]( options );
729		} else if ( effectName !== method && element[ effectName ] ) {
730			element[ effectName ]( options.duration, options.easing, callback );
731		} else {
732			element.queue( function( next ) {
733				$( this )[ method ]();
734				if ( callback ) {
735					callback.call( element[ 0 ] );
736				}
737				next();
738			} );
739		}
740	};
741} );
742
743var widget = $.widget;
744
745
746/*!
747 * jQuery UI Position 1.12.1
748 * http://jqueryui.com
749 *
750 * Copyright jQuery Foundation and other contributors
751 * Released under the MIT license.
752 * http://jquery.org/license
753 *
754 * http://api.jqueryui.com/position/
755 */
756
757//>>label: Position
758//>>group: Core
759//>>description: Positions elements relative to other elements.
760//>>docs: http://api.jqueryui.com/position/
761//>>demos: http://jqueryui.com/position/
762
763
764( function() {
765var cachedScrollbarWidth,
766	max = Math.max,
767	abs = Math.abs,
768	rhorizontal = /left|center|right/,
769	rvertical = /top|center|bottom/,
770	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
771	rposition = /^\w+/,
772	rpercent = /%$/,
773	_position = $.fn.position;
774
775function getOffsets( offsets, width, height ) {
776	return [
777		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
778		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
779	];
780}
781
782function parseCss( element, property ) {
783	return parseInt( $.css( element, property ), 10 ) || 0;
784}
785
786function getDimensions( elem ) {
787	var raw = elem[ 0 ];
788	if ( raw.nodeType === 9 ) {
789		return {
790			width: elem.width(),
791			height: elem.height(),
792			offset: { top: 0, left: 0 }
793		};
794	}
795	if ( $.isWindow( raw ) ) {
796		return {
797			width: elem.width(),
798			height: elem.height(),
799			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
800		};
801	}
802	if ( raw.preventDefault ) {
803		return {
804			width: 0,
805			height: 0,
806			offset: { top: raw.pageY, left: raw.pageX }
807		};
808	}
809	return {
810		width: elem.outerWidth(),
811		height: elem.outerHeight(),
812		offset: elem.offset()
813	};
814}
815
816$.position = {
817	scrollbarWidth: function() {
818		if ( cachedScrollbarWidth !== undefined ) {
819			return cachedScrollbarWidth;
820		}
821		var w1, w2,
822			div = $( "<div " +
823				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
824				"<div style='height:100px;width:auto;'></div></div>" ),
825			innerDiv = div.children()[ 0 ];
826
827		$( "body" ).append( div );
828		w1 = innerDiv.offsetWidth;
829		div.css( "overflow", "scroll" );
830
831		w2 = innerDiv.offsetWidth;
832
833		if ( w1 === w2 ) {
834			w2 = div[ 0 ].clientWidth;
835		}
836
837		div.remove();
838
839		return ( cachedScrollbarWidth = w1 - w2 );
840	},
841	getScrollInfo: function( within ) {
842		var overflowX = within.isWindow || within.isDocument ? "" :
843				within.element.css( "overflow-x" ),
844			overflowY = within.isWindow || within.isDocument ? "" :
845				within.element.css( "overflow-y" ),
846			hasOverflowX = overflowX === "scroll" ||
847				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
848			hasOverflowY = overflowY === "scroll" ||
849				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
850		return {
851			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
852			height: hasOverflowX ? $.position.scrollbarWidth() : 0
853		};
854	},
855	getWithinInfo: function( element ) {
856		var withinElement = $( element || window ),
857			isWindow = $.isWindow( withinElement[ 0 ] ),
858			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
859			hasOffset = !isWindow && !isDocument;
860		return {
861			element: withinElement,
862			isWindow: isWindow,
863			isDocument: isDocument,
864			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
865			scrollLeft: withinElement.scrollLeft(),
866			scrollTop: withinElement.scrollTop(),
867			width: withinElement.outerWidth(),
868			height: withinElement.outerHeight()
869		};
870	}
871};
872
873$.fn.position = function( options ) {
874	if ( !options || !options.of ) {
875		return _position.apply( this, arguments );
876	}
877
878	// Make a copy, we don't want to modify arguments
879	options = $.extend( {}, options );
880
881	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
882		target = $( options.of ),
883		within = $.position.getWithinInfo( options.within ),
884		scrollInfo = $.position.getScrollInfo( within ),
885		collision = ( options.collision || "flip" ).split( " " ),
886		offsets = {};
887
888	dimensions = getDimensions( target );
889	if ( target[ 0 ].preventDefault ) {
890
891		// Force left top to allow flipping
892		options.at = "left top";
893	}
894	targetWidth = dimensions.width;
895	targetHeight = dimensions.height;
896	targetOffset = dimensions.offset;
897
898	// Clone to reuse original targetOffset later
899	basePosition = $.extend( {}, targetOffset );
900
901	// Force my and at to have valid horizontal and vertical positions
902	// if a value is missing or invalid, it will be converted to center
903	$.each( [ "my", "at" ], function() {
904		var pos = ( options[ this ] || "" ).split( " " ),
905			horizontalOffset,
906			verticalOffset;
907
908		if ( pos.length === 1 ) {
909			pos = rhorizontal.test( pos[ 0 ] ) ?
910				pos.concat( [ "center" ] ) :
911				rvertical.test( pos[ 0 ] ) ?
912					[ "center" ].concat( pos ) :
913					[ "center", "center" ];
914		}
915		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
916		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
917
918		// Calculate offsets
919		horizontalOffset = roffset.exec( pos[ 0 ] );
920		verticalOffset = roffset.exec( pos[ 1 ] );
921		offsets[ this ] = [
922			horizontalOffset ? horizontalOffset[ 0 ] : 0,
923			verticalOffset ? verticalOffset[ 0 ] : 0
924		];
925
926		// Reduce to just the positions without the offsets
927		options[ this ] = [
928			rposition.exec( pos[ 0 ] )[ 0 ],
929			rposition.exec( pos[ 1 ] )[ 0 ]
930		];
931	} );
932
933	// Normalize collision option
934	if ( collision.length === 1 ) {
935		collision[ 1 ] = collision[ 0 ];
936	}
937
938	if ( options.at[ 0 ] === "right" ) {
939		basePosition.left += targetWidth;
940	} else if ( options.at[ 0 ] === "center" ) {
941		basePosition.left += targetWidth / 2;
942	}
943
944	if ( options.at[ 1 ] === "bottom" ) {
945		basePosition.top += targetHeight;
946	} else if ( options.at[ 1 ] === "center" ) {
947		basePosition.top += targetHeight / 2;
948	}
949
950	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
951	basePosition.left += atOffset[ 0 ];
952	basePosition.top += atOffset[ 1 ];
953
954	return this.each( function() {
955		var collisionPosition, using,
956			elem = $( this ),
957			elemWidth = elem.outerWidth(),
958			elemHeight = elem.outerHeight(),
959			marginLeft = parseCss( this, "marginLeft" ),
960			marginTop = parseCss( this, "marginTop" ),
961			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
962				scrollInfo.width,
963			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
964				scrollInfo.height,
965			position = $.extend( {}, basePosition ),
966			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
967
968		if ( options.my[ 0 ] === "right" ) {
969			position.left -= elemWidth;
970		} else if ( options.my[ 0 ] === "center" ) {
971			position.left -= elemWidth / 2;
972		}
973
974		if ( options.my[ 1 ] === "bottom" ) {
975			position.top -= elemHeight;
976		} else if ( options.my[ 1 ] === "center" ) {
977			position.top -= elemHeight / 2;
978		}
979
980		position.left += myOffset[ 0 ];
981		position.top += myOffset[ 1 ];
982
983		collisionPosition = {
984			marginLeft: marginLeft,
985			marginTop: marginTop
986		};
987
988		$.each( [ "left", "top" ], function( i, dir ) {
989			if ( $.ui.position[ collision[ i ] ] ) {
990				$.ui.position[ collision[ i ] ][ dir ]( position, {
991					targetWidth: targetWidth,
992					targetHeight: targetHeight,
993					elemWidth: elemWidth,
994					elemHeight: elemHeight,
995					collisionPosition: collisionPosition,
996					collisionWidth: collisionWidth,
997					collisionHeight: collisionHeight,
998					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
999					my: options.my,
1000					at: options.at,
1001					within: within,
1002					elem: elem
1003				} );
1004			}
1005		} );
1006
1007		if ( options.using ) {
1008
1009			// Adds feedback as second argument to using callback, if present
1010			using = function( props ) {
1011				var left = targetOffset.left - position.left,
1012					right = left + targetWidth - elemWidth,
1013					top = targetOffset.top - position.top,
1014					bottom = top + targetHeight - elemHeight,
1015					feedback = {
1016						target: {
1017							element: target,
1018							left: targetOffset.left,
1019							top: targetOffset.top,
1020							width: targetWidth,
1021							height: targetHeight
1022						},
1023						element: {
1024							element: elem,
1025							left: position.left,
1026							top: position.top,
1027							width: elemWidth,
1028							height: elemHeight
1029						},
1030						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1031						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1032					};
1033				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1034					feedback.horizontal = "center";
1035				}
1036				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1037					feedback.vertical = "middle";
1038				}
1039				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1040					feedback.important = "horizontal";
1041				} else {
1042					feedback.important = "vertical";
1043				}
1044				options.using.call( this, props, feedback );
1045			};
1046		}
1047
1048		elem.offset( $.extend( position, { using: using } ) );
1049	} );
1050};
1051
1052$.ui.position = {
1053	fit: {
1054		left: function( position, data ) {
1055			var within = data.within,
1056				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1057				outerWidth = within.width,
1058				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1059				overLeft = withinOffset - collisionPosLeft,
1060				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1061				newOverRight;
1062
1063			// Element is wider than within
1064			if ( data.collisionWidth > outerWidth ) {
1065
1066				// Element is initially over the left side of within
1067				if ( overLeft > 0 && overRight <= 0 ) {
1068					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1069						withinOffset;
1070					position.left += overLeft - newOverRight;
1071
1072				// Element is initially over right side of within
1073				} else if ( overRight > 0 && overLeft <= 0 ) {
1074					position.left = withinOffset;
1075
1076				// Element is initially over both left and right sides of within
1077				} else {
1078					if ( overLeft > overRight ) {
1079						position.left = withinOffset + outerWidth - data.collisionWidth;
1080					} else {
1081						position.left = withinOffset;
1082					}
1083				}
1084
1085			// Too far left -> align with left edge
1086			} else if ( overLeft > 0 ) {
1087				position.left += overLeft;
1088
1089			// Too far right -> align with right edge
1090			} else if ( overRight > 0 ) {
1091				position.left -= overRight;
1092
1093			// Adjust based on position and margin
1094			} else {
1095				position.left = max( position.left - collisionPosLeft, position.left );
1096			}
1097		},
1098		top: function( position, data ) {
1099			var within = data.within,
1100				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1101				outerHeight = data.within.height,
1102				collisionPosTop = position.top - data.collisionPosition.marginTop,
1103				overTop = withinOffset - collisionPosTop,
1104				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1105				newOverBottom;
1106
1107			// Element is taller than within
1108			if ( data.collisionHeight > outerHeight ) {
1109
1110				// Element is initially over the top of within
1111				if ( overTop > 0 && overBottom <= 0 ) {
1112					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1113						withinOffset;
1114					position.top += overTop - newOverBottom;
1115
1116				// Element is initially over bottom of within
1117				} else if ( overBottom > 0 && overTop <= 0 ) {
1118					position.top = withinOffset;
1119
1120				// Element is initially over both top and bottom of within
1121				} else {
1122					if ( overTop > overBottom ) {
1123						position.top = withinOffset + outerHeight - data.collisionHeight;
1124					} else {
1125						position.top = withinOffset;
1126					}
1127				}
1128
1129			// Too far up -> align with top
1130			} else if ( overTop > 0 ) {
1131				position.top += overTop;
1132
1133			// Too far down -> align with bottom edge
1134			} else if ( overBottom > 0 ) {
1135				position.top -= overBottom;
1136
1137			// Adjust based on position and margin
1138			} else {
1139				position.top = max( position.top - collisionPosTop, position.top );
1140			}
1141		}
1142	},
1143	flip: {
1144		left: function( position, data ) {
1145			var within = data.within,
1146				withinOffset = within.offset.left + within.scrollLeft,
1147				outerWidth = within.width,
1148				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1149				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1150				overLeft = collisionPosLeft - offsetLeft,
1151				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1152				myOffset = data.my[ 0 ] === "left" ?
1153					-data.elemWidth :
1154					data.my[ 0 ] === "right" ?
1155						data.elemWidth :
1156						0,
1157				atOffset = data.at[ 0 ] === "left" ?
1158					data.targetWidth :
1159					data.at[ 0 ] === "right" ?
1160						-data.targetWidth :
1161						0,
1162				offset = -2 * data.offset[ 0 ],
1163				newOverRight,
1164				newOverLeft;
1165
1166			if ( overLeft < 0 ) {
1167				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1168					outerWidth - withinOffset;
1169				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1170					position.left += myOffset + atOffset + offset;
1171				}
1172			} else if ( overRight > 0 ) {
1173				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1174					atOffset + offset - offsetLeft;
1175				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1176					position.left += myOffset + atOffset + offset;
1177				}
1178			}
1179		},
1180		top: function( position, data ) {
1181			var within = data.within,
1182				withinOffset = within.offset.top + within.scrollTop,
1183				outerHeight = within.height,
1184				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1185				collisionPosTop = position.top - data.collisionPosition.marginTop,
1186				overTop = collisionPosTop - offsetTop,
1187				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1188				top = data.my[ 1 ] === "top",
1189				myOffset = top ?
1190					-data.elemHeight :
1191					data.my[ 1 ] === "bottom" ?
1192						data.elemHeight :
1193						0,
1194				atOffset = data.at[ 1 ] === "top" ?
1195					data.targetHeight :
1196					data.at[ 1 ] === "bottom" ?
1197						-data.targetHeight :
1198						0,
1199				offset = -2 * data.offset[ 1 ],
1200				newOverTop,
1201				newOverBottom;
1202			if ( overTop < 0 ) {
1203				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1204					outerHeight - withinOffset;
1205				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1206					position.top += myOffset + atOffset + offset;
1207				}
1208			} else if ( overBottom > 0 ) {
1209				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1210					offset - offsetTop;
1211				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1212					position.top += myOffset + atOffset + offset;
1213				}
1214			}
1215		}
1216	},
1217	flipfit: {
1218		left: function() {
1219			$.ui.position.flip.left.apply( this, arguments );
1220			$.ui.position.fit.left.apply( this, arguments );
1221		},
1222		top: function() {
1223			$.ui.position.flip.top.apply( this, arguments );
1224			$.ui.position.fit.top.apply( this, arguments );
1225		}
1226	}
1227};
1228
1229} )();
1230
1231var position = $.ui.position;
1232
1233
1234/*!
1235 * jQuery UI :data 1.12.1
1236 * http://jqueryui.com
1237 *
1238 * Copyright jQuery Foundation and other contributors
1239 * Released under the MIT license.
1240 * http://jquery.org/license
1241 */
1242
1243//>>label: :data Selector
1244//>>group: Core
1245//>>description: Selects elements which have data stored under the specified key.
1246//>>docs: http://api.jqueryui.com/data-selector/
1247
1248
1249var data = $.extend( $.expr[ ":" ], {
1250	data: $.expr.createPseudo ?
1251		$.expr.createPseudo( function( dataName ) {
1252			return function( elem ) {
1253				return !!$.data( elem, dataName );
1254			};
1255		} ) :
1256
1257		// Support: jQuery <1.8
1258		function( elem, i, match ) {
1259			return !!$.data( elem, match[ 3 ] );
1260		}
1261} );
1262
1263/*!
1264 * jQuery UI Disable Selection 1.12.1
1265 * http://jqueryui.com
1266 *
1267 * Copyright jQuery Foundation and other contributors
1268 * Released under the MIT license.
1269 * http://jquery.org/license
1270 */
1271
1272//>>label: disableSelection
1273//>>group: Core
1274//>>description: Disable selection of text content within the set of matched elements.
1275//>>docs: http://api.jqueryui.com/disableSelection/
1276
1277// This file is deprecated
1278
1279
1280var disableSelection = $.fn.extend( {
1281	disableSelection: ( function() {
1282		var eventType = "onselectstart" in document.createElement( "div" ) ?
1283			"selectstart" :
1284			"mousedown";
1285
1286		return function() {
1287			return this.on( eventType + ".ui-disableSelection", function( event ) {
1288				event.preventDefault();
1289			} );
1290		};
1291	} )(),
1292
1293	enableSelection: function() {
1294		return this.off( ".ui-disableSelection" );
1295	}
1296} );
1297
1298
1299/*!
1300 * jQuery UI Focusable 1.12.1
1301 * http://jqueryui.com
1302 *
1303 * Copyright jQuery Foundation and other contributors
1304 * Released under the MIT license.
1305 * http://jquery.org/license
1306 */
1307
1308//>>label: :focusable Selector
1309//>>group: Core
1310//>>description: Selects elements which can be focused.
1311//>>docs: http://api.jqueryui.com/focusable-selector/
1312
1313
1314
1315// Selectors
1316$.ui.focusable = function( element, hasTabindex ) {
1317	var map, mapName, img, focusableIfVisible, fieldset,
1318		nodeName = element.nodeName.toLowerCase();
1319
1320	if ( "area" === nodeName ) {
1321		map = element.parentNode;
1322		mapName = map.name;
1323		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
1324			return false;
1325		}
1326		img = $( "img[usemap='#" + mapName + "']" );
1327		return img.length > 0 && img.is( ":visible" );
1328	}
1329
1330	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
1331		focusableIfVisible = !element.disabled;
1332
1333		if ( focusableIfVisible ) {
1334
1335			// Form controls within a disabled fieldset are disabled.
1336			// However, controls within the fieldset's legend do not get disabled.
1337			// Since controls generally aren't placed inside legends, we skip
1338			// this portion of the check.
1339			fieldset = $( element ).closest( "fieldset" )[ 0 ];
1340			if ( fieldset ) {
1341				focusableIfVisible = !fieldset.disabled;
1342			}
1343		}
1344	} else if ( "a" === nodeName ) {
1345		focusableIfVisible = element.href || hasTabindex;
1346	} else {
1347		focusableIfVisible = hasTabindex;
1348	}
1349
1350	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
1351};
1352
1353// Support: IE 8 only
1354// IE 8 doesn't resolve inherit to visible/hidden for computed values
1355function visible( element ) {
1356	var visibility = element.css( "visibility" );
1357	while ( visibility === "inherit" ) {
1358		element = element.parent();
1359		visibility = element.css( "visibility" );
1360	}
1361	return visibility !== "hidden";
1362}
1363
1364$.extend( $.expr[ ":" ], {
1365	focusable: function( element ) {
1366		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
1367	}
1368} );
1369
1370var focusable = $.ui.focusable;
1371
1372
1373
1374
1375// Support: IE8 Only
1376// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
1377// with a string, so we need to find the proper form.
1378var form = $.fn.form = function() {
1379	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
1380};
1381
1382
1383/*!
1384 * jQuery UI Form Reset Mixin 1.12.1
1385 * http://jqueryui.com
1386 *
1387 * Copyright jQuery Foundation and other contributors
1388 * Released under the MIT license.
1389 * http://jquery.org/license
1390 */
1391
1392//>>label: Form Reset Mixin
1393//>>group: Core
1394//>>description: Refresh input widgets when their form is reset
1395//>>docs: http://api.jqueryui.com/form-reset-mixin/
1396
1397
1398
1399var formResetMixin = $.ui.formResetMixin = {
1400	_formResetHandler: function() {
1401		var form = $( this );
1402
1403		// Wait for the form reset to actually happen before refreshing
1404		setTimeout( function() {
1405			var instances = form.data( "ui-form-reset-instances" );
1406			$.each( instances, function() {
1407				this.refresh();
1408			} );
1409		} );
1410	},
1411
1412	_bindFormResetHandler: function() {
1413		this.form = this.element.form();
1414		if ( !this.form.length ) {
1415			return;
1416		}
1417
1418		var instances = this.form.data( "ui-form-reset-instances" ) || [];
1419		if ( !instances.length ) {
1420
1421			// We don't use _on() here because we use a single event handler per form
1422			this.form.on( "reset.ui-form-reset", this._formResetHandler );
1423		}
1424		instances.push( this );
1425		this.form.data( "ui-form-reset-instances", instances );
1426	},
1427
1428	_unbindFormResetHandler: function() {
1429		if ( !this.form.length ) {
1430			return;
1431		}
1432
1433		var instances = this.form.data( "ui-form-reset-instances" );
1434		instances.splice( $.inArray( this, instances ), 1 );
1435		if ( instances.length ) {
1436			this.form.data( "ui-form-reset-instances", instances );
1437		} else {
1438			this.form
1439				.removeData( "ui-form-reset-instances" )
1440				.off( "reset.ui-form-reset" );
1441		}
1442	}
1443};
1444
1445
1446/*!
1447 * jQuery UI Support for jQuery core 1.7.x 1.12.1
1448 * http://jqueryui.com
1449 *
1450 * Copyright jQuery Foundation and other contributors
1451 * Released under the MIT license.
1452 * http://jquery.org/license
1453 *
1454 */
1455
1456//>>label: jQuery 1.7 Support
1457//>>group: Core
1458//>>description: Support version 1.7.x of jQuery core
1459
1460
1461
1462// Support: jQuery 1.7 only
1463// Not a great way to check versions, but since we only support 1.7+ and only
1464// need to detect <1.8, this is a simple check that should suffice. Checking
1465// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
1466// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
1467// 1.7 anymore). See #11197 for why we're not using feature detection.
1468if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
1469
1470	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
1471	// Unlike jQuery Core 1.8+, these only support numeric values to set the
1472	// dimensions in pixels
1473	$.each( [ "Width", "Height" ], function( i, name ) {
1474		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
1475			type = name.toLowerCase(),
1476			orig = {
1477				innerWidth: $.fn.innerWidth,
1478				innerHeight: $.fn.innerHeight,
1479				outerWidth: $.fn.outerWidth,
1480				outerHeight: $.fn.outerHeight
1481			};
1482
1483		function reduce( elem, size, border, margin ) {
1484			$.each( side, function() {
1485				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
1486				if ( border ) {
1487					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
1488				}
1489				if ( margin ) {
1490					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
1491				}
1492			} );
1493			return size;
1494		}
1495
1496		$.fn[ "inner" + name ] = function( size ) {
1497			if ( size === undefined ) {
1498				return orig[ "inner" + name ].call( this );
1499			}
1500
1501			return this.each( function() {
1502				$( this ).css( type, reduce( this, size ) + "px" );
1503			} );
1504		};
1505
1506		$.fn[ "outer" + name ] = function( size, margin ) {
1507			if ( typeof size !== "number" ) {
1508				return orig[ "outer" + name ].call( this, size );
1509			}
1510
1511			return this.each( function() {
1512				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
1513			} );
1514		};
1515	} );
1516
1517	$.fn.addBack = function( selector ) {
1518		return this.add( selector == null ?
1519			this.prevObject : this.prevObject.filter( selector )
1520		);
1521	};
1522}
1523
1524;
1525/*!
1526 * jQuery UI Keycode 1.12.1
1527 * http://jqueryui.com
1528 *
1529 * Copyright jQuery Foundation and other contributors
1530 * Released under the MIT license.
1531 * http://jquery.org/license
1532 */
1533
1534//>>label: Keycode
1535//>>group: Core
1536//>>description: Provide keycodes as keynames
1537//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
1538
1539
1540var keycode = $.ui.keyCode = {
1541	BACKSPACE: 8,
1542	COMMA: 188,
1543	DELETE: 46,
1544	DOWN: 40,
1545	END: 35,
1546	ENTER: 13,
1547	ESCAPE: 27,
1548	HOME: 36,
1549	LEFT: 37,
1550	PAGE_DOWN: 34,
1551	PAGE_UP: 33,
1552	PERIOD: 190,
1553	RIGHT: 39,
1554	SPACE: 32,
1555	TAB: 9,
1556	UP: 38
1557};
1558
1559
1560
1561
1562// Internal use only
1563var escapeSelector = $.ui.escapeSelector = ( function() {
1564	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
1565	return function( selector ) {
1566		return selector.replace( selectorEscape, "\\$1" );
1567	};
1568} )();
1569
1570
1571/*!
1572 * jQuery UI Labels 1.12.1
1573 * http://jqueryui.com
1574 *
1575 * Copyright jQuery Foundation and other contributors
1576 * Released under the MIT license.
1577 * http://jquery.org/license
1578 */
1579
1580//>>label: labels
1581//>>group: Core
1582//>>description: Find all the labels associated with a given input
1583//>>docs: http://api.jqueryui.com/labels/
1584
1585
1586
1587var labels = $.fn.labels = function() {
1588	var ancestor, selector, id, labels, ancestors;
1589
1590	// Check control.labels first
1591	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
1592		return this.pushStack( this[ 0 ].labels );
1593	}
1594
1595	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
1596	// Above browsers do not support control.labels. Everything below is to support them
1597	// as well as document fragments. control.labels does not work on document fragments
1598	labels = this.eq( 0 ).parents( "label" );
1599
1600	// Look for the label based on the id
1601	id = this.attr( "id" );
1602	if ( id ) {
1603
1604		// We don't search against the document in case the element
1605		// is disconnected from the DOM
1606		ancestor = this.eq( 0 ).parents().last();
1607
1608		// Get a full set of top level ancestors
1609		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
1610
1611		// Create a selector for the label based on the id
1612		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
1613
1614		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
1615
1616	}
1617
1618	// Return whatever we have found for labels
1619	return this.pushStack( labels );
1620};
1621
1622
1623/*!
1624 * jQuery UI Scroll Parent 1.12.1
1625 * http://jqueryui.com
1626 *
1627 * Copyright jQuery Foundation and other contributors
1628 * Released under the MIT license.
1629 * http://jquery.org/license
1630 */
1631
1632//>>label: scrollParent
1633//>>group: Core
1634//>>description: Get the closest ancestor element that is scrollable.
1635//>>docs: http://api.jqueryui.com/scrollParent/
1636
1637
1638
1639var scrollParent = $.fn.scrollParent = function( includeHidden ) {
1640	var position = this.css( "position" ),
1641		excludeStaticParent = position === "absolute",
1642		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
1643		scrollParent = this.parents().filter( function() {
1644			var parent = $( this );
1645			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
1646				return false;
1647			}
1648			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
1649				parent.css( "overflow-x" ) );
1650		} ).eq( 0 );
1651
1652	return position === "fixed" || !scrollParent.length ?
1653		$( this[ 0 ].ownerDocument || document ) :
1654		scrollParent;
1655};
1656
1657
1658/*!
1659 * jQuery UI Tabbable 1.12.1
1660 * http://jqueryui.com
1661 *
1662 * Copyright jQuery Foundation and other contributors
1663 * Released under the MIT license.
1664 * http://jquery.org/license
1665 */
1666
1667//>>label: :tabbable Selector
1668//>>group: Core
1669//>>description: Selects elements which can be tabbed to.
1670//>>docs: http://api.jqueryui.com/tabbable-selector/
1671
1672
1673
1674var tabbable = $.extend( $.expr[ ":" ], {
1675	tabbable: function( element ) {
1676		var tabIndex = $.attr( element, "tabindex" ),
1677			hasTabindex = tabIndex != null;
1678		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
1679	}
1680} );
1681
1682
1683/*!
1684 * jQuery UI Unique ID 1.12.1
1685 * http://jqueryui.com
1686 *
1687 * Copyright jQuery Foundation and other contributors
1688 * Released under the MIT license.
1689 * http://jquery.org/license
1690 */
1691
1692//>>label: uniqueId
1693//>>group: Core
1694//>>description: Functions to generate and remove uniqueId's
1695//>>docs: http://api.jqueryui.com/uniqueId/
1696
1697
1698
1699var uniqueId = $.fn.extend( {
1700	uniqueId: ( function() {
1701		var uuid = 0;
1702
1703		return function() {
1704			return this.each( function() {
1705				if ( !this.id ) {
1706					this.id = "ui-id-" + ( ++uuid );
1707				}
1708			} );
1709		};
1710	} )(),
1711
1712	removeUniqueId: function() {
1713		return this.each( function() {
1714			if ( /^ui-id-\d+$/.test( this.id ) ) {
1715				$( this ).removeAttr( "id" );
1716			}
1717		} );
1718	}
1719} );
1720
1721
vendor: 46,453 bytes, lines 1722-3408
1722
1723
1724// This file is deprecated
1725var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
1726
1727/*!
1728 * jQuery UI Mouse 1.12.1
1729 * http://jqueryui.com
1730 *
1731 * Copyright jQuery Foundation and other contributors
1732 * Released under the MIT license.
1733 * http://jquery.org/license
1734 */
1735
1736//>>label: Mouse
1737//>>group: Widgets
1738//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
1739//>>docs: http://api.jqueryui.com/mouse/
1740
1741
1742
1743var mouseHandled = false;
1744$( document ).on( "mouseup", function() {
1745	mouseHandled = false;
1746} );
1747
1748var widgetsMouse = $.widget( "ui.mouse", {
1749	version: "1.12.1",
1750	options: {
1751		cancel: "input, textarea, button, select, option",
1752		distance: 1,
1753		delay: 0
1754	},
1755	_mouseInit: function() {
1756		var that = this;
1757
1758		this.element
1759			.on( "mousedown." + this.widgetName, function( event ) {
1760				return that._mouseDown( event );
1761			} )
1762			.on( "click." + this.widgetName, function( event ) {
1763				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
1764					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
1765					event.stopImmediatePropagation();
1766					return false;
1767				}
1768			} );
1769
1770		this.started = false;
1771	},
1772
1773	// TODO: make sure destroying one instance of mouse doesn't mess with
1774	// other instances of mouse
1775	_mouseDestroy: function() {
1776		this.element.off( "." + this.widgetName );
1777		if ( this._mouseMoveDelegate ) {
1778			this.document
1779				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1780				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1781		}
1782	},
1783
1784	_mouseDown: function( event ) {
1785
1786		// don't let more than one widget handle mouseStart
1787		if ( mouseHandled ) {
1788			return;
1789		}
1790
1791		this._mouseMoved = false;
1792
1793		// We may have missed mouseup (out of window)
1794		( this._mouseStarted && this._mouseUp( event ) );
1795
1796		this._mouseDownEvent = event;
1797
1798		var that = this,
1799			btnIsLeft = ( event.which === 1 ),
1800
1801			// event.target.nodeName works around a bug in IE 8 with
1802			// disabled inputs (#7620)
1803			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
1804				$( event.target ).closest( this.options.cancel ).length : false );
1805		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
1806			return true;
1807		}
1808
1809		this.mouseDelayMet = !this.options.delay;
1810		if ( !this.mouseDelayMet ) {
1811			this._mouseDelayTimer = setTimeout( function() {
1812				that.mouseDelayMet = true;
1813			}, this.options.delay );
1814		}
1815
1816		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1817			this._mouseStarted = ( this._mouseStart( event ) !== false );
1818			if ( !this._mouseStarted ) {
1819				event.preventDefault();
1820				return true;
1821			}
1822		}
1823
1824		// Click event may never have fired (Gecko & Opera)
1825		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
1826			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
1827		}
1828
1829		// These delegates are required to keep context
1830		this._mouseMoveDelegate = function( event ) {
1831			return that._mouseMove( event );
1832		};
1833		this._mouseUpDelegate = function( event ) {
1834			return that._mouseUp( event );
1835		};
1836
1837		this.document
1838			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1839			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
1840
1841		event.preventDefault();
1842
1843		mouseHandled = true;
1844		return true;
1845	},
1846
1847	_mouseMove: function( event ) {
1848
1849		// Only check for mouseups outside the document if you've moved inside the document
1850		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
1851		// fire a mousemove event if content is placed under the cursor. See #7778
1852		// Support: IE <9
1853		if ( this._mouseMoved ) {
1854
1855			// IE mouseup check - mouseup happened when mouse was out of window
1856			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
1857					!event.button ) {
1858				return this._mouseUp( event );
1859
1860			// Iframe mouseup check - mouseup occurred in another document
1861			} else if ( !event.which ) {
1862
1863				// Support: Safari <=8 - 9
1864				// Safari sets which to 0 if you press any of the following keys
1865				// during a drag (#14461)
1866				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
1867						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
1868					this.ignoreMissingWhich = true;
1869				} else if ( !this.ignoreMissingWhich ) {
1870					return this._mouseUp( event );
1871				}
1872			}
1873		}
1874
1875		if ( event.which || event.button ) {
1876			this._mouseMoved = true;
1877		}
1878
1879		if ( this._mouseStarted ) {
1880			this._mouseDrag( event );
1881			return event.preventDefault();
1882		}
1883
1884		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1885			this._mouseStarted =
1886				( this._mouseStart( this._mouseDownEvent, event ) !== false );
1887			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
1888		}
1889
1890		return !this._mouseStarted;
1891	},
1892
1893	_mouseUp: function( event ) {
1894		this.document
1895			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1896			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1897
1898		if ( this._mouseStarted ) {
1899			this._mouseStarted = false;
1900
1901			if ( event.target === this._mouseDownEvent.target ) {
1902				$.data( event.target, this.widgetName + ".preventClickEvent", true );
1903			}
1904
1905			this._mouseStop( event );
1906		}
1907
1908		if ( this._mouseDelayTimer ) {
1909			clearTimeout( this._mouseDelayTimer );
1910			delete this._mouseDelayTimer;
1911		}
1912
1913		this.ignoreMissingWhich = false;
1914		mouseHandled = false;
1915		event.preventDefault();
1916	},
1917
1918	_mouseDistanceMet: function( event ) {
1919		return ( Math.max(
1920				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
1921				Math.abs( this._mouseDownEvent.pageY - event.pageY )
1922			) >= this.options.distance
1923		);
1924	},
1925
1926	_mouseDelayMet: function( /* event */ ) {
1927		return this.mouseDelayMet;
1928	},
1929
1930	// These are placeholder methods, to be overriden by extending plugin
1931	_mouseStart: function( /* event */ ) {},
1932	_mouseDrag: function( /* event */ ) {},
1933	_mouseStop: function( /* event */ ) {},
1934	_mouseCapture: function( /* event */ ) { return true; }
1935} );
1936
1937
1938
1939
1940// $.ui.plugin is deprecated. Use $.widget() extensions instead.
1941var plugin = $.ui.plugin = {
1942	add: function( module, option, set ) {
1943		var i,
1944			proto = $.ui[ module ].prototype;
1945		for ( i in set ) {
1946			proto.plugins[ i ] = proto.plugins[ i ] || [];
1947			proto.plugins[ i ].push( [ option, set[ i ] ] );
1948		}
1949	},
1950	call: function( instance, name, args, allowDisconnected ) {
1951		var i,
1952			set = instance.plugins[ name ];
1953
1954		if ( !set ) {
1955			return;
1956		}
1957
1958		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
1959				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
1960			return;
1961		}
1962
1963		for ( i = 0; i < set.length; i++ ) {
1964			if ( instance.options[ set[ i ][ 0 ] ] ) {
1965				set[ i ][ 1 ].apply( instance.element, args );
1966			}
1967		}
1968	}
1969};
1970
1971
1972
1973var safeActiveElement = $.ui.safeActiveElement = function( document ) {
1974	var activeElement;
1975
1976	// Support: IE 9 only
1977	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1978	try {
1979		activeElement = document.activeElement;
1980	} catch ( error ) {
1981		activeElement = document.body;
1982	}
1983
1984	// Support: IE 9 - 11 only
1985	// IE may return null instead of an element
1986	// Interestingly, this only seems to occur when NOT in an iframe
1987	if ( !activeElement ) {
1988		activeElement = document.body;
1989	}
1990
1991	// Support: IE 11 only
1992	// IE11 returns a seemingly empty object in some cases when accessing
1993	// document.activeElement from an <iframe>
1994	if ( !activeElement.nodeName ) {
1995		activeElement = document.body;
1996	}
1997
1998	return activeElement;
1999};
2000
2001
2002
2003var safeBlur = $.ui.safeBlur = function( element ) {
2004
2005	// Support: IE9 - 10 only
2006	// If the <body> is blurred, IE will switch windows, see #9420
2007	if ( element && element.nodeName.toLowerCase() !== "body" ) {
2008		$( element ).trigger( "blur" );
2009	}
2010};
2011
2012
2013/*!
2014 * jQuery UI Draggable 1.12.1
2015 * http://jqueryui.com
2016 *
2017 * Copyright jQuery Foundation and other contributors
2018 * Released under the MIT license.
2019 * http://jquery.org/license
2020 */
2021
2022//>>label: Draggable
2023//>>group: Interactions
2024//>>description: Enables dragging functionality for any element.
2025//>>docs: http://api.jqueryui.com/draggable/
2026//>>demos: http://jqueryui.com/draggable/
2027//>>css.structure: ../../themes/base/draggable.css
2028
2029
2030
2031$.widget( "ui.draggable", $.ui.mouse, {
2032	version: "1.12.1",
2033	widgetEventPrefix: "drag",
2034	options: {
2035		addClasses: true,
2036		appendTo: "parent",
2037		axis: false,
2038		connectToSortable: false,
2039		containment: false,
2040		cursor: "auto",
2041		cursorAt: false,
2042		grid: false,
2043		handle: false,
2044		helper: "original",
2045		iframeFix: false,
2046		opacity: false,
2047		refreshPositions: false,
2048		revert: false,
2049		revertDuration: 500,
2050		scope: "default",
2051		scroll: true,
2052		scrollSensitivity: 20,
2053		scrollSpeed: 20,
2054		snap: false,
2055		snapMode: "both",
2056		snapTolerance: 20,
2057		stack: false,
2058		zIndex: false,
2059
2060		// Callbacks
2061		drag: null,
2062		start: null,
2063		stop: null
2064	},
2065	_create: function() {
2066
2067		if ( this.options.helper === "original" ) {
2068			this._setPositionRelative();
2069		}
2070		if ( this.options.addClasses ) {
2071			this._addClass( "ui-draggable" );
2072		}
2073		this._setHandleClassName();
2074
2075		this._mouseInit();
2076	},
2077
2078	_setOption: function( key, value ) {
2079		this._super( key, value );
2080		if ( key === "handle" ) {
2081			this._removeHandleClassName();
2082			this._setHandleClassName();
2083		}
2084	},
2085
2086	_destroy: function() {
2087		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
2088			this.destroyOnClear = true;
2089			return;
2090		}
2091		this._removeHandleClassName();
2092		this._mouseDestroy();
2093	},
2094
2095	_mouseCapture: function( event ) {
2096		var o = this.options;
2097
2098		// Among others, prevent a drag on a resizable-handle
2099		if ( this.helper || o.disabled ||
2100				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
2101			return false;
2102		}
2103
2104		//Quit if we're not on a valid handle
2105		this.handle = this._getHandle( event );
2106		if ( !this.handle ) {
2107			return false;
2108		}
2109
2110		this._blurActiveElement( event );
2111
2112		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
2113
2114		return true;
2115
2116	},
2117
2118	_blockFrames: function( selector ) {
2119		this.iframeBlocks = this.document.find( selector ).map( function() {
2120			var iframe = $( this );
2121
2122			return $( "<div>" )
2123				.css( "position", "absolute" )
2124				.appendTo( iframe.parent() )
2125				.outerWidth( iframe.outerWidth() )
2126				.outerHeight( iframe.outerHeight() )
2127				.offset( iframe.offset() )[ 0 ];
2128		} );
2129	},
2130
2131	_unblockFrames: function() {
2132		if ( this.iframeBlocks ) {
2133			this.iframeBlocks.remove();
2134			delete this.iframeBlocks;
2135		}
2136	},
2137
2138	_blurActiveElement: function( event ) {
2139		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
2140			target = $( event.target );
2141
2142		// Don't blur if the event occurred on an element that is within
2143		// the currently focused element
2144		// See #10527, #12472
2145		if ( target.closest( activeElement ).length ) {
2146			return;
2147		}
2148
2149		// Blur any element that currently has focus, see #4261
2150		$.ui.safeBlur( activeElement );
2151	},
2152
2153	_mouseStart: function( event ) {
2154
2155		var o = this.options;
2156
2157		//Create and append the visible helper
2158		this.helper = this._createHelper( event );
2159
2160		this._addClass( this.helper, "ui-draggable-dragging" );
2161
2162		//Cache the helper size
2163		this._cacheHelperProportions();
2164
2165		//If ddmanager is used for droppables, set the global draggable
2166		if ( $.ui.ddmanager ) {
2167			$.ui.ddmanager.current = this;
2168		}
2169
2170		/*
2171		 * - Position generation -
2172		 * This block generates everything position related - it's the core of draggables.
2173		 */
2174
2175		//Cache the margins of the original element
2176		this._cacheMargins();
2177
2178		//Store the helper's css position
2179		this.cssPosition = this.helper.css( "position" );
2180		this.scrollParent = this.helper.scrollParent( true );
2181		this.offsetParent = this.helper.offsetParent();
2182		this.hasFixedAncestor = this.helper.parents().filter( function() {
2183				return $( this ).css( "position" ) === "fixed";
2184			} ).length > 0;
2185
2186		//The element's absolute position on the page minus margins
2187		this.positionAbs = this.element.offset();
2188		this._refreshOffsets( event );
2189
2190		//Generate the original position
2191		this.originalPosition = this.position = this._generatePosition( event, false );
2192		this.originalPageX = event.pageX;
2193		this.originalPageY = event.pageY;
2194
2195		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
2196		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
2197
2198		//Set a containment if given in the options
2199		this._setContainment();
2200
2201		//Trigger event + callbacks
2202		if ( this._trigger( "start", event ) === false ) {
2203			this._clear();
2204			return false;
2205		}
2206
2207		//Recache the helper size
2208		this._cacheHelperProportions();
2209
2210		//Prepare the droppable offsets
2211		if ( $.ui.ddmanager && !o.dropBehaviour ) {
2212			$.ui.ddmanager.prepareOffsets( this, event );
2213		}
2214
2215		// Execute the drag once - this causes the helper not to be visible before getting its
2216		// correct position
2217		this._mouseDrag( event, true );
2218
2219		// If the ddmanager is used for droppables, inform the manager that dragging has started
2220		// (see #5003)
2221		if ( $.ui.ddmanager ) {
2222			$.ui.ddmanager.dragStart( this, event );
2223		}
2224
2225		return true;
2226	},
2227
2228	_refreshOffsets: function( event ) {
2229		this.offset = {
2230			top: this.positionAbs.top - this.margins.top,
2231			left: this.positionAbs.left - this.margins.left,
2232			scroll: false,
2233			parent: this._getParentOffset(),
2234			relative: this._getRelativeOffset()
2235		};
2236
2237		this.offset.click = {
2238			left: event.pageX - this.offset.left,
2239			top: event.pageY - this.offset.top
2240		};
2241	},
2242
2243	_mouseDrag: function( event, noPropagation ) {
2244
2245		// reset any necessary cached properties (see #5009)
2246		if ( this.hasFixedAncestor ) {
2247			this.offset.parent = this._getParentOffset();
2248		}
2249
2250		//Compute the helpers position
2251		this.position = this._generatePosition( event, true );
2252		this.positionAbs = this._convertPositionTo( "absolute" );
2253
2254		//Call plugins and callbacks and use the resulting position if something is returned
2255		if ( !noPropagation ) {
2256			var ui = this._uiHash();
2257			if ( this._trigger( "drag", event, ui ) === false ) {
2258				this._mouseUp( new $.Event( "mouseup", event ) );
2259				return false;
2260			}
2261			this.position = ui.position;
2262		}
2263
2264		this.helper[ 0 ].style.left = this.position.left + "px";
2265		this.helper[ 0 ].style.top = this.position.top + "px";
2266
2267		if ( $.ui.ddmanager ) {
2268			$.ui.ddmanager.drag( this, event );
2269		}
2270
2271		return false;
2272	},
2273
2274	_mouseStop: function( event ) {
2275
2276		//If we are using droppables, inform the manager about the drop
2277		var that = this,
2278			dropped = false;
2279		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
2280			dropped = $.ui.ddmanager.drop( this, event );
2281		}
2282
2283		//if a drop comes from outside (a sortable)
2284		if ( this.dropped ) {
2285			dropped = this.dropped;
2286			this.dropped = false;
2287		}
2288
2289		if ( ( this.options.revert === "invalid" && !dropped ) ||
2290				( this.options.revert === "valid" && dropped ) ||
2291				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
2292				this.options.revert.call( this.element, dropped ) )
2293		) {
2294			$( this.helper ).animate(
2295				this.originalPosition,
2296				parseInt( this.options.revertDuration, 10 ),
2297				function() {
2298					if ( that._trigger( "stop", event ) !== false ) {
2299						that._clear();
2300					}
2301				}
2302			);
2303		} else {
2304			if ( this._trigger( "stop", event ) !== false ) {
2305				this._clear();
2306			}
2307		}
2308
2309		return false;
2310	},
2311
2312	_mouseUp: function( event ) {
2313		this._unblockFrames();
2314
2315		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
2316		// (see #5003)
2317		if ( $.ui.ddmanager ) {
2318			$.ui.ddmanager.dragStop( this, event );
2319		}
2320
2321		// Only need to focus if the event occurred on the draggable itself, see #10527
2322		if ( this.handleElement.is( event.target ) ) {
2323
2324			// The interaction is over; whether or not the click resulted in a drag,
2325			// focus the element
2326			this.element.trigger( "focus" );
2327		}
2328
2329		return $.ui.mouse.prototype._mouseUp.call( this, event );
2330	},
2331
2332	cancel: function() {
2333
2334		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
2335			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
2336		} else {
2337			this._clear();
2338		}
2339
2340		return this;
2341
2342	},
2343
2344	_getHandle: function( event ) {
2345		return this.options.handle ?
2346			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
2347			true;
2348	},
2349
2350	_setHandleClassName: function() {
2351		this.handleElement = this.options.handle ?
2352			this.element.find( this.options.handle ) : this.element;
2353		this._addClass( this.handleElement, "ui-draggable-handle" );
2354	},
2355
2356	_removeHandleClassName: function() {
2357		this._removeClass( this.handleElement, "ui-draggable-handle" );
2358	},
2359
2360	_createHelper: function( event ) {
2361
2362		var o = this.options,
2363			helperIsFunction = $.isFunction( o.helper ),
2364			helper = helperIsFunction ?
2365				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
2366				( o.helper === "clone" ?
2367					this.element.clone().removeAttr( "id" ) :
2368					this.element );
2369
2370		if ( !helper.parents( "body" ).length ) {
2371			helper.appendTo( ( o.appendTo === "parent" ?
2372				this.element[ 0 ].parentNode :
2373				o.appendTo ) );
2374		}
2375
2376		// Http://bugs.jqueryui.com/ticket/9446
2377		// a helper function can return the original element
2378		// which wouldn't have been set to relative in _create
2379		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
2380			this._setPositionRelative();
2381		}
2382
2383		if ( helper[ 0 ] !== this.element[ 0 ] &&
2384				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
2385			helper.css( "position", "absolute" );
2386		}
2387
2388		return helper;
2389
2390	},
2391
2392	_setPositionRelative: function() {
2393		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
2394			this.element[ 0 ].style.position = "relative";
2395		}
2396	},
2397
2398	_adjustOffsetFromHelper: function( obj ) {
2399		if ( typeof obj === "string" ) {
2400			obj = obj.split( " " );
2401		}
2402		if ( $.isArray( obj ) ) {
2403			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
2404		}
2405		if ( "left" in obj ) {
2406			this.offset.click.left = obj.left + this.margins.left;
2407		}
2408		if ( "right" in obj ) {
2409			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
2410		}
2411		if ( "top" in obj ) {
2412			this.offset.click.top = obj.top + this.margins.top;
2413		}
2414		if ( "bottom" in obj ) {
2415			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
2416		}
2417	},
2418
2419	_isRootNode: function( element ) {
2420		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
2421	},
2422
2423	_getParentOffset: function() {
2424
2425		//Get the offsetParent and cache its position
2426		var po = this.offsetParent.offset(),
2427			document = this.document[ 0 ];
2428
2429		// This is a special case where we need to modify a offset calculated on start, since the
2430		// following happened:
2431		// 1. The position of the helper is absolute, so it's position is calculated based on the
2432		// next positioned parent
2433		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
2434		// the document, which means that the scroll is included in the initial calculation of the
2435		// offset of the parent, and never recalculated upon drag
2436		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
2437				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
2438			po.left += this.scrollParent.scrollLeft();
2439			po.top += this.scrollParent.scrollTop();
2440		}
2441
2442		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
2443			po = { top: 0, left: 0 };
2444		}
2445
2446		return {
2447			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
2448			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
2449		};
2450
2451	},
2452
2453	_getRelativeOffset: function() {
2454		if ( this.cssPosition !== "relative" ) {
2455			return { top: 0, left: 0 };
2456		}
2457
2458		var p = this.element.position(),
2459			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2460
2461		return {
2462			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
2463				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
2464			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
2465				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
2466		};
2467
2468	},
2469
2470	_cacheMargins: function() {
2471		this.margins = {
2472			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
2473			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
2474			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
2475			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
2476		};
2477	},
2478
2479	_cacheHelperProportions: function() {
2480		this.helperProportions = {
2481			width: this.helper.outerWidth(),
2482			height: this.helper.outerHeight()
2483		};
2484	},
2485
2486	_setContainment: function() {
2487
2488		var isUserScrollable, c, ce,
2489			o = this.options,
2490			document = this.document[ 0 ];
2491
2492		this.relativeContainer = null;
2493
2494		if ( !o.containment ) {
2495			this.containment = null;
2496			return;
2497		}
2498
2499		if ( o.containment === "window" ) {
2500			this.containment = [
2501				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2502				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2503				$( window ).scrollLeft() + $( window ).width() -
2504					this.helperProportions.width - this.margins.left,
2505				$( window ).scrollTop() +
2506					( $( window ).height() || document.body.parentNode.scrollHeight ) -
2507					this.helperProportions.height - this.margins.top
2508			];
2509			return;
2510		}
2511
2512		if ( o.containment === "document" ) {
2513			this.containment = [
2514				0,
2515				0,
2516				$( document ).width() - this.helperProportions.width - this.margins.left,
2517				( $( document ).height() || document.body.parentNode.scrollHeight ) -
2518					this.helperProportions.height - this.margins.top
2519			];
2520			return;
2521		}
2522
2523		if ( o.containment.constructor === Array ) {
2524			this.containment = o.containment;
2525			return;
2526		}
2527
2528		if ( o.containment === "parent" ) {
2529			o.containment = this.helper[ 0 ].parentNode;
2530		}
2531
2532		c = $( o.containment );
2533		ce = c[ 0 ];
2534
2535		if ( !ce ) {
2536			return;
2537		}
2538
2539		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2540
2541		this.containment = [
2542			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
2543				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2544			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
2545				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2546			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2547				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2548				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2549				this.helperProportions.width -
2550				this.margins.left -
2551				this.margins.right,
2552			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2553				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2554				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2555				this.helperProportions.height -
2556				this.margins.top -
2557				this.margins.bottom
2558		];
2559		this.relativeContainer = c;
2560	},
2561
2562	_convertPositionTo: function( d, pos ) {
2563
2564		if ( !pos ) {
2565			pos = this.position;
2566		}
2567
2568		var mod = d === "absolute" ? 1 : -1,
2569			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2570
2571		return {
2572			top: (
2573
2574				// The absolute mouse position
2575				pos.top	+
2576
2577				// Only for relative positioned nodes: Relative offset from element to offset parent
2578				this.offset.relative.top * mod +
2579
2580				// The offsetParent's offset without borders (offset + border)
2581				this.offset.parent.top * mod -
2582				( ( this.cssPosition === "fixed" ?
2583					-this.offset.scroll.top :
2584					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
2585			),
2586			left: (
2587
2588				// The absolute mouse position
2589				pos.left +
2590
2591				// Only for relative positioned nodes: Relative offset from element to offset parent
2592				this.offset.relative.left * mod +
2593
2594				// The offsetParent's offset without borders (offset + border)
2595				this.offset.parent.left * mod	-
2596				( ( this.cssPosition === "fixed" ?
2597					-this.offset.scroll.left :
2598					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
2599			)
2600		};
2601
2602	},
2603
2604	_generatePosition: function( event, constrainPosition ) {
2605
2606		var containment, co, top, left,
2607			o = this.options,
2608			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2609			pageX = event.pageX,
2610			pageY = event.pageY;
2611
2612		// Cache the scroll
2613		if ( !scrollIsRootNode || !this.offset.scroll ) {
2614			this.offset.scroll = {
2615				top: this.scrollParent.scrollTop(),
2616				left: this.scrollParent.scrollLeft()
2617			};
2618		}
2619
2620		/*
2621		 * - Position constraining -
2622		 * Constrain the position to a mix of grid, containment.
2623		 */
2624
2625		// If we are not dragging yet, we won't check for options
2626		if ( constrainPosition ) {
2627			if ( this.containment ) {
2628				if ( this.relativeContainer ) {
2629					co = this.relativeContainer.offset();
2630					containment = [
2631						this.containment[ 0 ] + co.left,
2632						this.containment[ 1 ] + co.top,
2633						this.containment[ 2 ] + co.left,
2634						this.containment[ 3 ] + co.top
2635					];
2636				} else {
2637					containment = this.containment;
2638				}
2639
2640				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
2641					pageX = containment[ 0 ] + this.offset.click.left;
2642				}
2643				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
2644					pageY = containment[ 1 ] + this.offset.click.top;
2645				}
2646				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
2647					pageX = containment[ 2 ] + this.offset.click.left;
2648				}
2649				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
2650					pageY = containment[ 3 ] + this.offset.click.top;
2651				}
2652			}
2653
2654			if ( o.grid ) {
2655
2656				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
2657				// argument errors in IE (see ticket #6950)
2658				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
2659					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
2660				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
2661					top - this.offset.click.top > containment[ 3 ] ) ?
2662						top :
2663						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
2664							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
2665
2666				left = o.grid[ 0 ] ? this.originalPageX +
2667					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
2668					this.originalPageX;
2669				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
2670					left - this.offset.click.left > containment[ 2 ] ) ?
2671						left :
2672						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
2673							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
2674			}
2675
2676			if ( o.axis === "y" ) {
2677				pageX = this.originalPageX;
2678			}
2679
2680			if ( o.axis === "x" ) {
2681				pageY = this.originalPageY;
2682			}
2683		}
2684
2685		return {
2686			top: (
2687
2688				// The absolute mouse position
2689				pageY -
2690
2691				// Click offset (relative to the element)
2692				this.offset.click.top -
2693
2694				// Only for relative positioned nodes: Relative offset from element to offset parent
2695				this.offset.relative.top -
2696
2697				// The offsetParent's offset without borders (offset + border)
2698				this.offset.parent.top +
2699				( this.cssPosition === "fixed" ?
2700					-this.offset.scroll.top :
2701					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2702			),
2703			left: (
2704
2705				// The absolute mouse position
2706				pageX -
2707
2708				// Click offset (relative to the element)
2709				this.offset.click.left -
2710
2711				// Only for relative positioned nodes: Relative offset from element to offset parent
2712				this.offset.relative.left -
2713
2714				// The offsetParent's offset without borders (offset + border)
2715				this.offset.parent.left +
2716				( this.cssPosition === "fixed" ?
2717					-this.offset.scroll.left :
2718					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2719			)
2720		};
2721
2722	},
2723
2724	_clear: function() {
2725		this._removeClass( this.helper, "ui-draggable-dragging" );
2726		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
2727			this.helper.remove();
2728		}
2729		this.helper = null;
2730		this.cancelHelperRemoval = false;
2731		if ( this.destroyOnClear ) {
2732			this.destroy();
2733		}
2734	},
2735
2736	// From now on bulk stuff - mainly helpers
2737
2738	_trigger: function( type, event, ui ) {
2739		ui = ui || this._uiHash();
2740		$.ui.plugin.call( this, type, [ event, ui, this ], true );
2741
2742		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
2743		if ( /^(drag|start|stop)/.test( type ) ) {
2744			this.positionAbs = this._convertPositionTo( "absolute" );
2745			ui.offset = this.positionAbs;
2746		}
2747		return $.Widget.prototype._trigger.call( this, type, event, ui );
2748	},
2749
2750	plugins: {},
2751
2752	_uiHash: function() {
2753		return {
2754			helper: this.helper,
2755			position: this.position,
2756			originalPosition: this.originalPosition,
2757			offset: this.positionAbs
2758		};
2759	}
2760
2761} );
2762
2763$.ui.plugin.add( "draggable", "connectToSortable", {
2764	start: function( event, ui, draggable ) {
2765		var uiSortable = $.extend( {}, ui, {
2766			item: draggable.element
2767		} );
2768
2769		draggable.sortables = [];
2770		$( draggable.options.connectToSortable ).each( function() {
2771			var sortable = $( this ).sortable( "instance" );
2772
2773			if ( sortable && !sortable.options.disabled ) {
2774				draggable.sortables.push( sortable );
2775
2776				// RefreshPositions is called at drag start to refresh the containerCache
2777				// which is used in drag. This ensures it's initialized and synchronized
2778				// with any changes that might have happened on the page since initialization.
2779				sortable.refreshPositions();
2780				sortable._trigger( "activate", event, uiSortable );
2781			}
2782		} );
2783	},
2784	stop: function( event, ui, draggable ) {
2785		var uiSortable = $.extend( {}, ui, {
2786			item: draggable.element
2787		} );
2788
2789		draggable.cancelHelperRemoval = false;
2790
2791		$.each( draggable.sortables, function() {
2792			var sortable = this;
2793
2794			if ( sortable.isOver ) {
2795				sortable.isOver = 0;
2796
2797				// Allow this sortable to handle removing the helper
2798				draggable.cancelHelperRemoval = true;
2799				sortable.cancelHelperRemoval = false;
2800
2801				// Use _storedCSS To restore properties in the sortable,
2802				// as this also handles revert (#9675) since the draggable
2803				// may have modified them in unexpected ways (#8809)
2804				sortable._storedCSS = {
2805					position: sortable.placeholder.css( "position" ),
2806					top: sortable.placeholder.css( "top" ),
2807					left: sortable.placeholder.css( "left" )
2808				};
2809
2810				sortable._mouseStop( event );
2811
2812				// Once drag has ended, the sortable should return to using
2813				// its original helper, not the shared helper from draggable
2814				sortable.options.helper = sortable.options._helper;
2815			} else {
2816
2817				// Prevent this Sortable from removing the helper.
2818				// However, don't set the draggable to remove the helper
2819				// either as another connected Sortable may yet handle the removal.
2820				sortable.cancelHelperRemoval = true;
2821
2822				sortable._trigger( "deactivate", event, uiSortable );
2823			}
2824		} );
2825	},
2826	drag: function( event, ui, draggable ) {
2827		$.each( draggable.sortables, function() {
2828			var innermostIntersecting = false,
2829				sortable = this;
2830
2831			// Copy over variables that sortable's _intersectsWith uses
2832			sortable.positionAbs = draggable.positionAbs;
2833			sortable.helperProportions = draggable.helperProportions;
2834			sortable.offset.click = draggable.offset.click;
2835
2836			if ( sortable._intersectsWith( sortable.containerCache ) ) {
2837				innermostIntersecting = true;
2838
2839				$.each( draggable.sortables, function() {
2840
2841					// Copy over variables that sortable's _intersectsWith uses
2842					this.positionAbs = draggable.positionAbs;
2843					this.helperProportions = draggable.helperProportions;
2844					this.offset.click = draggable.offset.click;
2845
2846					if ( this !== sortable &&
2847							this._intersectsWith( this.containerCache ) &&
2848							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2849						innermostIntersecting = false;
2850					}
2851
2852					return innermostIntersecting;
2853				} );
2854			}
2855
2856			if ( innermostIntersecting ) {
2857
2858				// If it intersects, we use a little isOver variable and set it once,
2859				// so that the move-in stuff gets fired only once.
2860				if ( !sortable.isOver ) {
2861					sortable.isOver = 1;
2862
2863					// Store draggable's parent in case we need to reappend to it later.
2864					draggable._parent = ui.helper.parent();
2865
2866					sortable.currentItem = ui.helper
2867						.appendTo( sortable.element )
2868						.data( "ui-sortable-item", true );
2869
2870					// Store helper option to later restore it
2871					sortable.options._helper = sortable.options.helper;
2872
2873					sortable.options.helper = function() {
2874						return ui.helper[ 0 ];
2875					};
2876
2877					// Fire the start events of the sortable with our passed browser event,
2878					// and our own helper (so it doesn't create a new one)
2879					event.target = sortable.currentItem[ 0 ];
2880					sortable._mouseCapture( event, true );
2881					sortable._mouseStart( event, true, true );
2882
2883					// Because the browser event is way off the new appended portlet,
2884					// modify necessary variables to reflect the changes
2885					sortable.offset.click.top = draggable.offset.click.top;
2886					sortable.offset.click.left = draggable.offset.click.left;
2887					sortable.offset.parent.left -= draggable.offset.parent.left -
2888						sortable.offset.parent.left;
2889					sortable.offset.parent.top -= draggable.offset.parent.top -
2890						sortable.offset.parent.top;
2891
2892					draggable._trigger( "toSortable", event );
2893
2894					// Inform draggable that the helper is in a valid drop zone,
2895					// used solely in the revert option to handle "valid/invalid".
2896					draggable.dropped = sortable.element;
2897
2898					// Need to refreshPositions of all sortables in the case that
2899					// adding to one sortable changes the location of the other sortables (#9675)
2900					$.each( draggable.sortables, function() {
2901						this.refreshPositions();
2902					} );
2903
2904					// Hack so receive/update callbacks work (mostly)
2905					draggable.currentItem = draggable.element;
2906					sortable.fromOutside = draggable;
2907				}
2908
2909				if ( sortable.currentItem ) {
2910					sortable._mouseDrag( event );
2911
2912					// Copy the sortable's position because the draggable's can potentially reflect
2913					// a relative position, while sortable is always absolute, which the dragged
2914					// element has now become. (#8809)
2915					ui.position = sortable.position;
2916				}
2917			} else {
2918
2919				// If it doesn't intersect with the sortable, and it intersected before,
2920				// we fake the drag stop of the sortable, but make sure it doesn't remove
2921				// the helper by using cancelHelperRemoval.
2922				if ( sortable.isOver ) {
2923
2924					sortable.isOver = 0;
2925					sortable.cancelHelperRemoval = true;
2926
2927					// Calling sortable's mouseStop would trigger a revert,
2928					// so revert must be temporarily false until after mouseStop is called.
2929					sortable.options._revert = sortable.options.revert;
2930					sortable.options.revert = false;
2931
2932					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2933					sortable._mouseStop( event, true );
2934
2935					// Restore sortable behaviors that were modfied
2936					// when the draggable entered the sortable area (#9481)
2937					sortable.options.revert = sortable.options._revert;
2938					sortable.options.helper = sortable.options._helper;
2939
2940					if ( sortable.placeholder ) {
2941						sortable.placeholder.remove();
2942					}
2943
2944					// Restore and recalculate the draggable's offset considering the sortable
2945					// may have modified them in unexpected ways. (#8809, #10669)
2946					ui.helper.appendTo( draggable._parent );
2947					draggable._refreshOffsets( event );
2948					ui.position = draggable._generatePosition( event, true );
2949
2950					draggable._trigger( "fromSortable", event );
2951
2952					// Inform draggable that the helper is no longer in a valid drop zone
2953					draggable.dropped = false;
2954
2955					// Need to refreshPositions of all sortables just in case removing
2956					// from one sortable changes the location of other sortables (#9675)
2957					$.each( draggable.sortables, function() {
2958						this.refreshPositions();
2959					} );
2960				}
2961			}
2962		} );
2963	}
2964} );
2965
2966$.ui.plugin.add( "draggable", "cursor", {
2967	start: function( event, ui, instance ) {
2968		var t = $( "body" ),
2969			o = instance.options;
2970
2971		if ( t.css( "cursor" ) ) {
2972			o._cursor = t.css( "cursor" );
2973		}
2974		t.css( "cursor", o.cursor );
2975	},
2976	stop: function( event, ui, instance ) {
2977		var o = instance.options;
2978		if ( o._cursor ) {
2979			$( "body" ).css( "cursor", o._cursor );
2980		}
2981	}
2982} );
2983
2984$.ui.plugin.add( "draggable", "opacity", {
2985	start: function( event, ui, instance ) {
2986		var t = $( ui.helper ),
2987			o = instance.options;
2988		if ( t.css( "opacity" ) ) {
2989			o._opacity = t.css( "opacity" );
2990		}
2991		t.css( "opacity", o.opacity );
2992	},
2993	stop: function( event, ui, instance ) {
2994		var o = instance.options;
2995		if ( o._opacity ) {
2996			$( ui.helper ).css( "opacity", o._opacity );
2997		}
2998	}
2999} );
3000
3001$.ui.plugin.add( "draggable", "scroll", {
3002	start: function( event, ui, i ) {
3003		if ( !i.scrollParentNotHidden ) {
3004			i.scrollParentNotHidden = i.helper.scrollParent( false );
3005		}
3006
3007		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
3008				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
3009			i.overflowOffset = i.scrollParentNotHidden.offset();
3010		}
3011	},
3012	drag: function( event, ui, i  ) {
3013
3014		var o = i.options,
3015			scrolled = false,
3016			scrollParent = i.scrollParentNotHidden[ 0 ],
3017			document = i.document[ 0 ];
3018
3019		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
3020			if ( !o.axis || o.axis !== "x" ) {
3021				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
3022						o.scrollSensitivity ) {
3023					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
3024				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
3025					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
3026				}
3027			}
3028
3029			if ( !o.axis || o.axis !== "y" ) {
3030				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
3031						o.scrollSensitivity ) {
3032					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
3033				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
3034					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
3035				}
3036			}
3037
3038		} else {
3039
3040			if ( !o.axis || o.axis !== "x" ) {
3041				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
3042					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
3043				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
3044						o.scrollSensitivity ) {
3045					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
3046				}
3047			}
3048
3049			if ( !o.axis || o.axis !== "y" ) {
3050				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
3051					scrolled = $( document ).scrollLeft(
3052						$( document ).scrollLeft() - o.scrollSpeed
3053					);
3054				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
3055						o.scrollSensitivity ) {
3056					scrolled = $( document ).scrollLeft(
3057						$( document ).scrollLeft() + o.scrollSpeed
3058					);
3059				}
3060			}
3061
3062		}
3063
3064		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
3065			$.ui.ddmanager.prepareOffsets( i, event );
3066		}
3067
3068	}
3069} );
3070
3071$.ui.plugin.add( "draggable", "snap", {
3072	start: function( event, ui, i ) {
3073
3074		var o = i.options;
3075
3076		i.snapElements = [];
3077
3078		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
3079			.each( function() {
3080				var $t = $( this ),
3081					$o = $t.offset();
3082				if ( this !== i.element[ 0 ] ) {
3083					i.snapElements.push( {
3084						item: this,
3085						width: $t.outerWidth(), height: $t.outerHeight(),
3086						top: $o.top, left: $o.left
3087					} );
3088				}
3089			} );
3090
3091	},
3092	drag: function( event, ui, inst ) {
3093
3094		var ts, bs, ls, rs, l, r, t, b, i, first,
3095			o = inst.options,
3096			d = o.snapTolerance,
3097			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
3098			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
3099
3100		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
3101
3102			l = inst.snapElements[ i ].left - inst.margins.left;
3103			r = l + inst.snapElements[ i ].width;
3104			t = inst.snapElements[ i ].top - inst.margins.top;
3105			b = t + inst.snapElements[ i ].height;
3106
3107			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
3108					!$.contains( inst.snapElements[ i ].item.ownerDocument,
3109					inst.snapElements[ i ].item ) ) {
3110				if ( inst.snapElements[ i ].snapping ) {
3111					( inst.options.snap.release &&
3112						inst.options.snap.release.call(
3113							inst.element,
3114							event,
3115							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
3116						) );
3117				}
3118				inst.snapElements[ i ].snapping = false;
3119				continue;
3120			}
3121
3122			if ( o.snapMode !== "inner" ) {
3123				ts = Math.abs( t - y2 ) <= d;
3124				bs = Math.abs( b - y1 ) <= d;
3125				ls = Math.abs( l - x2 ) <= d;
3126				rs = Math.abs( r - x1 ) <= d;
3127				if ( ts ) {
3128					ui.position.top = inst._convertPositionTo( "relative", {
3129						top: t - inst.helperProportions.height,
3130						left: 0
3131					} ).top;
3132				}
3133				if ( bs ) {
3134					ui.position.top = inst._convertPositionTo( "relative", {
3135						top: b,
3136						left: 0
3137					} ).top;
3138				}
3139				if ( ls ) {
3140					ui.position.left = inst._convertPositionTo( "relative", {
3141						top: 0,
3142						left: l - inst.helperProportions.width
3143					} ).left;
3144				}
3145				if ( rs ) {
3146					ui.position.left = inst._convertPositionTo( "relative", {
3147						top: 0,
3148						left: r
3149					} ).left;
3150				}
3151			}
3152
3153			first = ( ts || bs || ls || rs );
3154
3155			if ( o.snapMode !== "outer" ) {
3156				ts = Math.abs( t - y1 ) <= d;
3157				bs = Math.abs( b - y2 ) <= d;
3158				ls = Math.abs( l - x1 ) <= d;
3159				rs = Math.abs( r - x2 ) <= d;
3160				if ( ts ) {
3161					ui.position.top = inst._convertPositionTo( "relative", {
3162						top: t,
3163						left: 0
3164					} ).top;
3165				}
3166				if ( bs ) {
3167					ui.position.top = inst._convertPositionTo( "relative", {
3168						top: b - inst.helperProportions.height,
3169						left: 0
3170					} ).top;
3171				}
3172				if ( ls ) {
3173					ui.position.left = inst._convertPositionTo( "relative", {
3174						top: 0,
3175						left: l
3176					} ).left;
3177				}
3178				if ( rs ) {
3179					ui.position.left = inst._convertPositionTo( "relative", {
3180						top: 0,
3181						left: r - inst.helperProportions.width
3182					} ).left;
3183				}
3184			}
3185
3186			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
3187				( inst.options.snap.snap &&
3188					inst.options.snap.snap.call(
3189						inst.element,
3190						event,
3191						$.extend( inst._uiHash(), {
3192							snapItem: inst.snapElements[ i ].item
3193						} ) ) );
3194			}
3195			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
3196
3197		}
3198
3199	}
3200} );
3201
3202$.ui.plugin.add( "draggable", "stack", {
3203	start: function( event, ui, instance ) {
3204		var min,
3205			o = instance.options,
3206			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
3207				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
3208					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
3209			} );
3210
3211		if ( !group.length ) { return; }
3212
3213		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
3214		$( group ).each( function( i ) {
3215			$( this ).css( "zIndex", min + i );
3216		} );
3217		this.css( "zIndex", ( min + group.length ) );
3218	}
3219} );
3220
3221$.ui.plugin.add( "draggable", "zIndex", {
3222	start: function( event, ui, instance ) {
3223		var t = $( ui.helper ),
3224			o = instance.options;
3225
3226		if ( t.css( "zIndex" ) ) {
3227			o._zIndex = t.css( "zIndex" );
3228		}
3229		t.css( "zIndex", o.zIndex );
3230	},
3231	stop: function( event, ui, instance ) {
3232		var o = instance.options;
3233
3234		if ( o._zIndex ) {
3235			$( ui.helper ).css( "zIndex", o._zIndex );
3236		}
3237	}
3238} );
3239
3240var widgetsDraggable = $.ui.draggable;
3241
3242
3243/*!
3244 * jQuery UI Droppable 1.12.1
3245 * http://jqueryui.com
3246 *
3247 * Copyright jQuery Foundation and other contributors
3248 * Released under the MIT license.
3249 * http://jquery.org/license
3250 */
3251
3252//>>label: Droppable
3253//>>group: Interactions
3254//>>description: Enables drop targets for draggable elements.
3255//>>docs: http://api.jqueryui.com/droppable/
3256//>>demos: http://jqueryui.com/droppable/
3257
3258
3259
3260$.widget( "ui.droppable", {
3261	version: "1.12.1",
3262	widgetEventPrefix: "drop",
3263	options: {
3264		accept: "*",
3265		addClasses: true,
3266		greedy: false,
3267		scope: "default",
3268		tolerance: "intersect",
3269
3270		// Callbacks
3271		activate: null,
3272		deactivate: null,
3273		drop: null,
3274		out: null,
3275		over: null
3276	},
3277	_create: function() {
3278
3279		var proportions,
3280			o = this.options,
3281			accept = o.accept;
3282
3283		this.isover = false;
3284		this.isout = true;
3285
3286		this.accept = $.isFunction( accept ) ? accept : function( d ) {
3287			return d.is( accept );
3288		};
3289
3290		this.proportions = function( /* valueToWrite */ ) {
3291			if ( arguments.length ) {
3292
3293				// Store the droppable's proportions
3294				proportions = arguments[ 0 ];
3295			} else {
3296
3297				// Retrieve or derive the droppable's proportions
3298				return proportions ?
3299					proportions :
3300					proportions = {
3301						width: this.element[ 0 ].offsetWidth,
3302						height: this.element[ 0 ].offsetHeight
3303					};
3304			}
3305		};
3306
3307		this._addToManager( o.scope );
3308
3309		o.addClasses && this._addClass( "ui-droppable" );
3310
3311	},
3312
3313	_addToManager: function( scope ) {
3314
3315		// Add the reference and positions to the manager
3316		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
3317		$.ui.ddmanager.droppables[ scope ].push( this );
3318	},
3319
3320	_splice: function( drop ) {
3321		var i = 0;
3322		for ( ; i < drop.length; i++ ) {
3323			if ( drop[ i ] === this ) {
3324				drop.splice( i, 1 );
3325			}
3326		}
3327	},
3328
3329	_destroy: function() {
3330		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
3331
3332		this._splice( drop );
3333	},
3334
3335	_setOption: function( key, value ) {
3336
3337		if ( key === "accept" ) {
3338			this.accept = $.isFunction( value ) ? value : function( d ) {
3339				return d.is( value );
3340			};
3341		} else if ( key === "scope" ) {
3342			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
3343
3344			this._splice( drop );
3345			this._addToManager( value );
3346		}
3347
3348		this._super( key, value );
3349	},
3350
3351	_activate: function( event ) {
3352		var draggable = $.ui.ddmanager.current;
3353
3354		this._addActiveClass();
3355		if ( draggable ) {
3356			this._trigger( "activate", event, this.ui( draggable ) );
3357		}
3358	},
3359
3360	_deactivate: function( event ) {
3361		var draggable = $.ui.ddmanager.current;
3362
3363		this._removeActiveClass();
3364		if ( draggable ) {
3365			this._trigger( "deactivate", event, this.ui( draggable ) );
3366		}
3367	},
3368
3369	_over: function( event ) {
3370
3371		var draggable = $.ui.ddmanager.current;
3372
3373		// Bail if draggable and droppable are same element
3374		if ( !draggable || ( draggable.currentItem ||
3375				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3376			return;
3377		}
3378
3379		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
3380				draggable.element ) ) ) {
3381			this._addHoverClass();
3382			this._trigger( "over", event, this.ui( draggable ) );
3383		}
3384
3385	},
3386
3387	_out: function( event ) {
3388
3389		var draggable = $.ui.ddmanager.current;
3390
3391		// Bail if draggable and droppable are same element
3392		if ( !draggable || ( draggable.currentItem ||
3393				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3394			return;
3395		}
3396
3397		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
3398				draggable.element ) ) ) {
3399			this._removeHoverClass();
3400			this._trigger( "out", event, this.ui( draggable ) );
3401		}
3402
3403	},
3404
3405	_drop: function( event, custom ) {
3406
3407		var draggable = custom || $.ui.ddmanager.current,
3408			childrenIntersection = false;
vendor: 4,744 bytes, lines 3409-3581
3409
3410		// Bail if draggable and droppable are same element
3411		if ( !draggable || ( draggable.currentItem ||
3412				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3413			return false;
3414		}
3415
3416		this.element
3417			.find( ":data(ui-droppable)" )
3418			.not( ".ui-draggable-dragging" )
3419			.each( function() {
3420				var inst = $( this ).droppable( "instance" );
3421				if (
3422					inst.options.greedy &&
3423					!inst.options.disabled &&
3424					inst.options.scope === draggable.options.scope &&
3425					inst.accept.call(
3426						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
3427					) &&
3428					intersect(
3429						draggable,
3430						$.extend( inst, { offset: inst.element.offset() } ),
3431						inst.options.tolerance, event
3432					)
3433				) {
3434					childrenIntersection = true;
3435					return false; }
3436			} );
3437		if ( childrenIntersection ) {
3438			return false;
3439		}
3440
3441		if ( this.accept.call( this.element[ 0 ],
3442				( draggable.currentItem || draggable.element ) ) ) {
3443			this._removeActiveClass();
3444			this._removeHoverClass();
3445
3446			this._trigger( "drop", event, this.ui( draggable ) );
3447			return this.element;
3448		}
3449
3450		return false;
3451
3452	},
3453
3454	ui: function( c ) {
3455		return {
3456			draggable: ( c.currentItem || c.element ),
3457			helper: c.helper,
3458			position: c.position,
3459			offset: c.positionAbs
3460		};
3461	},
3462
3463	// Extension points just to make backcompat sane and avoid duplicating logic
3464	// TODO: Remove in 1.13 along with call to it below
3465	_addHoverClass: function() {
3466		this._addClass( "ui-droppable-hover" );
3467	},
3468
3469	_removeHoverClass: function() {
3470		this._removeClass( "ui-droppable-hover" );
3471	},
3472
3473	_addActiveClass: function() {
3474		this._addClass( "ui-droppable-active" );
3475	},
3476
3477	_removeActiveClass: function() {
3478		this._removeClass( "ui-droppable-active" );
3479	}
3480} );
3481
3482var intersect = $.ui.intersect = ( function() {
3483	function isOverAxis( x, reference, size ) {
3484		return ( x >= reference ) && ( x < ( reference + size ) );
3485	}
3486
3487	return function( draggable, droppable, toleranceMode, event ) {
3488
3489		if ( !droppable.offset ) {
3490			return false;
3491		}
3492
3493		var x1 = ( draggable.positionAbs ||
3494				draggable.position.absolute ).left + draggable.margins.left,
3495			y1 = ( draggable.positionAbs ||
3496				draggable.position.absolute ).top + draggable.margins.top,
3497			x2 = x1 + draggable.helperProportions.width,
3498			y2 = y1 + draggable.helperProportions.height,
3499			l = droppable.offset.left,
3500			t = droppable.offset.top,
3501			r = l + droppable.proportions().width,
3502			b = t + droppable.proportions().height;
3503
3504		switch ( toleranceMode ) {
3505		case "fit":
3506			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
3507		case "intersect":
3508			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
3509				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
3510				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
3511				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
3512		case "pointer":
3513			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
3514				isOverAxis( event.pageX, l, droppable.proportions().width );
3515		case "touch":
3516			return (
3517				( y1 >= t && y1 <= b ) || // Top edge touching
3518				( y2 >= t && y2 <= b ) || // Bottom edge touching
3519				( y1 < t && y2 > b ) // Surrounded vertically
3520			) && (
3521				( x1 >= l && x1 <= r ) || // Left edge touching
3522				( x2 >= l && x2 <= r ) || // Right edge touching
3523				( x1 < l && x2 > r ) // Surrounded horizontally
3524			);
3525		default:
3526			return false;
3527		}
3528	};
3529} )();
3530
3531/*
3532	This manager tracks offsets of draggables and droppables
3533*/
3534$.ui.ddmanager = {
3535	current: null,
3536	droppables: { "default": [] },
3537	prepareOffsets: function( t, event ) {
3538
3539		var i, j,
3540			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
3541			type = event ? event.type : null, // workaround for #2317
3542			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
3543
3544		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
3545
3546			// No disabled and non-accepted
3547			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
3548					( t.currentItem || t.element ) ) ) ) {
3549				continue;
3550			}
3551
3552			// Filter out elements in the current dragged item
3553			for ( j = 0; j < list.length; j++ ) {
3554				if ( list[ j ] === m[ i ].element[ 0 ] ) {
3555					m[ i ].proportions().height = 0;
3556					continue droppablesLoop;
3557				}
3558			}
3559
3560			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
3561			if ( !m[ i ].visible ) {
3562				continue;
3563			}
3564
3565			// Activate the droppable if used directly from draggables
3566			if ( type === "mousedown" ) {
3567				m[ i ]._activate.call( m[ i ], event );
3568			}
3569
3570			m[ i ].offset = m[ i ].element.offset();
3571			m[ i ].proportions( {
3572				width: m[ i ].element[ 0 ].offsetWidth,
3573				height: m[ i ].element[ 0 ].offsetHeight
3574			} );
3575
3576		}
3577
3578	},
3579	drop: function( draggable, event ) {
3580
3581		var dropped = false;
vendor: 5,516 bytes, lines 3582-3787
3582
3583		// Create a copy of the droppables in case the list changes during the drop (#9116)
3584		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
3585
3586			if ( !this.options ) {
3587				return;
3588			}
3589			if ( !this.options.disabled && this.visible &&
3590					intersect( draggable, this, this.options.tolerance, event ) ) {
3591				dropped = this._drop.call( this, event ) || dropped;
3592			}
3593
3594			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
3595					( draggable.currentItem || draggable.element ) ) ) {
3596				this.isout = true;
3597				this.isover = false;
3598				this._deactivate.call( this, event );
3599			}
3600
3601		} );
3602		return dropped;
3603
3604	},
3605	dragStart: function( draggable, event ) {
3606
3607		// Listen for scrolling so that if the dragging causes scrolling the position of the
3608		// droppables can be recalculated (see #5003)
3609		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
3610			if ( !draggable.options.refreshPositions ) {
3611				$.ui.ddmanager.prepareOffsets( draggable, event );
3612			}
3613		} );
3614	},
3615	drag: function( draggable, event ) {
3616
3617		// If you have a highly dynamic page, you might try this option. It renders positions
3618		// every time you move the mouse.
3619		if ( draggable.options.refreshPositions ) {
3620			$.ui.ddmanager.prepareOffsets( draggable, event );
3621		}
3622
3623		// Run through all droppables and check their positions based on specific tolerance options
3624		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3625
3626			if ( this.options.disabled || this.greedyChild || !this.visible ) {
3627				return;
3628			}
3629
3630			var parentInstance, scope, parent,
3631				intersects = intersect( draggable, this, this.options.tolerance, event ),
3632				c = !intersects && this.isover ?
3633					"isout" :
3634					( intersects && !this.isover ? "isover" : null );
3635			if ( !c ) {
3636				return;
3637			}
3638
3639			if ( this.options.greedy ) {
3640
3641				// find droppable parents with same scope
3642				scope = this.options.scope;
3643				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
3644					return $( this ).droppable( "instance" ).options.scope === scope;
3645				} );
3646
3647				if ( parent.length ) {
3648					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3649					parentInstance.greedyChild = ( c === "isover" );
3650				}
3651			}
3652
3653			// We just moved into a greedy child
3654			if ( parentInstance && c === "isover" ) {
3655				parentInstance.isover = false;
3656				parentInstance.isout = true;
3657				parentInstance._out.call( parentInstance, event );
3658			}
3659
3660			this[ c ] = true;
3661			this[ c === "isout" ? "isover" : "isout" ] = false;
3662			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
3663
3664			// We just moved out of a greedy child
3665			if ( parentInstance && c === "isout" ) {
3666				parentInstance.isout = false;
3667				parentInstance.isover = true;
3668				parentInstance._over.call( parentInstance, event );
3669			}
3670		} );
3671
3672	},
3673	dragStop: function( draggable, event ) {
3674		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
3675
3676		// Call prepareOffsets one final time since IE does not fire return scroll events when
3677		// overflow was caused by drag (see #5003)
3678		if ( !draggable.options.refreshPositions ) {
3679			$.ui.ddmanager.prepareOffsets( draggable, event );
3680		}
3681	}
3682};
3683
3684// DEPRECATED
3685// TODO: switch return back to widget declaration at top of file when this is removed
3686if ( $.uiBackCompat !== false ) {
3687
3688	// Backcompat for activeClass and hoverClass options
3689	$.widget( "ui.droppable", $.ui.droppable, {
3690		options: {
3691			hoverClass: false,
3692			activeClass: false
3693		},
3694		_addActiveClass: function() {
3695			this._super();
3696			if ( this.options.activeClass ) {
3697				this.element.addClass( this.options.activeClass );
3698			}
3699		},
3700		_removeActiveClass: function() {
3701			this._super();
3702			if ( this.options.activeClass ) {
3703				this.element.removeClass( this.options.activeClass );
3704			}
3705		},
3706		_addHoverClass: function() {
3707			this._super();
3708			if ( this.options.hoverClass ) {
3709				this.element.addClass( this.options.hoverClass );
3710			}
3711		},
3712		_removeHoverClass: function() {
3713			this._super();
3714			if ( this.options.hoverClass ) {
3715				this.element.removeClass( this.options.hoverClass );
3716			}
3717		}
3718	} );
3719}
3720
3721var widgetsDroppable = $.ui.droppable;
3722
3723
3724/*!
3725 * jQuery UI Resizable 1.12.1
3726 * http://jqueryui.com
3727 *
3728 * Copyright jQuery Foundation and other contributors
3729 * Released under the MIT license.
3730 * http://jquery.org/license
3731 */
3732
3733//>>label: Resizable
3734//>>group: Interactions
3735//>>description: Enables resize functionality for any element.
3736//>>docs: http://api.jqueryui.com/resizable/
3737//>>demos: http://jqueryui.com/resizable/
3738//>>css.structure: ../../themes/base/core.css
3739//>>css.structure: ../../themes/base/resizable.css
3740//>>css.theme: ../../themes/base/theme.css
3741
3742
3743
3744$.widget( "ui.resizable", $.ui.mouse, {
3745	version: "1.12.1",
3746	widgetEventPrefix: "resize",
3747	options: {
3748		alsoResize: false,
3749		animate: false,
3750		animateDuration: "slow",
3751		animateEasing: "swing",
3752		aspectRatio: false,
3753		autoHide: false,
3754		classes: {
3755			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
3756		},
3757		containment: false,
3758		ghost: false,
3759		grid: false,
3760		handles: "e,s,se",
3761		helper: false,
3762		maxHeight: null,
3763		maxWidth: null,
3764		minHeight: 10,
3765		minWidth: 10,
3766
3767		// See #7960
3768		zIndex: 90,
3769
3770		// Callbacks
3771		resize: null,
3772		start: null,
3773		stop: null
3774	},
3775
3776	_num: function( value ) {
3777		return parseFloat( value ) || 0;
3778	},
3779
3780	_isNumber: function( value ) {
3781		return !isNaN( parseFloat( value ) );
3782	},
3783
3784	_hasScroll: function( el, a ) {
3785
3786		if ( $( el ).css( "overflow" ) === "hidden" ) {
3787			return false;
vendor: 26,006 bytes, lines 3788-4816
3788		}
3789
3790		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3791			has = false;
3792
3793		if ( el[ scroll ] > 0 ) {
3794			return true;
3795		}
3796
3797		// TODO: determine which cases actually cause this to happen
3798		// if the element doesn't have the scroll set, see if it's possible to
3799		// set the scroll
3800		el[ scroll ] = 1;
3801		has = ( el[ scroll ] > 0 );
3802		el[ scroll ] = 0;
3803		return has;
3804	},
3805
3806	_create: function() {
3807
3808		var margins,
3809			o = this.options,
3810			that = this;
3811		this._addClass( "ui-resizable" );
3812
3813		$.extend( this, {
3814			_aspectRatio: !!( o.aspectRatio ),
3815			aspectRatio: o.aspectRatio,
3816			originalElement: this.element,
3817			_proportionallyResizeElements: [],
3818			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3819		} );
3820
3821		// Wrap the element if it cannot hold child nodes
3822		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
3823
3824			this.element.wrap(
3825				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
3826					position: this.element.css( "position" ),
3827					width: this.element.outerWidth(),
3828					height: this.element.outerHeight(),
3829					top: this.element.css( "top" ),
3830					left: this.element.css( "left" )
3831				} )
3832			);
3833
3834			this.element = this.element.parent().data(
3835				"ui-resizable", this.element.resizable( "instance" )
3836			);
3837
3838			this.elementIsWrapper = true;
3839
3840			margins = {
3841				marginTop: this.originalElement.css( "marginTop" ),
3842				marginRight: this.originalElement.css( "marginRight" ),
3843				marginBottom: this.originalElement.css( "marginBottom" ),
3844				marginLeft: this.originalElement.css( "marginLeft" )
3845			};
3846
3847			this.element.css( margins );
3848			this.originalElement.css( "margin", 0 );
3849
3850			// support: Safari
3851			// Prevent Safari textarea resize
3852			this.originalResizeStyle = this.originalElement.css( "resize" );
3853			this.originalElement.css( "resize", "none" );
3854
3855			this._proportionallyResizeElements.push( this.originalElement.css( {
3856				position: "static",
3857				zoom: 1,
3858				display: "block"
3859			} ) );
3860
3861			// Support: IE9
3862			// avoid IE jump (hard set the margin)
3863			this.originalElement.css( margins );
3864
3865			this._proportionallyResize();
3866		}
3867
3868		this._setupHandles();
3869
3870		if ( o.autoHide ) {
3871			$( this.element )
3872				.on( "mouseenter", function() {
3873					if ( o.disabled ) {
3874						return;
3875					}
3876					that._removeClass( "ui-resizable-autohide" );
3877					that._handles.show();
3878				} )
3879				.on( "mouseleave", function() {
3880					if ( o.disabled ) {
3881						return;
3882					}
3883					if ( !that.resizing ) {
3884						that._addClass( "ui-resizable-autohide" );
3885						that._handles.hide();
3886					}
3887				} );
3888		}
3889
3890		this._mouseInit();
3891	},
3892
3893	_destroy: function() {
3894
3895		this._mouseDestroy();
3896
3897		var wrapper,
3898			_destroy = function( exp ) {
3899				$( exp )
3900					.removeData( "resizable" )
3901					.removeData( "ui-resizable" )
3902					.off( ".resizable" )
3903					.find( ".ui-resizable-handle" )
3904						.remove();
3905			};
3906
3907		// TODO: Unwrap at same DOM position
3908		if ( this.elementIsWrapper ) {
3909			_destroy( this.element );
3910			wrapper = this.element;
3911			this.originalElement.css( {
3912				position: wrapper.css( "position" ),
3913				width: wrapper.outerWidth(),
3914				height: wrapper.outerHeight(),
3915				top: wrapper.css( "top" ),
3916				left: wrapper.css( "left" )
3917			} ).insertAfter( wrapper );
3918			wrapper.remove();
3919		}
3920
3921		this.originalElement.css( "resize", this.originalResizeStyle );
3922		_destroy( this.originalElement );
3923
3924		return this;
3925	},
3926
3927	_setOption: function( key, value ) {
3928		this._super( key, value );
3929
3930		switch ( key ) {
3931		case "handles":
3932			this._removeHandles();
3933			this._setupHandles();
3934			break;
3935		default:
3936			break;
3937		}
3938	},
3939
3940	_setupHandles: function() {
3941		var o = this.options, handle, i, n, hname, axis, that = this;
3942		this.handles = o.handles ||
3943			( !$( ".ui-resizable-handle", this.element ).length ?
3944				"e,s,se" : {
3945					n: ".ui-resizable-n",
3946					e: ".ui-resizable-e",
3947					s: ".ui-resizable-s",
3948					w: ".ui-resizable-w",
3949					se: ".ui-resizable-se",
3950					sw: ".ui-resizable-sw",
3951					ne: ".ui-resizable-ne",
3952					nw: ".ui-resizable-nw"
3953				} );
3954
3955		this._handles = $();
3956		if ( this.handles.constructor === String ) {
3957
3958			if ( this.handles === "all" ) {
3959				this.handles = "n,e,s,w,se,sw,ne,nw";
3960			}
3961
3962			n = this.handles.split( "," );
3963			this.handles = {};
3964
3965			for ( i = 0; i < n.length; i++ ) {
3966
3967				handle = $.trim( n[ i ] );
3968				hname = "ui-resizable-" + handle;
3969				axis = $( "<div>" );
3970				this._addClass( axis, "ui-resizable-handle " + hname );
3971
3972				axis.css( { zIndex: o.zIndex } );
3973
3974				this.handles[ handle ] = ".ui-resizable-" + handle;
3975				this.element.append( axis );
3976			}
3977
3978		}
3979
3980		this._renderAxis = function( target ) {
3981
3982			var i, axis, padPos, padWrapper;
3983
3984			target = target || this.element;
3985
3986			for ( i in this.handles ) {
3987
3988				if ( this.handles[ i ].constructor === String ) {
3989					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
3990				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3991					this.handles[ i ] = $( this.handles[ i ] );
3992					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
3993				}
3994
3995				if ( this.elementIsWrapper &&
3996						this.originalElement[ 0 ]
3997							.nodeName
3998							.match( /^(textarea|input|select|button)$/i ) ) {
3999					axis = $( this.handles[ i ], this.element );
4000
4001					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
4002						axis.outerHeight() :
4003						axis.outerWidth();
4004
4005					padPos = [ "padding",
4006						/ne|nw|n/.test( i ) ? "Top" :
4007						/se|sw|s/.test( i ) ? "Bottom" :
4008						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
4009
4010					target.css( padPos, padWrapper );
4011
4012					this._proportionallyResize();
4013				}
4014
4015				this._handles = this._handles.add( this.handles[ i ] );
4016			}
4017		};
4018
4019		// TODO: make renderAxis a prototype function
4020		this._renderAxis( this.element );
4021
4022		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
4023		this._handles.disableSelection();
4024
4025		this._handles.on( "mouseover", function() {
4026			if ( !that.resizing ) {
4027				if ( this.className ) {
4028					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
4029				}
4030				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
4031			}
4032		} );
4033
4034		if ( o.autoHide ) {
4035			this._handles.hide();
4036			this._addClass( "ui-resizable-autohide" );
4037		}
4038	},
4039
4040	_removeHandles: function() {
4041		this._handles.remove();
4042	},
4043
4044	_mouseCapture: function( event ) {
4045		var i, handle,
4046			capture = false;
4047
4048		for ( i in this.handles ) {
4049			handle = $( this.handles[ i ] )[ 0 ];
4050			if ( handle === event.target || $.contains( handle, event.target ) ) {
4051				capture = true;
4052			}
4053		}
4054
4055		return !this.options.disabled && capture;
4056	},
4057
4058	_mouseStart: function( event ) {
4059
4060		var curleft, curtop, cursor,
4061			o = this.options,
4062			el = this.element;
4063
4064		this.resizing = true;
4065
4066		this._renderProxy();
4067
4068		curleft = this._num( this.helper.css( "left" ) );
4069		curtop = this._num( this.helper.css( "top" ) );
4070
4071		if ( o.containment ) {
4072			curleft += $( o.containment ).scrollLeft() || 0;
4073			curtop += $( o.containment ).scrollTop() || 0;
4074		}
4075
4076		this.offset = this.helper.offset();
4077		this.position = { left: curleft, top: curtop };
4078
4079		this.size = this._helper ? {
4080				width: this.helper.width(),
4081				height: this.helper.height()
4082			} : {
4083				width: el.width(),
4084				height: el.height()
4085			};
4086
4087		this.originalSize = this._helper ? {
4088				width: el.outerWidth(),
4089				height: el.outerHeight()
4090			} : {
4091				width: el.width(),
4092				height: el.height()
4093			};
4094
4095		this.sizeDiff = {
4096			width: el.outerWidth() - el.width(),
4097			height: el.outerHeight() - el.height()
4098		};
4099
4100		this.originalPosition = { left: curleft, top: curtop };
4101		this.originalMousePosition = { left: event.pageX, top: event.pageY };
4102
4103		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
4104			o.aspectRatio :
4105			( ( this.originalSize.width / this.originalSize.height ) || 1 );
4106
4107		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
4108		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
4109
4110		this._addClass( "ui-resizable-resizing" );
4111		this._propagate( "start", event );
4112		return true;
4113	},
4114
4115	_mouseDrag: function( event ) {
4116
4117		var data, props,
4118			smp = this.originalMousePosition,
4119			a = this.axis,
4120			dx = ( event.pageX - smp.left ) || 0,
4121			dy = ( event.pageY - smp.top ) || 0,
4122			trigger = this._change[ a ];
4123
4124		this._updatePrevProperties();
4125
4126		if ( !trigger ) {
4127			return false;
4128		}
4129
4130		data = trigger.apply( this, [ event, dx, dy ] );
4131
4132		this._updateVirtualBoundaries( event.shiftKey );
4133		if ( this._aspectRatio || event.shiftKey ) {
4134			data = this._updateRatio( data, event );
4135		}
4136
4137		data = this._respectSize( data, event );
4138
4139		this._updateCache( data );
4140
4141		this._propagate( "resize", event );
4142
4143		props = this._applyChanges();
4144
4145		if ( !this._helper && this._proportionallyResizeElements.length ) {
4146			this._proportionallyResize();
4147		}
4148
4149		if ( !$.isEmptyObject( props ) ) {
4150			this._updatePrevProperties();
4151			this._trigger( "resize", event, this.ui() );
4152			this._applyChanges();
4153		}
4154
4155		return false;
4156	},
4157
4158	_mouseStop: function( event ) {
4159
4160		this.resizing = false;
4161		var pr, ista, soffseth, soffsetw, s, left, top,
4162			o = this.options, that = this;
4163
4164		if ( this._helper ) {
4165
4166			pr = this._proportionallyResizeElements;
4167			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
4168			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
4169			soffsetw = ista ? 0 : that.sizeDiff.width;
4170
4171			s = {
4172				width: ( that.helper.width()  - soffsetw ),
4173				height: ( that.helper.height() - soffseth )
4174			};
4175			left = ( parseFloat( that.element.css( "left" ) ) +
4176				( that.position.left - that.originalPosition.left ) ) || null;
4177			top = ( parseFloat( that.element.css( "top" ) ) +
4178				( that.position.top - that.originalPosition.top ) ) || null;
4179
4180			if ( !o.animate ) {
4181				this.element.css( $.extend( s, { top: top, left: left } ) );
4182			}
4183
4184			that.helper.height( that.size.height );
4185			that.helper.width( that.size.width );
4186
4187			if ( this._helper && !o.animate ) {
4188				this._proportionallyResize();
4189			}
4190		}
4191
4192		$( "body" ).css( "cursor", "auto" );
4193
4194		this._removeClass( "ui-resizable-resizing" );
4195
4196		this._propagate( "stop", event );
4197
4198		if ( this._helper ) {
4199			this.helper.remove();
4200		}
4201
4202		return false;
4203
4204	},
4205
4206	_updatePrevProperties: function() {
4207		this.prevPosition = {
4208			top: this.position.top,
4209			left: this.position.left
4210		};
4211		this.prevSize = {
4212			width: this.size.width,
4213			height: this.size.height
4214		};
4215	},
4216
4217	_applyChanges: function() {
4218		var props = {};
4219
4220		if ( this.position.top !== this.prevPosition.top ) {
4221			props.top = this.position.top + "px";
4222		}
4223		if ( this.position.left !== this.prevPosition.left ) {
4224			props.left = this.position.left + "px";
4225		}
4226		if ( this.size.width !== this.prevSize.width ) {
4227			props.width = this.size.width + "px";
4228		}
4229		if ( this.size.height !== this.prevSize.height ) {
4230			props.height = this.size.height + "px";
4231		}
4232
4233		this.helper.css( props );
4234
4235		return props;
4236	},
4237
4238	_updateVirtualBoundaries: function( forceAspectRatio ) {
4239		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
4240			o = this.options;
4241
4242		b = {
4243			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
4244			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
4245			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
4246			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
4247		};
4248
4249		if ( this._aspectRatio || forceAspectRatio ) {
4250			pMinWidth = b.minHeight * this.aspectRatio;
4251			pMinHeight = b.minWidth / this.aspectRatio;
4252			pMaxWidth = b.maxHeight * this.aspectRatio;
4253			pMaxHeight = b.maxWidth / this.aspectRatio;
4254
4255			if ( pMinWidth > b.minWidth ) {
4256				b.minWidth = pMinWidth;
4257			}
4258			if ( pMinHeight > b.minHeight ) {
4259				b.minHeight = pMinHeight;
4260			}
4261			if ( pMaxWidth < b.maxWidth ) {
4262				b.maxWidth = pMaxWidth;
4263			}
4264			if ( pMaxHeight < b.maxHeight ) {
4265				b.maxHeight = pMaxHeight;
4266			}
4267		}
4268		this._vBoundaries = b;
4269	},
4270
4271	_updateCache: function( data ) {
4272		this.offset = this.helper.offset();
4273		if ( this._isNumber( data.left ) ) {
4274			this.position.left = data.left;
4275		}
4276		if ( this._isNumber( data.top ) ) {
4277			this.position.top = data.top;
4278		}
4279		if ( this._isNumber( data.height ) ) {
4280			this.size.height = data.height;
4281		}
4282		if ( this._isNumber( data.width ) ) {
4283			this.size.width = data.width;
4284		}
4285	},
4286
4287	_updateRatio: function( data ) {
4288
4289		var cpos = this.position,
4290			csize = this.size,
4291			a = this.axis;
4292
4293		if ( this._isNumber( data.height ) ) {
4294			data.width = ( data.height * this.aspectRatio );
4295		} else if ( this._isNumber( data.width ) ) {
4296			data.height = ( data.width / this.aspectRatio );
4297		}
4298
4299		if ( a === "sw" ) {
4300			data.left = cpos.left + ( csize.width - data.width );
4301			data.top = null;
4302		}
4303		if ( a === "nw" ) {
4304			data.top = cpos.top + ( csize.height - data.height );
4305			data.left = cpos.left + ( csize.width - data.width );
4306		}
4307
4308		return data;
4309	},
4310
4311	_respectSize: function( data ) {
4312
4313		var o = this._vBoundaries,
4314			a = this.axis,
4315			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
4316			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
4317			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
4318			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
4319			dw = this.originalPosition.left + this.originalSize.width,
4320			dh = this.originalPosition.top + this.originalSize.height,
4321			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
4322		if ( isminw ) {
4323			data.width = o.minWidth;
4324		}
4325		if ( isminh ) {
4326			data.height = o.minHeight;
4327		}
4328		if ( ismaxw ) {
4329			data.width = o.maxWidth;
4330		}
4331		if ( ismaxh ) {
4332			data.height = o.maxHeight;
4333		}
4334
4335		if ( isminw && cw ) {
4336			data.left = dw - o.minWidth;
4337		}
4338		if ( ismaxw && cw ) {
4339			data.left = dw - o.maxWidth;
4340		}
4341		if ( isminh && ch ) {
4342			data.top = dh - o.minHeight;
4343		}
4344		if ( ismaxh && ch ) {
4345			data.top = dh - o.maxHeight;
4346		}
4347
4348		// Fixing jump error on top/left - bug #2330
4349		if ( !data.width && !data.height && !data.left && data.top ) {
4350			data.top = null;
4351		} else if ( !data.width && !data.height && !data.top && data.left ) {
4352			data.left = null;
4353		}
4354
4355		return data;
4356	},
4357
4358	_getPaddingPlusBorderDimensions: function( element ) {
4359		var i = 0,
4360			widths = [],
4361			borders = [
4362				element.css( "borderTopWidth" ),
4363				element.css( "borderRightWidth" ),
4364				element.css( "borderBottomWidth" ),
4365				element.css( "borderLeftWidth" )
4366			],
4367			paddings = [
4368				element.css( "paddingTop" ),
4369				element.css( "paddingRight" ),
4370				element.css( "paddingBottom" ),
4371				element.css( "paddingLeft" )
4372			];
4373
4374		for ( ; i < 4; i++ ) {
4375			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
4376			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
4377		}
4378
4379		return {
4380			height: widths[ 0 ] + widths[ 2 ],
4381			width: widths[ 1 ] + widths[ 3 ]
4382		};
4383	},
4384
4385	_proportionallyResize: function() {
4386
4387		if ( !this._proportionallyResizeElements.length ) {
4388			return;
4389		}
4390
4391		var prel,
4392			i = 0,
4393			element = this.helper || this.element;
4394
4395		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
4396
4397			prel = this._proportionallyResizeElements[ i ];
4398
4399			// TODO: Seems like a bug to cache this.outerDimensions
4400			// considering that we are in a loop.
4401			if ( !this.outerDimensions ) {
4402				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
4403			}
4404
4405			prel.css( {
4406				height: ( element.height() - this.outerDimensions.height ) || 0,
4407				width: ( element.width() - this.outerDimensions.width ) || 0
4408			} );
4409
4410		}
4411
4412	},
4413
4414	_renderProxy: function() {
4415
4416		var el = this.element, o = this.options;
4417		this.elementOffset = el.offset();
4418
4419		if ( this._helper ) {
4420
4421			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
4422
4423			this._addClass( this.helper, this._helper );
4424			this.helper.css( {
4425				width: this.element.outerWidth(),
4426				height: this.element.outerHeight(),
4427				position: "absolute",
4428				left: this.elementOffset.left + "px",
4429				top: this.elementOffset.top + "px",
4430				zIndex: ++o.zIndex //TODO: Don't modify option
4431			} );
4432
4433			this.helper
4434				.appendTo( "body" )
4435				.disableSelection();
4436
4437		} else {
4438			this.helper = this.element;
4439		}
4440
4441	},
4442
4443	_change: {
4444		e: function( event, dx ) {
4445			return { width: this.originalSize.width + dx };
4446		},
4447		w: function( event, dx ) {
4448			var cs = this.originalSize, sp = this.originalPosition;
4449			return { left: sp.left + dx, width: cs.width - dx };
4450		},
4451		n: function( event, dx, dy ) {
4452			var cs = this.originalSize, sp = this.originalPosition;
4453			return { top: sp.top + dy, height: cs.height - dy };
4454		},
4455		s: function( event, dx, dy ) {
4456			return { height: this.originalSize.height + dy };
4457		},
4458		se: function( event, dx, dy ) {
4459			return $.extend( this._change.s.apply( this, arguments ),
4460				this._change.e.apply( this, [ event, dx, dy ] ) );
4461		},
4462		sw: function( event, dx, dy ) {
4463			return $.extend( this._change.s.apply( this, arguments ),
4464				this._change.w.apply( this, [ event, dx, dy ] ) );
4465		},
4466		ne: function( event, dx, dy ) {
4467			return $.extend( this._change.n.apply( this, arguments ),
4468				this._change.e.apply( this, [ event, dx, dy ] ) );
4469		},
4470		nw: function( event, dx, dy ) {
4471			return $.extend( this._change.n.apply( this, arguments ),
4472				this._change.w.apply( this, [ event, dx, dy ] ) );
4473		}
4474	},
4475
4476	_propagate: function( n, event ) {
4477		$.ui.plugin.call( this, n, [ event, this.ui() ] );
4478		( n !== "resize" && this._trigger( n, event, this.ui() ) );
4479	},
4480
4481	plugins: {},
4482
4483	ui: function() {
4484		return {
4485			originalElement: this.originalElement,
4486			element: this.element,
4487			helper: this.helper,
4488			position: this.position,
4489			size: this.size,
4490			originalSize: this.originalSize,
4491			originalPosition: this.originalPosition
4492		};
4493	}
4494
4495} );
4496
4497/*
4498 * Resizable Extensions
4499 */
4500
4501$.ui.plugin.add( "resizable", "animate", {
4502
4503	stop: function( event ) {
4504		var that = $( this ).resizable( "instance" ),
4505			o = that.options,
4506			pr = that._proportionallyResizeElements,
4507			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
4508			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
4509			soffsetw = ista ? 0 : that.sizeDiff.width,
4510			style = {
4511				width: ( that.size.width - soffsetw ),
4512				height: ( that.size.height - soffseth )
4513			},
4514			left = ( parseFloat( that.element.css( "left" ) ) +
4515				( that.position.left - that.originalPosition.left ) ) || null,
4516			top = ( parseFloat( that.element.css( "top" ) ) +
4517				( that.position.top - that.originalPosition.top ) ) || null;
4518
4519		that.element.animate(
4520			$.extend( style, top && left ? { top: top, left: left } : {} ), {
4521				duration: o.animateDuration,
4522				easing: o.animateEasing,
4523				step: function() {
4524
4525					var data = {
4526						width: parseFloat( that.element.css( "width" ) ),
4527						height: parseFloat( that.element.css( "height" ) ),
4528						top: parseFloat( that.element.css( "top" ) ),
4529						left: parseFloat( that.element.css( "left" ) )
4530					};
4531
4532					if ( pr && pr.length ) {
4533						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
4534					}
4535
4536					// Propagating resize, and updating values for each animation step
4537					that._updateCache( data );
4538					that._propagate( "resize", event );
4539
4540				}
4541			}
4542		);
4543	}
4544
4545} );
4546
4547$.ui.plugin.add( "resizable", "containment", {
4548
4549	start: function() {
4550		var element, p, co, ch, cw, width, height,
4551			that = $( this ).resizable( "instance" ),
4552			o = that.options,
4553			el = that.element,
4554			oc = o.containment,
4555			ce = ( oc instanceof $ ) ?
4556				oc.get( 0 ) :
4557				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
4558
4559		if ( !ce ) {
4560			return;
4561		}
4562
4563		that.containerElement = $( ce );
4564
4565		if ( /document/.test( oc ) || oc === document ) {
4566			that.containerOffset = {
4567				left: 0,
4568				top: 0
4569			};
4570			that.containerPosition = {
4571				left: 0,
4572				top: 0
4573			};
4574
4575			that.parentData = {
4576				element: $( document ),
4577				left: 0,
4578				top: 0,
4579				width: $( document ).width(),
4580				height: $( document ).height() || document.body.parentNode.scrollHeight
4581			};
4582		} else {
4583			element = $( ce );
4584			p = [];
4585			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
4586				p[ i ] = that._num( element.css( "padding" + name ) );
4587			} );
4588
4589			that.containerOffset = element.offset();
4590			that.containerPosition = element.position();
4591			that.containerSize = {
4592				height: ( element.innerHeight() - p[ 3 ] ),
4593				width: ( element.innerWidth() - p[ 1 ] )
4594			};
4595
4596			co = that.containerOffset;
4597			ch = that.containerSize.height;
4598			cw = that.containerSize.width;
4599			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
4600			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
4601
4602			that.parentData = {
4603				element: ce,
4604				left: co.left,
4605				top: co.top,
4606				width: width,
4607				height: height
4608			};
4609		}
4610	},
4611
4612	resize: function( event ) {
4613		var woset, hoset, isParent, isOffsetRelative,
4614			that = $( this ).resizable( "instance" ),
4615			o = that.options,
4616			co = that.containerOffset,
4617			cp = that.position,
4618			pRatio = that._aspectRatio || event.shiftKey,
4619			cop = {
4620				top: 0,
4621				left: 0
4622			},
4623			ce = that.containerElement,
4624			continueResize = true;
4625
4626		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
4627			cop = co;
4628		}
4629
4630		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
4631			that.size.width = that.size.width +
4632				( that._helper ?
4633					( that.position.left - co.left ) :
4634					( that.position.left - cop.left ) );
4635
4636			if ( pRatio ) {
4637				that.size.height = that.size.width / that.aspectRatio;
4638				continueResize = false;
4639			}
4640			that.position.left = o.helper ? co.left : 0;
4641		}
4642
4643		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
4644			that.size.height = that.size.height +
4645				( that._helper ?
4646					( that.position.top - co.top ) :
4647					that.position.top );
4648
4649			if ( pRatio ) {
4650				that.size.width = that.size.height * that.aspectRatio;
4651				continueResize = false;
4652			}
4653			that.position.top = that._helper ? co.top : 0;
4654		}
4655
4656		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
4657		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
4658
4659		if ( isParent && isOffsetRelative ) {
4660			that.offset.left = that.parentData.left + that.position.left;
4661			that.offset.top = that.parentData.top + that.position.top;
4662		} else {
4663			that.offset.left = that.element.offset().left;
4664			that.offset.top = that.element.offset().top;
4665		}
4666
4667		woset = Math.abs( that.sizeDiff.width +
4668			( that._helper ?
4669				that.offset.left - cop.left :
4670				( that.offset.left - co.left ) ) );
4671
4672		hoset = Math.abs( that.sizeDiff.height +
4673			( that._helper ?
4674				that.offset.top - cop.top :
4675				( that.offset.top - co.top ) ) );
4676
4677		if ( woset + that.size.width >= that.parentData.width ) {
4678			that.size.width = that.parentData.width - woset;
4679			if ( pRatio ) {
4680				that.size.height = that.size.width / that.aspectRatio;
4681				continueResize = false;
4682			}
4683		}
4684
4685		if ( hoset + that.size.height >= that.parentData.height ) {
4686			that.size.height = that.parentData.height - hoset;
4687			if ( pRatio ) {
4688				that.size.width = that.size.height * that.aspectRatio;
4689				continueResize = false;
4690			}
4691		}
4692
4693		if ( !continueResize ) {
4694			that.position.left = that.prevPosition.left;
4695			that.position.top = that.prevPosition.top;
4696			that.size.width = that.prevSize.width;
4697			that.size.height = that.prevSize.height;
4698		}
4699	},
4700
4701	stop: function() {
4702		var that = $( this ).resizable( "instance" ),
4703			o = that.options,
4704			co = that.containerOffset,
4705			cop = that.containerPosition,
4706			ce = that.containerElement,
4707			helper = $( that.helper ),
4708			ho = helper.offset(),
4709			w = helper.outerWidth() - that.sizeDiff.width,
4710			h = helper.outerHeight() - that.sizeDiff.height;
4711
4712		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4713			$( this ).css( {
4714				left: ho.left - cop.left - co.left,
4715				width: w,
4716				height: h
4717			} );
4718		}
4719
4720		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4721			$( this ).css( {
4722				left: ho.left - cop.left - co.left,
4723				width: w,
4724				height: h
4725			} );
4726		}
4727	}
4728} );
4729
4730$.ui.plugin.add( "resizable", "alsoResize", {
4731
4732	start: function() {
4733		var that = $( this ).resizable( "instance" ),
4734			o = that.options;
4735
4736		$( o.alsoResize ).each( function() {
4737			var el = $( this );
4738			el.data( "ui-resizable-alsoresize", {
4739				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
4740				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
4741			} );
4742		} );
4743	},
4744
4745	resize: function( event, ui ) {
4746		var that = $( this ).resizable( "instance" ),
4747			o = that.options,
4748			os = that.originalSize,
4749			op = that.originalPosition,
4750			delta = {
4751				height: ( that.size.height - os.height ) || 0,
4752				width: ( that.size.width - os.width ) || 0,
4753				top: ( that.position.top - op.top ) || 0,
4754				left: ( that.position.left - op.left ) || 0
4755			};
4756
4757			$( o.alsoResize ).each( function() {
4758				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
4759					css = el.parents( ui.originalElement[ 0 ] ).length ?
4760							[ "width", "height" ] :
4761							[ "width", "height", "top", "left" ];
4762
4763				$.each( css, function( i, prop ) {
4764					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
4765					if ( sum && sum >= 0 ) {
4766						style[ prop ] = sum || null;
4767					}
4768				} );
4769
4770				el.css( style );
4771			} );
4772	},
4773
4774	stop: function() {
4775		$( this ).removeData( "ui-resizable-alsoresize" );
4776	}
4777} );
4778
4779$.ui.plugin.add( "resizable", "ghost", {
4780
4781	start: function() {
4782
4783		var that = $( this ).resizable( "instance" ), cs = that.size;
4784
4785		that.ghost = that.originalElement.clone();
4786		that.ghost.css( {
4787			opacity: 0.25,
4788			display: "block",
4789			position: "relative",
4790			height: cs.height,
4791			width: cs.width,
4792			margin: 0,
4793			left: 0,
4794			top: 0
4795		} );
4796
4797		that._addClass( that.ghost, "ui-resizable-ghost" );
4798
4799		// DEPRECATED
4800		// TODO: remove after 1.12
4801		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
4802
4803			// Ghost option
4804			that.ghost.addClass( this.options.ghost );
4805		}
4806
4807		that.ghost.appendTo( that.helper );
4808
4809	},
4810
4811	resize: function() {
4812		var that = $( this ).resizable( "instance" );
4813		if ( that.ghost ) {
4814			that.ghost.css( {
4815				position: "relative",
4816				height: that.size.height,
vendor: 13,664 bytes, lines 4817-5361
4817				width: that.size.width
4818			} );
4819		}
4820	},
4821
4822	stop: function() {
4823		var that = $( this ).resizable( "instance" );
4824		if ( that.ghost && that.helper ) {
4825			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
4826		}
4827	}
4828
4829} );
4830
4831$.ui.plugin.add( "resizable", "grid", {
4832
4833	resize: function() {
4834		var outerDimensions,
4835			that = $( this ).resizable( "instance" ),
4836			o = that.options,
4837			cs = that.size,
4838			os = that.originalSize,
4839			op = that.originalPosition,
4840			a = that.axis,
4841			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4842			gridX = ( grid[ 0 ] || 1 ),
4843			gridY = ( grid[ 1 ] || 1 ),
4844			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
4845			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
4846			newWidth = os.width + ox,
4847			newHeight = os.height + oy,
4848			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
4849			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
4850			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
4851			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
4852
4853		o.grid = grid;
4854
4855		if ( isMinWidth ) {
4856			newWidth += gridX;
4857		}
4858		if ( isMinHeight ) {
4859			newHeight += gridY;
4860		}
4861		if ( isMaxWidth ) {
4862			newWidth -= gridX;
4863		}
4864		if ( isMaxHeight ) {
4865			newHeight -= gridY;
4866		}
4867
4868		if ( /^(se|s|e)$/.test( a ) ) {
4869			that.size.width = newWidth;
4870			that.size.height = newHeight;
4871		} else if ( /^(ne)$/.test( a ) ) {
4872			that.size.width = newWidth;
4873			that.size.height = newHeight;
4874			that.position.top = op.top - oy;
4875		} else if ( /^(sw)$/.test( a ) ) {
4876			that.size.width = newWidth;
4877			that.size.height = newHeight;
4878			that.position.left = op.left - ox;
4879		} else {
4880			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
4881				outerDimensions = that._getPaddingPlusBorderDimensions( this );
4882			}
4883
4884			if ( newHeight - gridY > 0 ) {
4885				that.size.height = newHeight;
4886				that.position.top = op.top - oy;
4887			} else {
4888				newHeight = gridY - outerDimensions.height;
4889				that.size.height = newHeight;
4890				that.position.top = op.top + os.height - newHeight;
4891			}
4892			if ( newWidth - gridX > 0 ) {
4893				that.size.width = newWidth;
4894				that.position.left = op.left - ox;
4895			} else {
4896				newWidth = gridX - outerDimensions.width;
4897				that.size.width = newWidth;
4898				that.position.left = op.left + os.width - newWidth;
4899			}
4900		}
4901	}
4902
4903} );
4904
4905var widgetsResizable = $.ui.resizable;
4906
4907
4908/*!
4909 * jQuery UI Selectable 1.12.1
4910 * http://jqueryui.com
4911 *
4912 * Copyright jQuery Foundation and other contributors
4913 * Released under the MIT license.
4914 * http://jquery.org/license
4915 */
4916
4917//>>label: Selectable
4918//>>group: Interactions
4919//>>description: Allows groups of elements to be selected with the mouse.
4920//>>docs: http://api.jqueryui.com/selectable/
4921//>>demos: http://jqueryui.com/selectable/
4922//>>css.structure: ../../themes/base/selectable.css
4923
4924
4925
4926var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
4927	version: "1.12.1",
4928	options: {
4929		appendTo: "body",
4930		autoRefresh: true,
4931		distance: 0,
4932		filter: "*",
4933		tolerance: "touch",
4934
4935		// Callbacks
4936		selected: null,
4937		selecting: null,
4938		start: null,
4939		stop: null,
4940		unselected: null,
4941		unselecting: null
4942	},
4943	_create: function() {
4944		var that = this;
4945
4946		this._addClass( "ui-selectable" );
4947
4948		this.dragged = false;
4949
4950		// Cache selectee children based on filter
4951		this.refresh = function() {
4952			that.elementPos = $( that.element[ 0 ] ).offset();
4953			that.selectees = $( that.options.filter, that.element[ 0 ] );
4954			that._addClass( that.selectees, "ui-selectee" );
4955			that.selectees.each( function() {
4956				var $this = $( this ),
4957					selecteeOffset = $this.offset(),
4958					pos = {
4959						left: selecteeOffset.left - that.elementPos.left,
4960						top: selecteeOffset.top - that.elementPos.top
4961					};
4962				$.data( this, "selectable-item", {
4963					element: this,
4964					$element: $this,
4965					left: pos.left,
4966					top: pos.top,
4967					right: pos.left + $this.outerWidth(),
4968					bottom: pos.top + $this.outerHeight(),
4969					startselected: false,
4970					selected: $this.hasClass( "ui-selected" ),
4971					selecting: $this.hasClass( "ui-selecting" ),
4972					unselecting: $this.hasClass( "ui-unselecting" )
4973				} );
4974			} );
4975		};
4976		this.refresh();
4977
4978		this._mouseInit();
4979
4980		this.helper = $( "<div>" );
4981		this._addClass( this.helper, "ui-selectable-helper" );
4982	},
4983
4984	_destroy: function() {
4985		this.selectees.removeData( "selectable-item" );
4986		this._mouseDestroy();
4987	},
4988
4989	_mouseStart: function( event ) {
4990		var that = this,
4991			options = this.options;
4992
4993		this.opos = [ event.pageX, event.pageY ];
4994		this.elementPos = $( this.element[ 0 ] ).offset();
4995
4996		if ( this.options.disabled ) {
4997			return;
4998		}
4999
5000		this.selectees = $( options.filter, this.element[ 0 ] );
5001
5002		this._trigger( "start", event );
5003
5004		$( options.appendTo ).append( this.helper );
5005
5006		// position helper (lasso)
5007		this.helper.css( {
5008			"left": event.pageX,
5009			"top": event.pageY,
5010			"width": 0,
5011			"height": 0
5012		} );
5013
5014		if ( options.autoRefresh ) {
5015			this.refresh();
5016		}
5017
5018		this.selectees.filter( ".ui-selected" ).each( function() {
5019			var selectee = $.data( this, "selectable-item" );
5020			selectee.startselected = true;
5021			if ( !event.metaKey && !event.ctrlKey ) {
5022				that._removeClass( selectee.$element, "ui-selected" );
5023				selectee.selected = false;
5024				that._addClass( selectee.$element, "ui-unselecting" );
5025				selectee.unselecting = true;
5026
5027				// selectable UNSELECTING callback
5028				that._trigger( "unselecting", event, {
5029					unselecting: selectee.element
5030				} );
5031			}
5032		} );
5033
5034		$( event.target ).parents().addBack().each( function() {
5035			var doSelect,
5036				selectee = $.data( this, "selectable-item" );
5037			if ( selectee ) {
5038				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
5039					!selectee.$element.hasClass( "ui-selected" );
5040				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
5041					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
5042				selectee.unselecting = !doSelect;
5043				selectee.selecting = doSelect;
5044				selectee.selected = doSelect;
5045
5046				// selectable (UN)SELECTING callback
5047				if ( doSelect ) {
5048					that._trigger( "selecting", event, {
5049						selecting: selectee.element
5050					} );
5051				} else {
5052					that._trigger( "unselecting", event, {
5053						unselecting: selectee.element
5054					} );
5055				}
5056				return false;
5057			}
5058		} );
5059
5060	},
5061
5062	_mouseDrag: function( event ) {
5063
5064		this.dragged = true;
5065
5066		if ( this.options.disabled ) {
5067			return;
5068		}
5069
5070		var tmp,
5071			that = this,
5072			options = this.options,
5073			x1 = this.opos[ 0 ],
5074			y1 = this.opos[ 1 ],
5075			x2 = event.pageX,
5076			y2 = event.pageY;
5077
5078		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
5079		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
5080		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
5081
5082		this.selectees.each( function() {
5083			var selectee = $.data( this, "selectable-item" ),
5084				hit = false,
5085				offset = {};
5086
5087			//prevent helper from being selected if appendTo: selectable
5088			if ( !selectee || selectee.element === that.element[ 0 ] ) {
5089				return;
5090			}
5091
5092			offset.left   = selectee.left   + that.elementPos.left;
5093			offset.right  = selectee.right  + that.elementPos.left;
5094			offset.top    = selectee.top    + that.elementPos.top;
5095			offset.bottom = selectee.bottom + that.elementPos.top;
5096
5097			if ( options.tolerance === "touch" ) {
5098				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
5099                    offset.bottom < y1 ) );
5100			} else if ( options.tolerance === "fit" ) {
5101				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
5102                    offset.bottom < y2 );
5103			}
5104
5105			if ( hit ) {
5106
5107				// SELECT
5108				if ( selectee.selected ) {
5109					that._removeClass( selectee.$element, "ui-selected" );
5110					selectee.selected = false;
5111				}
5112				if ( selectee.unselecting ) {
5113					that._removeClass( selectee.$element, "ui-unselecting" );
5114					selectee.unselecting = false;
5115				}
5116				if ( !selectee.selecting ) {
5117					that._addClass( selectee.$element, "ui-selecting" );
5118					selectee.selecting = true;
5119
5120					// selectable SELECTING callback
5121					that._trigger( "selecting", event, {
5122						selecting: selectee.element
5123					} );
5124				}
5125			} else {
5126
5127				// UNSELECT
5128				if ( selectee.selecting ) {
5129					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
5130						that._removeClass( selectee.$element, "ui-selecting" );
5131						selectee.selecting = false;
5132						that._addClass( selectee.$element, "ui-selected" );
5133						selectee.selected = true;
5134					} else {
5135						that._removeClass( selectee.$element, "ui-selecting" );
5136						selectee.selecting = false;
5137						if ( selectee.startselected ) {
5138							that._addClass( selectee.$element, "ui-unselecting" );
5139							selectee.unselecting = true;
5140						}
5141
5142						// selectable UNSELECTING callback
5143						that._trigger( "unselecting", event, {
5144							unselecting: selectee.element
5145						} );
5146					}
5147				}
5148				if ( selectee.selected ) {
5149					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
5150						that._removeClass( selectee.$element, "ui-selected" );
5151						selectee.selected = false;
5152
5153						that._addClass( selectee.$element, "ui-unselecting" );
5154						selectee.unselecting = true;
5155
5156						// selectable UNSELECTING callback
5157						that._trigger( "unselecting", event, {
5158							unselecting: selectee.element
5159						} );
5160					}
5161				}
5162			}
5163		} );
5164
5165		return false;
5166	},
5167
5168	_mouseStop: function( event ) {
5169		var that = this;
5170
5171		this.dragged = false;
5172
5173		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
5174			var selectee = $.data( this, "selectable-item" );
5175			that._removeClass( selectee.$element, "ui-unselecting" );
5176			selectee.unselecting = false;
5177			selectee.startselected = false;
5178			that._trigger( "unselected", event, {
5179				unselected: selectee.element
5180			} );
5181		} );
5182		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
5183			var selectee = $.data( this, "selectable-item" );
5184			that._removeClass( selectee.$element, "ui-selecting" )
5185				._addClass( selectee.$element, "ui-selected" );
5186			selectee.selecting = false;
5187			selectee.selected = true;
5188			selectee.startselected = true;
5189			that._trigger( "selected", event, {
5190				selected: selectee.element
5191			} );
5192		} );
5193		this._trigger( "stop", event );
5194
5195		this.helper.remove();
5196
5197		return false;
5198	}
5199
5200} );
5201
5202
5203/*!
5204 * jQuery UI Sortable 1.12.1
5205 * http://jqueryui.com
5206 *
5207 * Copyright jQuery Foundation and other contributors
5208 * Released under the MIT license.
5209 * http://jquery.org/license
5210 */
5211
5212//>>label: Sortable
5213//>>group: Interactions
5214//>>description: Enables items in a list to be sorted using the mouse.
5215//>>docs: http://api.jqueryui.com/sortable/
5216//>>demos: http://jqueryui.com/sortable/
5217//>>css.structure: ../../themes/base/sortable.css
5218
5219
5220
5221var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
5222	version: "1.12.1",
5223	widgetEventPrefix: "sort",
5224	ready: false,
5225	options: {
5226		appendTo: "parent",
5227		axis: false,
5228		connectWith: false,
5229		containment: false,
5230		cursor: "auto",
5231		cursorAt: false,
5232		dropOnEmpty: true,
5233		forcePlaceholderSize: false,
5234		forceHelperSize: false,
5235		grid: false,
5236		handle: false,
5237		helper: "original",
5238		items: "> *",
5239		opacity: false,
5240		placeholder: false,
5241		revert: false,
5242		scroll: true,
5243		scrollSensitivity: 20,
5244		scrollSpeed: 20,
5245		scope: "default",
5246		tolerance: "intersect",
5247		zIndex: 1000,
5248
5249		// Callbacks
5250		activate: null,
5251		beforeStop: null,
5252		change: null,
5253		deactivate: null,
5254		out: null,
5255		over: null,
5256		receive: null,
5257		remove: null,
5258		sort: null,
5259		start: null,
5260		stop: null,
5261		update: null
5262	},
5263
5264	_isOverAxis: function( x, reference, size ) {
5265		return ( x >= reference ) && ( x < ( reference + size ) );
5266	},
5267
5268	_isFloating: function( item ) {
5269		return ( /left|right/ ).test( item.css( "float" ) ) ||
5270			( /inline|table-cell/ ).test( item.css( "display" ) );
5271	},
5272
5273	_create: function() {
5274		this.containerCache = {};
5275		this._addClass( "ui-sortable" );
5276
5277		//Get the items
5278		this.refresh();
5279
5280		//Let's determine the parent's offset
5281		this.offset = this.element.offset();
5282
5283		//Initialize mouse events for interaction
5284		this._mouseInit();
5285
5286		this._setHandleClassName();
5287
5288		//We're ready to go
5289		this.ready = true;
5290
5291	},
5292
5293	_setOption: function( key, value ) {
5294		this._super( key, value );
5295
5296		if ( key === "handle" ) {
5297			this._setHandleClassName();
5298		}
5299	},
5300
5301	_setHandleClassName: function() {
5302		var that = this;
5303		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
5304		$.each( this.items, function() {
5305			that._addClass(
5306				this.instance.options.handle ?
5307					this.item.find( this.instance.options.handle ) :
5308					this.item,
5309				"ui-sortable-handle"
5310			);
5311		} );
5312	},
5313
5314	_destroy: function() {
5315		this._mouseDestroy();
5316
5317		for ( var i = this.items.length - 1; i >= 0; i-- ) {
5318			this.items[ i ].item.removeData( this.widgetName + "-item" );
5319		}
5320
5321		return this;
5322	},
5323
5324	_mouseCapture: function( event, overrideHandle ) {
5325		var currentItem = null,
5326			validHandle = false,
5327			that = this;
5328
5329		if ( this.reverting ) {
5330			return false;
5331		}
5332
5333		if ( this.options.disabled || this.options.type === "static" ) {
5334			return false;
5335		}
5336
5337		//We have to refresh the items data once first
5338		this._refreshItems( event );
5339
5340		//Find out if the clicked node (or one of its parents) is a actual item in this.items
5341		$( event.target ).parents().each( function() {
5342			if ( $.data( this, that.widgetName + "-item" ) === that ) {
5343				currentItem = $( this );
5344				return false;
5345			}
5346		} );
5347		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
5348			currentItem = $( event.target );
5349		}
5350
5351		if ( !currentItem ) {
5352			return false;
5353		}
5354		if ( this.options.handle && !overrideHandle ) {
5355			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
5356				if ( this === event.target ) {
5357					validHandle = true;
5358				}
5359			} );
5360			if ( !validHandle ) {
5361				return false;
vendor: 41,770 bytes, lines 5362-6712
5362			}
5363		}
5364
5365		this.currentItem = currentItem;
5366		this._removeCurrentsFromItems();
5367		return true;
5368
5369	},
5370
5371	_mouseStart: function( event, overrideHandle, noActivation ) {
5372
5373		var i, body,
5374			o = this.options;
5375
5376		this.currentContainer = this;
5377
5378		//We only need to call refreshPositions, because the refreshItems call has been moved to
5379		// mouseCapture
5380		this.refreshPositions();
5381
5382		//Create and append the visible helper
5383		this.helper = this._createHelper( event );
5384
5385		//Cache the helper size
5386		this._cacheHelperProportions();
5387
5388		/*
5389		 * - Position generation -
5390		 * This block generates everything position related - it's the core of draggables.
5391		 */
5392
5393		//Cache the margins of the original element
5394		this._cacheMargins();
5395
5396		//Get the next scrolling parent
5397		this.scrollParent = this.helper.scrollParent();
5398
5399		//The element's absolute position on the page minus margins
5400		this.offset = this.currentItem.offset();
5401		this.offset = {
5402			top: this.offset.top - this.margins.top,
5403			left: this.offset.left - this.margins.left
5404		};
5405
5406		$.extend( this.offset, {
5407			click: { //Where the click happened, relative to the element
5408				left: event.pageX - this.offset.left,
5409				top: event.pageY - this.offset.top
5410			},
5411			parent: this._getParentOffset(),
5412
5413			// This is a relative to absolute position minus the actual position calculation -
5414			// only used for relative positioned helper
5415			relative: this._getRelativeOffset()
5416		} );
5417
5418		// Only after we got the offset, we can change the helper's position to absolute
5419		// TODO: Still need to figure out a way to make relative sorting possible
5420		this.helper.css( "position", "absolute" );
5421		this.cssPosition = this.helper.css( "position" );
5422
5423		//Generate the original position
5424		this.originalPosition = this._generatePosition( event );
5425		this.originalPageX = event.pageX;
5426		this.originalPageY = event.pageY;
5427
5428		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
5429		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
5430
5431		//Cache the former DOM position
5432		this.domPosition = {
5433			prev: this.currentItem.prev()[ 0 ],
5434			parent: this.currentItem.parent()[ 0 ]
5435		};
5436
5437		// If the helper is not the original, hide the original so it's not playing any role during
5438		// the drag, won't cause anything bad this way
5439		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5440			this.currentItem.hide();
5441		}
5442
5443		//Create the placeholder
5444		this._createPlaceholder();
5445
5446		//Set a containment if given in the options
5447		if ( o.containment ) {
5448			this._setContainment();
5449		}
5450
5451		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
5452			body = this.document.find( "body" );
5453
5454			// Support: IE
5455			this.storedCursor = body.css( "cursor" );
5456			body.css( "cursor", o.cursor );
5457
5458			this.storedStylesheet =
5459				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
5460		}
5461
5462		if ( o.opacity ) { // opacity option
5463			if ( this.helper.css( "opacity" ) ) {
5464				this._storedOpacity = this.helper.css( "opacity" );
5465			}
5466			this.helper.css( "opacity", o.opacity );
5467		}
5468
5469		if ( o.zIndex ) { // zIndex option
5470			if ( this.helper.css( "zIndex" ) ) {
5471				this._storedZIndex = this.helper.css( "zIndex" );
5472			}
5473			this.helper.css( "zIndex", o.zIndex );
5474		}
5475
5476		//Prepare scrolling
5477		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5478				this.scrollParent[ 0 ].tagName !== "HTML" ) {
5479			this.overflowOffset = this.scrollParent.offset();
5480		}
5481
5482		//Call callbacks
5483		this._trigger( "start", event, this._uiHash() );
5484
5485		//Recache the helper size
5486		if ( !this._preserveHelperProportions ) {
5487			this._cacheHelperProportions();
5488		}
5489
5490		//Post "activate" events to possible containers
5491		if ( !noActivation ) {
5492			for ( i = this.containers.length - 1; i >= 0; i-- ) {
5493				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
5494			}
5495		}
5496
5497		//Prepare possible droppables
5498		if ( $.ui.ddmanager ) {
5499			$.ui.ddmanager.current = this;
5500		}
5501
5502		if ( $.ui.ddmanager && !o.dropBehaviour ) {
5503			$.ui.ddmanager.prepareOffsets( this, event );
5504		}
5505
5506		this.dragging = true;
5507
5508		this._addClass( this.helper, "ui-sortable-helper" );
5509
5510		// Execute the drag once - this causes the helper not to be visiblebefore getting its
5511		// correct position
5512		this._mouseDrag( event );
5513		return true;
5514
5515	},
5516
5517	_mouseDrag: function( event ) {
5518		var i, item, itemElement, intersection,
5519			o = this.options,
5520			scrolled = false;
5521
5522		//Compute the helpers position
5523		this.position = this._generatePosition( event );
5524		this.positionAbs = this._convertPositionTo( "absolute" );
5525
5526		if ( !this.lastPositionAbs ) {
5527			this.lastPositionAbs = this.positionAbs;
5528		}
5529
5530		//Do scrolling
5531		if ( this.options.scroll ) {
5532			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5533					this.scrollParent[ 0 ].tagName !== "HTML" ) {
5534
5535				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
5536						event.pageY < o.scrollSensitivity ) {
5537					this.scrollParent[ 0 ].scrollTop =
5538						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
5539				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
5540					this.scrollParent[ 0 ].scrollTop =
5541						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
5542				}
5543
5544				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
5545						event.pageX < o.scrollSensitivity ) {
5546					this.scrollParent[ 0 ].scrollLeft = scrolled =
5547						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
5548				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
5549					this.scrollParent[ 0 ].scrollLeft = scrolled =
5550						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
5551				}
5552
5553			} else {
5554
5555				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
5556					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
5557				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
5558						o.scrollSensitivity ) {
5559					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
5560				}
5561
5562				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
5563					scrolled = this.document.scrollLeft(
5564						this.document.scrollLeft() - o.scrollSpeed
5565					);
5566				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
5567						o.scrollSensitivity ) {
5568					scrolled = this.document.scrollLeft(
5569						this.document.scrollLeft() + o.scrollSpeed
5570					);
5571				}
5572
5573			}
5574
5575			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
5576				$.ui.ddmanager.prepareOffsets( this, event );
5577			}
5578		}
5579
5580		//Regenerate the absolute position used for position checks
5581		this.positionAbs = this._convertPositionTo( "absolute" );
5582
5583		//Set the helper position
5584		if ( !this.options.axis || this.options.axis !== "y" ) {
5585			this.helper[ 0 ].style.left = this.position.left + "px";
5586		}
5587		if ( !this.options.axis || this.options.axis !== "x" ) {
5588			this.helper[ 0 ].style.top = this.position.top + "px";
5589		}
5590
5591		//Rearrange
5592		for ( i = this.items.length - 1; i >= 0; i-- ) {
5593
5594			//Cache variables and intersection, continue if no intersection
5595			item = this.items[ i ];
5596			itemElement = item.item[ 0 ];
5597			intersection = this._intersectsWithPointer( item );
5598			if ( !intersection ) {
5599				continue;
5600			}
5601
5602			// Only put the placeholder inside the current Container, skip all
5603			// items from other containers. This works because when moving
5604			// an item from one container to another the
5605			// currentContainer is switched before the placeholder is moved.
5606			//
5607			// Without this, moving items in "sub-sortables" can cause
5608			// the placeholder to jitter between the outer and inner container.
5609			if ( item.instance !== this.currentContainer ) {
5610				continue;
5611			}
5612
5613			// Cannot intersect with itself
5614			// no useless actions that have been done before
5615			// no action if the item moved is the parent of the item checked
5616			if ( itemElement !== this.currentItem[ 0 ] &&
5617				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
5618				!$.contains( this.placeholder[ 0 ], itemElement ) &&
5619				( this.options.type === "semi-dynamic" ?
5620					!$.contains( this.element[ 0 ], itemElement ) :
5621					true
5622				)
5623			) {
5624
5625				this.direction = intersection === 1 ? "down" : "up";
5626
5627				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
5628					this._rearrange( event, item );
5629				} else {
5630					break;
5631				}
5632
5633				this._trigger( "change", event, this._uiHash() );
5634				break;
5635			}
5636		}
5637
5638		//Post events to containers
5639		this._contactContainers( event );
5640
5641		//Interconnect with droppables
5642		if ( $.ui.ddmanager ) {
5643			$.ui.ddmanager.drag( this, event );
5644		}
5645
5646		//Call callbacks
5647		this._trigger( "sort", event, this._uiHash() );
5648
5649		this.lastPositionAbs = this.positionAbs;
5650		return false;
5651
5652	},
5653
5654	_mouseStop: function( event, noPropagation ) {
5655
5656		if ( !event ) {
5657			return;
5658		}
5659
5660		//If we are using droppables, inform the manager about the drop
5661		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
5662			$.ui.ddmanager.drop( this, event );
5663		}
5664
5665		if ( this.options.revert ) {
5666			var that = this,
5667				cur = this.placeholder.offset(),
5668				axis = this.options.axis,
5669				animation = {};
5670
5671			if ( !axis || axis === "x" ) {
5672				animation.left = cur.left - this.offset.parent.left - this.margins.left +
5673					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
5674						0 :
5675						this.offsetParent[ 0 ].scrollLeft
5676					);
5677			}
5678			if ( !axis || axis === "y" ) {
5679				animation.top = cur.top - this.offset.parent.top - this.margins.top +
5680					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
5681						0 :
5682						this.offsetParent[ 0 ].scrollTop
5683					);
5684			}
5685			this.reverting = true;
5686			$( this.helper ).animate(
5687				animation,
5688				parseInt( this.options.revert, 10 ) || 500,
5689				function() {
5690					that._clear( event );
5691				}
5692			);
5693		} else {
5694			this._clear( event, noPropagation );
5695		}
5696
5697		return false;
5698
5699	},
5700
5701	cancel: function() {
5702
5703		if ( this.dragging ) {
5704
5705			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
5706
5707			if ( this.options.helper === "original" ) {
5708				this.currentItem.css( this._storedCSS );
5709				this._removeClass( this.currentItem, "ui-sortable-helper" );
5710			} else {
5711				this.currentItem.show();
5712			}
5713
5714			//Post deactivating events to containers
5715			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
5716				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
5717				if ( this.containers[ i ].containerCache.over ) {
5718					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
5719					this.containers[ i ].containerCache.over = 0;
5720				}
5721			}
5722
5723		}
5724
5725		if ( this.placeholder ) {
5726
5727			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
5728			// it unbinds ALL events from the original node!
5729			if ( this.placeholder[ 0 ].parentNode ) {
5730				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
5731			}
5732			if ( this.options.helper !== "original" && this.helper &&
5733					this.helper[ 0 ].parentNode ) {
5734				this.helper.remove();
5735			}
5736
5737			$.extend( this, {
5738				helper: null,
5739				dragging: false,
5740				reverting: false,
5741				_noFinalSort: null
5742			} );
5743
5744			if ( this.domPosition.prev ) {
5745				$( this.domPosition.prev ).after( this.currentItem );
5746			} else {
5747				$( this.domPosition.parent ).prepend( this.currentItem );
5748			}
5749		}
5750
5751		return this;
5752
5753	},
5754
5755	serialize: function( o ) {
5756
5757		var items = this._getItemsAsjQuery( o && o.connected ),
5758			str = [];
5759		o = o || {};
5760
5761		$( items ).each( function() {
5762			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
5763				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
5764			if ( res ) {
5765				str.push(
5766					( o.key || res[ 1 ] + "[]" ) +
5767					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
5768			}
5769		} );
5770
5771		if ( !str.length && o.key ) {
5772			str.push( o.key + "=" );
5773		}
5774
5775		return str.join( "&" );
5776
5777	},
5778
5779	toArray: function( o ) {
5780
5781		var items = this._getItemsAsjQuery( o && o.connected ),
5782			ret = [];
5783
5784		o = o || {};
5785
5786		items.each( function() {
5787			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
5788		} );
5789		return ret;
5790
5791	},
5792
5793	/* Be careful with the following core functions */
5794	_intersectsWith: function( item ) {
5795
5796		var x1 = this.positionAbs.left,
5797			x2 = x1 + this.helperProportions.width,
5798			y1 = this.positionAbs.top,
5799			y2 = y1 + this.helperProportions.height,
5800			l = item.left,
5801			r = l + item.width,
5802			t = item.top,
5803			b = t + item.height,
5804			dyClick = this.offset.click.top,
5805			dxClick = this.offset.click.left,
5806			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
5807				( y1 + dyClick ) < b ),
5808			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
5809				( x1 + dxClick ) < r ),
5810			isOverElement = isOverElementHeight && isOverElementWidth;
5811
5812		if ( this.options.tolerance === "pointer" ||
5813			this.options.forcePointerForContainers ||
5814			( this.options.tolerance !== "pointer" &&
5815				this.helperProportions[ this.floating ? "width" : "height" ] >
5816				item[ this.floating ? "width" : "height" ] )
5817		) {
5818			return isOverElement;
5819		} else {
5820
5821			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
5822				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
5823				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
5824				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
5825
5826		}
5827	},
5828
5829	_intersectsWithPointer: function( item ) {
5830		var verticalDirection, horizontalDirection,
5831			isOverElementHeight = ( this.options.axis === "x" ) ||
5832				this._isOverAxis(
5833					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
5834			isOverElementWidth = ( this.options.axis === "y" ) ||
5835				this._isOverAxis(
5836					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
5837			isOverElement = isOverElementHeight && isOverElementWidth;
5838
5839		if ( !isOverElement ) {
5840			return false;
5841		}
5842
5843		verticalDirection = this._getDragVerticalDirection();
5844		horizontalDirection = this._getDragHorizontalDirection();
5845
5846		return this.floating ?
5847			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
5848			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
5849
5850	},
5851
5852	_intersectsWithSides: function( item ) {
5853
5854		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
5855				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
5856			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
5857				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
5858			verticalDirection = this._getDragVerticalDirection(),
5859			horizontalDirection = this._getDragHorizontalDirection();
5860
5861		if ( this.floating && horizontalDirection ) {
5862			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
5863				( horizontalDirection === "left" && !isOverRightHalf ) );
5864		} else {
5865			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
5866				( verticalDirection === "up" && !isOverBottomHalf ) );
5867		}
5868
5869	},
5870
5871	_getDragVerticalDirection: function() {
5872		var delta = this.positionAbs.top - this.lastPositionAbs.top;
5873		return delta !== 0 && ( delta > 0 ? "down" : "up" );
5874	},
5875
5876	_getDragHorizontalDirection: function() {
5877		var delta = this.positionAbs.left - this.lastPositionAbs.left;
5878		return delta !== 0 && ( delta > 0 ? "right" : "left" );
5879	},
5880
5881	refresh: function( event ) {
5882		this._refreshItems( event );
5883		this._setHandleClassName();
5884		this.refreshPositions();
5885		return this;
5886	},
5887
5888	_connectWith: function() {
5889		var options = this.options;
5890		return options.connectWith.constructor === String ?
5891			[ options.connectWith ] :
5892			options.connectWith;
5893	},
5894
5895	_getItemsAsjQuery: function( connected ) {
5896
5897		var i, j, cur, inst,
5898			items = [],
5899			queries = [],
5900			connectWith = this._connectWith();
5901
5902		if ( connectWith && connected ) {
5903			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5904				cur = $( connectWith[ i ], this.document[ 0 ] );
5905				for ( j = cur.length - 1; j >= 0; j-- ) {
5906					inst = $.data( cur[ j ], this.widgetFullName );
5907					if ( inst && inst !== this && !inst.options.disabled ) {
5908						queries.push( [ $.isFunction( inst.options.items ) ?
5909							inst.options.items.call( inst.element ) :
5910							$( inst.options.items, inst.element )
5911								.not( ".ui-sortable-helper" )
5912								.not( ".ui-sortable-placeholder" ), inst ] );
5913					}
5914				}
5915			}
5916		}
5917
5918		queries.push( [ $.isFunction( this.options.items ) ?
5919			this.options.items
5920				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
5921			$( this.options.items, this.element )
5922				.not( ".ui-sortable-helper" )
5923				.not( ".ui-sortable-placeholder" ), this ] );
5924
5925		function addItems() {
5926			items.push( this );
5927		}
5928		for ( i = queries.length - 1; i >= 0; i-- ) {
5929			queries[ i ][ 0 ].each( addItems );
5930		}
5931
5932		return $( items );
5933
5934	},
5935
5936	_removeCurrentsFromItems: function() {
5937
5938		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
5939
5940		this.items = $.grep( this.items, function( item ) {
5941			for ( var j = 0; j < list.length; j++ ) {
5942				if ( list[ j ] === item.item[ 0 ] ) {
5943					return false;
5944				}
5945			}
5946			return true;
5947		} );
5948
5949	},
5950
5951	_refreshItems: function( event ) {
5952
5953		this.items = [];
5954		this.containers = [ this ];
5955
5956		var i, j, cur, inst, targetData, _queries, item, queriesLength,
5957			items = this.items,
5958			queries = [ [ $.isFunction( this.options.items ) ?
5959				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
5960				$( this.options.items, this.element ), this ] ],
5961			connectWith = this._connectWith();
5962
5963		//Shouldn't be run the first time through due to massive slow-down
5964		if ( connectWith && this.ready ) {
5965			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5966				cur = $( connectWith[ i ], this.document[ 0 ] );
5967				for ( j = cur.length - 1; j >= 0; j-- ) {
5968					inst = $.data( cur[ j ], this.widgetFullName );
5969					if ( inst && inst !== this && !inst.options.disabled ) {
5970						queries.push( [ $.isFunction( inst.options.items ) ?
5971							inst.options.items
5972								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
5973							$( inst.options.items, inst.element ), inst ] );
5974						this.containers.push( inst );
5975					}
5976				}
5977			}
5978		}
5979
5980		for ( i = queries.length - 1; i >= 0; i-- ) {
5981			targetData = queries[ i ][ 1 ];
5982			_queries = queries[ i ][ 0 ];
5983
5984			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
5985				item = $( _queries[ j ] );
5986
5987				// Data for target checking (mouse manager)
5988				item.data( this.widgetName + "-item", targetData );
5989
5990				items.push( {
5991					item: item,
5992					instance: targetData,
5993					width: 0, height: 0,
5994					left: 0, top: 0
5995				} );
5996			}
5997		}
5998
5999	},
6000
6001	refreshPositions: function( fast ) {
6002
6003		// Determine whether items are being displayed horizontally
6004		this.floating = this.items.length ?
6005			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
6006			false;
6007
6008		//This has to be redone because due to the item being moved out/into the offsetParent,
6009		// the offsetParent's position will change
6010		if ( this.offsetParent && this.helper ) {
6011			this.offset.parent = this._getParentOffset();
6012		}
6013
6014		var i, item, t, p;
6015
6016		for ( i = this.items.length - 1; i >= 0; i-- ) {
6017			item = this.items[ i ];
6018
6019			//We ignore calculating positions of all connected containers when we're not over them
6020			if ( item.instance !== this.currentContainer && this.currentContainer &&
6021					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
6022				continue;
6023			}
6024
6025			t = this.options.toleranceElement ?
6026				$( this.options.toleranceElement, item.item ) :
6027				item.item;
6028
6029			if ( !fast ) {
6030				item.width = t.outerWidth();
6031				item.height = t.outerHeight();
6032			}
6033
6034			p = t.offset();
6035			item.left = p.left;
6036			item.top = p.top;
6037		}
6038
6039		if ( this.options.custom && this.options.custom.refreshContainers ) {
6040			this.options.custom.refreshContainers.call( this );
6041		} else {
6042			for ( i = this.containers.length - 1; i >= 0; i-- ) {
6043				p = this.containers[ i ].element.offset();
6044				this.containers[ i ].containerCache.left = p.left;
6045				this.containers[ i ].containerCache.top = p.top;
6046				this.containers[ i ].containerCache.width =
6047					this.containers[ i ].element.outerWidth();
6048				this.containers[ i ].containerCache.height =
6049					this.containers[ i ].element.outerHeight();
6050			}
6051		}
6052
6053		return this;
6054	},
6055
6056	_createPlaceholder: function( that ) {
6057		that = that || this;
6058		var className,
6059			o = that.options;
6060
6061		if ( !o.placeholder || o.placeholder.constructor === String ) {
6062			className = o.placeholder;
6063			o.placeholder = {
6064				element: function() {
6065
6066					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
6067						element = $( "<" + nodeName + ">", that.document[ 0 ] );
6068
6069						that._addClass( element, "ui-sortable-placeholder",
6070								className || that.currentItem[ 0 ].className )
6071							._removeClass( element, "ui-sortable-helper" );
6072
6073					if ( nodeName === "tbody" ) {
6074						that._createTrPlaceholder(
6075							that.currentItem.find( "tr" ).eq( 0 ),
6076							$( "<tr>", that.document[ 0 ] ).appendTo( element )
6077						);
6078					} else if ( nodeName === "tr" ) {
6079						that._createTrPlaceholder( that.currentItem, element );
6080					} else if ( nodeName === "img" ) {
6081						element.attr( "src", that.currentItem.attr( "src" ) );
6082					}
6083
6084					if ( !className ) {
6085						element.css( "visibility", "hidden" );
6086					}
6087
6088					return element;
6089				},
6090				update: function( container, p ) {
6091
6092					// 1. If a className is set as 'placeholder option, we don't force sizes -
6093					// the class is responsible for that
6094					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
6095					// class name is specified
6096					if ( className && !o.forcePlaceholderSize ) {
6097						return;
6098					}
6099
6100					//If the element doesn't have a actual height by itself (without styles coming
6101					// from a stylesheet), it receives the inline height from the dragged item
6102					if ( !p.height() ) {
6103						p.height(
6104							that.currentItem.innerHeight() -
6105							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
6106							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
6107					}
6108					if ( !p.width() ) {
6109						p.width(
6110							that.currentItem.innerWidth() -
6111							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
6112							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
6113					}
6114				}
6115			};
6116		}
6117
6118		//Create the placeholder
6119		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
6120
6121		//Append it after the actual current item
6122		that.currentItem.after( that.placeholder );
6123
6124		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
6125		o.placeholder.update( that, that.placeholder );
6126
6127	},
6128
6129	_createTrPlaceholder: function( sourceTr, targetTr ) {
6130		var that = this;
6131
6132		sourceTr.children().each( function() {
6133			$( "<td>&#160;</td>", that.document[ 0 ] )
6134				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
6135				.appendTo( targetTr );
6136		} );
6137	},
6138
6139	_contactContainers: function( event ) {
6140		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
6141			floating, axis,
6142			innermostContainer = null,
6143			innermostIndex = null;
6144
6145		// Get innermost container that intersects with item
6146		for ( i = this.containers.length - 1; i >= 0; i-- ) {
6147
6148			// Never consider a container that's located within the item itself
6149			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
6150				continue;
6151			}
6152
6153			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
6154
6155				// If we've already found a container and it's more "inner" than this, then continue
6156				if ( innermostContainer &&
6157						$.contains(
6158							this.containers[ i ].element[ 0 ],
6159							innermostContainer.element[ 0 ] ) ) {
6160					continue;
6161				}
6162
6163				innermostContainer = this.containers[ i ];
6164				innermostIndex = i;
6165
6166			} else {
6167
6168				// container doesn't intersect. trigger "out" event if necessary
6169				if ( this.containers[ i ].containerCache.over ) {
6170					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
6171					this.containers[ i ].containerCache.over = 0;
6172				}
6173			}
6174
6175		}
6176
6177		// If no intersecting containers found, return
6178		if ( !innermostContainer ) {
6179			return;
6180		}
6181
6182		// Move the item into the container if it's not there already
6183		if ( this.containers.length === 1 ) {
6184			if ( !this.containers[ innermostIndex ].containerCache.over ) {
6185				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
6186				this.containers[ innermostIndex ].containerCache.over = 1;
6187			}
6188		} else {
6189
6190			// When entering a new container, we will find the item with the least distance and
6191			// append our item near it
6192			dist = 10000;
6193			itemWithLeastDistance = null;
6194			floating = innermostContainer.floating || this._isFloating( this.currentItem );
6195			posProperty = floating ? "left" : "top";
6196			sizeProperty = floating ? "width" : "height";
6197			axis = floating ? "pageX" : "pageY";
6198
6199			for ( j = this.items.length - 1; j >= 0; j-- ) {
6200				if ( !$.contains(
6201						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
6202				) {
6203					continue;
6204				}
6205				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
6206					continue;
6207				}
6208
6209				cur = this.items[ j ].item.offset()[ posProperty ];
6210				nearBottom = false;
6211				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
6212					nearBottom = true;
6213				}
6214
6215				if ( Math.abs( event[ axis ] - cur ) < dist ) {
6216					dist = Math.abs( event[ axis ] - cur );
6217					itemWithLeastDistance = this.items[ j ];
6218					this.direction = nearBottom ? "up" : "down";
6219				}
6220			}
6221
6222			//Check if dropOnEmpty is enabled
6223			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
6224				return;
6225			}
6226
6227			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
6228				if ( !this.currentContainer.containerCache.over ) {
6229					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
6230					this.currentContainer.containerCache.over = 1;
6231				}
6232				return;
6233			}
6234
6235			itemWithLeastDistance ?
6236				this._rearrange( event, itemWithLeastDistance, null, true ) :
6237				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
6238			this._trigger( "change", event, this._uiHash() );
6239			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
6240			this.currentContainer = this.containers[ innermostIndex ];
6241
6242			//Update the placeholder
6243			this.options.placeholder.update( this.currentContainer, this.placeholder );
6244
6245			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
6246			this.containers[ innermostIndex ].containerCache.over = 1;
6247		}
6248
6249	},
6250
6251	_createHelper: function( event ) {
6252
6253		var o = this.options,
6254			helper = $.isFunction( o.helper ) ?
6255				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
6256				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
6257
6258		//Add the helper to the DOM if that didn't happen already
6259		if ( !helper.parents( "body" ).length ) {
6260			$( o.appendTo !== "parent" ?
6261				o.appendTo :
6262				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
6263		}
6264
6265		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
6266			this._storedCSS = {
6267				width: this.currentItem[ 0 ].style.width,
6268				height: this.currentItem[ 0 ].style.height,
6269				position: this.currentItem.css( "position" ),
6270				top: this.currentItem.css( "top" ),
6271				left: this.currentItem.css( "left" )
6272			};
6273		}
6274
6275		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
6276			helper.width( this.currentItem.width() );
6277		}
6278		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
6279			helper.height( this.currentItem.height() );
6280		}
6281
6282		return helper;
6283
6284	},
6285
6286	_adjustOffsetFromHelper: function( obj ) {
6287		if ( typeof obj === "string" ) {
6288			obj = obj.split( " " );
6289		}
6290		if ( $.isArray( obj ) ) {
6291			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
6292		}
6293		if ( "left" in obj ) {
6294			this.offset.click.left = obj.left + this.margins.left;
6295		}
6296		if ( "right" in obj ) {
6297			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6298		}
6299		if ( "top" in obj ) {
6300			this.offset.click.top = obj.top + this.margins.top;
6301		}
6302		if ( "bottom" in obj ) {
6303			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6304		}
6305	},
6306
6307	_getParentOffset: function() {
6308
6309		//Get the offsetParent and cache its position
6310		this.offsetParent = this.helper.offsetParent();
6311		var po = this.offsetParent.offset();
6312
6313		// This is a special case where we need to modify a offset calculated on start, since the
6314		// following happened:
6315		// 1. The position of the helper is absolute, so it's position is calculated based on the
6316		// next positioned parent
6317		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
6318		// the document, which means that the scroll is included in the initial calculation of the
6319		// offset of the parent, and never recalculated upon drag
6320		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6321				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
6322			po.left += this.scrollParent.scrollLeft();
6323			po.top += this.scrollParent.scrollTop();
6324		}
6325
6326		// This needs to be actually done for all browsers, since pageX/pageY includes this
6327		// information with an ugly IE fix
6328		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
6329				( this.offsetParent[ 0 ].tagName &&
6330				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
6331			po = { top: 0, left: 0 };
6332		}
6333
6334		return {
6335			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
6336			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
6337		};
6338
6339	},
6340
6341	_getRelativeOffset: function() {
6342
6343		if ( this.cssPosition === "relative" ) {
6344			var p = this.currentItem.position();
6345			return {
6346				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
6347					this.scrollParent.scrollTop(),
6348				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
6349					this.scrollParent.scrollLeft()
6350			};
6351		} else {
6352			return { top: 0, left: 0 };
6353		}
6354
6355	},
6356
6357	_cacheMargins: function() {
6358		this.margins = {
6359			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
6360			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
6361		};
6362	},
6363
6364	_cacheHelperProportions: function() {
6365		this.helperProportions = {
6366			width: this.helper.outerWidth(),
6367			height: this.helper.outerHeight()
6368		};
6369	},
6370
6371	_setContainment: function() {
6372
6373		var ce, co, over,
6374			o = this.options;
6375		if ( o.containment === "parent" ) {
6376			o.containment = this.helper[ 0 ].parentNode;
6377		}
6378		if ( o.containment === "document" || o.containment === "window" ) {
6379			this.containment = [
6380				0 - this.offset.relative.left - this.offset.parent.left,
6381				0 - this.offset.relative.top - this.offset.parent.top,
6382				o.containment === "document" ?
6383					this.document.width() :
6384					this.window.width() - this.helperProportions.width - this.margins.left,
6385				( o.containment === "document" ?
6386					( this.document.height() || document.body.parentNode.scrollHeight ) :
6387					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
6388				) - this.helperProportions.height - this.margins.top
6389			];
6390		}
6391
6392		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
6393			ce = $( o.containment )[ 0 ];
6394			co = $( o.containment ).offset();
6395			over = ( $( ce ).css( "overflow" ) !== "hidden" );
6396
6397			this.containment = [
6398				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
6399					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
6400				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
6401					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
6402				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
6403					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
6404					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
6405					this.helperProportions.width - this.margins.left,
6406				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6407					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
6408					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
6409					this.helperProportions.height - this.margins.top
6410			];
6411		}
6412
6413	},
6414
6415	_convertPositionTo: function( d, pos ) {
6416
6417		if ( !pos ) {
6418			pos = this.position;
6419		}
6420		var mod = d === "absolute" ? 1 : -1,
6421			scroll = this.cssPosition === "absolute" &&
6422				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6423				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
6424					this.offsetParent :
6425					this.scrollParent,
6426			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
6427
6428		return {
6429			top: (
6430
6431				// The absolute mouse position
6432				pos.top	+
6433
6434				// Only for relative positioned nodes: Relative offset from element to offset parent
6435				this.offset.relative.top * mod +
6436
6437				// The offsetParent's offset without borders (offset + border)
6438				this.offset.parent.top * mod -
6439				( ( this.cssPosition === "fixed" ?
6440					-this.scrollParent.scrollTop() :
6441					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
6442			),
6443			left: (
6444
6445				// The absolute mouse position
6446				pos.left +
6447
6448				// Only for relative positioned nodes: Relative offset from element to offset parent
6449				this.offset.relative.left * mod +
6450
6451				// The offsetParent's offset without borders (offset + border)
6452				this.offset.parent.left * mod	-
6453				( ( this.cssPosition === "fixed" ?
6454					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
6455					scroll.scrollLeft() ) * mod )
6456			)
6457		};
6458
6459	},
6460
6461	_generatePosition: function( event ) {
6462
6463		var top, left,
6464			o = this.options,
6465			pageX = event.pageX,
6466			pageY = event.pageY,
6467			scroll = this.cssPosition === "absolute" &&
6468				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6469				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
6470					this.offsetParent :
6471					this.scrollParent,
6472				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
6473
6474		// This is another very weird special case that only happens for relative elements:
6475		// 1. If the css position is relative
6476		// 2. and the scroll parent is the document or similar to the offset parent
6477		// we have to refresh the relative offset during the scroll so there are no jumps
6478		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6479				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
6480			this.offset.relative = this._getRelativeOffset();
6481		}
6482
6483		/*
6484		 * - Position constraining -
6485		 * Constrain the position to a mix of grid, containment.
6486		 */
6487
6488		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
6489
6490			if ( this.containment ) {
6491				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
6492					pageX = this.containment[ 0 ] + this.offset.click.left;
6493				}
6494				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
6495					pageY = this.containment[ 1 ] + this.offset.click.top;
6496				}
6497				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
6498					pageX = this.containment[ 2 ] + this.offset.click.left;
6499				}
6500				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
6501					pageY = this.containment[ 3 ] + this.offset.click.top;
6502				}
6503			}
6504
6505			if ( o.grid ) {
6506				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
6507					o.grid[ 1 ] ) * o.grid[ 1 ];
6508				pageY = this.containment ?
6509					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
6510						top - this.offset.click.top <= this.containment[ 3 ] ) ?
6511							top :
6512							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
6513								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
6514								top;
6515
6516				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
6517					o.grid[ 0 ] ) * o.grid[ 0 ];
6518				pageX = this.containment ?
6519					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
6520						left - this.offset.click.left <= this.containment[ 2 ] ) ?
6521							left :
6522							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
6523								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
6524								left;
6525			}
6526
6527		}
6528
6529		return {
6530			top: (
6531
6532				// The absolute mouse position
6533				pageY -
6534
6535				// Click offset (relative to the element)
6536				this.offset.click.top -
6537
6538				// Only for relative positioned nodes: Relative offset from element to offset parent
6539				this.offset.relative.top -
6540
6541				// The offsetParent's offset without borders (offset + border)
6542				this.offset.parent.top +
6543				( ( this.cssPosition === "fixed" ?
6544					-this.scrollParent.scrollTop() :
6545					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
6546			),
6547			left: (
6548
6549				// The absolute mouse position
6550				pageX -
6551
6552				// Click offset (relative to the element)
6553				this.offset.click.left -
6554
6555				// Only for relative positioned nodes: Relative offset from element to offset parent
6556				this.offset.relative.left -
6557
6558				// The offsetParent's offset without borders (offset + border)
6559				this.offset.parent.left +
6560				( ( this.cssPosition === "fixed" ?
6561					-this.scrollParent.scrollLeft() :
6562					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
6563			)
6564		};
6565
6566	},
6567
6568	_rearrange: function( event, i, a, hardRefresh ) {
6569
6570		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
6571			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
6572				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
6573
6574		//Various things done here to improve the performance:
6575		// 1. we create a setTimeout, that calls refreshPositions
6576		// 2. on the instance, we have a counter variable, that get's higher after every append
6577		// 3. on the local scope, we copy the counter variable, and check in the timeout,
6578		// if it's still the same
6579		// 4. this lets only the last addition to the timeout stack through
6580		this.counter = this.counter ? ++this.counter : 1;
6581		var counter = this.counter;
6582
6583		this._delay( function() {
6584			if ( counter === this.counter ) {
6585
6586				//Precompute after each DOM insertion, NOT on mousemove
6587				this.refreshPositions( !hardRefresh );
6588			}
6589		} );
6590
6591	},
6592
6593	_clear: function( event, noPropagation ) {
6594
6595		this.reverting = false;
6596
6597		// We delay all events that have to be triggered to after the point where the placeholder
6598		// has been removed and everything else normalized again
6599		var i,
6600			delayedTriggers = [];
6601
6602		// We first have to update the dom position of the actual currentItem
6603		// Note: don't do it if the current item is already removed (by a user), or it gets
6604		// reappended (see #4088)
6605		if ( !this._noFinalSort && this.currentItem.parent().length ) {
6606			this.placeholder.before( this.currentItem );
6607		}
6608		this._noFinalSort = null;
6609
6610		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
6611			for ( i in this._storedCSS ) {
6612				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
6613					this._storedCSS[ i ] = "";
6614				}
6615			}
6616			this.currentItem.css( this._storedCSS );
6617			this._removeClass( this.currentItem, "ui-sortable-helper" );
6618		} else {
6619			this.currentItem.show();
6620		}
6621
6622		if ( this.fromOutside && !noPropagation ) {
6623			delayedTriggers.push( function( event ) {
6624				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
6625			} );
6626		}
6627		if ( ( this.fromOutside ||
6628				this.domPosition.prev !==
6629				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
6630				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
6631
6632			// Trigger update callback if the DOM position has changed
6633			delayedTriggers.push( function( event ) {
6634				this._trigger( "update", event, this._uiHash() );
6635			} );
6636		}
6637
6638		// Check if the items Container has Changed and trigger appropriate
6639		// events.
6640		if ( this !== this.currentContainer ) {
6641			if ( !noPropagation ) {
6642				delayedTriggers.push( function( event ) {
6643					this._trigger( "remove", event, this._uiHash() );
6644				} );
6645				delayedTriggers.push( ( function( c ) {
6646					return function( event ) {
6647						c._trigger( "receive", event, this._uiHash( this ) );
6648					};
6649				} ).call( this, this.currentContainer ) );
6650				delayedTriggers.push( ( function( c ) {
6651					return function( event ) {
6652						c._trigger( "update", event, this._uiHash( this ) );
6653					};
6654				} ).call( this, this.currentContainer ) );
6655			}
6656		}
6657
6658		//Post events to containers
6659		function delayEvent( type, instance, container ) {
6660			return function( event ) {
6661				container._trigger( type, event, instance._uiHash( instance ) );
6662			};
6663		}
6664		for ( i = this.containers.length - 1; i >= 0; i-- ) {
6665			if ( !noPropagation ) {
6666				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
6667			}
6668			if ( this.containers[ i ].containerCache.over ) {
6669				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
6670				this.containers[ i ].containerCache.over = 0;
6671			}
6672		}
6673
6674		//Do what was originally in plugins
6675		if ( this.storedCursor ) {
6676			this.document.find( "body" ).css( "cursor", this.storedCursor );
6677			this.storedStylesheet.remove();
6678		}
6679		if ( this._storedOpacity ) {
6680			this.helper.css( "opacity", this._storedOpacity );
6681		}
6682		if ( this._storedZIndex ) {
6683			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
6684		}
6685
6686		this.dragging = false;
6687
6688		if ( !noPropagation ) {
6689			this._trigger( "beforeStop", event, this._uiHash() );
6690		}
6691
6692		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
6693		// it unbinds ALL events from the original node!
6694		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
6695
6696		if ( !this.cancelHelperRemoval ) {
6697			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
6698				this.helper.remove();
6699			}
6700			this.helper = null;
6701		}
6702
6703		if ( !noPropagation ) {
6704			for ( i = 0; i < delayedTriggers.length; i++ ) {
6705
6706				// Trigger all delayed events
6707				delayedTriggers[ i ].call( this, event );
6708			}
6709			this._trigger( "stop", event, this._uiHash() );
6710		}
6711
6712		this.fromOutside = false;
vendor: 4,508 bytes, lines 6713-6907
6713		return !this.cancelHelperRemoval;
6714
6715	},
6716
6717	_trigger: function() {
6718		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
6719			this.cancel();
6720		}
6721	},
6722
6723	_uiHash: function( _inst ) {
6724		var inst = _inst || this;
6725		return {
6726			helper: inst.helper,
6727			placeholder: inst.placeholder || $( [] ),
6728			position: inst.position,
6729			originalPosition: inst.originalPosition,
6730			offset: inst.positionAbs,
6731			item: inst.currentItem,
6732			sender: _inst ? _inst.element : null
6733		};
6734	}
6735
6736} );
6737
6738
6739/*!
6740 * jQuery UI Accordion 1.12.1
6741 * http://jqueryui.com
6742 *
6743 * Copyright jQuery Foundation and other contributors
6744 * Released under the MIT license.
6745 * http://jquery.org/license
6746 */
6747
6748//>>label: Accordion
6749//>>group: Widgets
6750// jscs:disable maximumLineLength
6751//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
6752// jscs:enable maximumLineLength
6753//>>docs: http://api.jqueryui.com/accordion/
6754//>>demos: http://jqueryui.com/accordion/
6755//>>css.structure: ../../themes/base/core.css
6756//>>css.structure: ../../themes/base/accordion.css
6757//>>css.theme: ../../themes/base/theme.css
6758
6759
6760
6761var widgetsAccordion = $.widget( "ui.accordion", {
6762	version: "1.12.1",
6763	options: {
6764		active: 0,
6765		animate: {},
6766		classes: {
6767			"ui-accordion-header": "ui-corner-top",
6768			"ui-accordion-header-collapsed": "ui-corner-all",
6769			"ui-accordion-content": "ui-corner-bottom"
6770		},
6771		collapsible: false,
6772		event: "click",
6773		header: "> li > :first-child, > :not(li):even",
6774		heightStyle: "auto",
6775		icons: {
6776			activeHeader: "ui-icon-triangle-1-s",
6777			header: "ui-icon-triangle-1-e"
6778		},
6779
6780		// Callbacks
6781		activate: null,
6782		beforeActivate: null
6783	},
6784
6785	hideProps: {
6786		borderTopWidth: "hide",
6787		borderBottomWidth: "hide",
6788		paddingTop: "hide",
6789		paddingBottom: "hide",
6790		height: "hide"
6791	},
6792
6793	showProps: {
6794		borderTopWidth: "show",
6795		borderBottomWidth: "show",
6796		paddingTop: "show",
6797		paddingBottom: "show",
6798		height: "show"
6799	},
6800
6801	_create: function() {
6802		var options = this.options;
6803
6804		this.prevShow = this.prevHide = $();
6805		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
6806		this.element.attr( "role", "tablist" );
6807
6808		// Don't allow collapsible: false and active: false / null
6809		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
6810			options.active = 0;
6811		}
6812
6813		this._processPanels();
6814
6815		// handle negative values
6816		if ( options.active < 0 ) {
6817			options.active += this.headers.length;
6818		}
6819		this._refresh();
6820	},
6821
6822	_getCreateEventData: function() {
6823		return {
6824			header: this.active,
6825			panel: !this.active.length ? $() : this.active.next()
6826		};
6827	},
6828
6829	_createIcons: function() {
6830		var icon, children,
6831			icons = this.options.icons;
6832
6833		if ( icons ) {
6834			icon = $( "<span>" );
6835			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
6836			icon.prependTo( this.headers );
6837			children = this.active.children( ".ui-accordion-header-icon" );
6838			this._removeClass( children, icons.header )
6839				._addClass( children, null, icons.activeHeader )
6840				._addClass( this.headers, "ui-accordion-icons" );
6841		}
6842	},
6843
6844	_destroyIcons: function() {
6845		this._removeClass( this.headers, "ui-accordion-icons" );
6846		this.headers.children( ".ui-accordion-header-icon" ).remove();
6847	},
6848
6849	_destroy: function() {
6850		var contents;
6851
6852		// Clean up main element
6853		this.element.removeAttr( "role" );
6854
6855		// Clean up headers
6856		this.headers
6857			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
6858			.removeUniqueId();
6859
6860		this._destroyIcons();
6861
6862		// Clean up content panels
6863		contents = this.headers.next()
6864			.css( "display", "" )
6865			.removeAttr( "role aria-hidden aria-labelledby" )
6866			.removeUniqueId();
6867
6868		if ( this.options.heightStyle !== "content" ) {
6869			contents.css( "height", "" );
6870		}
6871	},
6872
6873	_setOption: function( key, value ) {
6874		if ( key === "active" ) {
6875
6876			// _activate() will handle invalid values and update this.options
6877			this._activate( value );
6878			return;
6879		}
6880
6881		if ( key === "event" ) {
6882			if ( this.options.event ) {
6883				this._off( this.headers, this.options.event );
6884			}
6885			this._setupEvents( value );
6886		}
6887
6888		this._super( key, value );
6889
6890		// Setting collapsible: false while collapsed; open first panel
6891		if ( key === "collapsible" && !value && this.options.active === false ) {
6892			this._activate( 0 );
6893		}
6894
6895		if ( key === "icons" ) {
6896			this._destroyIcons();
6897			if ( value ) {
6898				this._createIcons();
6899			}
6900		}
6901	},
6902
6903	_setOptionDisabled: function( value ) {
6904		this._super( value );
6905
6906		this.element.attr( "aria-disabled", value );
6907
vendor: 6,565 bytes, lines 6908-7158
6908		// Support: IE8 Only
6909		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
6910		// so we need to add the disabled class to the headers and panels
6911		this._toggleClass( null, "ui-state-disabled", !!value );
6912		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
6913			!!value );
6914	},
6915
6916	_keydown: function( event ) {
6917		if ( event.altKey || event.ctrlKey ) {
6918			return;
6919		}
6920
6921		var keyCode = $.ui.keyCode,
6922			length = this.headers.length,
6923			currentIndex = this.headers.index( event.target ),
6924			toFocus = false;
6925
6926		switch ( event.keyCode ) {
6927		case keyCode.RIGHT:
6928		case keyCode.DOWN:
6929			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6930			break;
6931		case keyCode.LEFT:
6932		case keyCode.UP:
6933			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6934			break;
6935		case keyCode.SPACE:
6936		case keyCode.ENTER:
6937			this._eventHandler( event );
6938			break;
6939		case keyCode.HOME:
6940			toFocus = this.headers[ 0 ];
6941			break;
6942		case keyCode.END:
6943			toFocus = this.headers[ length - 1 ];
6944			break;
6945		}
6946
6947		if ( toFocus ) {
6948			$( event.target ).attr( "tabIndex", -1 );
6949			$( toFocus ).attr( "tabIndex", 0 );
6950			$( toFocus ).trigger( "focus" );
6951			event.preventDefault();
6952		}
6953	},
6954
6955	_panelKeyDown: function( event ) {
6956		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6957			$( event.currentTarget ).prev().trigger( "focus" );
6958		}
6959	},
6960
6961	refresh: function() {
6962		var options = this.options;
6963		this._processPanels();
6964
6965		// Was collapsed or no panel
6966		if ( ( options.active === false && options.collapsible === true ) ||
6967				!this.headers.length ) {
6968			options.active = false;
6969			this.active = $();
6970
6971		// active false only when collapsible is true
6972		} else if ( options.active === false ) {
6973			this._activate( 0 );
6974
6975		// was active, but active panel is gone
6976		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6977
6978			// all remaining panel are disabled
6979			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
6980				options.active = false;
6981				this.active = $();
6982
6983			// activate previous panel
6984			} else {
6985				this._activate( Math.max( 0, options.active - 1 ) );
6986			}
6987
6988		// was active, active panel still exists
6989		} else {
6990
6991			// make sure active index is correct
6992			options.active = this.headers.index( this.active );
6993		}
6994
6995		this._destroyIcons();
6996
6997		this._refresh();
6998	},
6999
7000	_processPanels: function() {
7001		var prevHeaders = this.headers,
7002			prevPanels = this.panels;
7003
7004		this.headers = this.element.find( this.options.header );
7005		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
7006			"ui-state-default" );
7007
7008		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
7009		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
7010
7011		// Avoid memory leaks (#10056)
7012		if ( prevPanels ) {
7013			this._off( prevHeaders.not( this.headers ) );
7014			this._off( prevPanels.not( this.panels ) );
7015		}
7016	},
7017
7018	_refresh: function() {
7019		var maxHeight,
7020			options = this.options,
7021			heightStyle = options.heightStyle,
7022			parent = this.element.parent();
7023
7024		this.active = this._findActive( options.active );
7025		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
7026			._removeClass( this.active, "ui-accordion-header-collapsed" );
7027		this._addClass( this.active.next(), "ui-accordion-content-active" );
7028		this.active.next().show();
7029
7030		this.headers
7031			.attr( "role", "tab" )
7032			.each( function() {
7033				var header = $( this ),
7034					headerId = header.uniqueId().attr( "id" ),
7035					panel = header.next(),
7036					panelId = panel.uniqueId().attr( "id" );
7037				header.attr( "aria-controls", panelId );
7038				panel.attr( "aria-labelledby", headerId );
7039			} )
7040			.next()
7041				.attr( "role", "tabpanel" );
7042
7043		this.headers
7044			.not( this.active )
7045				.attr( {
7046					"aria-selected": "false",
7047					"aria-expanded": "false",
7048					tabIndex: -1
7049				} )
7050				.next()
7051					.attr( {
7052						"aria-hidden": "true"
7053					} )
7054					.hide();
7055
7056		// Make sure at least one header is in the tab order
7057		if ( !this.active.length ) {
7058			this.headers.eq( 0 ).attr( "tabIndex", 0 );
7059		} else {
7060			this.active.attr( {
7061				"aria-selected": "true",
7062				"aria-expanded": "true",
7063				tabIndex: 0
7064			} )
7065				.next()
7066					.attr( {
7067						"aria-hidden": "false"
7068					} );
7069		}
7070
7071		this._createIcons();
7072
7073		this._setupEvents( options.event );
7074
7075		if ( heightStyle === "fill" ) {
7076			maxHeight = parent.height();
7077			this.element.siblings( ":visible" ).each( function() {
7078				var elem = $( this ),
7079					position = elem.css( "position" );
7080
7081				if ( position === "absolute" || position === "fixed" ) {
7082					return;
7083				}
7084				maxHeight -= elem.outerHeight( true );
7085			} );
7086
7087			this.headers.each( function() {
7088				maxHeight -= $( this ).outerHeight( true );
7089			} );
7090
7091			this.headers.next()
7092				.each( function() {
7093					$( this ).height( Math.max( 0, maxHeight -
7094						$( this ).innerHeight() + $( this ).height() ) );
7095				} )
7096				.css( "overflow", "auto" );
7097		} else if ( heightStyle === "auto" ) {
7098			maxHeight = 0;
7099			this.headers.next()
7100				.each( function() {
7101					var isVisible = $( this ).is( ":visible" );
7102					if ( !isVisible ) {
7103						$( this ).show();
7104					}
7105					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
7106					if ( !isVisible ) {
7107						$( this ).hide();
7108					}
7109				} )
7110				.height( maxHeight );
7111		}
7112	},
7113
7114	_activate: function( index ) {
7115		var active = this._findActive( index )[ 0 ];
7116
7117		// Trying to activate the already active panel
7118		if ( active === this.active[ 0 ] ) {
7119			return;
7120		}
7121
7122		// Trying to collapse, simulate a click on the currently active header
7123		active = active || this.active[ 0 ];
7124
7125		this._eventHandler( {
7126			target: active,
7127			currentTarget: active,
7128			preventDefault: $.noop
7129		} );
7130	},
7131
7132	_findActive: function( selector ) {
7133		return typeof selector === "number" ? this.headers.eq( selector ) : $();
7134	},
7135
7136	_setupEvents: function( event ) {
7137		var events = {
7138			keydown: "_keydown"
7139		};
7140		if ( event ) {
7141			$.each( event.split( " " ), function( index, eventName ) {
7142				events[ eventName ] = "_eventHandler";
7143			} );
7144		}
7145
7146		this._off( this.headers.add( this.headers.next() ) );
7147		this._on( this.headers, events );
7148		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
7149		this._hoverable( this.headers );
7150		this._focusable( this.headers );
7151	},
7152
7153	_eventHandler: function( event ) {
7154		var activeChildren, clickedChildren,
7155			options = this.options,
7156			active = this.active,
7157			clicked = $( event.currentTarget ),
7158			clickedIsActive = clicked[ 0 ] === active[ 0 ],
vendor: 6,030 bytes, lines 7159-7383
7159			collapsing = clickedIsActive && options.collapsible,
7160			toShow = collapsing ? $() : clicked.next(),
7161			toHide = active.next(),
7162			eventData = {
7163				oldHeader: active,
7164				oldPanel: toHide,
7165				newHeader: collapsing ? $() : clicked,
7166				newPanel: toShow
7167			};
7168
7169		event.preventDefault();
7170
7171		if (
7172
7173				// click on active header, but not collapsible
7174				( clickedIsActive && !options.collapsible ) ||
7175
7176				// allow canceling activation
7177				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
7178			return;
7179		}
7180
7181		options.active = collapsing ? false : this.headers.index( clicked );
7182
7183		// When the call to ._toggle() comes after the class changes
7184		// it causes a very odd bug in IE 8 (see #6720)
7185		this.active = clickedIsActive ? $() : clicked;
7186		this._toggle( eventData );
7187
7188		// Switch classes
7189		// corner classes on the previously active header stay after the animation
7190		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
7191		if ( options.icons ) {
7192			activeChildren = active.children( ".ui-accordion-header-icon" );
7193			this._removeClass( activeChildren, null, options.icons.activeHeader )
7194				._addClass( activeChildren, null, options.icons.header );
7195		}
7196
7197		if ( !clickedIsActive ) {
7198			this._removeClass( clicked, "ui-accordion-header-collapsed" )
7199				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
7200			if ( options.icons ) {
7201				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
7202				this._removeClass( clickedChildren, null, options.icons.header )
7203					._addClass( clickedChildren, null, options.icons.activeHeader );
7204			}
7205
7206			this._addClass( clicked.next(), "ui-accordion-content-active" );
7207		}
7208	},
7209
7210	_toggle: function( data ) {
7211		var toShow = data.newPanel,
7212			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
7213
7214		// Handle activating a panel during the animation for another activation
7215		this.prevShow.add( this.prevHide ).stop( true, true );
7216		this.prevShow = toShow;
7217		this.prevHide = toHide;
7218
7219		if ( this.options.animate ) {
7220			this._animate( toShow, toHide, data );
7221		} else {
7222			toHide.hide();
7223			toShow.show();
7224			this._toggleComplete( data );
7225		}
7226
7227		toHide.attr( {
7228			"aria-hidden": "true"
7229		} );
7230		toHide.prev().attr( {
7231			"aria-selected": "false",
7232			"aria-expanded": "false"
7233		} );
7234
7235		// if we're switching panels, remove the old header from the tab order
7236		// if we're opening from collapsed state, remove the previous header from the tab order
7237		// if we're collapsing, then keep the collapsing header in the tab order
7238		if ( toShow.length && toHide.length ) {
7239			toHide.prev().attr( {
7240				"tabIndex": -1,
7241				"aria-expanded": "false"
7242			} );
7243		} else if ( toShow.length ) {
7244			this.headers.filter( function() {
7245				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
7246			} )
7247				.attr( "tabIndex", -1 );
7248		}
7249
7250		toShow
7251			.attr( "aria-hidden", "false" )
7252			.prev()
7253				.attr( {
7254					"aria-selected": "true",
7255					"aria-expanded": "true",
7256					tabIndex: 0
7257				} );
7258	},
7259
7260	_animate: function( toShow, toHide, data ) {
7261		var total, easing, duration,
7262			that = this,
7263			adjust = 0,
7264			boxSizing = toShow.css( "box-sizing" ),
7265			down = toShow.length &&
7266				( !toHide.length || ( toShow.index() < toHide.index() ) ),
7267			animate = this.options.animate || {},
7268			options = down && animate.down || animate,
7269			complete = function() {
7270				that._toggleComplete( data );
7271			};
7272
7273		if ( typeof options === "number" ) {
7274			duration = options;
7275		}
7276		if ( typeof options === "string" ) {
7277			easing = options;
7278		}
7279
7280		// fall back from options to animation in case of partial down settings
7281		easing = easing || options.easing || animate.easing;
7282		duration = duration || options.duration || animate.duration;
7283
7284		if ( !toHide.length ) {
7285			return toShow.animate( this.showProps, duration, easing, complete );
7286		}
7287		if ( !toShow.length ) {
7288			return toHide.animate( this.hideProps, duration, easing, complete );
7289		}
7290
7291		total = toShow.show().outerHeight();
7292		toHide.animate( this.hideProps, {
7293			duration: duration,
7294			easing: easing,
7295			step: function( now, fx ) {
7296				fx.now = Math.round( now );
7297			}
7298		} );
7299		toShow
7300			.hide()
7301			.animate( this.showProps, {
7302				duration: duration,
7303				easing: easing,
7304				complete: complete,
7305				step: function( now, fx ) {
7306					fx.now = Math.round( now );
7307					if ( fx.prop !== "height" ) {
7308						if ( boxSizing === "content-box" ) {
7309							adjust += fx.now;
7310						}
7311					} else if ( that.options.heightStyle !== "content" ) {
7312						fx.now = Math.round( total - toHide.outerHeight() - adjust );
7313						adjust = 0;
7314					}
7315				}
7316			} );
7317	},
7318
7319	_toggleComplete: function( data ) {
7320		var toHide = data.oldPanel,
7321			prev = toHide.prev();
7322
7323		this._removeClass( toHide, "ui-accordion-content-active" );
7324		this._removeClass( prev, "ui-accordion-header-active" )
7325			._addClass( prev, "ui-accordion-header-collapsed" );
7326
7327		// Work around for rendering bug in IE (#5421)
7328		if ( toHide.length ) {
7329			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
7330		}
7331		this._trigger( "activate", null, data );
7332	}
7333} );
7334
7335
7336/*!
7337 * jQuery UI Menu 1.12.1
7338 * http://jqueryui.com
7339 *
7340 * Copyright jQuery Foundation and other contributors
7341 * Released under the MIT license.
7342 * http://jquery.org/license
7343 */
7344
7345//>>label: Menu
7346//>>group: Widgets
7347//>>description: Creates nestable menus.
7348//>>docs: http://api.jqueryui.com/menu/
7349//>>demos: http://jqueryui.com/menu/
7350//>>css.structure: ../../themes/base/core.css
7351//>>css.structure: ../../themes/base/menu.css
7352//>>css.theme: ../../themes/base/theme.css
7353
7354
7355
7356var widgetsMenu = $.widget( "ui.menu", {
7357	version: "1.12.1",
7358	defaultElement: "<ul>",
7359	delay: 300,
7360	options: {
7361		icons: {
7362			submenu: "ui-icon-caret-1-e"
7363		},
7364		items: "> *",
7365		menus: "ul",
7366		position: {
7367			my: "left top",
7368			at: "right top"
7369		},
7370		role: "menu",
7371
7372		// Callbacks
7373		blur: null,
7374		focus: null,
7375		select: null
7376	},
7377
7378	_create: function() {
7379		this.activeMenu = this.element;
7380
7381		// Flag used to prevent firing of the click handler
7382		// as the event bubbles up through nested menus
7383		this.mouseHandled = false;
vendor: 139,549 bytes, lines 7384-11675
7384		this.element
7385			.uniqueId()
7386			.attr( {
7387				role: this.options.role,
7388				tabIndex: 0
7389			} );
7390
7391		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
7392		this._on( {
7393
7394			// Prevent focus from sticking to links inside menu after clicking
7395			// them (focus should always stay on UL during navigation).
7396			"mousedown .ui-menu-item": function( event ) {
7397				event.preventDefault();
7398			},
7399			"click .ui-menu-item": function( event ) {
7400				var target = $( event.target );
7401				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
7402				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
7403					this.select( event );
7404
7405					// Only set the mouseHandled flag if the event will bubble, see #9469.
7406					if ( !event.isPropagationStopped() ) {
7407						this.mouseHandled = true;
7408					}
7409
7410					// Open submenu on click
7411					if ( target.has( ".ui-menu" ).length ) {
7412						this.expand( event );
7413					} else if ( !this.element.is( ":focus" ) &&
7414							active.closest( ".ui-menu" ).length ) {
7415
7416						// Redirect focus to the menu
7417						this.element.trigger( "focus", [ true ] );
7418
7419						// If the active item is on the top level, let it stay active.
7420						// Otherwise, blur the active item since it is no longer visible.
7421						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
7422							clearTimeout( this.timer );
7423						}
7424					}
7425				}
7426			},
7427			"mouseenter .ui-menu-item": function( event ) {
7428
7429				// Ignore mouse events while typeahead is active, see #10458.
7430				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
7431				// is over an item in the menu
7432				if ( this.previousFilter ) {
7433					return;
7434				}
7435
7436				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
7437					target = $( event.currentTarget );
7438
7439				// Ignore bubbled events on parent items, see #11641
7440				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
7441					return;
7442				}
7443
7444				// Remove ui-state-active class from siblings of the newly focused menu item
7445				// to avoid a jump caused by adjacent elements both having a class with a border
7446				this._removeClass( target.siblings().children( ".ui-state-active" ),
7447					null, "ui-state-active" );
7448				this.focus( event, target );
7449			},
7450			mouseleave: "collapseAll",
7451			"mouseleave .ui-menu": "collapseAll",
7452			focus: function( event, keepActiveItem ) {
7453
7454				// If there's already an active item, keep it active
7455				// If not, activate the first item
7456				var item = this.active || this.element.find( this.options.items ).eq( 0 );
7457
7458				if ( !keepActiveItem ) {
7459					this.focus( event, item );
7460				}
7461			},
7462			blur: function( event ) {
7463				this._delay( function() {
7464					var notContained = !$.contains(
7465						this.element[ 0 ],
7466						$.ui.safeActiveElement( this.document[ 0 ] )
7467					);
7468					if ( notContained ) {
7469						this.collapseAll( event );
7470					}
7471				} );
7472			},
7473			keydown: "_keydown"
7474		} );
7475
7476		this.refresh();
7477
7478		// Clicks outside of a menu collapse any open menus
7479		this._on( this.document, {
7480			click: function( event ) {
7481				if ( this._closeOnDocumentClick( event ) ) {
7482					this.collapseAll( event );
7483				}
7484
7485				// Reset the mouseHandled flag
7486				this.mouseHandled = false;
7487			}
7488		} );
7489	},
7490
7491	_destroy: function() {
7492		var items = this.element.find( ".ui-menu-item" )
7493				.removeAttr( "role aria-disabled" ),
7494			submenus = items.children( ".ui-menu-item-wrapper" )
7495				.removeUniqueId()
7496				.removeAttr( "tabIndex role aria-haspopup" );
7497
7498		// Destroy (sub)menus
7499		this.element
7500			.removeAttr( "aria-activedescendant" )
7501			.find( ".ui-menu" ).addBack()
7502				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
7503					"tabIndex" )
7504				.removeUniqueId()
7505				.show();
7506
7507		submenus.children().each( function() {
7508			var elem = $( this );
7509			if ( elem.data( "ui-menu-submenu-caret" ) ) {
7510				elem.remove();
7511			}
7512		} );
7513	},
7514
7515	_keydown: function( event ) {
7516		var match, prev, character, skip,
7517			preventDefault = true;
7518
7519		switch ( event.keyCode ) {
7520		case $.ui.keyCode.PAGE_UP:
7521			this.previousPage( event );
7522			break;
7523		case $.ui.keyCode.PAGE_DOWN:
7524			this.nextPage( event );
7525			break;
7526		case $.ui.keyCode.HOME:
7527			this._move( "first", "first", event );
7528			break;
7529		case $.ui.keyCode.END:
7530			this._move( "last", "last", event );
7531			break;
7532		case $.ui.keyCode.UP:
7533			this.previous( event );
7534			break;
7535		case $.ui.keyCode.DOWN:
7536			this.next( event );
7537			break;
7538		case $.ui.keyCode.LEFT:
7539			this.collapse( event );
7540			break;
7541		case $.ui.keyCode.RIGHT:
7542			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7543				this.expand( event );
7544			}
7545			break;
7546		case $.ui.keyCode.ENTER:
7547		case $.ui.keyCode.SPACE:
7548			this._activate( event );
7549			break;
7550		case $.ui.keyCode.ESCAPE:
7551			this.collapse( event );
7552			break;
7553		default:
7554			preventDefault = false;
7555			prev = this.previousFilter || "";
7556			skip = false;
7557
7558			// Support number pad values
7559			character = event.keyCode >= 96 && event.keyCode <= 105 ?
7560				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
7561
7562			clearTimeout( this.filterTimer );
7563
7564			if ( character === prev ) {
7565				skip = true;
7566			} else {
7567				character = prev + character;
7568			}
7569
7570			match = this._filterMenuItems( character );
7571			match = skip && match.index( this.active.next() ) !== -1 ?
7572				this.active.nextAll( ".ui-menu-item" ) :
7573				match;
7574
7575			// If no matches on the current filter, reset to the last character pressed
7576			// to move down the menu to the first item that starts with that character
7577			if ( !match.length ) {
7578				character = String.fromCharCode( event.keyCode );
7579				match = this._filterMenuItems( character );
7580			}
7581
7582			if ( match.length ) {
7583				this.focus( event, match );
7584				this.previousFilter = character;
7585				this.filterTimer = this._delay( function() {
7586					delete this.previousFilter;
7587				}, 1000 );
7588			} else {
7589				delete this.previousFilter;
7590			}
7591		}
7592
7593		if ( preventDefault ) {
7594			event.preventDefault();
7595		}
7596	},
7597
7598	_activate: function( event ) {
7599		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7600			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
7601				this.expand( event );
7602			} else {
7603				this.select( event );
7604			}
7605		}
7606	},
7607
7608	refresh: function() {
7609		var menus, items, newSubmenus, newItems, newWrappers,
7610			that = this,
7611			icon = this.options.icons.submenu,
7612			submenus = this.element.find( this.options.menus );
7613
7614		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
7615
7616		// Initialize nested menus
7617		newSubmenus = submenus.filter( ":not(.ui-menu)" )
7618			.hide()
7619			.attr( {
7620				role: this.options.role,
7621				"aria-hidden": "true",
7622				"aria-expanded": "false"
7623			} )
7624			.each( function() {
7625				var menu = $( this ),
7626					item = menu.prev(),
7627					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
7628
7629				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
7630				item
7631					.attr( "aria-haspopup", "true" )
7632					.prepend( submenuCaret );
7633				menu.attr( "aria-labelledby", item.attr( "id" ) );
7634			} );
7635
7636		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
7637
7638		menus = submenus.add( this.element );
7639		items = menus.find( this.options.items );
7640
7641		// Initialize menu-items containing spaces and/or dashes only as dividers
7642		items.not( ".ui-menu-item" ).each( function() {
7643			var item = $( this );
7644			if ( that._isDivider( item ) ) {
7645				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
7646			}
7647		} );
7648
7649		// Don't refresh list items that are already adapted
7650		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
7651		newWrappers = newItems.children()
7652			.not( ".ui-menu" )
7653				.uniqueId()
7654				.attr( {
7655					tabIndex: -1,
7656					role: this._itemRole()
7657				} );
7658		this._addClass( newItems, "ui-menu-item" )
7659			._addClass( newWrappers, "ui-menu-item-wrapper" );
7660
7661		// Add aria-disabled attribute to any disabled menu item
7662		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
7663
7664		// If the active item has been removed, blur the menu
7665		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
7666			this.blur();
7667		}
7668	},
7669
7670	_itemRole: function() {
7671		return {
7672			menu: "menuitem",
7673			listbox: "option"
7674		}[ this.options.role ];
7675	},
7676
7677	_setOption: function( key, value ) {
7678		if ( key === "icons" ) {
7679			var icons = this.element.find( ".ui-menu-icon" );
7680			this._removeClass( icons, null, this.options.icons.submenu )
7681				._addClass( icons, null, value.submenu );
7682		}
7683		this._super( key, value );
7684	},
7685
7686	_setOptionDisabled: function( value ) {
7687		this._super( value );
7688
7689		this.element.attr( "aria-disabled", String( value ) );
7690		this._toggleClass( null, "ui-state-disabled", !!value );
7691	},
7692
7693	focus: function( event, item ) {
7694		var nested, focused, activeParent;
7695		this.blur( event, event && event.type === "focus" );
7696
7697		this._scrollIntoView( item );
7698
7699		this.active = item.first();
7700
7701		focused = this.active.children( ".ui-menu-item-wrapper" );
7702		this._addClass( focused, null, "ui-state-active" );
7703
7704		// Only update aria-activedescendant if there's a role
7705		// otherwise we assume focus is managed elsewhere
7706		if ( this.options.role ) {
7707			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
7708		}
7709
7710		// Highlight active parent menu item, if any
7711		activeParent = this.active
7712			.parent()
7713				.closest( ".ui-menu-item" )
7714					.children( ".ui-menu-item-wrapper" );
7715		this._addClass( activeParent, null, "ui-state-active" );
7716
7717		if ( event && event.type === "keydown" ) {
7718			this._close();
7719		} else {
7720			this.timer = this._delay( function() {
7721				this._close();
7722			}, this.delay );
7723		}
7724
7725		nested = item.children( ".ui-menu" );
7726		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
7727			this._startOpening( nested );
7728		}
7729		this.activeMenu = item.parent();
7730
7731		this._trigger( "focus", event, { item: item } );
7732	},
7733
7734	_scrollIntoView: function( item ) {
7735		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
7736		if ( this._hasScroll() ) {
7737			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
7738			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
7739			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
7740			scroll = this.activeMenu.scrollTop();
7741			elementHeight = this.activeMenu.height();
7742			itemHeight = item.outerHeight();
7743
7744			if ( offset < 0 ) {
7745				this.activeMenu.scrollTop( scroll + offset );
7746			} else if ( offset + itemHeight > elementHeight ) {
7747				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
7748			}
7749		}
7750	},
7751
7752	blur: function( event, fromFocus ) {
7753		if ( !fromFocus ) {
7754			clearTimeout( this.timer );
7755		}
7756
7757		if ( !this.active ) {
7758			return;
7759		}
7760
7761		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
7762			null, "ui-state-active" );
7763
7764		this._trigger( "blur", event, { item: this.active } );
7765		this.active = null;
7766	},
7767
7768	_startOpening: function( submenu ) {
7769		clearTimeout( this.timer );
7770
7771		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
7772		// shift in the submenu position when mousing over the caret icon
7773		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
7774			return;
7775		}
7776
7777		this.timer = this._delay( function() {
7778			this._close();
7779			this._open( submenu );
7780		}, this.delay );
7781	},
7782
7783	_open: function( submenu ) {
7784		var position = $.extend( {
7785			of: this.active
7786		}, this.options.position );
7787
7788		clearTimeout( this.timer );
7789		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
7790			.hide()
7791			.attr( "aria-hidden", "true" );
7792
7793		submenu
7794			.show()
7795			.removeAttr( "aria-hidden" )
7796			.attr( "aria-expanded", "true" )
7797			.position( position );
7798	},
7799
7800	collapseAll: function( event, all ) {
7801		clearTimeout( this.timer );
7802		this.timer = this._delay( function() {
7803
7804			// If we were passed an event, look for the submenu that contains the event
7805			var currentMenu = all ? this.element :
7806				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
7807
7808			// If we found no valid submenu ancestor, use the main menu to close all
7809			// sub menus anyway
7810			if ( !currentMenu.length ) {
7811				currentMenu = this.element;
7812			}
7813
7814			this._close( currentMenu );
7815
7816			this.blur( event );
7817
7818			// Work around active item staying active after menu is blurred
7819			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
7820
7821			this.activeMenu = currentMenu;
7822		}, this.delay );
7823	},
7824
7825	// With no arguments, closes the currently active menu - if nothing is active
7826	// it closes all menus.  If passed an argument, it will search for menus BELOW
7827	_close: function( startMenu ) {
7828		if ( !startMenu ) {
7829			startMenu = this.active ? this.active.parent() : this.element;
7830		}
7831
7832		startMenu.find( ".ui-menu" )
7833			.hide()
7834			.attr( "aria-hidden", "true" )
7835			.attr( "aria-expanded", "false" );
7836	},
7837
7838	_closeOnDocumentClick: function( event ) {
7839		return !$( event.target ).closest( ".ui-menu" ).length;
7840	},
7841
7842	_isDivider: function( item ) {
7843
7844		// Match hyphen, em dash, en dash
7845		return !/[^\-\u2014\u2013\s]/.test( item.text() );
7846	},
7847
7848	collapse: function( event ) {
7849		var newItem = this.active &&
7850			this.active.parent().closest( ".ui-menu-item", this.element );
7851		if ( newItem && newItem.length ) {
7852			this._close();
7853			this.focus( event, newItem );
7854		}
7855	},
7856
7857	expand: function( event ) {
7858		var newItem = this.active &&
7859			this.active
7860				.children( ".ui-menu " )
7861					.find( this.options.items )
7862						.first();
7863
7864		if ( newItem && newItem.length ) {
7865			this._open( newItem.parent() );
7866
7867			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
7868			this._delay( function() {
7869				this.focus( event, newItem );
7870			} );
7871		}
7872	},
7873
7874	next: function( event ) {
7875		this._move( "next", "first", event );
7876	},
7877
7878	previous: function( event ) {
7879		this._move( "prev", "last", event );
7880	},
7881
7882	isFirstItem: function() {
7883		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
7884	},
7885
7886	isLastItem: function() {
7887		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
7888	},
7889
7890	_move: function( direction, filter, event ) {
7891		var next;
7892		if ( this.active ) {
7893			if ( direction === "first" || direction === "last" ) {
7894				next = this.active
7895					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
7896					.eq( -1 );
7897			} else {
7898				next = this.active
7899					[ direction + "All" ]( ".ui-menu-item" )
7900					.eq( 0 );
7901			}
7902		}
7903		if ( !next || !next.length || !this.active ) {
7904			next = this.activeMenu.find( this.options.items )[ filter ]();
7905		}
7906
7907		this.focus( event, next );
7908	},
7909
7910	nextPage: function( event ) {
7911		var item, base, height;
7912
7913		if ( !this.active ) {
7914			this.next( event );
7915			return;
7916		}
7917		if ( this.isLastItem() ) {
7918			return;
7919		}
7920		if ( this._hasScroll() ) {
7921			base = this.active.offset().top;
7922			height = this.element.height();
7923			this.active.nextAll( ".ui-menu-item" ).each( function() {
7924				item = $( this );
7925				return item.offset().top - base - height < 0;
7926			} );
7927
7928			this.focus( event, item );
7929		} else {
7930			this.focus( event, this.activeMenu.find( this.options.items )
7931				[ !this.active ? "first" : "last" ]() );
7932		}
7933	},
7934
7935	previousPage: function( event ) {
7936		var item, base, height;
7937		if ( !this.active ) {
7938			this.next( event );
7939			return;
7940		}
7941		if ( this.isFirstItem() ) {
7942			return;
7943		}
7944		if ( this._hasScroll() ) {
7945			base = this.active.offset().top;
7946			height = this.element.height();
7947			this.active.prevAll( ".ui-menu-item" ).each( function() {
7948				item = $( this );
7949				return item.offset().top - base + height > 0;
7950			} );
7951
7952			this.focus( event, item );
7953		} else {
7954			this.focus( event, this.activeMenu.find( this.options.items ).first() );
7955		}
7956	},
7957
7958	_hasScroll: function() {
7959		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
7960	},
7961
7962	select: function( event ) {
7963
7964		// TODO: It should never be possible to not have an active item at this
7965		// point, but the tests don't trigger mouseenter before click.
7966		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
7967		var ui = { item: this.active };
7968		if ( !this.active.has( ".ui-menu" ).length ) {
7969			this.collapseAll( event, true );
7970		}
7971		this._trigger( "select", event, ui );
7972	},
7973
7974	_filterMenuItems: function( character ) {
7975		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
7976			regex = new RegExp( "^" + escapedCharacter, "i" );
7977
7978		return this.activeMenu
7979			.find( this.options.items )
7980
7981				// Only match on items, not dividers or other content (#10571)
7982				.filter( ".ui-menu-item" )
7983					.filter( function() {
7984						return regex.test(
7985							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
7986					} );
7987	}
7988} );
7989
7990
7991/*!
7992 * jQuery UI Autocomplete 1.12.1
7993 * http://jqueryui.com
7994 *
7995 * Copyright jQuery Foundation and other contributors
7996 * Released under the MIT license.
7997 * http://jquery.org/license
7998 */
7999
8000//>>label: Autocomplete
8001//>>group: Widgets
8002//>>description: Lists suggested words as the user is typing.
8003//>>docs: http://api.jqueryui.com/autocomplete/
8004//>>demos: http://jqueryui.com/autocomplete/
8005//>>css.structure: ../../themes/base/core.css
8006//>>css.structure: ../../themes/base/autocomplete.css
8007//>>css.theme: ../../themes/base/theme.css
8008
8009
8010
8011$.widget( "ui.autocomplete", {
8012	version: "1.12.1",
8013	defaultElement: "<input>",
8014	options: {
8015		appendTo: null,
8016		autoFocus: false,
8017		delay: 300,
8018		minLength: 1,
8019		position: {
8020			my: "left top",
8021			at: "left bottom",
8022			collision: "none"
8023		},
8024		source: null,
8025
8026		// Callbacks
8027		change: null,
8028		close: null,
8029		focus: null,
8030		open: null,
8031		response: null,
8032		search: null,
8033		select: null
8034	},
8035
8036	requestIndex: 0,
8037	pending: 0,
8038
8039	_create: function() {
8040
8041		// Some browsers only repeat keydown events, not keypress events,
8042		// so we use the suppressKeyPress flag to determine if we've already
8043		// handled the keydown event. #7269
8044		// Unfortunately the code for & in keypress is the same as the up arrow,
8045		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
8046		// events when we know the keydown event was used to modify the
8047		// search term. #7799
8048		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
8049			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
8050			isTextarea = nodeName === "textarea",
8051			isInput = nodeName === "input";
8052
8053		// Textareas are always multi-line
8054		// Inputs are always single-line, even if inside a contentEditable element
8055		// IE also treats inputs as contentEditable
8056		// All other element types are determined by whether or not they're contentEditable
8057		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
8058
8059		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
8060		this.isNewMenu = true;
8061
8062		this._addClass( "ui-autocomplete-input" );
8063		this.element.attr( "autocomplete", "off" );
8064
8065		this._on( this.element, {
8066			keydown: function( event ) {
8067				if ( this.element.prop( "readOnly" ) ) {
8068					suppressKeyPress = true;
8069					suppressInput = true;
8070					suppressKeyPressRepeat = true;
8071					return;
8072				}
8073
8074				suppressKeyPress = false;
8075				suppressInput = false;
8076				suppressKeyPressRepeat = false;
8077				var keyCode = $.ui.keyCode;
8078				switch ( event.keyCode ) {
8079				case keyCode.PAGE_UP:
8080					suppressKeyPress = true;
8081					this._move( "previousPage", event );
8082					break;
8083				case keyCode.PAGE_DOWN:
8084					suppressKeyPress = true;
8085					this._move( "nextPage", event );
8086					break;
8087				case keyCode.UP:
8088					suppressKeyPress = true;
8089					this._keyEvent( "previous", event );
8090					break;
8091				case keyCode.DOWN:
8092					suppressKeyPress = true;
8093					this._keyEvent( "next", event );
8094					break;
8095				case keyCode.ENTER:
8096
8097					// when menu is open and has focus
8098					if ( this.menu.active ) {
8099
8100						// #6055 - Opera still allows the keypress to occur
8101						// which causes forms to submit
8102						suppressKeyPress = true;
8103						event.preventDefault();
8104						this.menu.select( event );
8105					}
8106					break;
8107				case keyCode.TAB:
8108					if ( this.menu.active ) {
8109						this.menu.select( event );
8110					}
8111					break;
8112				case keyCode.ESCAPE:
8113					if ( this.menu.element.is( ":visible" ) ) {
8114						if ( !this.isMultiLine ) {
8115							this._value( this.term );
8116						}
8117						this.close( event );
8118
8119						// Different browsers have different default behavior for escape
8120						// Single press can mean undo or clear
8121						// Double press in IE means clear the whole form
8122						event.preventDefault();
8123					}
8124					break;
8125				default:
8126					suppressKeyPressRepeat = true;
8127
8128					// search timeout should be triggered before the input value is changed
8129					this._searchTimeout( event );
8130					break;
8131				}
8132			},
8133			keypress: function( event ) {
8134				if ( suppressKeyPress ) {
8135					suppressKeyPress = false;
8136					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8137						event.preventDefault();
8138					}
8139					return;
8140				}
8141				if ( suppressKeyPressRepeat ) {
8142					return;
8143				}
8144
8145				// Replicate some key handlers to allow them to repeat in Firefox and Opera
8146				var keyCode = $.ui.keyCode;
8147				switch ( event.keyCode ) {
8148				case keyCode.PAGE_UP:
8149					this._move( "previousPage", event );
8150					break;
8151				case keyCode.PAGE_DOWN:
8152					this._move( "nextPage", event );
8153					break;
8154				case keyCode.UP:
8155					this._keyEvent( "previous", event );
8156					break;
8157				case keyCode.DOWN:
8158					this._keyEvent( "next", event );
8159					break;
8160				}
8161			},
8162			input: function( event ) {
8163				if ( suppressInput ) {
8164					suppressInput = false;
8165					event.preventDefault();
8166					return;
8167				}
8168				this._searchTimeout( event );
8169			},
8170			focus: function() {
8171				this.selectedItem = null;
8172				this.previous = this._value();
8173			},
8174			blur: function( event ) {
8175				if ( this.cancelBlur ) {
8176					delete this.cancelBlur;
8177					return;
8178				}
8179
8180				clearTimeout( this.searching );
8181				this.close( event );
8182				this._change( event );
8183			}
8184		} );
8185
8186		this._initSource();
8187		this.menu = $( "<ul>" )
8188			.appendTo( this._appendTo() )
8189			.menu( {
8190
8191				// disable ARIA support, the live region takes care of that
8192				role: null
8193			} )
8194			.hide()
8195			.menu( "instance" );
8196
8197		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
8198		this._on( this.menu.element, {
8199			mousedown: function( event ) {
8200
8201				// prevent moving focus out of the text field
8202				event.preventDefault();
8203
8204				// IE doesn't prevent moving focus even with event.preventDefault()
8205				// so we set a flag to know when we should ignore the blur event
8206				this.cancelBlur = true;
8207				this._delay( function() {
8208					delete this.cancelBlur;
8209
8210					// Support: IE 8 only
8211					// Right clicking a menu item or selecting text from the menu items will
8212					// result in focus moving out of the input. However, we've already received
8213					// and ignored the blur event because of the cancelBlur flag set above. So
8214					// we restore focus to ensure that the menu closes properly based on the user's
8215					// next actions.
8216					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
8217						this.element.trigger( "focus" );
8218					}
8219				} );
8220			},
8221			menufocus: function( event, ui ) {
8222				var label, item;
8223
8224				// support: Firefox
8225				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
8226				if ( this.isNewMenu ) {
8227					this.isNewMenu = false;
8228					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
8229						this.menu.blur();
8230
8231						this.document.one( "mousemove", function() {
8232							$( event.target ).trigger( event.originalEvent );
8233						} );
8234
8235						return;
8236					}
8237				}
8238
8239				item = ui.item.data( "ui-autocomplete-item" );
8240				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
8241
8242					// use value to match what will end up in the input, if it was a key event
8243					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
8244						this._value( item.value );
8245					}
8246				}
8247
8248				// Announce the value in the liveRegion
8249				label = ui.item.attr( "aria-label" ) || item.value;
8250				if ( label && $.trim( label ).length ) {
8251					this.liveRegion.children().hide();
8252					$( "<div>" ).text( label ).appendTo( this.liveRegion );
8253				}
8254			},
8255			menuselect: function( event, ui ) {
8256				var item = ui.item.data( "ui-autocomplete-item" ),
8257					previous = this.previous;
8258
8259				// Only trigger when focus was lost (click on menu)
8260				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
8261					this.element.trigger( "focus" );
8262					this.previous = previous;
8263
8264					// #6109 - IE triggers two focus events and the second
8265					// is asynchronous, so we need to reset the previous
8266					// term synchronously and asynchronously :-(
8267					this._delay( function() {
8268						this.previous = previous;
8269						this.selectedItem = item;
8270					} );
8271				}
8272
8273				if ( false !== this._trigger( "select", event, { item: item } ) ) {
8274					this._value( item.value );
8275				}
8276
8277				// reset the term after the select event
8278				// this allows custom select handling to work properly
8279				this.term = this._value();
8280
8281				this.close( event );
8282				this.selectedItem = item;
8283			}
8284		} );
8285
8286		this.liveRegion = $( "<div>", {
8287			role: "status",
8288			"aria-live": "assertive",
8289			"aria-relevant": "additions"
8290		} )
8291			.appendTo( this.document[ 0 ].body );
8292
8293		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
8294
8295		// Turning off autocomplete prevents the browser from remembering the
8296		// value when navigating through history, so we re-enable autocomplete
8297		// if the page is unloaded before the widget is destroyed. #7790
8298		this._on( this.window, {
8299			beforeunload: function() {
8300				this.element.removeAttr( "autocomplete" );
8301			}
8302		} );
8303	},
8304
8305	_destroy: function() {
8306		clearTimeout( this.searching );
8307		this.element.removeAttr( "autocomplete" );
8308		this.menu.element.remove();
8309		this.liveRegion.remove();
8310	},
8311
8312	_setOption: function( key, value ) {
8313		this._super( key, value );
8314		if ( key === "source" ) {
8315			this._initSource();
8316		}
8317		if ( key === "appendTo" ) {
8318			this.menu.element.appendTo( this._appendTo() );
8319		}
8320		if ( key === "disabled" && value && this.xhr ) {
8321			this.xhr.abort();
8322		}
8323	},
8324
8325	_isEventTargetInWidget: function( event ) {
8326		var menuElement = this.menu.element[ 0 ];
8327
8328		return event.target === this.element[ 0 ] ||
8329			event.target === menuElement ||
8330			$.contains( menuElement, event.target );
8331	},
8332
8333	_closeOnClickOutside: function( event ) {
8334		if ( !this._isEventTargetInWidget( event ) ) {
8335			this.close();
8336		}
8337	},
8338
8339	_appendTo: function() {
8340		var element = this.options.appendTo;
8341
8342		if ( element ) {
8343			element = element.jquery || element.nodeType ?
8344				$( element ) :
8345				this.document.find( element ).eq( 0 );
8346		}
8347
8348		if ( !element || !element[ 0 ] ) {
8349			element = this.element.closest( ".ui-front, dialog" );
8350		}
8351
8352		if ( !element.length ) {
8353			element = this.document[ 0 ].body;
8354		}
8355
8356		return element;
8357	},
8358
8359	_initSource: function() {
8360		var array, url,
8361			that = this;
8362		if ( $.isArray( this.options.source ) ) {
8363			array = this.options.source;
8364			this.source = function( request, response ) {
8365				response( $.ui.autocomplete.filter( array, request.term ) );
8366			};
8367		} else if ( typeof this.options.source === "string" ) {
8368			url = this.options.source;
8369			this.source = function( request, response ) {
8370				if ( that.xhr ) {
8371					that.xhr.abort();
8372				}
8373				that.xhr = $.ajax( {
8374					url: url,
8375					data: request,
8376					dataType: "json",
8377					success: function( data ) {
8378						response( data );
8379					},
8380					error: function() {
8381						response( [] );
8382					}
8383				} );
8384			};
8385		} else {
8386			this.source = this.options.source;
8387		}
8388	},
8389
8390	_searchTimeout: function( event ) {
8391		clearTimeout( this.searching );
8392		this.searching = this._delay( function() {
8393
8394			// Search if the value has changed, or if the user retypes the same value (see #7434)
8395			var equalValues = this.term === this._value(),
8396				menuVisible = this.menu.element.is( ":visible" ),
8397				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
8398
8399			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
8400				this.selectedItem = null;
8401				this.search( null, event );
8402			}
8403		}, this.options.delay );
8404	},
8405
8406	search: function( value, event ) {
8407		value = value != null ? value : this._value();
8408
8409		// Always save the actual value, not the one passed as an argument
8410		this.term = this._value();
8411
8412		if ( value.length < this.options.minLength ) {
8413			return this.close( event );
8414		}
8415
8416		if ( this._trigger( "search", event ) === false ) {
8417			return;
8418		}
8419
8420		return this._search( value );
8421	},
8422
8423	_search: function( value ) {
8424		this.pending++;
8425		this._addClass( "ui-autocomplete-loading" );
8426		this.cancelSearch = false;
8427
8428		this.source( { term: value }, this._response() );
8429	},
8430
8431	_response: function() {
8432		var index = ++this.requestIndex;
8433
8434		return $.proxy( function( content ) {
8435			if ( index === this.requestIndex ) {
8436				this.__response( content );
8437			}
8438
8439			this.pending--;
8440			if ( !this.pending ) {
8441				this._removeClass( "ui-autocomplete-loading" );
8442			}
8443		}, this );
8444	},
8445
8446	__response: function( content ) {
8447		if ( content ) {
8448			content = this._normalize( content );
8449		}
8450		this._trigger( "response", null, { content: content } );
8451		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
8452			this._suggest( content );
8453			this._trigger( "open" );
8454		} else {
8455
8456			// use ._close() instead of .close() so we don't cancel future searches
8457			this._close();
8458		}
8459	},
8460
8461	close: function( event ) {
8462		this.cancelSearch = true;
8463		this._close( event );
8464	},
8465
8466	_close: function( event ) {
8467
8468		// Remove the handler that closes the menu on outside clicks
8469		this._off( this.document, "mousedown" );
8470
8471		if ( this.menu.element.is( ":visible" ) ) {
8472			this.menu.element.hide();
8473			this.menu.blur();
8474			this.isNewMenu = true;
8475			this._trigger( "close", event );
8476		}
8477	},
8478
8479	_change: function( event ) {
8480		if ( this.previous !== this._value() ) {
8481			this._trigger( "change", event, { item: this.selectedItem } );
8482		}
8483	},
8484
8485	_normalize: function( items ) {
8486
8487		// assume all items have the right format when the first item is complete
8488		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
8489			return items;
8490		}
8491		return $.map( items, function( item ) {
8492			if ( typeof item === "string" ) {
8493				return {
8494					label: item,
8495					value: item
8496				};
8497			}
8498			return $.extend( {}, item, {
8499				label: item.label || item.value,
8500				value: item.value || item.label
8501			} );
8502		} );
8503	},
8504
8505	_suggest: function( items ) {
8506		var ul = this.menu.element.empty();
8507		this._renderMenu( ul, items );
8508		this.isNewMenu = true;
8509		this.menu.refresh();
8510
8511		// Size and position menu
8512		ul.show();
8513		this._resizeMenu();
8514		ul.position( $.extend( {
8515			of: this.element
8516		}, this.options.position ) );
8517
8518		if ( this.options.autoFocus ) {
8519			this.menu.next();
8520		}
8521
8522		// Listen for interactions outside of the widget (#6642)
8523		this._on( this.document, {
8524			mousedown: "_closeOnClickOutside"
8525		} );
8526	},
8527
8528	_resizeMenu: function() {
8529		var ul = this.menu.element;
8530		ul.outerWidth( Math.max(
8531
8532			// Firefox wraps long text (possibly a rounding bug)
8533			// so we add 1px to avoid the wrapping (#7513)
8534			ul.width( "" ).outerWidth() + 1,
8535			this.element.outerWidth()
8536		) );
8537	},
8538
8539	_renderMenu: function( ul, items ) {
8540		var that = this;
8541		$.each( items, function( index, item ) {
8542			that._renderItemData( ul, item );
8543		} );
8544	},
8545
8546	_renderItemData: function( ul, item ) {
8547		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
8548	},
8549
8550	_renderItem: function( ul, item ) {
8551		return $( "<li>" )
8552			.append( $( "<div>" ).text( item.label ) )
8553			.appendTo( ul );
8554	},
8555
8556	_move: function( direction, event ) {
8557		if ( !this.menu.element.is( ":visible" ) ) {
8558			this.search( null, event );
8559			return;
8560		}
8561		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
8562				this.menu.isLastItem() && /^next/.test( direction ) ) {
8563
8564			if ( !this.isMultiLine ) {
8565				this._value( this.term );
8566			}
8567
8568			this.menu.blur();
8569			return;
8570		}
8571		this.menu[ direction ]( event );
8572	},
8573
8574	widget: function() {
8575		return this.menu.element;
8576	},
8577
8578	_value: function() {
8579		return this.valueMethod.apply( this.element, arguments );
8580	},
8581
8582	_keyEvent: function( keyEvent, event ) {
8583		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8584			this._move( keyEvent, event );
8585
8586			// Prevents moving cursor to beginning/end of the text field in some browsers
8587			event.preventDefault();
8588		}
8589	},
8590
8591	// Support: Chrome <=50
8592	// We should be able to just use this.element.prop( "isContentEditable" )
8593	// but hidden elements always report false in Chrome.
8594	// https://code.google.com/p/chromium/issues/detail?id=313082
8595	_isContentEditable: function( element ) {
8596		if ( !element.length ) {
8597			return false;
8598		}
8599
8600		var editable = element.prop( "contentEditable" );
8601
8602		if ( editable === "inherit" ) {
8603		  return this._isContentEditable( element.parent() );
8604		}
8605
8606		return editable === "true";
8607	}
8608} );
8609
8610$.extend( $.ui.autocomplete, {
8611	escapeRegex: function( value ) {
8612		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
8613	},
8614	filter: function( array, term ) {
8615		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
8616		return $.grep( array, function( value ) {
8617			return matcher.test( value.label || value.value || value );
8618		} );
8619	}
8620} );
8621
8622// Live region extension, adding a `messages` option
8623// NOTE: This is an experimental API. We are still investigating
8624// a full solution for string manipulation and internationalization.
8625$.widget( "ui.autocomplete", $.ui.autocomplete, {
8626	options: {
8627		messages: {
8628			noResults: "No search results.",
8629			results: function( amount ) {
8630				return amount + ( amount > 1 ? " results are" : " result is" ) +
8631					" available, use up and down arrow keys to navigate.";
8632			}
8633		}
8634	},
8635
8636	__response: function( content ) {
8637		var message;
8638		this._superApply( arguments );
8639		if ( this.options.disabled || this.cancelSearch ) {
8640			return;
8641		}
8642		if ( content && content.length ) {
8643			message = this.options.messages.results( content.length );
8644		} else {
8645			message = this.options.messages.noResults;
8646		}
8647		this.liveRegion.children().hide();
8648		$( "<div>" ).text( message ).appendTo( this.liveRegion );
8649	}
8650} );
8651
8652var widgetsAutocomplete = $.ui.autocomplete;
8653
8654
8655/*!
8656 * jQuery UI Controlgroup 1.12.1
8657 * http://jqueryui.com
8658 *
8659 * Copyright jQuery Foundation and other contributors
8660 * Released under the MIT license.
8661 * http://jquery.org/license
8662 */
8663
8664//>>label: Controlgroup
8665//>>group: Widgets
8666//>>description: Visually groups form control widgets
8667//>>docs: http://api.jqueryui.com/controlgroup/
8668//>>demos: http://jqueryui.com/controlgroup/
8669//>>css.structure: ../../themes/base/core.css
8670//>>css.structure: ../../themes/base/controlgroup.css
8671//>>css.theme: ../../themes/base/theme.css
8672
8673
8674var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
8675
8676var widgetsControlgroup = $.widget( "ui.controlgroup", {
8677	version: "1.12.1",
8678	defaultElement: "<div>",
8679	options: {
8680		direction: "horizontal",
8681		disabled: null,
8682		onlyVisible: true,
8683		items: {
8684			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
8685			"controlgroupLabel": ".ui-controlgroup-label",
8686			"checkboxradio": "input[type='checkbox'], input[type='radio']",
8687			"selectmenu": "select",
8688			"spinner": ".ui-spinner-input"
8689		}
8690	},
8691
8692	_create: function() {
8693		this._enhance();
8694	},
8695
8696	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
8697	_enhance: function() {
8698		this.element.attr( "role", "toolbar" );
8699		this.refresh();
8700	},
8701
8702	_destroy: function() {
8703		this._callChildMethod( "destroy" );
8704		this.childWidgets.removeData( "ui-controlgroup-data" );
8705		this.element.removeAttr( "role" );
8706		if ( this.options.items.controlgroupLabel ) {
8707			this.element
8708				.find( this.options.items.controlgroupLabel )
8709				.find( ".ui-controlgroup-label-contents" )
8710				.contents().unwrap();
8711		}
8712	},
8713
8714	_initWidgets: function() {
8715		var that = this,
8716			childWidgets = [];
8717
8718		// First we iterate over each of the items options
8719		$.each( this.options.items, function( widget, selector ) {
8720			var labels;
8721			var options = {};
8722
8723			// Make sure the widget has a selector set
8724			if ( !selector ) {
8725				return;
8726			}
8727
8728			if ( widget === "controlgroupLabel" ) {
8729				labels = that.element.find( selector );
8730				labels.each( function() {
8731					var element = $( this );
8732
8733					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
8734						return;
8735					}
8736					element.contents()
8737						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
8738				} );
8739				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
8740				childWidgets = childWidgets.concat( labels.get() );
8741				return;
8742			}
8743
8744			// Make sure the widget actually exists
8745			if ( !$.fn[ widget ] ) {
8746				return;
8747			}
8748
8749			// We assume everything is in the middle to start because we can't determine
8750			// first / last elements until all enhancments are done.
8751			if ( that[ "_" + widget + "Options" ] ) {
8752				options = that[ "_" + widget + "Options" ]( "middle" );
8753			} else {
8754				options = { classes: {} };
8755			}
8756
8757			// Find instances of this widget inside controlgroup and init them
8758			that.element
8759				.find( selector )
8760				.each( function() {
8761					var element = $( this );
8762					var instance = element[ widget ]( "instance" );
8763
8764					// We need to clone the default options for this type of widget to avoid
8765					// polluting the variable options which has a wider scope than a single widget.
8766					var instanceOptions = $.widget.extend( {}, options );
8767
8768					// If the button is the child of a spinner ignore it
8769					// TODO: Find a more generic solution
8770					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
8771						return;
8772					}
8773
8774					// Create the widget if it doesn't exist
8775					if ( !instance ) {
8776						instance = element[ widget ]()[ widget ]( "instance" );
8777					}
8778					if ( instance ) {
8779						instanceOptions.classes =
8780							that._resolveClassesValues( instanceOptions.classes, instance );
8781					}
8782					element[ widget ]( instanceOptions );
8783
8784					// Store an instance of the controlgroup to be able to reference
8785					// from the outermost element for changing options and refresh
8786					var widgetElement = element[ widget ]( "widget" );
8787					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
8788						instance ? instance : element[ widget ]( "instance" ) );
8789
8790					childWidgets.push( widgetElement[ 0 ] );
8791				} );
8792		} );
8793
8794		this.childWidgets = $( $.unique( childWidgets ) );
8795		this._addClass( this.childWidgets, "ui-controlgroup-item" );
8796	},
8797
8798	_callChildMethod: function( method ) {
8799		this.childWidgets.each( function() {
8800			var element = $( this ),
8801				data = element.data( "ui-controlgroup-data" );
8802			if ( data && data[ method ] ) {
8803				data[ method ]();
8804			}
8805		} );
8806	},
8807
8808	_updateCornerClass: function( element, position ) {
8809		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
8810		var add = this._buildSimpleOptions( position, "label" ).classes.label;
8811
8812		this._removeClass( element, null, remove );
8813		this._addClass( element, null, add );
8814	},
8815
8816	_buildSimpleOptions: function( position, key ) {
8817		var direction = this.options.direction === "vertical";
8818		var result = {
8819			classes: {}
8820		};
8821		result.classes[ key ] = {
8822			"middle": "",
8823			"first": "ui-corner-" + ( direction ? "top" : "left" ),
8824			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
8825			"only": "ui-corner-all"
8826		}[ position ];
8827
8828		return result;
8829	},
8830
8831	_spinnerOptions: function( position ) {
8832		var options = this._buildSimpleOptions( position, "ui-spinner" );
8833
8834		options.classes[ "ui-spinner-up" ] = "";
8835		options.classes[ "ui-spinner-down" ] = "";
8836
8837		return options;
8838	},
8839
8840	_buttonOptions: function( position ) {
8841		return this._buildSimpleOptions( position, "ui-button" );
8842	},
8843
8844	_checkboxradioOptions: function( position ) {
8845		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
8846	},
8847
8848	_selectmenuOptions: function( position ) {
8849		var direction = this.options.direction === "vertical";
8850		return {
8851			width: direction ? "auto" : false,
8852			classes: {
8853				middle: {
8854					"ui-selectmenu-button-open": "",
8855					"ui-selectmenu-button-closed": ""
8856				},
8857				first: {
8858					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
8859					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
8860				},
8861				last: {
8862					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
8863					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
8864				},
8865				only: {
8866					"ui-selectmenu-button-open": "ui-corner-top",
8867					"ui-selectmenu-button-closed": "ui-corner-all"
8868				}
8869
8870			}[ position ]
8871		};
8872	},
8873
8874	_resolveClassesValues: function( classes, instance ) {
8875		var result = {};
8876		$.each( classes, function( key ) {
8877			var current = instance.options.classes[ key ] || "";
8878			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
8879			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
8880		} );
8881		return result;
8882	},
8883
8884	_setOption: function( key, value ) {
8885		if ( key === "direction" ) {
8886			this._removeClass( "ui-controlgroup-" + this.options.direction );
8887		}
8888
8889		this._super( key, value );
8890		if ( key === "disabled" ) {
8891			this._callChildMethod( value ? "disable" : "enable" );
8892			return;
8893		}
8894
8895		this.refresh();
8896	},
8897
8898	refresh: function() {
8899		var children,
8900			that = this;
8901
8902		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
8903
8904		if ( this.options.direction === "horizontal" ) {
8905			this._addClass( null, "ui-helper-clearfix" );
8906		}
8907		this._initWidgets();
8908
8909		children = this.childWidgets;
8910
8911		// We filter here because we need to track all childWidgets not just the visible ones
8912		if ( this.options.onlyVisible ) {
8913			children = children.filter( ":visible" );
8914		}
8915
8916		if ( children.length ) {
8917
8918			// We do this last because we need to make sure all enhancment is done
8919			// before determining first and last
8920			$.each( [ "first", "last" ], function( index, value ) {
8921				var instance = children[ value ]().data( "ui-controlgroup-data" );
8922
8923				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
8924					var options = that[ "_" + instance.widgetName + "Options" ](
8925						children.length === 1 ? "only" : value
8926					);
8927					options.classes = that._resolveClassesValues( options.classes, instance );
8928					instance.element[ instance.widgetName ]( options );
8929				} else {
8930					that._updateCornerClass( children[ value ](), value );
8931				}
8932			} );
8933
8934			// Finally call the refresh method on each of the child widgets.
8935			this._callChildMethod( "refresh" );
8936		}
8937	}
8938} );
8939
8940/*!
8941 * jQuery UI Checkboxradio 1.12.1
8942 * http://jqueryui.com
8943 *
8944 * Copyright jQuery Foundation and other contributors
8945 * Released under the MIT license.
8946 * http://jquery.org/license
8947 */
8948
8949//>>label: Checkboxradio
8950//>>group: Widgets
8951//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
8952//>>docs: http://api.jqueryui.com/checkboxradio/
8953//>>demos: http://jqueryui.com/checkboxradio/
8954//>>css.structure: ../../themes/base/core.css
8955//>>css.structure: ../../themes/base/button.css
8956//>>css.structure: ../../themes/base/checkboxradio.css
8957//>>css.theme: ../../themes/base/theme.css
8958
8959
8960
8961$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
8962	version: "1.12.1",
8963	options: {
8964		disabled: null,
8965		label: null,
8966		icon: true,
8967		classes: {
8968			"ui-checkboxradio-label": "ui-corner-all",
8969			"ui-checkboxradio-icon": "ui-corner-all"
8970		}
8971	},
8972
8973	_getCreateOptions: function() {
8974		var disabled, labels;
8975		var that = this;
8976		var options = this._super() || {};
8977
8978		// We read the type here, because it makes more sense to throw a element type error first,
8979		// rather then the error for lack of a label. Often if its the wrong type, it
8980		// won't have a label (e.g. calling on a div, btn, etc)
8981		this._readType();
8982
8983		labels = this.element.labels();
8984
8985		// If there are multiple labels, use the last one
8986		this.label = $( labels[ labels.length - 1 ] );
8987		if ( !this.label.length ) {
8988			$.error( "No label found for checkboxradio widget" );
8989		}
8990
8991		this.originalLabel = "";
8992
8993		// We need to get the label text but this may also need to make sure it does not contain the
8994		// input itself.
8995		this.label.contents().not( this.element[ 0 ] ).each( function() {
8996
8997			// The label contents could be text, html, or a mix. We concat each element to get a
8998			// string representation of the label, without the input as part of it.
8999			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
9000		} );
9001
9002		// Set the label option if we found label text
9003		if ( this.originalLabel ) {
9004			options.label = this.originalLabel;
9005		}
9006
9007		disabled = this.element[ 0 ].disabled;
9008		if ( disabled != null ) {
9009			options.disabled = disabled;
9010		}
9011		return options;
9012	},
9013
9014	_create: function() {
9015		var checked = this.element[ 0 ].checked;
9016
9017		this._bindFormResetHandler();
9018
9019		if ( this.options.disabled == null ) {
9020			this.options.disabled = this.element[ 0 ].disabled;
9021		}
9022
9023		this._setOption( "disabled", this.options.disabled );
9024		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
9025		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
9026
9027		if ( this.type === "radio" ) {
9028			this._addClass( this.label, "ui-checkboxradio-radio-label" );
9029		}
9030
9031		if ( this.options.label && this.options.label !== this.originalLabel ) {
9032			this._updateLabel();
9033		} else if ( this.originalLabel ) {
9034			this.options.label = this.originalLabel;
9035		}
9036
9037		this._enhance();
9038
9039		if ( checked ) {
9040			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
9041			if ( this.icon ) {
9042				this._addClass( this.icon, null, "ui-state-hover" );
9043			}
9044		}
9045
9046		this._on( {
9047			change: "_toggleClasses",
9048			focus: function() {
9049				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
9050			},
9051			blur: function() {
9052				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
9053			}
9054		} );
9055	},
9056
9057	_readType: function() {
9058		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
9059		this.type = this.element[ 0 ].type;
9060		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
9061			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
9062				" and element.type=" + this.type );
9063		}
9064	},
9065
9066	// Support jQuery Mobile enhanced option
9067	_enhance: function() {
9068		this._updateIcon( this.element[ 0 ].checked );
9069	},
9070
9071	widget: function() {
9072		return this.label;
9073	},
9074
9075	_getRadioGroup: function() {
9076		var group;
9077		var name = this.element[ 0 ].name;
9078		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
9079
9080		if ( !name ) {
9081			return $( [] );
9082		}
9083
9084		if ( this.form.length ) {
9085			group = $( this.form[ 0 ].elements ).filter( nameSelector );
9086		} else {
9087
9088			// Not inside a form, check all inputs that also are not inside a form
9089			group = $( nameSelector ).filter( function() {
9090				return $( this ).form().length === 0;
9091			} );
9092		}
9093
9094		return group.not( this.element );
9095	},
9096
9097	_toggleClasses: function() {
9098		var checked = this.element[ 0 ].checked;
9099		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9100
9101		if ( this.options.icon && this.type === "checkbox" ) {
9102			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
9103				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
9104		}
9105
9106		if ( this.type === "radio" ) {
9107			this._getRadioGroup()
9108				.each( function() {
9109					var instance = $( this ).checkboxradio( "instance" );
9110
9111					if ( instance ) {
9112						instance._removeClass( instance.label,
9113							"ui-checkboxradio-checked", "ui-state-active" );
9114					}
9115				} );
9116		}
9117	},
9118
9119	_destroy: function() {
9120		this._unbindFormResetHandler();
9121
9122		if ( this.icon ) {
9123			this.icon.remove();
9124			this.iconSpace.remove();
9125		}
9126	},
9127
9128	_setOption: function( key, value ) {
9129
9130		// We don't allow the value to be set to nothing
9131		if ( key === "label" && !value ) {
9132			return;
9133		}
9134
9135		this._super( key, value );
9136
9137		if ( key === "disabled" ) {
9138			this._toggleClass( this.label, null, "ui-state-disabled", value );
9139			this.element[ 0 ].disabled = value;
9140
9141			// Don't refresh when setting disabled
9142			return;
9143		}
9144		this.refresh();
9145	},
9146
9147	_updateIcon: function( checked ) {
9148		var toAdd = "ui-icon ui-icon-background ";
9149
9150		if ( this.options.icon ) {
9151			if ( !this.icon ) {
9152				this.icon = $( "<span>" );
9153				this.iconSpace = $( "<span> </span>" );
9154				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
9155			}
9156
9157			if ( this.type === "checkbox" ) {
9158				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
9159				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
9160			} else {
9161				toAdd += "ui-icon-blank";
9162			}
9163			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
9164			if ( !checked ) {
9165				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
9166			}
9167			this.icon.prependTo( this.label ).after( this.iconSpace );
9168		} else if ( this.icon !== undefined ) {
9169			this.icon.remove();
9170			this.iconSpace.remove();
9171			delete this.icon;
9172		}
9173	},
9174
9175	_updateLabel: function() {
9176
9177		// Remove the contents of the label ( minus the icon, icon space, and input )
9178		var contents = this.label.contents().not( this.element[ 0 ] );
9179		if ( this.icon ) {
9180			contents = contents.not( this.icon[ 0 ] );
9181		}
9182		if ( this.iconSpace ) {
9183			contents = contents.not( this.iconSpace[ 0 ] );
9184		}
9185		contents.remove();
9186
9187		this.label.append( this.options.label );
9188	},
9189
9190	refresh: function() {
9191		var checked = this.element[ 0 ].checked,
9192			isDisabled = this.element[ 0 ].disabled;
9193
9194		this._updateIcon( checked );
9195		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9196		if ( this.options.label !== null ) {
9197			this._updateLabel();
9198		}
9199
9200		if ( isDisabled !== this.options.disabled ) {
9201			this._setOptions( { "disabled": isDisabled } );
9202		}
9203	}
9204
9205} ] );
9206
9207var widgetsCheckboxradio = $.ui.checkboxradio;
9208
9209
9210/*!
9211 * jQuery UI Button 1.12.1
9212 * http://jqueryui.com
9213 *
9214 * Copyright jQuery Foundation and other contributors
9215 * Released under the MIT license.
9216 * http://jquery.org/license
9217 */
9218
9219//>>label: Button
9220//>>group: Widgets
9221//>>description: Enhances a form with themeable buttons.
9222//>>docs: http://api.jqueryui.com/button/
9223//>>demos: http://jqueryui.com/button/
9224//>>css.structure: ../../themes/base/core.css
9225//>>css.structure: ../../themes/base/button.css
9226//>>css.theme: ../../themes/base/theme.css
9227
9228
9229
9230$.widget( "ui.button", {
9231	version: "1.12.1",
9232	defaultElement: "<button>",
9233	options: {
9234		classes: {
9235			"ui-button": "ui-corner-all"
9236		},
9237		disabled: null,
9238		icon: null,
9239		iconPosition: "beginning",
9240		label: null,
9241		showLabel: true
9242	},
9243
9244	_getCreateOptions: function() {
9245		var disabled,
9246
9247			// This is to support cases like in jQuery Mobile where the base widget does have
9248			// an implementation of _getCreateOptions
9249			options = this._super() || {};
9250
9251		this.isInput = this.element.is( "input" );
9252
9253		disabled = this.element[ 0 ].disabled;
9254		if ( disabled != null ) {
9255			options.disabled = disabled;
9256		}
9257
9258		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
9259		if ( this.originalLabel ) {
9260			options.label = this.originalLabel;
9261		}
9262
9263		return options;
9264	},
9265
9266	_create: function() {
9267		if ( !this.option.showLabel & !this.options.icon ) {
9268			this.options.showLabel = true;
9269		}
9270
9271		// We have to check the option again here even though we did in _getCreateOptions,
9272		// because null may have been passed on init which would override what was set in
9273		// _getCreateOptions
9274		if ( this.options.disabled == null ) {
9275			this.options.disabled = this.element[ 0 ].disabled || false;
9276		}
9277
9278		this.hasTitle = !!this.element.attr( "title" );
9279
9280		// Check to see if the label needs to be set or if its already correct
9281		if ( this.options.label && this.options.label !== this.originalLabel ) {
9282			if ( this.isInput ) {
9283				this.element.val( this.options.label );
9284			} else {
9285				this.element.html( this.options.label );
9286			}
9287		}
9288		this._addClass( "ui-button", "ui-widget" );
9289		this._setOption( "disabled", this.options.disabled );
9290		this._enhance();
9291
9292		if ( this.element.is( "a" ) ) {
9293			this._on( {
9294				"keyup": function( event ) {
9295					if ( event.keyCode === $.ui.keyCode.SPACE ) {
9296						event.preventDefault();
9297
9298						// Support: PhantomJS <= 1.9, IE 8 Only
9299						// If a native click is available use it so we actually cause navigation
9300						// otherwise just trigger a click event
9301						if ( this.element[ 0 ].click ) {
9302							this.element[ 0 ].click();
9303						} else {
9304							this.element.trigger( "click" );
9305						}
9306					}
9307				}
9308			} );
9309		}
9310	},
9311
9312	_enhance: function() {
9313		if ( !this.element.is( "button" ) ) {
9314			this.element.attr( "role", "button" );
9315		}
9316
9317		if ( this.options.icon ) {
9318			this._updateIcon( "icon", this.options.icon );
9319			this._updateTooltip();
9320		}
9321	},
9322
9323	_updateTooltip: function() {
9324		this.title = this.element.attr( "title" );
9325
9326		if ( !this.options.showLabel && !this.title ) {
9327			this.element.attr( "title", this.options.label );
9328		}
9329	},
9330
9331	_updateIcon: function( option, value ) {
9332		var icon = option !== "iconPosition",
9333			position = icon ? this.options.iconPosition : value,
9334			displayBlock = position === "top" || position === "bottom";
9335
9336		// Create icon
9337		if ( !this.icon ) {
9338			this.icon = $( "<span>" );
9339
9340			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
9341
9342			if ( !this.options.showLabel ) {
9343				this._addClass( "ui-button-icon-only" );
9344			}
9345		} else if ( icon ) {
9346
9347			// If we are updating the icon remove the old icon class
9348			this._removeClass( this.icon, null, this.options.icon );
9349		}
9350
9351		// If we are updating the icon add the new icon class
9352		if ( icon ) {
9353			this._addClass( this.icon, null, value );
9354		}
9355
9356		this._attachIcon( position );
9357
9358		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
9359		// the iconSpace if there is one.
9360		if ( displayBlock ) {
9361			this._addClass( this.icon, null, "ui-widget-icon-block" );
9362			if ( this.iconSpace ) {
9363				this.iconSpace.remove();
9364			}
9365		} else {
9366
9367			// Position is beginning or end so remove the ui-widget-icon-block class and add the
9368			// space if it does not exist
9369			if ( !this.iconSpace ) {
9370				this.iconSpace = $( "<span> </span>" );
9371				this._addClass( this.iconSpace, "ui-button-icon-space" );
9372			}
9373			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
9374			this._attachIconSpace( position );
9375		}
9376	},
9377
9378	_destroy: function() {
9379		this.element.removeAttr( "role" );
9380
9381		if ( this.icon ) {
9382			this.icon.remove();
9383		}
9384		if ( this.iconSpace ) {
9385			this.iconSpace.remove();
9386		}
9387		if ( !this.hasTitle ) {
9388			this.element.removeAttr( "title" );
9389		}
9390	},
9391
9392	_attachIconSpace: function( iconPosition ) {
9393		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
9394	},
9395
9396	_attachIcon: function( iconPosition ) {
9397		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
9398	},
9399
9400	_setOptions: function( options ) {
9401		var newShowLabel = options.showLabel === undefined ?
9402				this.options.showLabel :
9403				options.showLabel,
9404			newIcon = options.icon === undefined ? this.options.icon : options.icon;
9405
9406		if ( !newShowLabel && !newIcon ) {
9407			options.showLabel = true;
9408		}
9409		this._super( options );
9410	},
9411
9412	_setOption: function( key, value ) {
9413		if ( key === "icon" ) {
9414			if ( value ) {
9415				this._updateIcon( key, value );
9416			} else if ( this.icon ) {
9417				this.icon.remove();
9418				if ( this.iconSpace ) {
9419					this.iconSpace.remove();
9420				}
9421			}
9422		}
9423
9424		if ( key === "iconPosition" ) {
9425			this._updateIcon( key, value );
9426		}
9427
9428		// Make sure we can't end up with a button that has neither text nor icon
9429		if ( key === "showLabel" ) {
9430				this._toggleClass( "ui-button-icon-only", null, !value );
9431				this._updateTooltip();
9432		}
9433
9434		if ( key === "label" ) {
9435			if ( this.isInput ) {
9436				this.element.val( value );
9437			} else {
9438
9439				// If there is an icon, append it, else nothing then append the value
9440				// this avoids removal of the icon when setting label text
9441				this.element.html( value );
9442				if ( this.icon ) {
9443					this._attachIcon( this.options.iconPosition );
9444					this._attachIconSpace( this.options.iconPosition );
9445				}
9446			}
9447		}
9448
9449		this._super( key, value );
9450
9451		if ( key === "disabled" ) {
9452			this._toggleClass( null, "ui-state-disabled", value );
9453			this.element[ 0 ].disabled = value;
9454			if ( value ) {
9455				this.element.blur();
9456			}
9457		}
9458	},
9459
9460	refresh: function() {
9461
9462		// Make sure to only check disabled if its an element that supports this otherwise
9463		// check for the disabled class to determine state
9464		var isDisabled = this.element.is( "input, button" ) ?
9465			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
9466
9467		if ( isDisabled !== this.options.disabled ) {
9468			this._setOptions( { disabled: isDisabled } );
9469		}
9470
9471		this._updateTooltip();
9472	}
9473} );
9474
9475// DEPRECATED
9476if ( $.uiBackCompat !== false ) {
9477
9478	// Text and Icons options
9479	$.widget( "ui.button", $.ui.button, {
9480		options: {
9481			text: true,
9482			icons: {
9483				primary: null,
9484				secondary: null
9485			}
9486		},
9487
9488		_create: function() {
9489			if ( this.options.showLabel && !this.options.text ) {
9490				this.options.showLabel = this.options.text;
9491			}
9492			if ( !this.options.showLabel && this.options.text ) {
9493				this.options.text = this.options.showLabel;
9494			}
9495			if ( !this.options.icon && ( this.options.icons.primary ||
9496					this.options.icons.secondary ) ) {
9497				if ( this.options.icons.primary ) {
9498					this.options.icon = this.options.icons.primary;
9499				} else {
9500					this.options.icon = this.options.icons.secondary;
9501					this.options.iconPosition = "end";
9502				}
9503			} else if ( this.options.icon ) {
9504				this.options.icons.primary = this.options.icon;
9505			}
9506			this._super();
9507		},
9508
9509		_setOption: function( key, value ) {
9510			if ( key === "text" ) {
9511				this._super( "showLabel", value );
9512				return;
9513			}
9514			if ( key === "showLabel" ) {
9515				this.options.text = value;
9516			}
9517			if ( key === "icon" ) {
9518				this.options.icons.primary = value;
9519			}
9520			if ( key === "icons" ) {
9521				if ( value.primary ) {
9522					this._super( "icon", value.primary );
9523					this._super( "iconPosition", "beginning" );
9524				} else if ( value.secondary ) {
9525					this._super( "icon", value.secondary );
9526					this._super( "iconPosition", "end" );
9527				}
9528			}
9529			this._superApply( arguments );
9530		}
9531	} );
9532
9533	$.fn.button = ( function( orig ) {
9534		return function() {
9535			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
9536					( this.length && this[ 0 ].tagName === "INPUT" && (
9537						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
9538					) ) ) {
9539				return orig.apply( this, arguments );
9540			}
9541			if ( !$.ui.checkboxradio ) {
9542				$.error( "Checkboxradio widget missing" );
9543			}
9544			if ( arguments.length === 0 ) {
9545				return this.checkboxradio( {
9546					"icon": false
9547				} );
9548			}
9549			return this.checkboxradio.apply( this, arguments );
9550		};
9551	} )( $.fn.button );
9552
9553	$.fn.buttonset = function() {
9554		if ( !$.ui.controlgroup ) {
9555			$.error( "Controlgroup widget missing" );
9556		}
9557		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
9558			return this.controlgroup.apply( this,
9559				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
9560		}
9561		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
9562			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
9563		}
9564		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
9565			arguments[ 0 ].items = {
9566				button: arguments[ 0 ].items
9567			};
9568		}
9569		return this.controlgroup.apply( this, arguments );
9570	};
9571}
9572
9573var widgetsButton = $.ui.button;
9574
9575
9576// jscs:disable maximumLineLength
9577/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
9578/*!
9579 * jQuery UI Datepicker 1.12.1
9580 * http://jqueryui.com
9581 *
9582 * Copyright jQuery Foundation and other contributors
9583 * Released under the MIT license.
9584 * http://jquery.org/license
9585 */
9586
9587//>>label: Datepicker
9588//>>group: Widgets
9589//>>description: Displays a calendar from an input or inline for selecting dates.
9590//>>docs: http://api.jqueryui.com/datepicker/
9591//>>demos: http://jqueryui.com/datepicker/
9592//>>css.structure: ../../themes/base/core.css
9593//>>css.structure: ../../themes/base/datepicker.css
9594//>>css.theme: ../../themes/base/theme.css
9595
9596
9597
9598$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
9599
9600var datepicker_instActive;
9601
9602function datepicker_getZindex( elem ) {
9603	var position, value;
9604	while ( elem.length && elem[ 0 ] !== document ) {
9605
9606		// Ignore z-index if position is set to a value where z-index is ignored by the browser
9607		// This makes behavior of this function consistent across browsers
9608		// WebKit always returns auto if the element is positioned
9609		position = elem.css( "position" );
9610		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
9611
9612			// IE returns 0 when zIndex is not specified
9613			// other browsers return a string
9614			// we ignore the case of nested elements with an explicit value of 0
9615			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
9616			value = parseInt( elem.css( "zIndex" ), 10 );
9617			if ( !isNaN( value ) && value !== 0 ) {
9618				return value;
9619			}
9620		}
9621		elem = elem.parent();
9622	}
9623
9624	return 0;
9625}
9626/* Date picker manager.
9627   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
9628   Settings for (groups of) date pickers are maintained in an instance object,
9629   allowing multiple different settings on the same page. */
9630
9631function Datepicker() {
9632	this._curInst = null; // The current instance in use
9633	this._keyEvent = false; // If the last event was a key event
9634	this._disabledInputs = []; // List of date picker inputs that have been disabled
9635	this._datepickerShowing = false; // True if the popup picker is showing , false if not
9636	this._inDialog = false; // True if showing within a "dialog", false if not
9637	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
9638	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
9639	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
9640	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
9641	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
9642	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
9643	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
9644	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
9645	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
9646	this.regional = []; // Available regional settings, indexed by language code
9647	this.regional[ "" ] = { // Default regional settings
9648		closeText: "Done", // Display text for close link
9649		prevText: "Prev", // Display text for previous month link
9650		nextText: "Next", // Display text for next month link
9651		currentText: "Today", // Display text for current month link
9652		monthNames: [ "January","February","March","April","May","June",
9653			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
9654		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
9655		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
9656		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
9657		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
9658		weekHeader: "Wk", // Column header for week of the year
9659		dateFormat: "mm/dd/yy", // See format options on parseDate
9660		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
9661		isRTL: false, // True if right-to-left language, false if left-to-right
9662		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
9663		yearSuffix: "" // Additional text to append to the year in the month headers
9664	};
9665	this._defaults = { // Global defaults for all the date picker instances
9666		showOn: "focus", // "focus" for popup on focus,
9667			// "button" for trigger button, or "both" for either
9668		showAnim: "fadeIn", // Name of jQuery animation for popup
9669		showOptions: {}, // Options for enhanced animations
9670		defaultDate: null, // Used when field is blank: actual date,
9671			// +/-number for offset from today, null for today
9672		appendText: "", // Display text following the input box, e.g. showing the format
9673		buttonText: "...", // Text for trigger button
9674		buttonImage: "", // URL for trigger button image
9675		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
9676		hideIfNoPrevNext: false, // True to hide next/previous month links
9677			// if not applicable, false to just disable them
9678		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
9679		gotoCurrent: false, // True if today link goes back to current selection instead
9680		changeMonth: false, // True if month can be selected directly, false if only prev/next
9681		changeYear: false, // True if year can be selected directly, false if only prev/next
9682		yearRange: "c-10:c+10", // Range of years to display in drop-down,
9683			// either relative to today's year (-nn:+nn), relative to currently displayed year
9684			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
9685		showOtherMonths: false, // True to show dates in other months, false to leave blank
9686		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
9687		showWeek: false, // True to show week of the year, false to not show it
9688		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
9689			// takes a Date and returns the number of the week for it
9690		shortYearCutoff: "+10", // Short year values < this are in the current century,
9691			// > this are in the previous century,
9692			// string value starting with "+" for current year + value
9693		minDate: null, // The earliest selectable date, or null for no limit
9694		maxDate: null, // The latest selectable date, or null for no limit
9695		duration: "fast", // Duration of display/closure
9696		beforeShowDay: null, // Function that takes a date and returns an array with
9697			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
9698			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
9699		beforeShow: null, // Function that takes an input field and
9700			// returns a set of custom settings for the date picker
9701		onSelect: null, // Define a callback function when a date is selected
9702		onChangeMonthYear: null, // Define a callback function when the month or year is changed
9703		onClose: null, // Define a callback function when the datepicker is closed
9704		numberOfMonths: 1, // Number of months to show at a time
9705		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
9706		stepMonths: 1, // Number of months to step back/forward
9707		stepBigMonths: 12, // Number of months to step back/forward for the big links
9708		altField: "", // Selector for an alternate field to store selected dates into
9709		altFormat: "", // The date format to use for the alternate field
9710		constrainInput: true, // The input is constrained by the current date format
9711		showButtonPanel: false, // True to show button panel, false to not show it
9712		autoSize: false, // True to size the input for the date format, false to leave as is
9713		disabled: false // The initial disabled state
9714	};
9715	$.extend( this._defaults, this.regional[ "" ] );
9716	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
9717	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
9718	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
9719}
9720
9721$.extend( Datepicker.prototype, {
9722	/* Class name added to elements to indicate already configured with a date picker. */
9723	markerClassName: "hasDatepicker",
9724
9725	//Keep track of the maximum number of rows displayed (see #7043)
9726	maxRows: 4,
9727
9728	// TODO rename to "widget" when switching to widget factory
9729	_widgetDatepicker: function() {
9730		return this.dpDiv;
9731	},
9732
9733	/* Override the default settings for all instances of the date picker.
9734	 * @param  settings  object - the new settings to use as defaults (anonymous object)
9735	 * @return the manager object
9736	 */
9737	setDefaults: function( settings ) {
9738		datepicker_extendRemove( this._defaults, settings || {} );
9739		return this;
9740	},
9741
9742	/* Attach the date picker to a jQuery selection.
9743	 * @param  target	element - the target input field or division or span
9744	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
9745	 */
9746	_attachDatepicker: function( target, settings ) {
9747		var nodeName, inline, inst;
9748		nodeName = target.nodeName.toLowerCase();
9749		inline = ( nodeName === "div" || nodeName === "span" );
9750		if ( !target.id ) {
9751			this.uuid += 1;
9752			target.id = "dp" + this.uuid;
9753		}
9754		inst = this._newInst( $( target ), inline );
9755		inst.settings = $.extend( {}, settings || {} );
9756		if ( nodeName === "input" ) {
9757			this._connectDatepicker( target, inst );
9758		} else if ( inline ) {
9759			this._inlineDatepicker( target, inst );
9760		}
9761	},
9762
9763	/* Create a new instance object. */
9764	_newInst: function( target, inline ) {
9765		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
9766		return { id: id, input: target, // associated target
9767			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
9768			drawMonth: 0, drawYear: 0, // month being drawn
9769			inline: inline, // is datepicker inline or not
9770			dpDiv: ( !inline ? this.dpDiv : // presentation div
9771			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
9772	},
9773
9774	/* Attach the date picker to an input field. */
9775	_connectDatepicker: function( target, inst ) {
9776		var input = $( target );
9777		inst.append = $( [] );
9778		inst.trigger = $( [] );
9779		if ( input.hasClass( this.markerClassName ) ) {
9780			return;
9781		}
9782		this._attachments( input, inst );
9783		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
9784			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
9785		this._autoSize( inst );
9786		$.data( target, "datepicker", inst );
9787
9788		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
9789		if ( inst.settings.disabled ) {
9790			this._disableDatepicker( target );
9791		}
9792	},
9793
9794	/* Make attachments based on settings. */
9795	_attachments: function( input, inst ) {
9796		var showOn, buttonText, buttonImage,
9797			appendText = this._get( inst, "appendText" ),
9798			isRTL = this._get( inst, "isRTL" );
9799
9800		if ( inst.append ) {
9801			inst.append.remove();
9802		}
9803		if ( appendText ) {
9804			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
9805			input[ isRTL ? "before" : "after" ]( inst.append );
9806		}
9807
9808		input.off( "focus", this._showDatepicker );
9809
9810		if ( inst.trigger ) {
9811			inst.trigger.remove();
9812		}
9813
9814		showOn = this._get( inst, "showOn" );
9815		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
9816			input.on( "focus", this._showDatepicker );
9817		}
9818		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
9819			buttonText = this._get( inst, "buttonText" );
9820			buttonImage = this._get( inst, "buttonImage" );
9821			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
9822				$( "<img/>" ).addClass( this._triggerClass ).
9823					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
9824				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
9825					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
9826					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
9827			input[ isRTL ? "before" : "after" ]( inst.trigger );
9828			inst.trigger.on( "click", function() {
9829				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
9830					$.datepicker._hideDatepicker();
9831				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
9832					$.datepicker._hideDatepicker();
9833					$.datepicker._showDatepicker( input[ 0 ] );
9834				} else {
9835					$.datepicker._showDatepicker( input[ 0 ] );
9836				}
9837				return false;
9838			} );
9839		}
9840	},
9841
9842	/* Apply the maximum length for the date format. */
9843	_autoSize: function( inst ) {
9844		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
9845			var findMax, max, maxI, i,
9846				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
9847				dateFormat = this._get( inst, "dateFormat" );
9848
9849			if ( dateFormat.match( /[DM]/ ) ) {
9850				findMax = function( names ) {
9851					max = 0;
9852					maxI = 0;
9853					for ( i = 0; i < names.length; i++ ) {
9854						if ( names[ i ].length > max ) {
9855							max = names[ i ].length;
9856							maxI = i;
9857						}
9858					}
9859					return maxI;
9860				};
9861				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
9862					"monthNames" : "monthNamesShort" ) ) ) );
9863				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
9864					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
9865			}
9866			inst.input.attr( "size", this._formatDate( inst, date ).length );
9867		}
9868	},
9869
9870	/* Attach an inline date picker to a div. */
9871	_inlineDatepicker: function( target, inst ) {
9872		var divSpan = $( target );
9873		if ( divSpan.hasClass( this.markerClassName ) ) {
9874			return;
9875		}
9876		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
9877		$.data( target, "datepicker", inst );
9878		this._setDate( inst, this._getDefaultDate( inst ), true );
9879		this._updateDatepicker( inst );
9880		this._updateAlternate( inst );
9881
9882		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
9883		if ( inst.settings.disabled ) {
9884			this._disableDatepicker( target );
9885		}
9886
9887		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
9888		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
9889		inst.dpDiv.css( "display", "block" );
9890	},
9891
9892	/* Pop-up the date picker in a "dialog" box.
9893	 * @param  input element - ignored
9894	 * @param  date	string or Date - the initial date to display
9895	 * @param  onSelect  function - the function to call when a date is selected
9896	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
9897	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
9898	 *					event - with x/y coordinates or
9899	 *					leave empty for default (screen centre)
9900	 * @return the manager object
9901	 */
9902	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
9903		var id, browserWidth, browserHeight, scrollX, scrollY,
9904			inst = this._dialogInst; // internal instance
9905
9906		if ( !inst ) {
9907			this.uuid += 1;
9908			id = "dp" + this.uuid;
9909			this._dialogInput = $( "<input type='text' id='" + id +
9910				"' style='position: absolute; top: -100px; width: 0px;'/>" );
9911			this._dialogInput.on( "keydown", this._doKeyDown );
9912			$( "body" ).append( this._dialogInput );
9913			inst = this._dialogInst = this._newInst( this._dialogInput, false );
9914			inst.settings = {};
9915			$.data( this._dialogInput[ 0 ], "datepicker", inst );
9916		}
9917		datepicker_extendRemove( inst.settings, settings || {} );
9918		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
9919		this._dialogInput.val( date );
9920
9921		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
9922		if ( !this._pos ) {
9923			browserWidth = document.documentElement.clientWidth;
9924			browserHeight = document.documentElement.clientHeight;
9925			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
9926			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
9927			this._pos = // should use actual width/height below
9928				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
9929		}
9930
9931		// Move input on screen for focus, but hidden behind dialog
9932		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
9933		inst.settings.onSelect = onSelect;
9934		this._inDialog = true;
9935		this.dpDiv.addClass( this._dialogClass );
9936		this._showDatepicker( this._dialogInput[ 0 ] );
9937		if ( $.blockUI ) {
9938			$.blockUI( this.dpDiv );
9939		}
9940		$.data( this._dialogInput[ 0 ], "datepicker", inst );
9941		return this;
9942	},
9943
9944	/* Detach a datepicker from its control.
9945	 * @param  target	element - the target input field or division or span
9946	 */
9947	_destroyDatepicker: function( target ) {
9948		var nodeName,
9949			$target = $( target ),
9950			inst = $.data( target, "datepicker" );
9951
9952		if ( !$target.hasClass( this.markerClassName ) ) {
9953			return;
9954		}
9955
9956		nodeName = target.nodeName.toLowerCase();
9957		$.removeData( target, "datepicker" );
9958		if ( nodeName === "input" ) {
9959			inst.append.remove();
9960			inst.trigger.remove();
9961			$target.removeClass( this.markerClassName ).
9962				off( "focus", this._showDatepicker ).
9963				off( "keydown", this._doKeyDown ).
9964				off( "keypress", this._doKeyPress ).
9965				off( "keyup", this._doKeyUp );
9966		} else if ( nodeName === "div" || nodeName === "span" ) {
9967			$target.removeClass( this.markerClassName ).empty();
9968		}
9969
9970		if ( datepicker_instActive === inst ) {
9971			datepicker_instActive = null;
9972		}
9973	},
9974
9975	/* Enable the date picker to a jQuery selection.
9976	 * @param  target	element - the target input field or division or span
9977	 */
9978	_enableDatepicker: function( target ) {
9979		var nodeName, inline,
9980			$target = $( target ),
9981			inst = $.data( target, "datepicker" );
9982
9983		if ( !$target.hasClass( this.markerClassName ) ) {
9984			return;
9985		}
9986
9987		nodeName = target.nodeName.toLowerCase();
9988		if ( nodeName === "input" ) {
9989			target.disabled = false;
9990			inst.trigger.filter( "button" ).
9991				each( function() { this.disabled = false; } ).end().
9992				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
9993		} else if ( nodeName === "div" || nodeName === "span" ) {
9994			inline = $target.children( "." + this._inlineClass );
9995			inline.children().removeClass( "ui-state-disabled" );
9996			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
9997				prop( "disabled", false );
9998		}
9999		this._disabledInputs = $.map( this._disabledInputs,
10000			function( value ) { return ( value === target ? null : value ); } ); // delete entry
10001	},
10002
10003	/* Disable the date picker to a jQuery selection.
10004	 * @param  target	element - the target input field or division or span
10005	 */
10006	_disableDatepicker: function( target ) {
10007		var nodeName, inline,
10008			$target = $( target ),
10009			inst = $.data( target, "datepicker" );
10010
10011		if ( !$target.hasClass( this.markerClassName ) ) {
10012			return;
10013		}
10014
10015		nodeName = target.nodeName.toLowerCase();
10016		if ( nodeName === "input" ) {
10017			target.disabled = true;
10018			inst.trigger.filter( "button" ).
10019				each( function() { this.disabled = true; } ).end().
10020				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
10021		} else if ( nodeName === "div" || nodeName === "span" ) {
10022			inline = $target.children( "." + this._inlineClass );
10023			inline.children().addClass( "ui-state-disabled" );
10024			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
10025				prop( "disabled", true );
10026		}
10027		this._disabledInputs = $.map( this._disabledInputs,
10028			function( value ) { return ( value === target ? null : value ); } ); // delete entry
10029		this._disabledInputs[ this._disabledInputs.length ] = target;
10030	},
10031
10032	/* Is the first field in a jQuery collection disabled as a datepicker?
10033	 * @param  target	element - the target input field or division or span
10034	 * @return boolean - true if disabled, false if enabled
10035	 */
10036	_isDisabledDatepicker: function( target ) {
10037		if ( !target ) {
10038			return false;
10039		}
10040		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
10041			if ( this._disabledInputs[ i ] === target ) {
10042				return true;
10043			}
10044		}
10045		return false;
10046	},
10047
10048	/* Retrieve the instance data for the target control.
10049	 * @param  target  element - the target input field or division or span
10050	 * @return  object - the associated instance data
10051	 * @throws  error if a jQuery problem getting data
10052	 */
10053	_getInst: function( target ) {
10054		try {
10055			return $.data( target, "datepicker" );
10056		}
10057		catch ( err ) {
10058			throw "Missing instance data for this datepicker";
10059		}
10060	},
10061
10062	/* Update or retrieve the settings for a date picker attached to an input field or division.
10063	 * @param  target  element - the target input field or division or span
10064	 * @param  name	object - the new settings to update or
10065	 *				string - the name of the setting to change or retrieve,
10066	 *				when retrieving also "all" for all instance settings or
10067	 *				"defaults" for all global defaults
10068	 * @param  value   any - the new value for the setting
10069	 *				(omit if above is an object or to retrieve a value)
10070	 */
10071	_optionDatepicker: function( target, name, value ) {
10072		var settings, date, minDate, maxDate,
10073			inst = this._getInst( target );
10074
10075		if ( arguments.length === 2 && typeof name === "string" ) {
10076			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
10077				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
10078				this._get( inst, name ) ) : null ) );
10079		}
10080
10081		settings = name || {};
10082		if ( typeof name === "string" ) {
10083			settings = {};
10084			settings[ name ] = value;
10085		}
10086
10087		if ( inst ) {
10088			if ( this._curInst === inst ) {
10089				this._hideDatepicker();
10090			}
10091
10092			date = this._getDateDatepicker( target, true );
10093			minDate = this._getMinMaxDate( inst, "min" );
10094			maxDate = this._getMinMaxDate( inst, "max" );
10095			datepicker_extendRemove( inst.settings, settings );
10096
10097			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
10098			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
10099				inst.settings.minDate = this._formatDate( inst, minDate );
10100			}
10101			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
10102				inst.settings.maxDate = this._formatDate( inst, maxDate );
10103			}
10104			if ( "disabled" in settings ) {
10105				if ( settings.disabled ) {
10106					this._disableDatepicker( target );
10107				} else {
10108					this._enableDatepicker( target );
10109				}
10110			}
10111			this._attachments( $( target ), inst );
10112			this._autoSize( inst );
10113			this._setDate( inst, date );
10114			this._updateAlternate( inst );
10115			this._updateDatepicker( inst );
10116		}
10117	},
10118
10119	// Change method deprecated
10120	_changeDatepicker: function( target, name, value ) {
10121		this._optionDatepicker( target, name, value );
10122	},
10123
10124	/* Redraw the date picker attached to an input field or division.
10125	 * @param  target  element - the target input field or division or span
10126	 */
10127	_refreshDatepicker: function( target ) {
10128		var inst = this._getInst( target );
10129		if ( inst ) {
10130			this._updateDatepicker( inst );
10131		}
10132	},
10133
10134	/* Set the dates for a jQuery selection.
10135	 * @param  target element - the target input field or division or span
10136	 * @param  date	Date - the new date
10137	 */
10138	_setDateDatepicker: function( target, date ) {
10139		var inst = this._getInst( target );
10140		if ( inst ) {
10141			this._setDate( inst, date );
10142			this._updateDatepicker( inst );
10143			this._updateAlternate( inst );
10144		}
10145	},
10146
10147	/* Get the date(s) for the first entry in a jQuery selection.
10148	 * @param  target element - the target input field or division or span
10149	 * @param  noDefault boolean - true if no default date is to be used
10150	 * @return Date - the current date
10151	 */
10152	_getDateDatepicker: function( target, noDefault ) {
10153		var inst = this._getInst( target );
10154		if ( inst && !inst.inline ) {
10155			this._setDateFromField( inst, noDefault );
10156		}
10157		return ( inst ? this._getDate( inst ) : null );
10158	},
10159
10160	/* Handle keystrokes. */
10161	_doKeyDown: function( event ) {
10162		var onSelect, dateStr, sel,
10163			inst = $.datepicker._getInst( event.target ),
10164			handled = true,
10165			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
10166
10167		inst._keyEvent = true;
10168		if ( $.datepicker._datepickerShowing ) {
10169			switch ( event.keyCode ) {
10170				case 9: $.datepicker._hideDatepicker();
10171						handled = false;
10172						break; // hide on tab out
10173				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
10174									$.datepicker._currentClass + ")", inst.dpDiv );
10175						if ( sel[ 0 ] ) {
10176							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
10177						}
10178
10179						onSelect = $.datepicker._get( inst, "onSelect" );
10180						if ( onSelect ) {
10181							dateStr = $.datepicker._formatDate( inst );
10182
10183							// Trigger custom callback
10184							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
10185						} else {
10186							$.datepicker._hideDatepicker();
10187						}
10188
10189						return false; // don't submit the form
10190				case 27: $.datepicker._hideDatepicker();
10191						break; // hide on escape
10192				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10193							-$.datepicker._get( inst, "stepBigMonths" ) :
10194							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10195						break; // previous month/year on page up/+ ctrl
10196				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10197							+$.datepicker._get( inst, "stepBigMonths" ) :
10198							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10199						break; // next month/year on page down/+ ctrl
10200				case 35: if ( event.ctrlKey || event.metaKey ) {
10201							$.datepicker._clearDate( event.target );
10202						}
10203						handled = event.ctrlKey || event.metaKey;
10204						break; // clear on ctrl or command +end
10205				case 36: if ( event.ctrlKey || event.metaKey ) {
10206							$.datepicker._gotoToday( event.target );
10207						}
10208						handled = event.ctrlKey || event.metaKey;
10209						break; // current on ctrl or command +home
10210				case 37: if ( event.ctrlKey || event.metaKey ) {
10211							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
10212						}
10213						handled = event.ctrlKey || event.metaKey;
10214
10215						// -1 day on ctrl or command +left
10216						if ( event.originalEvent.altKey ) {
10217							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10218								-$.datepicker._get( inst, "stepBigMonths" ) :
10219								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10220						}
10221
10222						// next month/year on alt +left on Mac
10223						break;
10224				case 38: if ( event.ctrlKey || event.metaKey ) {
10225							$.datepicker._adjustDate( event.target, -7, "D" );
10226						}
10227						handled = event.ctrlKey || event.metaKey;
10228						break; // -1 week on ctrl or command +up
10229				case 39: if ( event.ctrlKey || event.metaKey ) {
10230							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
10231						}
10232						handled = event.ctrlKey || event.metaKey;
10233
10234						// +1 day on ctrl or command +right
10235						if ( event.originalEvent.altKey ) {
10236							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10237								+$.datepicker._get( inst, "stepBigMonths" ) :
10238								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10239						}
10240
10241						// next month/year on alt +right
10242						break;
10243				case 40: if ( event.ctrlKey || event.metaKey ) {
10244							$.datepicker._adjustDate( event.target, +7, "D" );
10245						}
10246						handled = event.ctrlKey || event.metaKey;
10247						break; // +1 week on ctrl or command +down
10248				default: handled = false;
10249			}
10250		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
10251			$.datepicker._showDatepicker( this );
10252		} else {
10253			handled = false;
10254		}
10255
10256		if ( handled ) {
10257			event.preventDefault();
10258			event.stopPropagation();
10259		}
10260	},
10261
10262	/* Filter entered characters - based on date format. */
10263	_doKeyPress: function( event ) {
10264		var chars, chr,
10265			inst = $.datepicker._getInst( event.target );
10266
10267		if ( $.datepicker._get( inst, "constrainInput" ) ) {
10268			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
10269			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
10270			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
10271		}
10272	},
10273
10274	/* Synchronise manual entry and field/alternate field. */
10275	_doKeyUp: function( event ) {
10276		var date,
10277			inst = $.datepicker._getInst( event.target );
10278
10279		if ( inst.input.val() !== inst.lastVal ) {
10280			try {
10281				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
10282					( inst.input ? inst.input.val() : null ),
10283					$.datepicker._getFormatConfig( inst ) );
10284
10285				if ( date ) { // only if valid
10286					$.datepicker._setDateFromField( inst );
10287					$.datepicker._updateAlternate( inst );
10288					$.datepicker._updateDatepicker( inst );
10289				}
10290			}
10291			catch ( err ) {
10292			}
10293		}
10294		return true;
10295	},
10296
10297	/* Pop-up the date picker for a given input field.
10298	 * If false returned from beforeShow event handler do not show.
10299	 * @param  input  element - the input field attached to the date picker or
10300	 *					event - if triggered by focus
10301	 */
10302	_showDatepicker: function( input ) {
10303		input = input.target || input;
10304		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
10305			input = $( "input", input.parentNode )[ 0 ];
10306		}
10307
10308		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
10309			return;
10310		}
10311
10312		var inst, beforeShow, beforeShowSettings, isFixed,
10313			offset, showAnim, duration;
10314
10315		inst = $.datepicker._getInst( input );
10316		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
10317			$.datepicker._curInst.dpDiv.stop( true, true );
10318			if ( inst && $.datepicker._datepickerShowing ) {
10319				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
10320			}
10321		}
10322
10323		beforeShow = $.datepicker._get( inst, "beforeShow" );
10324		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
10325		if ( beforeShowSettings === false ) {
10326			return;
10327		}
10328		datepicker_extendRemove( inst.settings, beforeShowSettings );
10329
10330		inst.lastVal = null;
10331		$.datepicker._lastInput = input;
10332		$.datepicker._setDateFromField( inst );
10333
10334		if ( $.datepicker._inDialog ) { // hide cursor
10335			input.value = "";
10336		}
10337		if ( !$.datepicker._pos ) { // position below input
10338			$.datepicker._pos = $.datepicker._findPos( input );
10339			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
10340		}
10341
10342		isFixed = false;
10343		$( input ).parents().each( function() {
10344			isFixed |= $( this ).css( "position" ) === "fixed";
10345			return !isFixed;
10346		} );
10347
10348		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
10349		$.datepicker._pos = null;
10350
10351		//to avoid flashes on Firefox
10352		inst.dpDiv.empty();
10353
10354		// determine sizing offscreen
10355		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
10356		$.datepicker._updateDatepicker( inst );
10357
10358		// fix width for dynamic number of date pickers
10359		// and adjust position before showing
10360		offset = $.datepicker._checkOffset( inst, offset, isFixed );
10361		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
10362			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
10363			left: offset.left + "px", top: offset.top + "px" } );
10364
10365		if ( !inst.inline ) {
10366			showAnim = $.datepicker._get( inst, "showAnim" );
10367			duration = $.datepicker._get( inst, "duration" );
10368			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
10369			$.datepicker._datepickerShowing = true;
10370
10371			if ( $.effects && $.effects.effect[ showAnim ] ) {
10372				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
10373			} else {
10374				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
10375			}
10376
10377			if ( $.datepicker._shouldFocusInput( inst ) ) {
10378				inst.input.trigger( "focus" );
10379			}
10380
10381			$.datepicker._curInst = inst;
10382		}
10383	},
10384
10385	/* Generate the date picker content. */
10386	_updateDatepicker: function( inst ) {
10387		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
10388		datepicker_instActive = inst; // for delegate hover events
10389		inst.dpDiv.empty().append( this._generateHTML( inst ) );
10390		this._attachHandlers( inst );
10391
10392		var origyearshtml,
10393			numMonths = this._getNumberOfMonths( inst ),
10394			cols = numMonths[ 1 ],
10395			width = 17,
10396			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
10397
10398		if ( activeCell.length > 0 ) {
10399			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
10400		}
10401
10402		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
10403		if ( cols > 1 ) {
10404			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
10405		}
10406		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
10407			"Class" ]( "ui-datepicker-multi" );
10408		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
10409			"Class" ]( "ui-datepicker-rtl" );
10410
10411		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
10412			inst.input.trigger( "focus" );
10413		}
10414
10415		// Deffered render of the years select (to avoid flashes on Firefox)
10416		if ( inst.yearshtml ) {
10417			origyearshtml = inst.yearshtml;
10418			setTimeout( function() {
10419
10420				//assure that inst.yearshtml didn't change.
10421				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
10422					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
10423				}
10424				origyearshtml = inst.yearshtml = null;
10425			}, 0 );
10426		}
10427	},
10428
10429	// #6694 - don't focus the input if it's already focused
10430	// this breaks the change event in IE
10431	// Support: IE and jQuery <1.9
10432	_shouldFocusInput: function( inst ) {
10433		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
10434	},
10435
10436	/* Check positioning to remain on screen. */
10437	_checkOffset: function( inst, offset, isFixed ) {
10438		var dpWidth = inst.dpDiv.outerWidth(),
10439			dpHeight = inst.dpDiv.outerHeight(),
10440			inputWidth = inst.input ? inst.input.outerWidth() : 0,
10441			inputHeight = inst.input ? inst.input.outerHeight() : 0,
10442			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
10443			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
10444
10445		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
10446		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
10447		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
10448
10449		// Now check if datepicker is showing outside window viewport - move to a better place if so.
10450		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
10451			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
10452		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
10453			Math.abs( dpHeight + inputHeight ) : 0 );
10454
10455		return offset;
10456	},
10457
10458	/* Find an object's position on the screen. */
10459	_findPos: function( obj ) {
10460		var position,
10461			inst = this._getInst( obj ),
10462			isRTL = this._get( inst, "isRTL" );
10463
10464		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
10465			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
10466		}
10467
10468		position = $( obj ).offset();
10469		return [ position.left, position.top ];
10470	},
10471
10472	/* Hide the date picker from view.
10473	 * @param  input  element - the input field attached to the date picker
10474	 */
10475	_hideDatepicker: function( input ) {
10476		var showAnim, duration, postProcess, onClose,
10477			inst = this._curInst;
10478
10479		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
10480			return;
10481		}
10482
10483		if ( this._datepickerShowing ) {
10484			showAnim = this._get( inst, "showAnim" );
10485			duration = this._get( inst, "duration" );
10486			postProcess = function() {
10487				$.datepicker._tidyDialog( inst );
10488			};
10489
10490			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
10491			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
10492				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
10493			} else {
10494				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
10495					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
10496			}
10497
10498			if ( !showAnim ) {
10499				postProcess();
10500			}
10501			this._datepickerShowing = false;
10502
10503			onClose = this._get( inst, "onClose" );
10504			if ( onClose ) {
10505				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
10506			}
10507
10508			this._lastInput = null;
10509			if ( this._inDialog ) {
10510				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
10511				if ( $.blockUI ) {
10512					$.unblockUI();
10513					$( "body" ).append( this.dpDiv );
10514				}
10515			}
10516			this._inDialog = false;
10517		}
10518	},
10519
10520	/* Tidy up after a dialog display. */
10521	_tidyDialog: function( inst ) {
10522		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
10523	},
10524
10525	/* Close date picker if clicked elsewhere. */
10526	_checkExternalClick: function( event ) {
10527		if ( !$.datepicker._curInst ) {
10528			return;
10529		}
10530
10531		var $target = $( event.target ),
10532			inst = $.datepicker._getInst( $target[ 0 ] );
10533
10534		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
10535				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
10536				!$target.hasClass( $.datepicker.markerClassName ) &&
10537				!$target.closest( "." + $.datepicker._triggerClass ).length &&
10538				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
10539			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
10540				$.datepicker._hideDatepicker();
10541		}
10542	},
10543
10544	/* Adjust one of the date sub-fields. */
10545	_adjustDate: function( id, offset, period ) {
10546		var target = $( id ),
10547			inst = this._getInst( target[ 0 ] );
10548
10549		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
10550			return;
10551		}
10552		this._adjustInstDate( inst, offset +
10553			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
10554			period );
10555		this._updateDatepicker( inst );
10556	},
10557
10558	/* Action for current link. */
10559	_gotoToday: function( id ) {
10560		var date,
10561			target = $( id ),
10562			inst = this._getInst( target[ 0 ] );
10563
10564		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
10565			inst.selectedDay = inst.currentDay;
10566			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
10567			inst.drawYear = inst.selectedYear = inst.currentYear;
10568		} else {
10569			date = new Date();
10570			inst.selectedDay = date.getDate();
10571			inst.drawMonth = inst.selectedMonth = date.getMonth();
10572			inst.drawYear = inst.selectedYear = date.getFullYear();
10573		}
10574		this._notifyChange( inst );
10575		this._adjustDate( target );
10576	},
10577
10578	/* Action for selecting a new month/year. */
10579	_selectMonthYear: function( id, select, period ) {
10580		var target = $( id ),
10581			inst = this._getInst( target[ 0 ] );
10582
10583		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
10584		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
10585			parseInt( select.options[ select.selectedIndex ].value, 10 );
10586
10587		this._notifyChange( inst );
10588		this._adjustDate( target );
10589	},
10590
10591	/* Action for selecting a day. */
10592	_selectDay: function( id, month, year, td ) {
10593		var inst,
10594			target = $( id );
10595
10596		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
10597			return;
10598		}
10599
10600		inst = this._getInst( target[ 0 ] );
10601		inst.selectedDay = inst.currentDay = $( "a", td ).html();
10602		inst.selectedMonth = inst.currentMonth = month;
10603		inst.selectedYear = inst.currentYear = year;
10604		this._selectDate( id, this._formatDate( inst,
10605			inst.currentDay, inst.currentMonth, inst.currentYear ) );
10606	},
10607
10608	/* Erase the input field and hide the date picker. */
10609	_clearDate: function( id ) {
10610		var target = $( id );
10611		this._selectDate( target, "" );
10612	},
10613
10614	/* Update the input field with the selected date. */
10615	_selectDate: function( id, dateStr ) {
10616		var onSelect,
10617			target = $( id ),
10618			inst = this._getInst( target[ 0 ] );
10619
10620		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
10621		if ( inst.input ) {
10622			inst.input.val( dateStr );
10623		}
10624		this._updateAlternate( inst );
10625
10626		onSelect = this._get( inst, "onSelect" );
10627		if ( onSelect ) {
10628			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
10629		} else if ( inst.input ) {
10630			inst.input.trigger( "change" ); // fire the change event
10631		}
10632
10633		if ( inst.inline ) {
10634			this._updateDatepicker( inst );
10635		} else {
10636			this._hideDatepicker();
10637			this._lastInput = inst.input[ 0 ];
10638			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
10639				inst.input.trigger( "focus" ); // restore focus
10640			}
10641			this._lastInput = null;
10642		}
10643	},
10644
10645	/* Update any alternate field to synchronise with the main field. */
10646	_updateAlternate: function( inst ) {
10647		var altFormat, date, dateStr,
10648			altField = this._get( inst, "altField" );
10649
10650		if ( altField ) { // update alternate field too
10651			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
10652			date = this._getDate( inst );
10653			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
10654			$( altField ).val( dateStr );
10655		}
10656	},
10657
10658	/* Set as beforeShowDay function to prevent selection of weekends.
10659	 * @param  date  Date - the date to customise
10660	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
10661	 */
10662	noWeekends: function( date ) {
10663		var day = date.getDay();
10664		return [ ( day > 0 && day < 6 ), "" ];
10665	},
10666
10667	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
10668	 * @param  date  Date - the date to get the week for
10669	 * @return  number - the number of the week within the year that contains this date
10670	 */
10671	iso8601Week: function( date ) {
10672		var time,
10673			checkDate = new Date( date.getTime() );
10674
10675		// Find Thursday of this week starting on Monday
10676		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
10677
10678		time = checkDate.getTime();
10679		checkDate.setMonth( 0 ); // Compare with Jan 1
10680		checkDate.setDate( 1 );
10681		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
10682	},
10683
10684	/* Parse a string value into a date object.
10685	 * See formatDate below for the possible formats.
10686	 *
10687	 * @param  format string - the expected format of the date
10688	 * @param  value string - the date in the above format
10689	 * @param  settings Object - attributes include:
10690	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
10691	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
10692	 *					dayNames		string[7] - names of the days from Sunday (optional)
10693	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
10694	 *					monthNames		string[12] - names of the months (optional)
10695	 * @return  Date - the extracted date value or null if value is blank
10696	 */
10697	parseDate: function( format, value, settings ) {
10698		if ( format == null || value == null ) {
10699			throw "Invalid arguments";
10700		}
10701
10702		value = ( typeof value === "object" ? value.toString() : value + "" );
10703		if ( value === "" ) {
10704			return null;
10705		}
10706
10707		var iFormat, dim, extra,
10708			iValue = 0,
10709			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
10710			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
10711				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
10712			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
10713			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
10714			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
10715			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
10716			year = -1,
10717			month = -1,
10718			day = -1,
10719			doy = -1,
10720			literal = false,
10721			date,
10722
10723			// Check whether a format character is doubled
10724			lookAhead = function( match ) {
10725				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10726				if ( matches ) {
10727					iFormat++;
10728				}
10729				return matches;
10730			},
10731
10732			// Extract a number from the string value
10733			getNumber = function( match ) {
10734				var isDoubled = lookAhead( match ),
10735					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
10736					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
10737					minSize = ( match === "y" ? size : 1 ),
10738					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
10739					num = value.substring( iValue ).match( digits );
10740				if ( !num ) {
10741					throw "Missing number at position " + iValue;
10742				}
10743				iValue += num[ 0 ].length;
10744				return parseInt( num[ 0 ], 10 );
10745			},
10746
10747			// Extract a name from the string value and convert to an index
10748			getName = function( match, shortNames, longNames ) {
10749				var index = -1,
10750					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
10751						return [ [ k, v ] ];
10752					} ).sort( function( a, b ) {
10753						return -( a[ 1 ].length - b[ 1 ].length );
10754					} );
10755
10756				$.each( names, function( i, pair ) {
10757					var name = pair[ 1 ];
10758					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
10759						index = pair[ 0 ];
10760						iValue += name.length;
10761						return false;
10762					}
10763				} );
10764				if ( index !== -1 ) {
10765					return index + 1;
10766				} else {
10767					throw "Unknown name at position " + iValue;
10768				}
10769			},
10770
10771			// Confirm that a literal character matches the string value
10772			checkLiteral = function() {
10773				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
10774					throw "Unexpected literal at position " + iValue;
10775				}
10776				iValue++;
10777			};
10778
10779		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
10780			if ( literal ) {
10781				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
10782					literal = false;
10783				} else {
10784					checkLiteral();
10785				}
10786			} else {
10787				switch ( format.charAt( iFormat ) ) {
10788					case "d":
10789						day = getNumber( "d" );
10790						break;
10791					case "D":
10792						getName( "D", dayNamesShort, dayNames );
10793						break;
10794					case "o":
10795						doy = getNumber( "o" );
10796						break;
10797					case "m":
10798						month = getNumber( "m" );
10799						break;
10800					case "M":
10801						month = getName( "M", monthNamesShort, monthNames );
10802						break;
10803					case "y":
10804						year = getNumber( "y" );
10805						break;
10806					case "@":
10807						date = new Date( getNumber( "@" ) );
10808						year = date.getFullYear();
10809						month = date.getMonth() + 1;
10810						day = date.getDate();
10811						break;
10812					case "!":
10813						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
10814						year = date.getFullYear();
10815						month = date.getMonth() + 1;
10816						day = date.getDate();
10817						break;
10818					case "'":
10819						if ( lookAhead( "'" ) ) {
10820							checkLiteral();
10821						} else {
10822							literal = true;
10823						}
10824						break;
10825					default:
10826						checkLiteral();
10827				}
10828			}
10829		}
10830
10831		if ( iValue < value.length ) {
10832			extra = value.substr( iValue );
10833			if ( !/^\s+/.test( extra ) ) {
10834				throw "Extra/unparsed characters found in date: " + extra;
10835			}
10836		}
10837
10838		if ( year === -1 ) {
10839			year = new Date().getFullYear();
10840		} else if ( year < 100 ) {
10841			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
10842				( year <= shortYearCutoff ? 0 : -100 );
10843		}
10844
10845		if ( doy > -1 ) {
10846			month = 1;
10847			day = doy;
10848			do {
10849				dim = this._getDaysInMonth( year, month - 1 );
10850				if ( day <= dim ) {
10851					break;
10852				}
10853				month++;
10854				day -= dim;
10855			} while ( true );
10856		}
10857
10858		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
10859		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
10860			throw "Invalid date"; // E.g. 31/02/00
10861		}
10862		return date;
10863	},
10864
10865	/* Standard date formats. */
10866	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
10867	COOKIE: "D, dd M yy",
10868	ISO_8601: "yy-mm-dd",
10869	RFC_822: "D, d M y",
10870	RFC_850: "DD, dd-M-y",
10871	RFC_1036: "D, d M y",
10872	RFC_1123: "D, d M yy",
10873	RFC_2822: "D, d M yy",
10874	RSS: "D, d M y", // RFC 822
10875	TICKS: "!",
10876	TIMESTAMP: "@",
10877	W3C: "yy-mm-dd", // ISO 8601
10878
10879	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
10880		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
10881
10882	/* Format a date object into a string value.
10883	 * The format can be combinations of the following:
10884	 * d  - day of month (no leading zero)
10885	 * dd - day of month (two digit)
10886	 * o  - day of year (no leading zeros)
10887	 * oo - day of year (three digit)
10888	 * D  - day name short
10889	 * DD - day name long
10890	 * m  - month of year (no leading zero)
10891	 * mm - month of year (two digit)
10892	 * M  - month name short
10893	 * MM - month name long
10894	 * y  - year (two digit)
10895	 * yy - year (four digit)
10896	 * @ - Unix timestamp (ms since 01/01/1970)
10897	 * ! - Windows ticks (100ns since 01/01/0001)
10898	 * "..." - literal text
10899	 * '' - single quote
10900	 *
10901	 * @param  format string - the desired format of the date
10902	 * @param  date Date - the date value to format
10903	 * @param  settings Object - attributes include:
10904	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
10905	 *					dayNames		string[7] - names of the days from Sunday (optional)
10906	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
10907	 *					monthNames		string[12] - names of the months (optional)
10908	 * @return  string - the date in the above format
10909	 */
10910	formatDate: function( format, date, settings ) {
10911		if ( !date ) {
10912			return "";
10913		}
10914
10915		var iFormat,
10916			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
10917			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
10918			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
10919			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
10920
10921			// Check whether a format character is doubled
10922			lookAhead = function( match ) {
10923				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10924				if ( matches ) {
10925					iFormat++;
10926				}
10927				return matches;
10928			},
10929
10930			// Format a number, with leading zero if necessary
10931			formatNumber = function( match, value, len ) {
10932				var num = "" + value;
10933				if ( lookAhead( match ) ) {
10934					while ( num.length < len ) {
10935						num = "0" + num;
10936					}
10937				}
10938				return num;
10939			},
10940
10941			// Format a name, short or long as requested
10942			formatName = function( match, value, shortNames, longNames ) {
10943				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
10944			},
10945			output = "",
10946			literal = false;
10947
10948		if ( date ) {
10949			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
10950				if ( literal ) {
10951					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
10952						literal = false;
10953					} else {
10954						output += format.charAt( iFormat );
10955					}
10956				} else {
10957					switch ( format.charAt( iFormat ) ) {
10958						case "d":
10959							output += formatNumber( "d", date.getDate(), 2 );
10960							break;
10961						case "D":
10962							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
10963							break;
10964						case "o":
10965							output += formatNumber( "o",
10966								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
10967							break;
10968						case "m":
10969							output += formatNumber( "m", date.getMonth() + 1, 2 );
10970							break;
10971						case "M":
10972							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
10973							break;
10974						case "y":
10975							output += ( lookAhead( "y" ) ? date.getFullYear() :
10976								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
10977							break;
10978						case "@":
10979							output += date.getTime();
10980							break;
10981						case "!":
10982							output += date.getTime() * 10000 + this._ticksTo1970;
10983							break;
10984						case "'":
10985							if ( lookAhead( "'" ) ) {
10986								output += "'";
10987							} else {
10988								literal = true;
10989							}
10990							break;
10991						default:
10992							output += format.charAt( iFormat );
10993					}
10994				}
10995			}
10996		}
10997		return output;
10998	},
10999
11000	/* Extract all possible characters from the date format. */
11001	_possibleChars: function( format ) {
11002		var iFormat,
11003			chars = "",
11004			literal = false,
11005
11006			// Check whether a format character is doubled
11007			lookAhead = function( match ) {
11008				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
11009				if ( matches ) {
11010					iFormat++;
11011				}
11012				return matches;
11013			};
11014
11015		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
11016			if ( literal ) {
11017				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
11018					literal = false;
11019				} else {
11020					chars += format.charAt( iFormat );
11021				}
11022			} else {
11023				switch ( format.charAt( iFormat ) ) {
11024					case "d": case "m": case "y": case "@":
11025						chars += "0123456789";
11026						break;
11027					case "D": case "M":
11028						return null; // Accept anything
11029					case "'":
11030						if ( lookAhead( "'" ) ) {
11031							chars += "'";
11032						} else {
11033							literal = true;
11034						}
11035						break;
11036					default:
11037						chars += format.charAt( iFormat );
11038				}
11039			}
11040		}
11041		return chars;
11042	},
11043
11044	/* Get a setting value, defaulting if necessary. */
11045	_get: function( inst, name ) {
11046		return inst.settings[ name ] !== undefined ?
11047			inst.settings[ name ] : this._defaults[ name ];
11048	},
11049
11050	/* Parse existing date and initialise date picker. */
11051	_setDateFromField: function( inst, noDefault ) {
11052		if ( inst.input.val() === inst.lastVal ) {
11053			return;
11054		}
11055
11056		var dateFormat = this._get( inst, "dateFormat" ),
11057			dates = inst.lastVal = inst.input ? inst.input.val() : null,
11058			defaultDate = this._getDefaultDate( inst ),
11059			date = defaultDate,
11060			settings = this._getFormatConfig( inst );
11061
11062		try {
11063			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
11064		} catch ( event ) {
11065			dates = ( noDefault ? "" : dates );
11066		}
11067		inst.selectedDay = date.getDate();
11068		inst.drawMonth = inst.selectedMonth = date.getMonth();
11069		inst.drawYear = inst.selectedYear = date.getFullYear();
11070		inst.currentDay = ( dates ? date.getDate() : 0 );
11071		inst.currentMonth = ( dates ? date.getMonth() : 0 );
11072		inst.currentYear = ( dates ? date.getFullYear() : 0 );
11073		this._adjustInstDate( inst );
11074	},
11075
11076	/* Retrieve the default date shown on opening. */
11077	_getDefaultDate: function( inst ) {
11078		return this._restrictMinMax( inst,
11079			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
11080	},
11081
11082	/* A date may be specified as an exact value or a relative one. */
11083	_determineDate: function( inst, date, defaultDate ) {
11084		var offsetNumeric = function( offset ) {
11085				var date = new Date();
11086				date.setDate( date.getDate() + offset );
11087				return date;
11088			},
11089			offsetString = function( offset ) {
11090				try {
11091					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
11092						offset, $.datepicker._getFormatConfig( inst ) );
11093				}
11094				catch ( e ) {
11095
11096					// Ignore
11097				}
11098
11099				var date = ( offset.toLowerCase().match( /^c/ ) ?
11100					$.datepicker._getDate( inst ) : null ) || new Date(),
11101					year = date.getFullYear(),
11102					month = date.getMonth(),
11103					day = date.getDate(),
11104					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
11105					matches = pattern.exec( offset );
11106
11107				while ( matches ) {
11108					switch ( matches[ 2 ] || "d" ) {
11109						case "d" : case "D" :
11110							day += parseInt( matches[ 1 ], 10 ); break;
11111						case "w" : case "W" :
11112							day += parseInt( matches[ 1 ], 10 ) * 7; break;
11113						case "m" : case "M" :
11114							month += parseInt( matches[ 1 ], 10 );
11115							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11116							break;
11117						case "y": case "Y" :
11118							year += parseInt( matches[ 1 ], 10 );
11119							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11120							break;
11121					}
11122					matches = pattern.exec( offset );
11123				}
11124				return new Date( year, month, day );
11125			},
11126			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
11127				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
11128
11129		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
11130		if ( newDate ) {
11131			newDate.setHours( 0 );
11132			newDate.setMinutes( 0 );
11133			newDate.setSeconds( 0 );
11134			newDate.setMilliseconds( 0 );
11135		}
11136		return this._daylightSavingAdjust( newDate );
11137	},
11138
11139	/* Handle switch to/from daylight saving.
11140	 * Hours may be non-zero on daylight saving cut-over:
11141	 * > 12 when midnight changeover, but then cannot generate
11142	 * midnight datetime, so jump to 1AM, otherwise reset.
11143	 * @param  date  (Date) the date to check
11144	 * @return  (Date) the corrected date
11145	 */
11146	_daylightSavingAdjust: function( date ) {
11147		if ( !date ) {
11148			return null;
11149		}
11150		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
11151		return date;
11152	},
11153
11154	/* Set the date(s) directly. */
11155	_setDate: function( inst, date, noChange ) {
11156		var clear = !date,
11157			origMonth = inst.selectedMonth,
11158			origYear = inst.selectedYear,
11159			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
11160
11161		inst.selectedDay = inst.currentDay = newDate.getDate();
11162		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
11163		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
11164		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
11165			this._notifyChange( inst );
11166		}
11167		this._adjustInstDate( inst );
11168		if ( inst.input ) {
11169			inst.input.val( clear ? "" : this._formatDate( inst ) );
11170		}
11171	},
11172
11173	/* Retrieve the date(s) directly. */
11174	_getDate: function( inst ) {
11175		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
11176			this._daylightSavingAdjust( new Date(
11177			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11178			return startDate;
11179	},
11180
11181	/* Attach the onxxx handlers.  These are declared statically so
11182	 * they work with static code transformers like Caja.
11183	 */
11184	_attachHandlers: function( inst ) {
11185		var stepMonths = this._get( inst, "stepMonths" ),
11186			id = "#" + inst.id.replace( /\\\\/g, "\\" );
11187		inst.dpDiv.find( "[data-handler]" ).map( function() {
11188			var handler = {
11189				prev: function() {
11190					$.datepicker._adjustDate( id, -stepMonths, "M" );
11191				},
11192				next: function() {
11193					$.datepicker._adjustDate( id, +stepMonths, "M" );
11194				},
11195				hide: function() {
11196					$.datepicker._hideDatepicker();
11197				},
11198				today: function() {
11199					$.datepicker._gotoToday( id );
11200				},
11201				selectDay: function() {
11202					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
11203					return false;
11204				},
11205				selectMonth: function() {
11206					$.datepicker._selectMonthYear( id, this, "M" );
11207					return false;
11208				},
11209				selectYear: function() {
11210					$.datepicker._selectMonthYear( id, this, "Y" );
11211					return false;
11212				}
11213			};
11214			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
11215		} );
11216	},
11217
11218	/* Generate the HTML for the current state of the date picker. */
11219	_generateHTML: function( inst ) {
11220		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
11221			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
11222			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
11223			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
11224			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
11225			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
11226			tempDate = new Date(),
11227			today = this._daylightSavingAdjust(
11228				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
11229			isRTL = this._get( inst, "isRTL" ),
11230			showButtonPanel = this._get( inst, "showButtonPanel" ),
11231			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
11232			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
11233			numMonths = this._getNumberOfMonths( inst ),
11234			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
11235			stepMonths = this._get( inst, "stepMonths" ),
11236			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
11237			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
11238				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
11239			minDate = this._getMinMaxDate( inst, "min" ),
11240			maxDate = this._getMinMaxDate( inst, "max" ),
11241			drawMonth = inst.drawMonth - showCurrentAtPos,
11242			drawYear = inst.drawYear;
11243
11244		if ( drawMonth < 0 ) {
11245			drawMonth += 12;
11246			drawYear--;
11247		}
11248		if ( maxDate ) {
11249			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
11250				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
11251			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
11252			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
11253				drawMonth--;
11254				if ( drawMonth < 0 ) {
11255					drawMonth = 11;
11256					drawYear--;
11257				}
11258			}
11259		}
11260		inst.drawMonth = drawMonth;
11261		inst.drawYear = drawYear;
11262
11263		prevText = this._get( inst, "prevText" );
11264		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
11265			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
11266			this._getFormatConfig( inst ) ) );
11267
11268		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
11269			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
11270			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
11271			( 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>" ) );
11272
11273		nextText = this._get( inst, "nextText" );
11274		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
11275			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
11276			this._getFormatConfig( inst ) ) );
11277
11278		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
11279			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
11280			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
11281			( 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>" ) );
11282
11283		currentText = this._get( inst, "currentText" );
11284		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
11285		currentText = ( !navigationAsDateFormat ? currentText :
11286			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
11287
11288		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'>" +
11289			this._get( inst, "closeText" ) + "</button>" : "" );
11290
11291		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
11292			( 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'" +
11293			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
11294
11295		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
11296		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
11297
11298		showWeek = this._get( inst, "showWeek" );
11299		dayNames = this._get( inst, "dayNames" );
11300		dayNamesMin = this._get( inst, "dayNamesMin" );
11301		monthNames = this._get( inst, "monthNames" );
11302		monthNamesShort = this._get( inst, "monthNamesShort" );
11303		beforeShowDay = this._get( inst, "beforeShowDay" );
11304		showOtherMonths = this._get( inst, "showOtherMonths" );
11305		selectOtherMonths = this._get( inst, "selectOtherMonths" );
11306		defaultDate = this._getDefaultDate( inst );
11307		html = "";
11308
11309		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
11310			group = "";
11311			this.maxRows = 4;
11312			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
11313				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
11314				cornerClass = " ui-corner-all";
11315				calender = "";
11316				if ( isMultiMonth ) {
11317					calender += "<div class='ui-datepicker-group";
11318					if ( numMonths[ 1 ] > 1 ) {
11319						switch ( col ) {
11320							case 0: calender += " ui-datepicker-group-first";
11321								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
11322							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
11323								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
11324							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
11325						}
11326					}
11327					calender += "'>";
11328				}
11329				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
11330					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
11331					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
11332					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
11333					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
11334					"</div><table class='ui-datepicker-calendar'><thead>" +
11335					"<tr>";
11336				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
11337				for ( dow = 0; dow < 7; dow++ ) { // days of the week
11338					day = ( dow + firstDay ) % 7;
11339					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
11340						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
11341				}
11342				calender += thead + "</tr></thead><tbody>";
11343				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
11344				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
11345					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
11346				}
11347				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
11348				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
11349				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
11350				this.maxRows = numRows;
11351				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
11352				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
11353					calender += "<tr>";
11354					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
11355						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
11356					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
11357						daySettings = ( beforeShowDay ?
11358							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
11359						otherMonth = ( printDate.getMonth() !== drawMonth );
11360						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
11361							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
11362						tbody += "<td class='" +
11363							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
11364							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
11365							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
11366							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
11367
11368							// or defaultDate is current printedDate and defaultDate is selectedDate
11369							" " + this._dayOverClass : "" ) + // highlight selected day
11370							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
11371							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
11372							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
11373							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
11374							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
11375							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
11376							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
11377							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
11378							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
11379							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
11380							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
11381							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
11382						printDate.setDate( printDate.getDate() + 1 );
11383						printDate = this._daylightSavingAdjust( printDate );
11384					}
11385					calender += tbody + "</tr>";
11386				}
11387				drawMonth++;
11388				if ( drawMonth > 11 ) {
11389					drawMonth = 0;
11390					drawYear++;
11391				}
11392				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
11393							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
11394				group += calender;
11395			}
11396			html += group;
11397		}
11398		html += buttonPanel;
11399		inst._keyEvent = false;
11400		return html;
11401	},
11402
11403	/* Generate the month and year header. */
11404	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
11405			secondary, monthNames, monthNamesShort ) {
11406
11407		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
11408			changeMonth = this._get( inst, "changeMonth" ),
11409			changeYear = this._get( inst, "changeYear" ),
11410			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
11411			html = "<div class='ui-datepicker-title'>",
11412			monthHtml = "";
11413
11414		// Month selection
11415		if ( secondary || !changeMonth ) {
11416			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
11417		} else {
11418			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
11419			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
11420			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
11421			for ( month = 0; month < 12; month++ ) {
11422				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
11423					monthHtml += "<option value='" + month + "'" +
11424						( month === drawMonth ? " selected='selected'" : "" ) +
11425						">" + monthNamesShort[ month ] + "</option>";
11426				}
11427			}
11428			monthHtml += "</select>";
11429		}
11430
11431		if ( !showMonthAfterYear ) {
11432			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
11433		}
11434
11435		// Year selection
11436		if ( !inst.yearshtml ) {
11437			inst.yearshtml = "";
11438			if ( secondary || !changeYear ) {
11439				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
11440			} else {
11441
11442				// determine range of years to display
11443				years = this._get( inst, "yearRange" ).split( ":" );
11444				thisYear = new Date().getFullYear();
11445				determineYear = function( value ) {
11446					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
11447						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
11448						parseInt( value, 10 ) ) );
11449					return ( isNaN( year ) ? thisYear : year );
11450				};
11451				year = determineYear( years[ 0 ] );
11452				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
11453				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
11454				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
11455				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
11456				for ( ; year <= endYear; year++ ) {
11457					inst.yearshtml += "<option value='" + year + "'" +
11458						( year === drawYear ? " selected='selected'" : "" ) +
11459						">" + year + "</option>";
11460				}
11461				inst.yearshtml += "</select>";
11462
11463				html += inst.yearshtml;
11464				inst.yearshtml = null;
11465			}
11466		}
11467
11468		html += this._get( inst, "yearSuffix" );
11469		if ( showMonthAfterYear ) {
11470			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
11471		}
11472		html += "</div>"; // Close datepicker_header
11473		return html;
11474	},
11475
11476	/* Adjust one of the date sub-fields. */
11477	_adjustInstDate: function( inst, offset, period ) {
11478		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
11479			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
11480			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
11481			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
11482
11483		inst.selectedDay = date.getDate();
11484		inst.drawMonth = inst.selectedMonth = date.getMonth();
11485		inst.drawYear = inst.selectedYear = date.getFullYear();
11486		if ( period === "M" || period === "Y" ) {
11487			this._notifyChange( inst );
11488		}
11489	},
11490
11491	/* Ensure a date is within any min/max bounds. */
11492	_restrictMinMax: function( inst, date ) {
11493		var minDate = this._getMinMaxDate( inst, "min" ),
11494			maxDate = this._getMinMaxDate( inst, "max" ),
11495			newDate = ( minDate && date < minDate ? minDate : date );
11496		return ( maxDate && newDate > maxDate ? maxDate : newDate );
11497	},
11498
11499	/* Notify change of month/year. */
11500	_notifyChange: function( inst ) {
11501		var onChange = this._get( inst, "onChangeMonthYear" );
11502		if ( onChange ) {
11503			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
11504				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
11505		}
11506	},
11507
11508	/* Determine the number of months to show. */
11509	_getNumberOfMonths: function( inst ) {
11510		var numMonths = this._get( inst, "numberOfMonths" );
11511		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
11512	},
11513
11514	/* Determine the current maximum date - ensure no time components are set. */
11515	_getMinMaxDate: function( inst, minMax ) {
11516		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
11517	},
11518
11519	/* Find the number of days in a given month. */
11520	_getDaysInMonth: function( year, month ) {
11521		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
11522	},
11523
11524	/* Find the day of the week of the first of a month. */
11525	_getFirstDayOfMonth: function( year, month ) {
11526		return new Date( year, month, 1 ).getDay();
11527	},
11528
11529	/* Determines if we should allow a "next/prev" month display change. */
11530	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
11531		var numMonths = this._getNumberOfMonths( inst ),
11532			date = this._daylightSavingAdjust( new Date( curYear,
11533			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
11534
11535		if ( offset < 0 ) {
11536			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
11537		}
11538		return this._isInRange( inst, date );
11539	},
11540
11541	/* Is the given date in the accepted range? */
11542	_isInRange: function( inst, date ) {
11543		var yearSplit, currentYear,
11544			minDate = this._getMinMaxDate( inst, "min" ),
11545			maxDate = this._getMinMaxDate( inst, "max" ),
11546			minYear = null,
11547			maxYear = null,
11548			years = this._get( inst, "yearRange" );
11549			if ( years ) {
11550				yearSplit = years.split( ":" );
11551				currentYear = new Date().getFullYear();
11552				minYear = parseInt( yearSplit[ 0 ], 10 );
11553				maxYear = parseInt( yearSplit[ 1 ], 10 );
11554				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
11555					minYear += currentYear;
11556				}
11557				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
11558					maxYear += currentYear;
11559				}
11560			}
11561
11562		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
11563			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
11564			( !minYear || date.getFullYear() >= minYear ) &&
11565			( !maxYear || date.getFullYear() <= maxYear ) );
11566	},
11567
11568	/* Provide the configuration settings for formatting/parsing. */
11569	_getFormatConfig: function( inst ) {
11570		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
11571		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
11572			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
11573		return { shortYearCutoff: shortYearCutoff,
11574			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
11575			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
11576	},
11577
11578	/* Format the given date for display. */
11579	_formatDate: function( inst, day, month, year ) {
11580		if ( !day ) {
11581			inst.currentDay = inst.selectedDay;
11582			inst.currentMonth = inst.selectedMonth;
11583			inst.currentYear = inst.selectedYear;
11584		}
11585		var date = ( day ? ( typeof day === "object" ? day :
11586			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
11587			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11588		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
11589	}
11590} );
11591
11592/*
11593 * Bind hover events for datepicker elements.
11594 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
11595 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
11596 */
11597function datepicker_bindHover( dpDiv ) {
11598	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
11599	return dpDiv.on( "mouseout", selector, function() {
11600			$( this ).removeClass( "ui-state-hover" );
11601			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11602				$( this ).removeClass( "ui-datepicker-prev-hover" );
11603			}
11604			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11605				$( this ).removeClass( "ui-datepicker-next-hover" );
11606			}
11607		} )
11608		.on( "mouseover", selector, datepicker_handleMouseover );
11609}
11610
11611function datepicker_handleMouseover() {
11612	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
11613		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
11614		$( this ).addClass( "ui-state-hover" );
11615		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11616			$( this ).addClass( "ui-datepicker-prev-hover" );
11617		}
11618		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11619			$( this ).addClass( "ui-datepicker-next-hover" );
11620		}
11621	}
11622}
11623
11624/* jQuery extend now ignores nulls! */
11625function datepicker_extendRemove( target, props ) {
11626	$.extend( target, props );
11627	for ( var name in props ) {
11628		if ( props[ name ] == null ) {
11629			target[ name ] = props[ name ];
11630		}
11631	}
11632	return target;
11633}
11634
11635/* Invoke the datepicker functionality.
11636   @param  options  string - a command, optionally followed by additional parameters or
11637					Object - settings for attaching new datepicker functionality
11638   @return  jQuery object */
11639$.fn.datepicker = function( options ) {
11640
11641	/* Verify an empty collection wasn't passed - Fixes #6976 */
11642	if ( !this.length ) {
11643		return this;
11644	}
11645
11646	/* Initialise the date picker. */
11647	if ( !$.datepicker.initialized ) {
11648		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
11649		$.datepicker.initialized = true;
11650	}
11651
11652	/* Append datepicker main container to body if not exist. */
11653	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
11654		$( "body" ).append( $.datepicker.dpDiv );
11655	}
11656
11657	var otherArgs = Array.prototype.slice.call( arguments, 1 );
11658	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
11659		return $.datepicker[ "_" + options + "Datepicker" ].
11660			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11661	}
11662	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
11663		return $.datepicker[ "_" + options + "Datepicker" ].
11664			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11665	}
11666	return this.each( function() {
11667		typeof options === "string" ?
11668			$.datepicker[ "_" + options + "Datepicker" ].
11669				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
11670			$.datepicker._attachDatepicker( this, options );
11671	} );
11672};
11673
11674$.datepicker = new Datepicker(); // singleton instance
11675$.datepicker.initialized = false;
vendor: 36,125 bytes, lines 11676-13148
11676$.datepicker.uuid = new Date().getTime();
11677$.datepicker.version = "1.12.1";
11678
11679var widgetsDatepicker = $.datepicker;
11680
11681
11682/*!
11683 * jQuery UI Dialog 1.12.1
11684 * http://jqueryui.com
11685 *
11686 * Copyright jQuery Foundation and other contributors
11687 * Released under the MIT license.
11688 * http://jquery.org/license
11689 */
11690
11691//>>label: Dialog
11692//>>group: Widgets
11693//>>description: Displays customizable dialog windows.
11694//>>docs: http://api.jqueryui.com/dialog/
11695//>>demos: http://jqueryui.com/dialog/
11696//>>css.structure: ../../themes/base/core.css
11697//>>css.structure: ../../themes/base/dialog.css
11698//>>css.theme: ../../themes/base/theme.css
11699
11700
11701
11702$.widget( "ui.dialog", {
11703	version: "1.12.1",
11704	options: {
11705		appendTo: "body",
11706		autoOpen: true,
11707		buttons: [],
11708		classes: {
11709			"ui-dialog": "ui-corner-all",
11710			"ui-dialog-titlebar": "ui-corner-all"
11711		},
11712		closeOnEscape: true,
11713		closeText: "Close",
11714		draggable: true,
11715		hide: null,
11716		height: "auto",
11717		maxHeight: null,
11718		maxWidth: null,
11719		minHeight: 150,
11720		minWidth: 150,
11721		modal: false,
11722		position: {
11723			my: "center",
11724			at: "center",
11725			of: window,
11726			collision: "fit",
11727
11728			// Ensure the titlebar is always visible
11729			using: function( pos ) {
11730				var topOffset = $( this ).css( pos ).offset().top;
11731				if ( topOffset < 0 ) {
11732					$( this ).css( "top", pos.top - topOffset );
11733				}
11734			}
11735		},
11736		resizable: true,
11737		show: null,
11738		title: null,
11739		width: 300,
11740
11741		// Callbacks
11742		beforeClose: null,
11743		close: null,
11744		drag: null,
11745		dragStart: null,
11746		dragStop: null,
11747		focus: null,
11748		open: null,
11749		resize: null,
11750		resizeStart: null,
11751		resizeStop: null
11752	},
11753
11754	sizeRelatedOptions: {
11755		buttons: true,
11756		height: true,
11757		maxHeight: true,
11758		maxWidth: true,
11759		minHeight: true,
11760		minWidth: true,
11761		width: true
11762	},
11763
11764	resizableRelatedOptions: {
11765		maxHeight: true,
11766		maxWidth: true,
11767		minHeight: true,
11768		minWidth: true
11769	},
11770
11771	_create: function() {
11772		this.originalCss = {
11773			display: this.element[ 0 ].style.display,
11774			width: this.element[ 0 ].style.width,
11775			minHeight: this.element[ 0 ].style.minHeight,
11776			maxHeight: this.element[ 0 ].style.maxHeight,
11777			height: this.element[ 0 ].style.height
11778		};
11779		this.originalPosition = {
11780			parent: this.element.parent(),
11781			index: this.element.parent().children().index( this.element )
11782		};
11783		this.originalTitle = this.element.attr( "title" );
11784		if ( this.options.title == null && this.originalTitle != null ) {
11785			this.options.title = this.originalTitle;
11786		}
11787
11788		// Dialogs can't be disabled
11789		if ( this.options.disabled ) {
11790			this.options.disabled = false;
11791		}
11792
11793		this._createWrapper();
11794
11795		this.element
11796			.show()
11797			.removeAttr( "title" )
11798			.appendTo( this.uiDialog );
11799
11800		this._addClass( "ui-dialog-content", "ui-widget-content" );
11801
11802		this._createTitlebar();
11803		this._createButtonPane();
11804
11805		if ( this.options.draggable && $.fn.draggable ) {
11806			this._makeDraggable();
11807		}
11808		if ( this.options.resizable && $.fn.resizable ) {
11809			this._makeResizable();
11810		}
11811
11812		this._isOpen = false;
11813
11814		this._trackFocus();
11815	},
11816
11817	_init: function() {
11818		if ( this.options.autoOpen ) {
11819			this.open();
11820		}
11821	},
11822
11823	_appendTo: function() {
11824		var element = this.options.appendTo;
11825		if ( element && ( element.jquery || element.nodeType ) ) {
11826			return $( element );
11827		}
11828		return this.document.find( element || "body" ).eq( 0 );
11829	},
11830
11831	_destroy: function() {
11832		var next,
11833			originalPosition = this.originalPosition;
11834
11835		this._untrackInstance();
11836		this._destroyOverlay();
11837
11838		this.element
11839			.removeUniqueId()
11840			.css( this.originalCss )
11841
11842			// Without detaching first, the following becomes really slow
11843			.detach();
11844
11845		this.uiDialog.remove();
11846
11847		if ( this.originalTitle ) {
11848			this.element.attr( "title", this.originalTitle );
11849		}
11850
11851		next = originalPosition.parent.children().eq( originalPosition.index );
11852
11853		// Don't try to place the dialog next to itself (#8613)
11854		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
11855			next.before( this.element );
11856		} else {
11857			originalPosition.parent.append( this.element );
11858		}
11859	},
11860
11861	widget: function() {
11862		return this.uiDialog;
11863	},
11864
11865	disable: $.noop,
11866	enable: $.noop,
11867
11868	close: function( event ) {
11869		var that = this;
11870
11871		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
11872			return;
11873		}
11874
11875		this._isOpen = false;
11876		this._focusedElement = null;
11877		this._destroyOverlay();
11878		this._untrackInstance();
11879
11880		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
11881
11882			// Hiding a focused element doesn't trigger blur in WebKit
11883			// so in case we have nothing to focus on, explicitly blur the active element
11884			// https://bugs.webkit.org/show_bug.cgi?id=47182
11885			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
11886		}
11887
11888		this._hide( this.uiDialog, this.options.hide, function() {
11889			that._trigger( "close", event );
11890		} );
11891	},
11892
11893	isOpen: function() {
11894		return this._isOpen;
11895	},
11896
11897	moveToTop: function() {
11898		this._moveToTop();
11899	},
11900
11901	_moveToTop: function( event, silent ) {
11902		var moved = false,
11903			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
11904				return +$( this ).css( "z-index" );
11905			} ).get(),
11906			zIndexMax = Math.max.apply( null, zIndices );
11907
11908		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
11909			this.uiDialog.css( "z-index", zIndexMax + 1 );
11910			moved = true;
11911		}
11912
11913		if ( moved && !silent ) {
11914			this._trigger( "focus", event );
11915		}
11916		return moved;
11917	},
11918
11919	open: function() {
11920		var that = this;
11921		if ( this._isOpen ) {
11922			if ( this._moveToTop() ) {
11923				this._focusTabbable();
11924			}
11925			return;
11926		}
11927
11928		this._isOpen = true;
11929		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
11930
11931		this._size();
11932		this._position();
11933		this._createOverlay();
11934		this._moveToTop( null, true );
11935
11936		// Ensure the overlay is moved to the top with the dialog, but only when
11937		// opening. The overlay shouldn't move after the dialog is open so that
11938		// modeless dialogs opened after the modal dialog stack properly.
11939		if ( this.overlay ) {
11940			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
11941		}
11942
11943		this._show( this.uiDialog, this.options.show, function() {
11944			that._focusTabbable();
11945			that._trigger( "focus" );
11946		} );
11947
11948		// Track the dialog immediately upon openening in case a focus event
11949		// somehow occurs outside of the dialog before an element inside the
11950		// dialog is focused (#10152)
11951		this._makeFocusTarget();
11952
11953		this._trigger( "open" );
11954	},
11955
11956	_focusTabbable: function() {
11957
11958		// Set focus to the first match:
11959		// 1. An element that was focused previously
11960		// 2. First element inside the dialog matching [autofocus]
11961		// 3. Tabbable element inside the content element
11962		// 4. Tabbable element inside the buttonpane
11963		// 5. The close button
11964		// 6. The dialog itself
11965		var hasFocus = this._focusedElement;
11966		if ( !hasFocus ) {
11967			hasFocus = this.element.find( "[autofocus]" );
11968		}
11969		if ( !hasFocus.length ) {
11970			hasFocus = this.element.find( ":tabbable" );
11971		}
11972		if ( !hasFocus.length ) {
11973			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
11974		}
11975		if ( !hasFocus.length ) {
11976			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
11977		}
11978		if ( !hasFocus.length ) {
11979			hasFocus = this.uiDialog;
11980		}
11981		hasFocus.eq( 0 ).trigger( "focus" );
11982	},
11983
11984	_keepFocus: function( event ) {
11985		function checkFocus() {
11986			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
11987				isActive = this.uiDialog[ 0 ] === activeElement ||
11988					$.contains( this.uiDialog[ 0 ], activeElement );
11989			if ( !isActive ) {
11990				this._focusTabbable();
11991			}
11992		}
11993		event.preventDefault();
11994		checkFocus.call( this );
11995
11996		// support: IE
11997		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
11998		// so we check again later
11999		this._delay( checkFocus );
12000	},
12001
12002	_createWrapper: function() {
12003		this.uiDialog = $( "<div>" )
12004			.hide()
12005			.attr( {
12006
12007				// Setting tabIndex makes the div focusable
12008				tabIndex: -1,
12009				role: "dialog"
12010			} )
12011			.appendTo( this._appendTo() );
12012
12013		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12014		this._on( this.uiDialog, {
12015			keydown: function( event ) {
12016				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12017						event.keyCode === $.ui.keyCode.ESCAPE ) {
12018					event.preventDefault();
12019					this.close( event );
12020					return;
12021				}
12022
12023				// Prevent tabbing out of dialogs
12024				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12025					return;
12026				}
12027				var tabbables = this.uiDialog.find( ":tabbable" ),
12028					first = tabbables.filter( ":first" ),
12029					last = tabbables.filter( ":last" );
12030
12031				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12032						!event.shiftKey ) {
12033					this._delay( function() {
12034						first.trigger( "focus" );
12035					} );
12036					event.preventDefault();
12037				} else if ( ( event.target === first[ 0 ] ||
12038						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12039					this._delay( function() {
12040						last.trigger( "focus" );
12041					} );
12042					event.preventDefault();
12043				}
12044			},
12045			mousedown: function( event ) {
12046				if ( this._moveToTop( event ) ) {
12047					this._focusTabbable();
12048				}
12049			}
12050		} );
12051
12052		// We assume that any existing aria-describedby attribute means
12053		// that the dialog content is marked up properly
12054		// otherwise we brute force the content as the description
12055		if ( !this.element.find( "[aria-describedby]" ).length ) {
12056			this.uiDialog.attr( {
12057				"aria-describedby": this.element.uniqueId().attr( "id" )
12058			} );
12059		}
12060	},
12061
12062	_createTitlebar: function() {
12063		var uiDialogTitle;
12064
12065		this.uiDialogTitlebar = $( "<div>" );
12066		this._addClass( this.uiDialogTitlebar,
12067			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12068		this._on( this.uiDialogTitlebar, {
12069			mousedown: function( event ) {
12070
12071				// Don't prevent click on close button (#8838)
12072				// Focusing a dialog that is partially scrolled out of view
12073				// causes the browser to scroll it into view, preventing the click event
12074				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12075
12076					// Dialog isn't getting focus when dragging (#8063)
12077					this.uiDialog.trigger( "focus" );
12078				}
12079			}
12080		} );
12081
12082		// Support: IE
12083		// Use type="button" to prevent enter keypresses in textboxes from closing the
12084		// dialog in IE (#9312)
12085		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12086			.button( {
12087				label: $( "<a>" ).text( this.options.closeText ).html(),
12088				icon: "ui-icon-closethick",
12089				showLabel: false
12090			} )
12091			.appendTo( this.uiDialogTitlebar );
12092
12093		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12094		this._on( this.uiDialogTitlebarClose, {
12095			click: function( event ) {
12096				event.preventDefault();
12097				this.close( event );
12098			}
12099		} );
12100
12101		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12102		this._addClass( uiDialogTitle, "ui-dialog-title" );
12103		this._title( uiDialogTitle );
12104
12105		this.uiDialogTitlebar.prependTo( this.uiDialog );
12106
12107		this.uiDialog.attr( {
12108			"aria-labelledby": uiDialogTitle.attr( "id" )
12109		} );
12110	},
12111
12112	_title: function( title ) {
12113		if ( this.options.title ) {
12114			title.text( this.options.title );
12115		} else {
12116			title.html( "&#160;" );
12117		}
12118	},
12119
12120	_createButtonPane: function() {
12121		this.uiDialogButtonPane = $( "<div>" );
12122		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12123			"ui-widget-content ui-helper-clearfix" );
12124
12125		this.uiButtonSet = $( "<div>" )
12126			.appendTo( this.uiDialogButtonPane );
12127		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12128
12129		this._createButtons();
12130	},
12131
12132	_createButtons: function() {
12133		var that = this,
12134			buttons = this.options.buttons;
12135
12136		// If we already have a button pane, remove it
12137		this.uiDialogButtonPane.remove();
12138		this.uiButtonSet.empty();
12139
12140		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12141			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12142			return;
12143		}
12144
12145		$.each( buttons, function( name, props ) {
12146			var click, buttonOptions;
12147			props = $.isFunction( props ) ?
12148				{ click: props, text: name } :
12149				props;
12150
12151			// Default to a non-submitting button
12152			props = $.extend( { type: "button" }, props );
12153
12154			// Change the context for the click callback to be the main element
12155			click = props.click;
12156			buttonOptions = {
12157				icon: props.icon,
12158				iconPosition: props.iconPosition,
12159				showLabel: props.showLabel,
12160
12161				// Deprecated options
12162				icons: props.icons,
12163				text: props.text
12164			};
12165
12166			delete props.click;
12167			delete props.icon;
12168			delete props.iconPosition;
12169			delete props.showLabel;
12170
12171			// Deprecated options
12172			delete props.icons;
12173			if ( typeof props.text === "boolean" ) {
12174				delete props.text;
12175			}
12176
12177			$( "<button></button>", props )
12178				.button( buttonOptions )
12179				.appendTo( that.uiButtonSet )
12180				.on( "click", function() {
12181					click.apply( that.element[ 0 ], arguments );
12182				} );
12183		} );
12184		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12185		this.uiDialogButtonPane.appendTo( this.uiDialog );
12186	},
12187
12188	_makeDraggable: function() {
12189		var that = this,
12190			options = this.options;
12191
12192		function filteredUi( ui ) {
12193			return {
12194				position: ui.position,
12195				offset: ui.offset
12196			};
12197		}
12198
12199		this.uiDialog.draggable( {
12200			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12201			handle: ".ui-dialog-titlebar",
12202			containment: "document",
12203			start: function( event, ui ) {
12204				that._addClass( $( this ), "ui-dialog-dragging" );
12205				that._blockFrames();
12206				that._trigger( "dragStart", event, filteredUi( ui ) );
12207			},
12208			drag: function( event, ui ) {
12209				that._trigger( "drag", event, filteredUi( ui ) );
12210			},
12211			stop: function( event, ui ) {
12212				var left = ui.offset.left - that.document.scrollLeft(),
12213					top = ui.offset.top - that.document.scrollTop();
12214
12215				options.position = {
12216					my: "left top",
12217					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12218						"top" + ( top >= 0 ? "+" : "" ) + top,
12219					of: that.window
12220				};
12221				that._removeClass( $( this ), "ui-dialog-dragging" );
12222				that._unblockFrames();
12223				that._trigger( "dragStop", event, filteredUi( ui ) );
12224			}
12225		} );
12226	},
12227
12228	_makeResizable: function() {
12229		var that = this,
12230			options = this.options,
12231			handles = options.resizable,
12232
12233			// .ui-resizable has position: relative defined in the stylesheet
12234			// but dialogs have to use absolute or fixed positioning
12235			position = this.uiDialog.css( "position" ),
12236			resizeHandles = typeof handles === "string" ?
12237				handles :
12238				"n,e,s,w,se,sw,ne,nw";
12239
12240		function filteredUi( ui ) {
12241			return {
12242				originalPosition: ui.originalPosition,
12243				originalSize: ui.originalSize,
12244				position: ui.position,
12245				size: ui.size
12246			};
12247		}
12248
12249		this.uiDialog.resizable( {
12250			cancel: ".ui-dialog-content",
12251			containment: "document",
12252			alsoResize: this.element,
12253			maxWidth: options.maxWidth,
12254			maxHeight: options.maxHeight,
12255			minWidth: options.minWidth,
12256			minHeight: this._minHeight(),
12257			handles: resizeHandles,
12258			start: function( event, ui ) {
12259				that._addClass( $( this ), "ui-dialog-resizing" );
12260				that._blockFrames();
12261				that._trigger( "resizeStart", event, filteredUi( ui ) );
12262			},
12263			resize: function( event, ui ) {
12264				that._trigger( "resize", event, filteredUi( ui ) );
12265			},
12266			stop: function( event, ui ) {
12267				var offset = that.uiDialog.offset(),
12268					left = offset.left - that.document.scrollLeft(),
12269					top = offset.top - that.document.scrollTop();
12270
12271				options.height = that.uiDialog.height();
12272				options.width = that.uiDialog.width();
12273				options.position = {
12274					my: "left top",
12275					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12276						"top" + ( top >= 0 ? "+" : "" ) + top,
12277					of: that.window
12278				};
12279				that._removeClass( $( this ), "ui-dialog-resizing" );
12280				that._unblockFrames();
12281				that._trigger( "resizeStop", event, filteredUi( ui ) );
12282			}
12283		} )
12284			.css( "position", position );
12285	},
12286
12287	_trackFocus: function() {
12288		this._on( this.widget(), {
12289			focusin: function( event ) {
12290				this._makeFocusTarget();
12291				this._focusedElement = $( event.target );
12292			}
12293		} );
12294	},
12295
12296	_makeFocusTarget: function() {
12297		this._untrackInstance();
12298		this._trackingInstances().unshift( this );
12299	},
12300
12301	_untrackInstance: function() {
12302		var instances = this._trackingInstances(),
12303			exists = $.inArray( this, instances );
12304		if ( exists !== -1 ) {
12305			instances.splice( exists, 1 );
12306		}
12307	},
12308
12309	_trackingInstances: function() {
12310		var instances = this.document.data( "ui-dialog-instances" );
12311		if ( !instances ) {
12312			instances = [];
12313			this.document.data( "ui-dialog-instances", instances );
12314		}
12315		return instances;
12316	},
12317
12318	_minHeight: function() {
12319		var options = this.options;
12320
12321		return options.height === "auto" ?
12322			options.minHeight :
12323			Math.min( options.minHeight, options.height );
12324	},
12325
12326	_position: function() {
12327
12328		// Need to show the dialog to get the actual offset in the position plugin
12329		var isVisible = this.uiDialog.is( ":visible" );
12330		if ( !isVisible ) {
12331			this.uiDialog.show();
12332		}
12333		this.uiDialog.position( this.options.position );
12334		if ( !isVisible ) {
12335			this.uiDialog.hide();
12336		}
12337	},
12338
12339	_setOptions: function( options ) {
12340		var that = this,
12341			resize = false,
12342			resizableOptions = {};
12343
12344		$.each( options, function( key, value ) {
12345			that._setOption( key, value );
12346
12347			if ( key in that.sizeRelatedOptions ) {
12348				resize = true;
12349			}
12350			if ( key in that.resizableRelatedOptions ) {
12351				resizableOptions[ key ] = value;
12352			}
12353		} );
12354
12355		if ( resize ) {
12356			this._size();
12357			this._position();
12358		}
12359		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12360			this.uiDialog.resizable( "option", resizableOptions );
12361		}
12362	},
12363
12364	_setOption: function( key, value ) {
12365		var isDraggable, isResizable,
12366			uiDialog = this.uiDialog;
12367
12368		if ( key === "disabled" ) {
12369			return;
12370		}
12371
12372		this._super( key, value );
12373
12374		if ( key === "appendTo" ) {
12375			this.uiDialog.appendTo( this._appendTo() );
12376		}
12377
12378		if ( key === "buttons" ) {
12379			this._createButtons();
12380		}
12381
12382		if ( key === "closeText" ) {
12383			this.uiDialogTitlebarClose.button( {
12384
12385				// Ensure that we always pass a string
12386				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12387			} );
12388		}
12389
12390		if ( key === "draggable" ) {
12391			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12392			if ( isDraggable && !value ) {
12393				uiDialog.draggable( "destroy" );
12394			}
12395
12396			if ( !isDraggable && value ) {
12397				this._makeDraggable();
12398			}
12399		}
12400
12401		if ( key === "position" ) {
12402			this._position();
12403		}
12404
12405		if ( key === "resizable" ) {
12406
12407			// currently resizable, becoming non-resizable
12408			isResizable = uiDialog.is( ":data(ui-resizable)" );
12409			if ( isResizable && !value ) {
12410				uiDialog.resizable( "destroy" );
12411			}
12412
12413			// Currently resizable, changing handles
12414			if ( isResizable && typeof value === "string" ) {
12415				uiDialog.resizable( "option", "handles", value );
12416			}
12417
12418			// Currently non-resizable, becoming resizable
12419			if ( !isResizable && value !== false ) {
12420				this._makeResizable();
12421			}
12422		}
12423
12424		if ( key === "title" ) {
12425			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12426		}
12427	},
12428
12429	_size: function() {
12430
12431		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12432		// divs will both have width and height set, so we need to reset them
12433		var nonContentHeight, minContentHeight, maxContentHeight,
12434			options = this.options;
12435
12436		// Reset content sizing
12437		this.element.show().css( {
12438			width: "auto",
12439			minHeight: 0,
12440			maxHeight: "none",
12441			height: 0
12442		} );
12443
12444		if ( options.minWidth > options.width ) {
12445			options.width = options.minWidth;
12446		}
12447
12448		// Reset wrapper sizing
12449		// determine the height of all the non-content elements
12450		nonContentHeight = this.uiDialog.css( {
12451			height: "auto",
12452			width: options.width
12453		} )
12454			.outerHeight();
12455		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12456		maxContentHeight = typeof options.maxHeight === "number" ?
12457			Math.max( 0, options.maxHeight - nonContentHeight ) :
12458			"none";
12459
12460		if ( options.height === "auto" ) {
12461			this.element.css( {
12462				minHeight: minContentHeight,
12463				maxHeight: maxContentHeight,
12464				height: "auto"
12465			} );
12466		} else {
12467			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12468		}
12469
12470		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12471			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12472		}
12473	},
12474
12475	_blockFrames: function() {
12476		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12477			var iframe = $( this );
12478
12479			return $( "<div>" )
12480				.css( {
12481					position: "absolute",
12482					width: iframe.outerWidth(),
12483					height: iframe.outerHeight()
12484				} )
12485				.appendTo( iframe.parent() )
12486				.offset( iframe.offset() )[ 0 ];
12487		} );
12488	},
12489
12490	_unblockFrames: function() {
12491		if ( this.iframeBlocks ) {
12492			this.iframeBlocks.remove();
12493			delete this.iframeBlocks;
12494		}
12495	},
12496
12497	_allowInteraction: function( event ) {
12498		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12499			return true;
12500		}
12501
12502		// TODO: Remove hack when datepicker implements
12503		// the .ui-front logic (#8989)
12504		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12505	},
12506
12507	_createOverlay: function() {
12508		if ( !this.options.modal ) {
12509			return;
12510		}
12511
12512		// We use a delay in case the overlay is created from an
12513		// event that we're going to be cancelling (#2804)
12514		var isOpening = true;
12515		this._delay( function() {
12516			isOpening = false;
12517		} );
12518
12519		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12520
12521			// Prevent use of anchors and inputs
12522			// Using _on() for an event handler shared across many instances is
12523			// safe because the dialogs stack and must be closed in reverse order
12524			this._on( this.document, {
12525				focusin: function( event ) {
12526					if ( isOpening ) {
12527						return;
12528					}
12529
12530					if ( !this._allowInteraction( event ) ) {
12531						event.preventDefault();
12532						this._trackingInstances()[ 0 ]._focusTabbable();
12533					}
12534				}
12535			} );
12536		}
12537
12538		this.overlay = $( "<div>" )
12539			.appendTo( this._appendTo() );
12540
12541		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12542		this._on( this.overlay, {
12543			mousedown: "_keepFocus"
12544		} );
12545		this.document.data( "ui-dialog-overlays",
12546			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12547	},
12548
12549	_destroyOverlay: function() {
12550		if ( !this.options.modal ) {
12551			return;
12552		}
12553
12554		if ( this.overlay ) {
12555			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12556
12557			if ( !overlays ) {
12558				this._off( this.document, "focusin" );
12559				this.document.removeData( "ui-dialog-overlays" );
12560			} else {
12561				this.document.data( "ui-dialog-overlays", overlays );
12562			}
12563
12564			this.overlay.remove();
12565			this.overlay = null;
12566		}
12567	}
12568} );
12569
12570// DEPRECATED
12571// TODO: switch return back to widget declaration at top of file when this is removed
12572if ( $.uiBackCompat !== false ) {
12573
12574	// Backcompat for dialogClass option
12575	$.widget( "ui.dialog", $.ui.dialog, {
12576		options: {
12577			dialogClass: ""
12578		},
12579		_createWrapper: function() {
12580			this._super();
12581			this.uiDialog.addClass( this.options.dialogClass );
12582		},
12583		_setOption: function( key, value ) {
12584			if ( key === "dialogClass" ) {
12585				this.uiDialog
12586					.removeClass( this.options.dialogClass )
12587					.addClass( value );
12588			}
12589			this._superApply( arguments );
12590		}
12591	} );
12592}
12593
12594var widgetsDialog = $.ui.dialog;
12595
12596
12597/*!
12598 * jQuery UI Progressbar 1.12.1
12599 * http://jqueryui.com
12600 *
12601 * Copyright jQuery Foundation and other contributors
12602 * Released under the MIT license.
12603 * http://jquery.org/license
12604 */
12605
12606//>>label: Progressbar
12607//>>group: Widgets
12608// jscs:disable maximumLineLength
12609//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
12610// jscs:enable maximumLineLength
12611//>>docs: http://api.jqueryui.com/progressbar/
12612//>>demos: http://jqueryui.com/progressbar/
12613//>>css.structure: ../../themes/base/core.css
12614//>>css.structure: ../../themes/base/progressbar.css
12615//>>css.theme: ../../themes/base/theme.css
12616
12617
12618
12619var widgetsProgressbar = $.widget( "ui.progressbar", {
12620	version: "1.12.1",
12621	options: {
12622		classes: {
12623			"ui-progressbar": "ui-corner-all",
12624			"ui-progressbar-value": "ui-corner-left",
12625			"ui-progressbar-complete": "ui-corner-right"
12626		},
12627		max: 100,
12628		value: 0,
12629
12630		change: null,
12631		complete: null
12632	},
12633
12634	min: 0,
12635
12636	_create: function() {
12637
12638		// Constrain initial value
12639		this.oldValue = this.options.value = this._constrainedValue();
12640
12641		this.element.attr( {
12642
12643			// Only set static values; aria-valuenow and aria-valuemax are
12644			// set inside _refreshValue()
12645			role: "progressbar",
12646			"aria-valuemin": this.min
12647		} );
12648		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
12649
12650		this.valueDiv = $( "<div>" ).appendTo( this.element );
12651		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
12652		this._refreshValue();
12653	},
12654
12655	_destroy: function() {
12656		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
12657
12658		this.valueDiv.remove();
12659	},
12660
12661	value: function( newValue ) {
12662		if ( newValue === undefined ) {
12663			return this.options.value;
12664		}
12665
12666		this.options.value = this._constrainedValue( newValue );
12667		this._refreshValue();
12668	},
12669
12670	_constrainedValue: function( newValue ) {
12671		if ( newValue === undefined ) {
12672			newValue = this.options.value;
12673		}
12674
12675		this.indeterminate = newValue === false;
12676
12677		// Sanitize value
12678		if ( typeof newValue !== "number" ) {
12679			newValue = 0;
12680		}
12681
12682		return this.indeterminate ? false :
12683			Math.min( this.options.max, Math.max( this.min, newValue ) );
12684	},
12685
12686	_setOptions: function( options ) {
12687
12688		// Ensure "value" option is set after other values (like max)
12689		var value = options.value;
12690		delete options.value;
12691
12692		this._super( options );
12693
12694		this.options.value = this._constrainedValue( value );
12695		this._refreshValue();
12696	},
12697
12698	_setOption: function( key, value ) {
12699		if ( key === "max" ) {
12700
12701			// Don't allow a max less than min
12702			value = Math.max( this.min, value );
12703		}
12704		this._super( key, value );
12705	},
12706
12707	_setOptionDisabled: function( value ) {
12708		this._super( value );
12709
12710		this.element.attr( "aria-disabled", value );
12711		this._toggleClass( null, "ui-state-disabled", !!value );
12712	},
12713
12714	_percentage: function() {
12715		return this.indeterminate ?
12716			100 :
12717			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12718	},
12719
12720	_refreshValue: function() {
12721		var value = this.options.value,
12722			percentage = this._percentage();
12723
12724		this.valueDiv
12725			.toggle( this.indeterminate || value > this.min )
12726			.width( percentage.toFixed( 0 ) + "%" );
12727
12728		this
12729			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
12730				value === this.options.max )
12731			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
12732
12733		if ( this.indeterminate ) {
12734			this.element.removeAttr( "aria-valuenow" );
12735			if ( !this.overlayDiv ) {
12736				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
12737				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
12738			}
12739		} else {
12740			this.element.attr( {
12741				"aria-valuemax": this.options.max,
12742				"aria-valuenow": value
12743			} );
12744			if ( this.overlayDiv ) {
12745				this.overlayDiv.remove();
12746				this.overlayDiv = null;
12747			}
12748		}
12749
12750		if ( this.oldValue !== value ) {
12751			this.oldValue = value;
12752			this._trigger( "change" );
12753		}
12754		if ( value === this.options.max ) {
12755			this._trigger( "complete" );
12756		}
12757	}
12758} );
12759
12760
12761/*!
12762 * jQuery UI Selectmenu 1.12.1
12763 * http://jqueryui.com
12764 *
12765 * Copyright jQuery Foundation and other contributors
12766 * Released under the MIT license.
12767 * http://jquery.org/license
12768 */
12769
12770//>>label: Selectmenu
12771//>>group: Widgets
12772// jscs:disable maximumLineLength
12773//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
12774// jscs:enable maximumLineLength
12775//>>docs: http://api.jqueryui.com/selectmenu/
12776//>>demos: http://jqueryui.com/selectmenu/
12777//>>css.structure: ../../themes/base/core.css
12778//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
12779//>>css.theme: ../../themes/base/theme.css
12780
12781
12782
12783var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
12784	version: "1.12.1",
12785	defaultElement: "<select>",
12786	options: {
12787		appendTo: null,
12788		classes: {
12789			"ui-selectmenu-button-open": "ui-corner-top",
12790			"ui-selectmenu-button-closed": "ui-corner-all"
12791		},
12792		disabled: null,
12793		icons: {
12794			button: "ui-icon-triangle-1-s"
12795		},
12796		position: {
12797			my: "left top",
12798			at: "left bottom",
12799			collision: "none"
12800		},
12801		width: false,
12802
12803		// Callbacks
12804		change: null,
12805		close: null,
12806		focus: null,
12807		open: null,
12808		select: null
12809	},
12810
12811	_create: function() {
12812		var selectmenuId = this.element.uniqueId().attr( "id" );
12813		this.ids = {
12814			element: selectmenuId,
12815			button: selectmenuId + "-button",
12816			menu: selectmenuId + "-menu"
12817		};
12818
12819		this._drawButton();
12820		this._drawMenu();
12821		this._bindFormResetHandler();
12822
12823		this._rendered = false;
12824		this.menuItems = $();
12825	},
12826
12827	_drawButton: function() {
12828		var icon,
12829			that = this,
12830			item = this._parseOption(
12831				this.element.find( "option:selected" ),
12832				this.element[ 0 ].selectedIndex
12833			);
12834
12835		// Associate existing label with the new button
12836		this.labels = this.element.labels().attr( "for", this.ids.button );
12837		this._on( this.labels, {
12838			click: function( event ) {
12839				this.button.focus();
12840				event.preventDefault();
12841			}
12842		} );
12843
12844		// Hide original select element
12845		this.element.hide();
12846
12847		// Create button
12848		this.button = $( "<span>", {
12849			tabindex: this.options.disabled ? -1 : 0,
12850			id: this.ids.button,
12851			role: "combobox",
12852			"aria-expanded": "false",
12853			"aria-autocomplete": "list",
12854			"aria-owns": this.ids.menu,
12855			"aria-haspopup": "true",
12856			title: this.element.attr( "title" )
12857		} )
12858			.insertAfter( this.element );
12859
12860		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
12861			"ui-button ui-widget" );
12862
12863		icon = $( "<span>" ).appendTo( this.button );
12864		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
12865		this.buttonItem = this._renderButtonItem( item )
12866			.appendTo( this.button );
12867
12868		if ( this.options.width !== false ) {
12869			this._resizeButton();
12870		}
12871
12872		this._on( this.button, this._buttonEvents );
12873		this.button.one( "focusin", function() {
12874
12875			// Delay rendering the menu items until the button receives focus.
12876			// The menu may have already been rendered via a programmatic open.
12877			if ( !that._rendered ) {
12878				that._refreshMenu();
12879			}
12880		} );
12881	},
12882
12883	_drawMenu: function() {
12884		var that = this;
12885
12886		// Create menu
12887		this.menu = $( "<ul>", {
12888			"aria-hidden": "true",
12889			"aria-labelledby": this.ids.button,
12890			id: this.ids.menu
12891		} );
12892
12893		// Wrap menu
12894		this.menuWrap = $( "<div>" ).append( this.menu );
12895		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
12896		this.menuWrap.appendTo( this._appendTo() );
12897
12898		// Initialize menu widget
12899		this.menuInstance = this.menu
12900			.menu( {
12901				classes: {
12902					"ui-menu": "ui-corner-bottom"
12903				},
12904				role: "listbox",
12905				select: function( event, ui ) {
12906					event.preventDefault();
12907
12908					// Support: IE8
12909					// If the item was selected via a click, the text selection
12910					// will be destroyed in IE
12911					that._setSelection();
12912
12913					that._select( ui.item.data( "ui-selectmenu-item" ), event );
12914				},
12915				focus: function( event, ui ) {
12916					var item = ui.item.data( "ui-selectmenu-item" );
12917
12918					// Prevent inital focus from firing and check if its a newly focused item
12919					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12920						that._trigger( "focus", event, { item: item } );
12921						if ( !that.isOpen ) {
12922							that._select( item, event );
12923						}
12924					}
12925					that.focusIndex = item.index;
12926
12927					that.button.attr( "aria-activedescendant",
12928						that.menuItems.eq( item.index ).attr( "id" ) );
12929				}
12930			} )
12931			.menu( "instance" );
12932
12933		// Don't close the menu on mouseleave
12934		this.menuInstance._off( this.menu, "mouseleave" );
12935
12936		// Cancel the menu's collapseAll on document click
12937		this.menuInstance._closeOnDocumentClick = function() {
12938			return false;
12939		};
12940
12941		// Selects often contain empty items, but never contain dividers
12942		this.menuInstance._isDivider = function() {
12943			return false;
12944		};
12945	},
12946
12947	refresh: function() {
12948		this._refreshMenu();
12949		this.buttonItem.replaceWith(
12950			this.buttonItem = this._renderButtonItem(
12951
12952				// Fall back to an empty object in case there are no options
12953				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
12954			)
12955		);
12956		if ( this.options.width === null ) {
12957			this._resizeButton();
12958		}
12959	},
12960
12961	_refreshMenu: function() {
12962		var item,
12963			options = this.element.find( "option" );
12964
12965		this.menu.empty();
12966
12967		this._parseOptions( options );
12968		this._renderMenu( this.menu, this.items );
12969
12970		this.menuInstance.refresh();
12971		this.menuItems = this.menu.find( "li" )
12972			.not( ".ui-selectmenu-optgroup" )
12973				.find( ".ui-menu-item-wrapper" );
12974
12975		this._rendered = true;
12976
12977		if ( !options.length ) {
12978			return;
12979		}
12980
12981		item = this._getSelectedItem();
12982
12983		// Update the menu to have the correct item focused
12984		this.menuInstance.focus( null, item );
12985		this._setAria( item.data( "ui-selectmenu-item" ) );
12986
12987		// Set disabled state
12988		this._setOption( "disabled", this.element.prop( "disabled" ) );
12989	},
12990
12991	open: function( event ) {
12992		if ( this.options.disabled ) {
12993			return;
12994		}
12995
12996		// If this is the first time the menu is being opened, render the items
12997		if ( !this._rendered ) {
12998			this._refreshMenu();
12999		} else {
13000
13001			// Menu clears focus on close, reset focus to selected item
13002			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
13003			this.menuInstance.focus( null, this._getSelectedItem() );
13004		}
13005
13006		// If there are no options, don't open the menu
13007		if ( !this.menuItems.length ) {
13008			return;
13009		}
13010
13011		this.isOpen = true;
13012		this._toggleAttr();
13013		this._resizeMenu();
13014		this._position();
13015
13016		this._on( this.document, this._documentClick );
13017
13018		this._trigger( "open", event );
13019	},
13020
13021	_position: function() {
13022		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
13023	},
13024
13025	close: function( event ) {
13026		if ( !this.isOpen ) {
13027			return;
13028		}
13029
13030		this.isOpen = false;
13031		this._toggleAttr();
13032
13033		this.range = null;
13034		this._off( this.document );
13035
13036		this._trigger( "close", event );
13037	},
13038
13039	widget: function() {
13040		return this.button;
13041	},
13042
13043	menuWidget: function() {
13044		return this.menu;
13045	},
13046
13047	_renderButtonItem: function( item ) {
13048		var buttonItem = $( "<span>" );
13049
13050		this._setText( buttonItem, item.label );
13051		this._addClass( buttonItem, "ui-selectmenu-text" );
13052
13053		return buttonItem;
13054	},
13055
13056	_renderMenu: function( ul, items ) {
13057		var that = this,
13058			currentOptgroup = "";
13059
13060		$.each( items, function( index, item ) {
13061			var li;
13062
13063			if ( item.optgroup !== currentOptgroup ) {
13064				li = $( "<li>", {
13065					text: item.optgroup
13066				} );
13067				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
13068					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
13069						" ui-state-disabled" :
13070						"" ) );
13071
13072				li.appendTo( ul );
13073
13074				currentOptgroup = item.optgroup;
13075			}
13076
13077			that._renderItemData( ul, item );
13078		} );
13079	},
13080
13081	_renderItemData: function( ul, item ) {
13082		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
13083	},
13084
13085	_renderItem: function( ul, item ) {
13086		var li = $( "<li>" ),
13087			wrapper = $( "<div>", {
13088				title: item.element.attr( "title" )
13089			} );
13090
13091		if ( item.disabled ) {
13092			this._addClass( li, null, "ui-state-disabled" );
13093		}
13094		this._setText( wrapper, item.label );
13095
13096		return li.append( wrapper ).appendTo( ul );
13097	},
13098
13099	_setText: function( element, value ) {
13100		if ( value ) {
13101			element.text( value );
13102		} else {
13103			element.html( "&#160;" );
13104		}
13105	},
13106
13107	_move: function( direction, event ) {
13108		var item, next,
13109			filter = ".ui-menu-item";
13110
13111		if ( this.isOpen ) {
13112			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13113		} else {
13114			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13115			filter += ":not(.ui-state-disabled)";
13116		}
13117
13118		if ( direction === "first" || direction === "last" ) {
13119			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
13120		} else {
13121			next = item[ direction + "All" ]( filter ).eq( 0 );
13122		}
13123
13124		if ( next.length ) {
13125			this.menuInstance.focus( event, next );
13126		}
13127	},
13128
13129	_getSelectedItem: function() {
13130		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13131	},
13132
13133	_toggle: function( event ) {
13134		this[ this.isOpen ? "close" : "open" ]( event );
13135	},
13136
13137	_setSelection: function() {
13138		var selection;
13139
13140		if ( !this.range ) {
13141			return;
13142		}
13143
13144		if ( window.getSelection ) {
13145			selection = window.getSelection();
13146			selection.removeAllRanges();
13147			selection.addRange( this.range );
13148
vendor: 53,835 bytes, lines 13149-15249
13149		// Support: IE8
13150		} else {
13151			this.range.select();
13152		}
13153
13154		// Support: IE
13155		// Setting the text selection kills the button focus in IE, but
13156		// restoring the focus doesn't kill the selection.
13157		this.button.focus();
13158	},
13159
13160	_documentClick: {
13161		mousedown: function( event ) {
13162			if ( !this.isOpen ) {
13163				return;
13164			}
13165
13166			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
13167					$.ui.escapeSelector( this.ids.button ) ).length ) {
13168				this.close( event );
13169			}
13170		}
13171	},
13172
13173	_buttonEvents: {
13174
13175		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
13176		mousedown: function() {
13177			var selection;
13178
13179			if ( window.getSelection ) {
13180				selection = window.getSelection();
13181				if ( selection.rangeCount ) {
13182					this.range = selection.getRangeAt( 0 );
13183				}
13184
13185			// Support: IE8
13186			} else {
13187				this.range = document.selection.createRange();
13188			}
13189		},
13190
13191		click: function( event ) {
13192			this._setSelection();
13193			this._toggle( event );
13194		},
13195
13196		keydown: function( event ) {
13197			var preventDefault = true;
13198			switch ( event.keyCode ) {
13199			case $.ui.keyCode.TAB:
13200			case $.ui.keyCode.ESCAPE:
13201				this.close( event );
13202				preventDefault = false;
13203				break;
13204			case $.ui.keyCode.ENTER:
13205				if ( this.isOpen ) {
13206					this._selectFocusedItem( event );
13207				}
13208				break;
13209			case $.ui.keyCode.UP:
13210				if ( event.altKey ) {
13211					this._toggle( event );
13212				} else {
13213					this._move( "prev", event );
13214				}
13215				break;
13216			case $.ui.keyCode.DOWN:
13217				if ( event.altKey ) {
13218					this._toggle( event );
13219				} else {
13220					this._move( "next", event );
13221				}
13222				break;
13223			case $.ui.keyCode.SPACE:
13224				if ( this.isOpen ) {
13225					this._selectFocusedItem( event );
13226				} else {
13227					this._toggle( event );
13228				}
13229				break;
13230			case $.ui.keyCode.LEFT:
13231				this._move( "prev", event );
13232				break;
13233			case $.ui.keyCode.RIGHT:
13234				this._move( "next", event );
13235				break;
13236			case $.ui.keyCode.HOME:
13237			case $.ui.keyCode.PAGE_UP:
13238				this._move( "first", event );
13239				break;
13240			case $.ui.keyCode.END:
13241			case $.ui.keyCode.PAGE_DOWN:
13242				this._move( "last", event );
13243				break;
13244			default:
13245				this.menu.trigger( event );
13246				preventDefault = false;
13247			}
13248
13249			if ( preventDefault ) {
13250				event.preventDefault();
13251			}
13252		}
13253	},
13254
13255	_selectFocusedItem: function( event ) {
13256		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13257		if ( !item.hasClass( "ui-state-disabled" ) ) {
13258			this._select( item.data( "ui-selectmenu-item" ), event );
13259		}
13260	},
13261
13262	_select: function( item, event ) {
13263		var oldIndex = this.element[ 0 ].selectedIndex;
13264
13265		// Change native select element
13266		this.element[ 0 ].selectedIndex = item.index;
13267		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
13268		this._setAria( item );
13269		this._trigger( "select", event, { item: item } );
13270
13271		if ( item.index !== oldIndex ) {
13272			this._trigger( "change", event, { item: item } );
13273		}
13274
13275		this.close( event );
13276	},
13277
13278	_setAria: function( item ) {
13279		var id = this.menuItems.eq( item.index ).attr( "id" );
13280
13281		this.button.attr( {
13282			"aria-labelledby": id,
13283			"aria-activedescendant": id
13284		} );
13285		this.menu.attr( "aria-activedescendant", id );
13286	},
13287
13288	_setOption: function( key, value ) {
13289		if ( key === "icons" ) {
13290			var icon = this.button.find( "span.ui-icon" );
13291			this._removeClass( icon, null, this.options.icons.button )
13292				._addClass( icon, null, value.button );
13293		}
13294
13295		this._super( key, value );
13296
13297		if ( key === "appendTo" ) {
13298			this.menuWrap.appendTo( this._appendTo() );
13299		}
13300
13301		if ( key === "width" ) {
13302			this._resizeButton();
13303		}
13304	},
13305
13306	_setOptionDisabled: function( value ) {
13307		this._super( value );
13308
13309		this.menuInstance.option( "disabled", value );
13310		this.button.attr( "aria-disabled", value );
13311		this._toggleClass( this.button, null, "ui-state-disabled", value );
13312
13313		this.element.prop( "disabled", value );
13314		if ( value ) {
13315			this.button.attr( "tabindex", -1 );
13316			this.close();
13317		} else {
13318			this.button.attr( "tabindex", 0 );
13319		}
13320	},
13321
13322	_appendTo: function() {
13323		var element = this.options.appendTo;
13324
13325		if ( element ) {
13326			element = element.jquery || element.nodeType ?
13327				$( element ) :
13328				this.document.find( element ).eq( 0 );
13329		}
13330
13331		if ( !element || !element[ 0 ] ) {
13332			element = this.element.closest( ".ui-front, dialog" );
13333		}
13334
13335		if ( !element.length ) {
13336			element = this.document[ 0 ].body;
13337		}
13338
13339		return element;
13340	},
13341
13342	_toggleAttr: function() {
13343		this.button.attr( "aria-expanded", this.isOpen );
13344
13345		// We can't use two _toggleClass() calls here, because we need to make sure
13346		// we always remove classes first and add them second, otherwise if both classes have the
13347		// same theme class, it will be removed after we add it.
13348		this._removeClass( this.button, "ui-selectmenu-button-" +
13349			( this.isOpen ? "closed" : "open" ) )
13350			._addClass( this.button, "ui-selectmenu-button-" +
13351				( this.isOpen ? "open" : "closed" ) )
13352			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
13353
13354		this.menu.attr( "aria-hidden", !this.isOpen );
13355	},
13356
13357	_resizeButton: function() {
13358		var width = this.options.width;
13359
13360		// For `width: false`, just remove inline style and stop
13361		if ( width === false ) {
13362			this.button.css( "width", "" );
13363			return;
13364		}
13365
13366		// For `width: null`, match the width of the original element
13367		if ( width === null ) {
13368			width = this.element.show().outerWidth();
13369			this.element.hide();
13370		}
13371
13372		this.button.outerWidth( width );
13373	},
13374
13375	_resizeMenu: function() {
13376		this.menu.outerWidth( Math.max(
13377			this.button.outerWidth(),
13378
13379			// Support: IE10
13380			// IE10 wraps long text (possibly a rounding bug)
13381			// so we add 1px to avoid the wrapping
13382			this.menu.width( "" ).outerWidth() + 1
13383		) );
13384	},
13385
13386	_getCreateOptions: function() {
13387		var options = this._super();
13388
13389		options.disabled = this.element.prop( "disabled" );
13390
13391		return options;
13392	},
13393
13394	_parseOptions: function( options ) {
13395		var that = this,
13396			data = [];
13397		options.each( function( index, item ) {
13398			data.push( that._parseOption( $( item ), index ) );
13399		} );
13400		this.items = data;
13401	},
13402
13403	_parseOption: function( option, index ) {
13404		var optgroup = option.parent( "optgroup" );
13405
13406		return {
13407			element: option,
13408			index: index,
13409			value: option.val(),
13410			label: option.text(),
13411			optgroup: optgroup.attr( "label" ) || "",
13412			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
13413		};
13414	},
13415
13416	_destroy: function() {
13417		this._unbindFormResetHandler();
13418		this.menuWrap.remove();
13419		this.button.remove();
13420		this.element.show();
13421		this.element.removeUniqueId();
13422		this.labels.attr( "for", this.ids.element );
13423	}
13424} ] );
13425
13426
13427/*!
13428 * jQuery UI Spinner 1.12.1
13429 * http://jqueryui.com
13430 *
13431 * Copyright jQuery Foundation and other contributors
13432 * Released under the MIT license.
13433 * http://jquery.org/license
13434 */
13435
13436//>>label: Spinner
13437//>>group: Widgets
13438//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
13439//>>docs: http://api.jqueryui.com/spinner/
13440//>>demos: http://jqueryui.com/spinner/
13441//>>css.structure: ../../themes/base/core.css
13442//>>css.structure: ../../themes/base/spinner.css
13443//>>css.theme: ../../themes/base/theme.css
13444
13445
13446
13447function spinnerModifer( fn ) {
13448	return function() {
13449		var previous = this.element.val();
13450		fn.apply( this, arguments );
13451		this._refresh();
13452		if ( previous !== this.element.val() ) {
13453			this._trigger( "change" );
13454		}
13455	};
13456}
13457
13458$.widget( "ui.spinner", {
13459	version: "1.12.1",
13460	defaultElement: "<input>",
13461	widgetEventPrefix: "spin",
13462	options: {
13463		classes: {
13464			"ui-spinner": "ui-corner-all",
13465			"ui-spinner-down": "ui-corner-br",
13466			"ui-spinner-up": "ui-corner-tr"
13467		},
13468		culture: null,
13469		icons: {
13470			down: "ui-icon-triangle-1-s",
13471			up: "ui-icon-triangle-1-n"
13472		},
13473		incremental: true,
13474		max: null,
13475		min: null,
13476		numberFormat: null,
13477		page: 10,
13478		step: 1,
13479
13480		change: null,
13481		spin: null,
13482		start: null,
13483		stop: null
13484	},
13485
13486	_create: function() {
13487
13488		// handle string values that need to be parsed
13489		this._setOption( "max", this.options.max );
13490		this._setOption( "min", this.options.min );
13491		this._setOption( "step", this.options.step );
13492
13493		// Only format if there is a value, prevents the field from being marked
13494		// as invalid in Firefox, see #9573.
13495		if ( this.value() !== "" ) {
13496
13497			// Format the value, but don't constrain.
13498			this._value( this.element.val(), true );
13499		}
13500
13501		this._draw();
13502		this._on( this._events );
13503		this._refresh();
13504
13505		// Turning off autocomplete prevents the browser from remembering the
13506		// value when navigating through history, so we re-enable autocomplete
13507		// if the page is unloaded before the widget is destroyed. #7790
13508		this._on( this.window, {
13509			beforeunload: function() {
13510				this.element.removeAttr( "autocomplete" );
13511			}
13512		} );
13513	},
13514
13515	_getCreateOptions: function() {
13516		var options = this._super();
13517		var element = this.element;
13518
13519		$.each( [ "min", "max", "step" ], function( i, option ) {
13520			var value = element.attr( option );
13521			if ( value != null && value.length ) {
13522				options[ option ] = value;
13523			}
13524		} );
13525
13526		return options;
13527	},
13528
13529	_events: {
13530		keydown: function( event ) {
13531			if ( this._start( event ) && this._keydown( event ) ) {
13532				event.preventDefault();
13533			}
13534		},
13535		keyup: "_stop",
13536		focus: function() {
13537			this.previous = this.element.val();
13538		},
13539		blur: function( event ) {
13540			if ( this.cancelBlur ) {
13541				delete this.cancelBlur;
13542				return;
13543			}
13544
13545			this._stop();
13546			this._refresh();
13547			if ( this.previous !== this.element.val() ) {
13548				this._trigger( "change", event );
13549			}
13550		},
13551		mousewheel: function( event, delta ) {
13552			if ( !delta ) {
13553				return;
13554			}
13555			if ( !this.spinning && !this._start( event ) ) {
13556				return false;
13557			}
13558
13559			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
13560			clearTimeout( this.mousewheelTimer );
13561			this.mousewheelTimer = this._delay( function() {
13562				if ( this.spinning ) {
13563					this._stop( event );
13564				}
13565			}, 100 );
13566			event.preventDefault();
13567		},
13568		"mousedown .ui-spinner-button": function( event ) {
13569			var previous;
13570
13571			// We never want the buttons to have focus; whenever the user is
13572			// interacting with the spinner, the focus should be on the input.
13573			// If the input is focused then this.previous is properly set from
13574			// when the input first received focus. If the input is not focused
13575			// then we need to set this.previous based on the value before spinning.
13576			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
13577				this.previous : this.element.val();
13578			function checkFocus() {
13579				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
13580				if ( !isActive ) {
13581					this.element.trigger( "focus" );
13582					this.previous = previous;
13583
13584					// support: IE
13585					// IE sets focus asynchronously, so we need to check if focus
13586					// moved off of the input because the user clicked on the button.
13587					this._delay( function() {
13588						this.previous = previous;
13589					} );
13590				}
13591			}
13592
13593			// Ensure focus is on (or stays on) the text field
13594			event.preventDefault();
13595			checkFocus.call( this );
13596
13597			// Support: IE
13598			// IE doesn't prevent moving focus even with event.preventDefault()
13599			// so we set a flag to know when we should ignore the blur event
13600			// and check (again) if focus moved off of the input.
13601			this.cancelBlur = true;
13602			this._delay( function() {
13603				delete this.cancelBlur;
13604				checkFocus.call( this );
13605			} );
13606
13607			if ( this._start( event ) === false ) {
13608				return;
13609			}
13610
13611			this._repeat( null, $( event.currentTarget )
13612				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13613		},
13614		"mouseup .ui-spinner-button": "_stop",
13615		"mouseenter .ui-spinner-button": function( event ) {
13616
13617			// button will add ui-state-active if mouse was down while mouseleave and kept down
13618			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
13619				return;
13620			}
13621
13622			if ( this._start( event ) === false ) {
13623				return false;
13624			}
13625			this._repeat( null, $( event.currentTarget )
13626				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13627		},
13628
13629		// TODO: do we really want to consider this a stop?
13630		// shouldn't we just stop the repeater and wait until mouseup before
13631		// we trigger the stop event?
13632		"mouseleave .ui-spinner-button": "_stop"
13633	},
13634
13635	// Support mobile enhanced option and make backcompat more sane
13636	_enhance: function() {
13637		this.uiSpinner = this.element
13638			.attr( "autocomplete", "off" )
13639			.wrap( "<span>" )
13640			.parent()
13641
13642				// Add buttons
13643				.append(
13644					"<a></a><a></a>"
13645				);
13646	},
13647
13648	_draw: function() {
13649		this._enhance();
13650
13651		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
13652		this._addClass( "ui-spinner-input" );
13653
13654		this.element.attr( "role", "spinbutton" );
13655
13656		// Button bindings
13657		this.buttons = this.uiSpinner.children( "a" )
13658			.attr( "tabIndex", -1 )
13659			.attr( "aria-hidden", true )
13660			.button( {
13661				classes: {
13662					"ui-button": ""
13663				}
13664			} );
13665
13666		// TODO: Right now button does not support classes this is already updated in button PR
13667		this._removeClass( this.buttons, "ui-corner-all" );
13668
13669		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
13670		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
13671		this.buttons.first().button( {
13672			"icon": this.options.icons.up,
13673			"showLabel": false
13674		} );
13675		this.buttons.last().button( {
13676			"icon": this.options.icons.down,
13677			"showLabel": false
13678		} );
13679
13680		// IE 6 doesn't understand height: 50% for the buttons
13681		// unless the wrapper has an explicit height
13682		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
13683				this.uiSpinner.height() > 0 ) {
13684			this.uiSpinner.height( this.uiSpinner.height() );
13685		}
13686	},
13687
13688	_keydown: function( event ) {
13689		var options = this.options,
13690			keyCode = $.ui.keyCode;
13691
13692		switch ( event.keyCode ) {
13693		case keyCode.UP:
13694			this._repeat( null, 1, event );
13695			return true;
13696		case keyCode.DOWN:
13697			this._repeat( null, -1, event );
13698			return true;
13699		case keyCode.PAGE_UP:
13700			this._repeat( null, options.page, event );
13701			return true;
13702		case keyCode.PAGE_DOWN:
13703			this._repeat( null, -options.page, event );
13704			return true;
13705		}
13706
13707		return false;
13708	},
13709
13710	_start: function( event ) {
13711		if ( !this.spinning && this._trigger( "start", event ) === false ) {
13712			return false;
13713		}
13714
13715		if ( !this.counter ) {
13716			this.counter = 1;
13717		}
13718		this.spinning = true;
13719		return true;
13720	},
13721
13722	_repeat: function( i, steps, event ) {
13723		i = i || 500;
13724
13725		clearTimeout( this.timer );
13726		this.timer = this._delay( function() {
13727			this._repeat( 40, steps, event );
13728		}, i );
13729
13730		this._spin( steps * this.options.step, event );
13731	},
13732
13733	_spin: function( step, event ) {
13734		var value = this.value() || 0;
13735
13736		if ( !this.counter ) {
13737			this.counter = 1;
13738		}
13739
13740		value = this._adjustValue( value + step * this._increment( this.counter ) );
13741
13742		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
13743			this._value( value );
13744			this.counter++;
13745		}
13746	},
13747
13748	_increment: function( i ) {
13749		var incremental = this.options.incremental;
13750
13751		if ( incremental ) {
13752			return $.isFunction( incremental ) ?
13753				incremental( i ) :
13754				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
13755		}
13756
13757		return 1;
13758	},
13759
13760	_precision: function() {
13761		var precision = this._precisionOf( this.options.step );
13762		if ( this.options.min !== null ) {
13763			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13764		}
13765		return precision;
13766	},
13767
13768	_precisionOf: function( num ) {
13769		var str = num.toString(),
13770			decimal = str.indexOf( "." );
13771		return decimal === -1 ? 0 : str.length - decimal - 1;
13772	},
13773
13774	_adjustValue: function( value ) {
13775		var base, aboveMin,
13776			options = this.options;
13777
13778		// Make sure we're at a valid step
13779		// - find out where we are relative to the base (min or 0)
13780		base = options.min !== null ? options.min : 0;
13781		aboveMin = value - base;
13782
13783		// - round to the nearest step
13784		aboveMin = Math.round( aboveMin / options.step ) * options.step;
13785
13786		// - rounding is based on 0, so adjust back to our base
13787		value = base + aboveMin;
13788
13789		// Fix precision from bad JS floating point math
13790		value = parseFloat( value.toFixed( this._precision() ) );
13791
13792		// Clamp the value
13793		if ( options.max !== null && value > options.max ) {
13794			return options.max;
13795		}
13796		if ( options.min !== null && value < options.min ) {
13797			return options.min;
13798		}
13799
13800		return value;
13801	},
13802
13803	_stop: function( event ) {
13804		if ( !this.spinning ) {
13805			return;
13806		}
13807
13808		clearTimeout( this.timer );
13809		clearTimeout( this.mousewheelTimer );
13810		this.counter = 0;
13811		this.spinning = false;
13812		this._trigger( "stop", event );
13813	},
13814
13815	_setOption: function( key, value ) {
13816		var prevValue, first, last;
13817
13818		if ( key === "culture" || key === "numberFormat" ) {
13819			prevValue = this._parse( this.element.val() );
13820			this.options[ key ] = value;
13821			this.element.val( this._format( prevValue ) );
13822			return;
13823		}
13824
13825		if ( key === "max" || key === "min" || key === "step" ) {
13826			if ( typeof value === "string" ) {
13827				value = this._parse( value );
13828			}
13829		}
13830		if ( key === "icons" ) {
13831			first = this.buttons.first().find( ".ui-icon" );
13832			this._removeClass( first, null, this.options.icons.up );
13833			this._addClass( first, null, value.up );
13834			last = this.buttons.last().find( ".ui-icon" );
13835			this._removeClass( last, null, this.options.icons.down );
13836			this._addClass( last, null, value.down );
13837		}
13838
13839		this._super( key, value );
13840	},
13841
13842	_setOptionDisabled: function( value ) {
13843		this._super( value );
13844
13845		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
13846		this.element.prop( "disabled", !!value );
13847		this.buttons.button( value ? "disable" : "enable" );
13848	},
13849
13850	_setOptions: spinnerModifer( function( options ) {
13851		this._super( options );
13852	} ),
13853
13854	_parse: function( val ) {
13855		if ( typeof val === "string" && val !== "" ) {
13856			val = window.Globalize && this.options.numberFormat ?
13857				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13858		}
13859		return val === "" || isNaN( val ) ? null : val;
13860	},
13861
13862	_format: function( value ) {
13863		if ( value === "" ) {
13864			return "";
13865		}
13866		return window.Globalize && this.options.numberFormat ?
13867			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13868			value;
13869	},
13870
13871	_refresh: function() {
13872		this.element.attr( {
13873			"aria-valuemin": this.options.min,
13874			"aria-valuemax": this.options.max,
13875
13876			// TODO: what should we do with values that can't be parsed?
13877			"aria-valuenow": this._parse( this.element.val() )
13878		} );
13879	},
13880
13881	isValid: function() {
13882		var value = this.value();
13883
13884		// Null is invalid
13885		if ( value === null ) {
13886			return false;
13887		}
13888
13889		// If value gets adjusted, it's invalid
13890		return value === this._adjustValue( value );
13891	},
13892
13893	// Update the value without triggering change
13894	_value: function( value, allowAny ) {
13895		var parsed;
13896		if ( value !== "" ) {
13897			parsed = this._parse( value );
13898			if ( parsed !== null ) {
13899				if ( !allowAny ) {
13900					parsed = this._adjustValue( parsed );
13901				}
13902				value = this._format( parsed );
13903			}
13904		}
13905		this.element.val( value );
13906		this._refresh();
13907	},
13908
13909	_destroy: function() {
13910		this.element
13911			.prop( "disabled", false )
13912			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
13913
13914		this.uiSpinner.replaceWith( this.element );
13915	},
13916
13917	stepUp: spinnerModifer( function( steps ) {
13918		this._stepUp( steps );
13919	} ),
13920	_stepUp: function( steps ) {
13921		if ( this._start() ) {
13922			this._spin( ( steps || 1 ) * this.options.step );
13923			this._stop();
13924		}
13925	},
13926
13927	stepDown: spinnerModifer( function( steps ) {
13928		this._stepDown( steps );
13929	} ),
13930	_stepDown: function( steps ) {
13931		if ( this._start() ) {
13932			this._spin( ( steps || 1 ) * -this.options.step );
13933			this._stop();
13934		}
13935	},
13936
13937	pageUp: spinnerModifer( function( pages ) {
13938		this._stepUp( ( pages || 1 ) * this.options.page );
13939	} ),
13940
13941	pageDown: spinnerModifer( function( pages ) {
13942		this._stepDown( ( pages || 1 ) * this.options.page );
13943	} ),
13944
13945	value: function( newVal ) {
13946		if ( !arguments.length ) {
13947			return this._parse( this.element.val() );
13948		}
13949		spinnerModifer( this._value ).call( this, newVal );
13950	},
13951
13952	widget: function() {
13953		return this.uiSpinner;
13954	}
13955} );
13956
13957// DEPRECATED
13958// TODO: switch return back to widget declaration at top of file when this is removed
13959if ( $.uiBackCompat !== false ) {
13960
13961	// Backcompat for spinner html extension points
13962	$.widget( "ui.spinner", $.ui.spinner, {
13963		_enhance: function() {
13964			this.uiSpinner = this.element
13965				.attr( "autocomplete", "off" )
13966				.wrap( this._uiSpinnerHtml() )
13967				.parent()
13968
13969					// Add buttons
13970					.append( this._buttonHtml() );
13971		},
13972		_uiSpinnerHtml: function() {
13973			return "<span>";
13974		},
13975
13976		_buttonHtml: function() {
13977			return "<a></a><a></a>";
13978		}
13979	} );
13980}
13981
13982var widgetsSpinner = $.ui.spinner;
13983
13984
13985/*!
13986 * jQuery UI Tabs 1.12.1
13987 * http://jqueryui.com
13988 *
13989 * Copyright jQuery Foundation and other contributors
13990 * Released under the MIT license.
13991 * http://jquery.org/license
13992 */
13993
13994//>>label: Tabs
13995//>>group: Widgets
13996//>>description: Transforms a set of container elements into a tab structure.
13997//>>docs: http://api.jqueryui.com/tabs/
13998//>>demos: http://jqueryui.com/tabs/
13999//>>css.structure: ../../themes/base/core.css
14000//>>css.structure: ../../themes/base/tabs.css
14001//>>css.theme: ../../themes/base/theme.css
14002
14003
14004
14005$.widget( "ui.tabs", {
14006	version: "1.12.1",
14007	delay: 300,
14008	options: {
14009		active: null,
14010		classes: {
14011			"ui-tabs": "ui-corner-all",
14012			"ui-tabs-nav": "ui-corner-all",
14013			"ui-tabs-panel": "ui-corner-bottom",
14014			"ui-tabs-tab": "ui-corner-top"
14015		},
14016		collapsible: false,
14017		event: "click",
14018		heightStyle: "content",
14019		hide: null,
14020		show: null,
14021
14022		// Callbacks
14023		activate: null,
14024		beforeActivate: null,
14025		beforeLoad: null,
14026		load: null
14027	},
14028
14029	_isLocal: ( function() {
14030		var rhash = /#.*$/;
14031
14032		return function( anchor ) {
14033			var anchorUrl, locationUrl;
14034
14035			anchorUrl = anchor.href.replace( rhash, "" );
14036			locationUrl = location.href.replace( rhash, "" );
14037
14038			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
14039			try {
14040				anchorUrl = decodeURIComponent( anchorUrl );
14041			} catch ( error ) {}
14042			try {
14043				locationUrl = decodeURIComponent( locationUrl );
14044			} catch ( error ) {}
14045
14046			return anchor.hash.length > 1 && anchorUrl === locationUrl;
14047		};
14048	} )(),
14049
14050	_create: function() {
14051		var that = this,
14052			options = this.options;
14053
14054		this.running = false;
14055
14056		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
14057		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
14058
14059		this._processTabs();
14060		options.active = this._initialActive();
14061
14062		// Take disabling tabs via class attribute from HTML
14063		// into account and update option properly.
14064		if ( $.isArray( options.disabled ) ) {
14065			options.disabled = $.unique( options.disabled.concat(
14066				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
14067					return that.tabs.index( li );
14068				} )
14069			) ).sort();
14070		}
14071
14072		// Check for length avoids error when initializing empty list
14073		if ( this.options.active !== false && this.anchors.length ) {
14074			this.active = this._findActive( options.active );
14075		} else {
14076			this.active = $();
14077		}
14078
14079		this._refresh();
14080
14081		if ( this.active.length ) {
14082			this.load( options.active );
14083		}
14084	},
14085
14086	_initialActive: function() {
14087		var active = this.options.active,
14088			collapsible = this.options.collapsible,
14089			locationHash = location.hash.substring( 1 );
14090
14091		if ( active === null ) {
14092
14093			// check the fragment identifier in the URL
14094			if ( locationHash ) {
14095				this.tabs.each( function( i, tab ) {
14096					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
14097						active = i;
14098						return false;
14099					}
14100				} );
14101			}
14102
14103			// Check for a tab marked active via a class
14104			if ( active === null ) {
14105				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
14106			}
14107
14108			// No active tab, set to false
14109			if ( active === null || active === -1 ) {
14110				active = this.tabs.length ? 0 : false;
14111			}
14112		}
14113
14114		// Handle numbers: negative, out of range
14115		if ( active !== false ) {
14116			active = this.tabs.index( this.tabs.eq( active ) );
14117			if ( active === -1 ) {
14118				active = collapsible ? false : 0;
14119			}
14120		}
14121
14122		// Don't allow collapsible: false and active: false
14123		if ( !collapsible && active === false && this.anchors.length ) {
14124			active = 0;
14125		}
14126
14127		return active;
14128	},
14129
14130	_getCreateEventData: function() {
14131		return {
14132			tab: this.active,
14133			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
14134		};
14135	},
14136
14137	_tabKeydown: function( event ) {
14138		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
14139			selectedIndex = this.tabs.index( focusedTab ),
14140			goingForward = true;
14141
14142		if ( this._handlePageNav( event ) ) {
14143			return;
14144		}
14145
14146		switch ( event.keyCode ) {
14147		case $.ui.keyCode.RIGHT:
14148		case $.ui.keyCode.DOWN:
14149			selectedIndex++;
14150			break;
14151		case $.ui.keyCode.UP:
14152		case $.ui.keyCode.LEFT:
14153			goingForward = false;
14154			selectedIndex--;
14155			break;
14156		case $.ui.keyCode.END:
14157			selectedIndex = this.anchors.length - 1;
14158			break;
14159		case $.ui.keyCode.HOME:
14160			selectedIndex = 0;
14161			break;
14162		case $.ui.keyCode.SPACE:
14163
14164			// Activate only, no collapsing
14165			event.preventDefault();
14166			clearTimeout( this.activating );
14167			this._activate( selectedIndex );
14168			return;
14169		case $.ui.keyCode.ENTER:
14170
14171			// Toggle (cancel delayed activation, allow collapsing)
14172			event.preventDefault();
14173			clearTimeout( this.activating );
14174
14175			// Determine if we should collapse or activate
14176			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
14177			return;
14178		default:
14179			return;
14180		}
14181
14182		// Focus the appropriate tab, based on which key was pressed
14183		event.preventDefault();
14184		clearTimeout( this.activating );
14185		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
14186
14187		// Navigating with control/command key will prevent automatic activation
14188		if ( !event.ctrlKey && !event.metaKey ) {
14189
14190			// Update aria-selected immediately so that AT think the tab is already selected.
14191			// Otherwise AT may confuse the user by stating that they need to activate the tab,
14192			// but the tab will already be activated by the time the announcement finishes.
14193			focusedTab.attr( "aria-selected", "false" );
14194			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
14195
14196			this.activating = this._delay( function() {
14197				this.option( "active", selectedIndex );
14198			}, this.delay );
14199		}
14200	},
14201
14202	_panelKeydown: function( event ) {
14203		if ( this._handlePageNav( event ) ) {
14204			return;
14205		}
14206
14207		// Ctrl+up moves focus to the current tab
14208		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
14209			event.preventDefault();
14210			this.active.trigger( "focus" );
14211		}
14212	},
14213
14214	// Alt+page up/down moves focus to the previous/next tab (and activates)
14215	_handlePageNav: function( event ) {
14216		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
14217			this._activate( this._focusNextTab( this.options.active - 1, false ) );
14218			return true;
14219		}
14220		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
14221			this._activate( this._focusNextTab( this.options.active + 1, true ) );
14222			return true;
14223		}
14224	},
14225
14226	_findNextTab: function( index, goingForward ) {
14227		var lastTabIndex = this.tabs.length - 1;
14228
14229		function constrain() {
14230			if ( index > lastTabIndex ) {
14231				index = 0;
14232			}
14233			if ( index < 0 ) {
14234				index = lastTabIndex;
14235			}
14236			return index;
14237		}
14238
14239		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14240			index = goingForward ? index + 1 : index - 1;
14241		}
14242
14243		return index;
14244	},
14245
14246	_focusNextTab: function( index, goingForward ) {
14247		index = this._findNextTab( index, goingForward );
14248		this.tabs.eq( index ).trigger( "focus" );
14249		return index;
14250	},
14251
14252	_setOption: function( key, value ) {
14253		if ( key === "active" ) {
14254
14255			// _activate() will handle invalid values and update this.options
14256			this._activate( value );
14257			return;
14258		}
14259
14260		this._super( key, value );
14261
14262		if ( key === "collapsible" ) {
14263			this._toggleClass( "ui-tabs-collapsible", null, value );
14264
14265			// Setting collapsible: false while collapsed; open first panel
14266			if ( !value && this.options.active === false ) {
14267				this._activate( 0 );
14268			}
14269		}
14270
14271		if ( key === "event" ) {
14272			this._setupEvents( value );
14273		}
14274
14275		if ( key === "heightStyle" ) {
14276			this._setupHeightStyle( value );
14277		}
14278	},
14279
14280	_sanitizeSelector: function( hash ) {
14281		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
14282	},
14283
14284	refresh: function() {
14285		var options = this.options,
14286			lis = this.tablist.children( ":has(a[href])" );
14287
14288		// Get disabled tabs from class attribute from HTML
14289		// this will get converted to a boolean if needed in _refresh()
14290		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
14291			return lis.index( tab );
14292		} );
14293
14294		this._processTabs();
14295
14296		// Was collapsed or no tabs
14297		if ( options.active === false || !this.anchors.length ) {
14298			options.active = false;
14299			this.active = $();
14300
14301		// was active, but active tab is gone
14302		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
14303
14304			// all remaining tabs are disabled
14305			if ( this.tabs.length === options.disabled.length ) {
14306				options.active = false;
14307				this.active = $();
14308
14309			// activate previous tab
14310			} else {
14311				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
14312			}
14313
14314		// was active, active tab still exists
14315		} else {
14316
14317			// make sure active index is correct
14318			options.active = this.tabs.index( this.active );
14319		}
14320
14321		this._refresh();
14322	},
14323
14324	_refresh: function() {
14325		this._setOptionDisabled( this.options.disabled );
14326		this._setupEvents( this.options.event );
14327		this._setupHeightStyle( this.options.heightStyle );
14328
14329		this.tabs.not( this.active ).attr( {
14330			"aria-selected": "false",
14331			"aria-expanded": "false",
14332			tabIndex: -1
14333		} );
14334		this.panels.not( this._getPanelForTab( this.active ) )
14335			.hide()
14336			.attr( {
14337				"aria-hidden": "true"
14338			} );
14339
14340		// Make sure one tab is in the tab order
14341		if ( !this.active.length ) {
14342			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
14343		} else {
14344			this.active
14345				.attr( {
14346					"aria-selected": "true",
14347					"aria-expanded": "true",
14348					tabIndex: 0
14349				} );
14350			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
14351			this._getPanelForTab( this.active )
14352				.show()
14353				.attr( {
14354					"aria-hidden": "false"
14355				} );
14356		}
14357	},
14358
14359	_processTabs: function() {
14360		var that = this,
14361			prevTabs = this.tabs,
14362			prevAnchors = this.anchors,
14363			prevPanels = this.panels;
14364
14365		this.tablist = this._getList().attr( "role", "tablist" );
14366		this._addClass( this.tablist, "ui-tabs-nav",
14367			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
14368
14369		// Prevent users from focusing disabled tabs via click
14370		this.tablist
14371			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
14372				if ( $( this ).is( ".ui-state-disabled" ) ) {
14373					event.preventDefault();
14374				}
14375			} )
14376
14377			// Support: IE <9
14378			// Preventing the default action in mousedown doesn't prevent IE
14379			// from focusing the element, so if the anchor gets focused, blur.
14380			// We don't have to worry about focusing the previously focused
14381			// element since clicking on a non-focusable element should focus
14382			// the body anyway.
14383			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
14384				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
14385					this.blur();
14386				}
14387			} );
14388
14389		this.tabs = this.tablist.find( "> li:has(a[href])" )
14390			.attr( {
14391				role: "tab",
14392				tabIndex: -1
14393			} );
14394		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
14395
14396		this.anchors = this.tabs.map( function() {
14397			return $( "a", this )[ 0 ];
14398		} )
14399			.attr( {
14400				role: "presentation",
14401				tabIndex: -1
14402			} );
14403		this._addClass( this.anchors, "ui-tabs-anchor" );
14404
14405		this.panels = $();
14406
14407		this.anchors.each( function( i, anchor ) {
14408			var selector, panel, panelId,
14409				anchorId = $( anchor ).uniqueId().attr( "id" ),
14410				tab = $( anchor ).closest( "li" ),
14411				originalAriaControls = tab.attr( "aria-controls" );
14412
14413			// Inline tab
14414			if ( that._isLocal( anchor ) ) {
14415				selector = anchor.hash;
14416				panelId = selector.substring( 1 );
14417				panel = that.element.find( that._sanitizeSelector( selector ) );
14418
14419			// remote tab
14420			} else {
14421
14422				// If the tab doesn't already have aria-controls,
14423				// generate an id by using a throw-away element
14424				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
14425				selector = "#" + panelId;
14426				panel = that.element.find( selector );
14427				if ( !panel.length ) {
14428					panel = that._createPanel( panelId );
14429					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
14430				}
14431				panel.attr( "aria-live", "polite" );
14432			}
14433
14434			if ( panel.length ) {
14435				that.panels = that.panels.add( panel );
14436			}
14437			if ( originalAriaControls ) {
14438				tab.data( "ui-tabs-aria-controls", originalAriaControls );
14439			}
14440			tab.attr( {
14441				"aria-controls": panelId,
14442				"aria-labelledby": anchorId
14443			} );
14444			panel.attr( "aria-labelledby", anchorId );
14445		} );
14446
14447		this.panels.attr( "role", "tabpanel" );
14448		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
14449
14450		// Avoid memory leaks (#10056)
14451		if ( prevTabs ) {
14452			this._off( prevTabs.not( this.tabs ) );
14453			this._off( prevAnchors.not( this.anchors ) );
14454			this._off( prevPanels.not( this.panels ) );
14455		}
14456	},
14457
14458	// Allow overriding how to find the list for rare usage scenarios (#7715)
14459	_getList: function() {
14460		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
14461	},
14462
14463	_createPanel: function( id ) {
14464		return $( "<div>" )
14465			.attr( "id", id )
14466			.data( "ui-tabs-destroy", true );
14467	},
14468
14469	_setOptionDisabled: function( disabled ) {
14470		var currentItem, li, i;
14471
14472		if ( $.isArray( disabled ) ) {
14473			if ( !disabled.length ) {
14474				disabled = false;
14475			} else if ( disabled.length === this.anchors.length ) {
14476				disabled = true;
14477			}
14478		}
14479
14480		// Disable tabs
14481		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
14482			currentItem = $( li );
14483			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
14484				currentItem.attr( "aria-disabled", "true" );
14485				this._addClass( currentItem, null, "ui-state-disabled" );
14486			} else {
14487				currentItem.removeAttr( "aria-disabled" );
14488				this._removeClass( currentItem, null, "ui-state-disabled" );
14489			}
14490		}
14491
14492		this.options.disabled = disabled;
14493
14494		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
14495			disabled === true );
14496	},
14497
14498	_setupEvents: function( event ) {
14499		var events = {};
14500		if ( event ) {
14501			$.each( event.split( " " ), function( index, eventName ) {
14502				events[ eventName ] = "_eventHandler";
14503			} );
14504		}
14505
14506		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
14507
14508		// Always prevent the default action, even when disabled
14509		this._on( true, this.anchors, {
14510			click: function( event ) {
14511				event.preventDefault();
14512			}
14513		} );
14514		this._on( this.anchors, events );
14515		this._on( this.tabs, { keydown: "_tabKeydown" } );
14516		this._on( this.panels, { keydown: "_panelKeydown" } );
14517
14518		this._focusable( this.tabs );
14519		this._hoverable( this.tabs );
14520	},
14521
14522	_setupHeightStyle: function( heightStyle ) {
14523		var maxHeight,
14524			parent = this.element.parent();
14525
14526		if ( heightStyle === "fill" ) {
14527			maxHeight = parent.height();
14528			maxHeight -= this.element.outerHeight() - this.element.height();
14529
14530			this.element.siblings( ":visible" ).each( function() {
14531				var elem = $( this ),
14532					position = elem.css( "position" );
14533
14534				if ( position === "absolute" || position === "fixed" ) {
14535					return;
14536				}
14537				maxHeight -= elem.outerHeight( true );
14538			} );
14539
14540			this.element.children().not( this.panels ).each( function() {
14541				maxHeight -= $( this ).outerHeight( true );
14542			} );
14543
14544			this.panels.each( function() {
14545				$( this ).height( Math.max( 0, maxHeight -
14546					$( this ).innerHeight() + $( this ).height() ) );
14547			} )
14548				.css( "overflow", "auto" );
14549		} else if ( heightStyle === "auto" ) {
14550			maxHeight = 0;
14551			this.panels.each( function() {
14552				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
14553			} ).height( maxHeight );
14554		}
14555	},
14556
14557	_eventHandler: function( event ) {
14558		var options = this.options,
14559			active = this.active,
14560			anchor = $( event.currentTarget ),
14561			tab = anchor.closest( "li" ),
14562			clickedIsActive = tab[ 0 ] === active[ 0 ],
14563			collapsing = clickedIsActive && options.collapsible,
14564			toShow = collapsing ? $() : this._getPanelForTab( tab ),
14565			toHide = !active.length ? $() : this._getPanelForTab( active ),
14566			eventData = {
14567				oldTab: active,
14568				oldPanel: toHide,
14569				newTab: collapsing ? $() : tab,
14570				newPanel: toShow
14571			};
14572
14573		event.preventDefault();
14574
14575		if ( tab.hasClass( "ui-state-disabled" ) ||
14576
14577				// tab is already loading
14578				tab.hasClass( "ui-tabs-loading" ) ||
14579
14580				// can't switch durning an animation
14581				this.running ||
14582
14583				// click on active header, but not collapsible
14584				( clickedIsActive && !options.collapsible ) ||
14585
14586				// allow canceling activation
14587				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
14588			return;
14589		}
14590
14591		options.active = collapsing ? false : this.tabs.index( tab );
14592
14593		this.active = clickedIsActive ? $() : tab;
14594		if ( this.xhr ) {
14595			this.xhr.abort();
14596		}
14597
14598		if ( !toHide.length && !toShow.length ) {
14599			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
14600		}
14601
14602		if ( toShow.length ) {
14603			this.load( this.tabs.index( tab ), event );
14604		}
14605		this._toggle( event, eventData );
14606	},
14607
14608	// Handles show/hide for selecting tabs
14609	_toggle: function( event, eventData ) {
14610		var that = this,
14611			toShow = eventData.newPanel,
14612			toHide = eventData.oldPanel;
14613
14614		this.running = true;
14615
14616		function complete() {
14617			that.running = false;
14618			that._trigger( "activate", event, eventData );
14619		}
14620
14621		function show() {
14622			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
14623
14624			if ( toShow.length && that.options.show ) {
14625				that._show( toShow, that.options.show, complete );
14626			} else {
14627				toShow.show();
14628				complete();
14629			}
14630		}
14631
14632		// Start out by hiding, then showing, then completing
14633		if ( toHide.length && this.options.hide ) {
14634			this._hide( toHide, this.options.hide, function() {
14635				that._removeClass( eventData.oldTab.closest( "li" ),
14636					"ui-tabs-active", "ui-state-active" );
14637				show();
14638			} );
14639		} else {
14640			this._removeClass( eventData.oldTab.closest( "li" ),
14641				"ui-tabs-active", "ui-state-active" );
14642			toHide.hide();
14643			show();
14644		}
14645
14646		toHide.attr( "aria-hidden", "true" );
14647		eventData.oldTab.attr( {
14648			"aria-selected": "false",
14649			"aria-expanded": "false"
14650		} );
14651
14652		// If we're switching tabs, remove the old tab from the tab order.
14653		// If we're opening from collapsed state, remove the previous tab from the tab order.
14654		// If we're collapsing, then keep the collapsing tab in the tab order.
14655		if ( toShow.length && toHide.length ) {
14656			eventData.oldTab.attr( "tabIndex", -1 );
14657		} else if ( toShow.length ) {
14658			this.tabs.filter( function() {
14659				return $( this ).attr( "tabIndex" ) === 0;
14660			} )
14661				.attr( "tabIndex", -1 );
14662		}
14663
14664		toShow.attr( "aria-hidden", "false" );
14665		eventData.newTab.attr( {
14666			"aria-selected": "true",
14667			"aria-expanded": "true",
14668			tabIndex: 0
14669		} );
14670	},
14671
14672	_activate: function( index ) {
14673		var anchor,
14674			active = this._findActive( index );
14675
14676		// Trying to activate the already active panel
14677		if ( active[ 0 ] === this.active[ 0 ] ) {
14678			return;
14679		}
14680
14681		// Trying to collapse, simulate a click on the current active header
14682		if ( !active.length ) {
14683			active = this.active;
14684		}
14685
14686		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
14687		this._eventHandler( {
14688			target: anchor,
14689			currentTarget: anchor,
14690			preventDefault: $.noop
14691		} );
14692	},
14693
14694	_findActive: function( index ) {
14695		return index === false ? $() : this.tabs.eq( index );
14696	},
14697
14698	_getIndex: function( index ) {
14699
14700		// meta-function to give users option to provide a href string instead of a numerical index.
14701		if ( typeof index === "string" ) {
14702			index = this.anchors.index( this.anchors.filter( "[href$='" +
14703				$.ui.escapeSelector( index ) + "']" ) );
14704		}
14705
14706		return index;
14707	},
14708
14709	_destroy: function() {
14710		if ( this.xhr ) {
14711			this.xhr.abort();
14712		}
14713
14714		this.tablist
14715			.removeAttr( "role" )
14716			.off( this.eventNamespace );
14717
14718		this.anchors
14719			.removeAttr( "role tabIndex" )
14720			.removeUniqueId();
14721
14722		this.tabs.add( this.panels ).each( function() {
14723			if ( $.data( this, "ui-tabs-destroy" ) ) {
14724				$( this ).remove();
14725			} else {
14726				$( this ).removeAttr( "role tabIndex " +
14727					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
14728			}
14729		} );
14730
14731		this.tabs.each( function() {
14732			var li = $( this ),
14733				prev = li.data( "ui-tabs-aria-controls" );
14734			if ( prev ) {
14735				li
14736					.attr( "aria-controls", prev )
14737					.removeData( "ui-tabs-aria-controls" );
14738			} else {
14739				li.removeAttr( "aria-controls" );
14740			}
14741		} );
14742
14743		this.panels.show();
14744
14745		if ( this.options.heightStyle !== "content" ) {
14746			this.panels.css( "height", "" );
14747		}
14748	},
14749
14750	enable: function( index ) {
14751		var disabled = this.options.disabled;
14752		if ( disabled === false ) {
14753			return;
14754		}
14755
14756		if ( index === undefined ) {
14757			disabled = false;
14758		} else {
14759			index = this._getIndex( index );
14760			if ( $.isArray( disabled ) ) {
14761				disabled = $.map( disabled, function( num ) {
14762					return num !== index ? num : null;
14763				} );
14764			} else {
14765				disabled = $.map( this.tabs, function( li, num ) {
14766					return num !== index ? num : null;
14767				} );
14768			}
14769		}
14770		this._setOptionDisabled( disabled );
14771	},
14772
14773	disable: function( index ) {
14774		var disabled = this.options.disabled;
14775		if ( disabled === true ) {
14776			return;
14777		}
14778
14779		if ( index === undefined ) {
14780			disabled = true;
14781		} else {
14782			index = this._getIndex( index );
14783			if ( $.inArray( index, disabled ) !== -1 ) {
14784				return;
14785			}
14786			if ( $.isArray( disabled ) ) {
14787				disabled = $.merge( [ index ], disabled ).sort();
14788			} else {
14789				disabled = [ index ];
14790			}
14791		}
14792		this._setOptionDisabled( disabled );
14793	},
14794
14795	load: function( index, event ) {
14796		index = this._getIndex( index );
14797		var that = this,
14798			tab = this.tabs.eq( index ),
14799			anchor = tab.find( ".ui-tabs-anchor" ),
14800			panel = this._getPanelForTab( tab ),
14801			eventData = {
14802				tab: tab,
14803				panel: panel
14804			},
14805			complete = function( jqXHR, status ) {
14806				if ( status === "abort" ) {
14807					that.panels.stop( false, true );
14808				}
14809
14810				that._removeClass( tab, "ui-tabs-loading" );
14811				panel.removeAttr( "aria-busy" );
14812
14813				if ( jqXHR === that.xhr ) {
14814					delete that.xhr;
14815				}
14816			};
14817
14818		// Not remote
14819		if ( this._isLocal( anchor[ 0 ] ) ) {
14820			return;
14821		}
14822
14823		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
14824
14825		// Support: jQuery <1.8
14826		// jQuery <1.8 returns false if the request is canceled in beforeSend,
14827		// but as of 1.8, $.ajax() always returns a jqXHR object.
14828		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
14829			this._addClass( tab, "ui-tabs-loading" );
14830			panel.attr( "aria-busy", "true" );
14831
14832			this.xhr
14833				.done( function( response, status, jqXHR ) {
14834
14835					// support: jQuery <1.8
14836					// http://bugs.jquery.com/ticket/11778
14837					setTimeout( function() {
14838						panel.html( response );
14839						that._trigger( "load", event, eventData );
14840
14841						complete( jqXHR, status );
14842					}, 1 );
14843				} )
14844				.fail( function( jqXHR, status ) {
14845
14846					// support: jQuery <1.8
14847					// http://bugs.jquery.com/ticket/11778
14848					setTimeout( function() {
14849						complete( jqXHR, status );
14850					}, 1 );
14851				} );
14852		}
14853	},
14854
14855	_ajaxSettings: function( anchor, event, eventData ) {
14856		var that = this;
14857		return {
14858
14859			// Support: IE <11 only
14860			// Strip any hash that exists to prevent errors with the Ajax request
14861			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
14862			beforeSend: function( jqXHR, settings ) {
14863				return that._trigger( "beforeLoad", event,
14864					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
14865			}
14866		};
14867	},
14868
14869	_getPanelForTab: function( tab ) {
14870		var id = $( tab ).attr( "aria-controls" );
14871		return this.element.find( this._sanitizeSelector( "#" + id ) );
14872	}
14873} );
14874
14875// DEPRECATED
14876// TODO: Switch return back to widget declaration at top of file when this is removed
14877if ( $.uiBackCompat !== false ) {
14878
14879	// Backcompat for ui-tab class (now ui-tabs-tab)
14880	$.widget( "ui.tabs", $.ui.tabs, {
14881		_processTabs: function() {
14882			this._superApply( arguments );
14883			this._addClass( this.tabs, "ui-tab" );
14884		}
14885	} );
14886}
14887
14888var widgetsTabs = $.ui.tabs;
14889
14890
14891/*!
14892 * jQuery UI Tooltip 1.12.1
14893 * http://jqueryui.com
14894 *
14895 * Copyright jQuery Foundation and other contributors
14896 * Released under the MIT license.
14897 * http://jquery.org/license
14898 */
14899
14900//>>label: Tooltip
14901//>>group: Widgets
14902//>>description: Shows additional information for any element on hover or focus.
14903//>>docs: http://api.jqueryui.com/tooltip/
14904//>>demos: http://jqueryui.com/tooltip/
14905//>>css.structure: ../../themes/base/core.css
14906//>>css.structure: ../../themes/base/tooltip.css
14907//>>css.theme: ../../themes/base/theme.css
14908
14909
14910
14911$.widget( "ui.tooltip", {
14912	version: "1.12.1",
14913	options: {
14914		classes: {
14915			"ui-tooltip": "ui-corner-all ui-widget-shadow"
14916		},
14917		content: function() {
14918
14919			// support: IE<9, Opera in jQuery <1.7
14920			// .text() can't accept undefined, so coerce to a string
14921			var title = $( this ).attr( "title" ) || "";
14922
14923			// Escape title, since we're going from an attribute to raw HTML
14924			return $( "<a>" ).text( title ).html();
14925		},
14926		hide: true,
14927
14928		// Disabled elements have inconsistent behavior across browsers (#8661)
14929		items: "[title]:not([disabled])",
14930		position: {
14931			my: "left top+15",
14932			at: "left bottom",
14933			collision: "flipfit flip"
14934		},
14935		show: true,
14936		track: false,
14937
14938		// Callbacks
14939		close: null,
14940		open: null
14941	},
14942
14943	_addDescribedBy: function( elem, id ) {
14944		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
14945		describedby.push( id );
14946		elem
14947			.data( "ui-tooltip-id", id )
14948			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14949	},
14950
14951	_removeDescribedBy: function( elem ) {
14952		var id = elem.data( "ui-tooltip-id" ),
14953			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
14954			index = $.inArray( id, describedby );
14955
14956		if ( index !== -1 ) {
14957			describedby.splice( index, 1 );
14958		}
14959
14960		elem.removeData( "ui-tooltip-id" );
14961		describedby = $.trim( describedby.join( " " ) );
14962		if ( describedby ) {
14963			elem.attr( "aria-describedby", describedby );
14964		} else {
14965			elem.removeAttr( "aria-describedby" );
14966		}
14967	},
14968
14969	_create: function() {
14970		this._on( {
14971			mouseover: "open",
14972			focusin: "open"
14973		} );
14974
14975		// IDs of generated tooltips, needed for destroy
14976		this.tooltips = {};
14977
14978		// IDs of parent tooltips where we removed the title attribute
14979		this.parents = {};
14980
14981		// Append the aria-live region so tooltips announce correctly
14982		this.liveRegion = $( "<div>" )
14983			.attr( {
14984				role: "log",
14985				"aria-live": "assertive",
14986				"aria-relevant": "additions"
14987			} )
14988			.appendTo( this.document[ 0 ].body );
14989		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
14990
14991		this.disabledTitles = $( [] );
14992	},
14993
14994	_setOption: function( key, value ) {
14995		var that = this;
14996
14997		this._super( key, value );
14998
14999		if ( key === "content" ) {
15000			$.each( this.tooltips, function( id, tooltipData ) {
15001				that._updateContent( tooltipData.element );
15002			} );
15003		}
15004	},
15005
15006	_setOptionDisabled: function( value ) {
15007		this[ value ? "_disable" : "_enable" ]();
15008	},
15009
15010	_disable: function() {
15011		var that = this;
15012
15013		// Close open tooltips
15014		$.each( this.tooltips, function( id, tooltipData ) {
15015			var event = $.Event( "blur" );
15016			event.target = event.currentTarget = tooltipData.element[ 0 ];
15017			that.close( event, true );
15018		} );
15019
15020		// Remove title attributes to prevent native tooltips
15021		this.disabledTitles = this.disabledTitles.add(
15022			this.element.find( this.options.items ).addBack()
15023				.filter( function() {
15024					var element = $( this );
15025					if ( element.is( "[title]" ) ) {
15026						return element
15027							.data( "ui-tooltip-title", element.attr( "title" ) )
15028							.removeAttr( "title" );
15029					}
15030				} )
15031		);
15032	},
15033
15034	_enable: function() {
15035
15036		// restore title attributes
15037		this.disabledTitles.each( function() {
15038			var element = $( this );
15039			if ( element.data( "ui-tooltip-title" ) ) {
15040				element.attr( "title", element.data( "ui-tooltip-title" ) );
15041			}
15042		} );
15043		this.disabledTitles = $( [] );
15044	},
15045
15046	open: function( event ) {
15047		var that = this,
15048			target = $( event ? event.target : this.element )
15049
15050				// we need closest here due to mouseover bubbling,
15051				// but always pointing at the same event target
15052				.closest( this.options.items );
15053
15054		// No element to show a tooltip for or the tooltip is already open
15055		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
15056			return;
15057		}
15058
15059		if ( target.attr( "title" ) ) {
15060			target.data( "ui-tooltip-title", target.attr( "title" ) );
15061		}
15062
15063		target.data( "ui-tooltip-open", true );
15064
15065		// Kill parent tooltips, custom or native, for hover
15066		if ( event && event.type === "mouseover" ) {
15067			target.parents().each( function() {
15068				var parent = $( this ),
15069					blurEvent;
15070				if ( parent.data( "ui-tooltip-open" ) ) {
15071					blurEvent = $.Event( "blur" );
15072					blurEvent.target = blurEvent.currentTarget = this;
15073					that.close( blurEvent, true );
15074				}
15075				if ( parent.attr( "title" ) ) {
15076					parent.uniqueId();
15077					that.parents[ this.id ] = {
15078						element: this,
15079						title: parent.attr( "title" )
15080					};
15081					parent.attr( "title", "" );
15082				}
15083			} );
15084		}
15085
15086		this._registerCloseHandlers( event, target );
15087		this._updateContent( target, event );
15088	},
15089
15090	_updateContent: function( target, event ) {
15091		var content,
15092			contentOption = this.options.content,
15093			that = this,
15094			eventType = event ? event.type : null;
15095
15096		if ( typeof contentOption === "string" || contentOption.nodeType ||
15097				contentOption.jquery ) {
15098			return this._open( event, target, contentOption );
15099		}
15100
15101		content = contentOption.call( target[ 0 ], function( response ) {
15102
15103			// IE may instantly serve a cached response for ajax requests
15104			// delay this call to _open so the other call to _open runs first
15105			that._delay( function() {
15106
15107				// Ignore async response if tooltip was closed already
15108				if ( !target.data( "ui-tooltip-open" ) ) {
15109					return;
15110				}
15111
15112				// JQuery creates a special event for focusin when it doesn't
15113				// exist natively. To improve performance, the native event
15114				// object is reused and the type is changed. Therefore, we can't
15115				// rely on the type being correct after the event finished
15116				// bubbling, so we set it back to the previous value. (#8740)
15117				if ( event ) {
15118					event.type = eventType;
15119				}
15120				this._open( event, target, response );
15121			} );
15122		} );
15123		if ( content ) {
15124			this._open( event, target, content );
15125		}
15126	},
15127
15128	_open: function( event, target, content ) {
15129		var tooltipData, tooltip, delayedShow, a11yContent,
15130			positionOption = $.extend( {}, this.options.position );
15131
15132		if ( !content ) {
15133			return;
15134		}
15135
15136		// Content can be updated multiple times. If the tooltip already
15137		// exists, then just update the content and bail.
15138		tooltipData = this._find( target );
15139		if ( tooltipData ) {
15140			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
15141			return;
15142		}
15143
15144		// If we have a title, clear it to prevent the native tooltip
15145		// we have to check first to avoid defining a title if none exists
15146		// (we don't want to cause an element to start matching [title])
15147		//
15148		// We use removeAttr only for key events, to allow IE to export the correct
15149		// accessible attributes. For mouse events, set to empty string to avoid
15150		// native tooltip showing up (happens only when removing inside mouseover).
15151		if ( target.is( "[title]" ) ) {
15152			if ( event && event.type === "mouseover" ) {
15153				target.attr( "title", "" );
15154			} else {
15155				target.removeAttr( "title" );
15156			}
15157		}
15158
15159		tooltipData = this._tooltip( target );
15160		tooltip = tooltipData.tooltip;
15161		this._addDescribedBy( target, tooltip.attr( "id" ) );
15162		tooltip.find( ".ui-tooltip-content" ).html( content );
15163
15164		// Support: Voiceover on OS X, JAWS on IE <= 9
15165		// JAWS announces deletions even when aria-relevant="additions"
15166		// Voiceover will sometimes re-read the entire log region's contents from the beginning
15167		this.liveRegion.children().hide();
15168		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
15169		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
15170		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
15171		a11yContent.appendTo( this.liveRegion );
15172
15173		function position( event ) {
15174			positionOption.of = event;
15175			if ( tooltip.is( ":hidden" ) ) {
15176				return;
15177			}
15178			tooltip.position( positionOption );
15179		}
15180		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
15181			this._on( this.document, {
15182				mousemove: position
15183			} );
15184
15185			// trigger once to override element-relative positioning
15186			position( event );
15187		} else {
15188			tooltip.position( $.extend( {
15189				of: target
15190			}, this.options.position ) );
15191		}
15192
15193		tooltip.hide();
15194
15195		this._show( tooltip, this.options.show );
15196
15197		// Handle tracking tooltips that are shown with a delay (#8644). As soon
15198		// as the tooltip is visible, position the tooltip using the most recent
15199		// event.
15200		// Adds the check to add the timers only when both delay and track options are set (#14682)
15201		if ( this.options.track && this.options.show && this.options.show.delay ) {
15202			delayedShow = this.delayedShow = setInterval( function() {
15203				if ( tooltip.is( ":visible" ) ) {
15204					position( positionOption.of );
15205					clearInterval( delayedShow );
15206				}
15207			}, $.fx.interval );
15208		}
15209
15210		this._trigger( "open", event, { tooltip: tooltip } );
15211	},
15212
15213	_registerCloseHandlers: function( event, target ) {
15214		var events = {
15215			keyup: function( event ) {
15216				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
15217					var fakeEvent = $.Event( event );
15218					fakeEvent.currentTarget = target[ 0 ];
15219					this.close( fakeEvent, true );
15220				}
15221			}
15222		};
15223
15224		// Only bind remove handler for delegated targets. Non-delegated
15225		// tooltips will handle this in destroy.
15226		if ( target[ 0 ] !== this.element[ 0 ] ) {
15227			events.remove = function() {
15228				this._removeTooltip( this._find( target ).tooltip );
15229			};
15230		}
15231
15232		if ( !event || event.type === "mouseover" ) {
15233			events.mouseleave = "close";
15234		}
15235		if ( !event || event.type === "focusin" ) {
15236			events.focusout = "close";
15237		}
15238		this._on( true, target, events );
15239	},
15240
15241	close: function( event ) {
15242		var tooltip,
15243			that = this,
15244			target = $( event ? event.currentTarget : this.element ),
15245			tooltipData = this._find( target );
15246
15247		// The tooltip may already be closed
15248		if ( !tooltipData ) {
15249
vendor: 17,492 bytes, lines 15250-15950
15250			// We set ui-tooltip-open immediately upon open (in open()), but only set the
15251			// additional data once there's actually content to show (in _open()). So even if the
15252			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
15253			// the period between open() and _open().
15254			target.removeData( "ui-tooltip-open" );
15255			return;
15256		}
15257
15258		tooltip = tooltipData.tooltip;
15259
15260		// Disabling closes the tooltip, so we need to track when we're closing
15261		// to avoid an infinite loop in case the tooltip becomes disabled on close
15262		if ( tooltipData.closing ) {
15263			return;
15264		}
15265
15266		// Clear the interval for delayed tracking tooltips
15267		clearInterval( this.delayedShow );
15268
15269		// Only set title if we had one before (see comment in _open())
15270		// If the title attribute has changed since open(), don't restore
15271		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
15272			target.attr( "title", target.data( "ui-tooltip-title" ) );
15273		}
15274
15275		this._removeDescribedBy( target );
15276
15277		tooltipData.hiding = true;
15278		tooltip.stop( true );
15279		this._hide( tooltip, this.options.hide, function() {
15280			that._removeTooltip( $( this ) );
15281		} );
15282
15283		target.removeData( "ui-tooltip-open" );
15284		this._off( target, "mouseleave focusout keyup" );
15285
15286		// Remove 'remove' binding only on delegated targets
15287		if ( target[ 0 ] !== this.element[ 0 ] ) {
15288			this._off( target, "remove" );
15289		}
15290		this._off( this.document, "mousemove" );
15291
15292		if ( event && event.type === "mouseleave" ) {
15293			$.each( this.parents, function( id, parent ) {
15294				$( parent.element ).attr( "title", parent.title );
15295				delete that.parents[ id ];
15296			} );
15297		}
15298
15299		tooltipData.closing = true;
15300		this._trigger( "close", event, { tooltip: tooltip } );
15301		if ( !tooltipData.hiding ) {
15302			tooltipData.closing = false;
15303		}
15304	},
15305
15306	_tooltip: function( element ) {
15307		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
15308			content = $( "<div>" ).appendTo( tooltip ),
15309			id = tooltip.uniqueId().attr( "id" );
15310
15311		this._addClass( content, "ui-tooltip-content" );
15312		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
15313
15314		tooltip.appendTo( this._appendTo( element ) );
15315
15316		return this.tooltips[ id ] = {
15317			element: element,
15318			tooltip: tooltip
15319		};
15320	},
15321
15322	_find: function( target ) {
15323		var id = target.data( "ui-tooltip-id" );
15324		return id ? this.tooltips[ id ] : null;
15325	},
15326
15327	_removeTooltip: function( tooltip ) {
15328		tooltip.remove();
15329		delete this.tooltips[ tooltip.attr( "id" ) ];
15330	},
15331
15332	_appendTo: function( target ) {
15333		var element = target.closest( ".ui-front, dialog" );
15334
15335		if ( !element.length ) {
15336			element = this.document[ 0 ].body;
15337		}
15338
15339		return element;
15340	},
15341
15342	_destroy: function() {
15343		var that = this;
15344
15345		// Close open tooltips
15346		$.each( this.tooltips, function( id, tooltipData ) {
15347
15348			// Delegate to close method to handle common cleanup
15349			var event = $.Event( "blur" ),
15350				element = tooltipData.element;
15351			event.target = event.currentTarget = element[ 0 ];
15352			that.close( event, true );
15353
15354			// Remove immediately; destroying an open tooltip doesn't use the
15355			// hide animation
15356			$( "#" + id ).remove();
15357
15358			// Restore the title
15359			if ( element.data( "ui-tooltip-title" ) ) {
15360
15361				// If the title attribute has changed since open(), don't restore
15362				if ( !element.attr( "title" ) ) {
15363					element.attr( "title", element.data( "ui-tooltip-title" ) );
15364				}
15365				element.removeData( "ui-tooltip-title" );
15366			}
15367		} );
15368		this.liveRegion.remove();
15369	}
15370} );
15371
15372// DEPRECATED
15373// TODO: Switch return back to widget declaration at top of file when this is removed
15374if ( $.uiBackCompat !== false ) {
15375
15376	// Backcompat for tooltipClass option
15377	$.widget( "ui.tooltip", $.ui.tooltip, {
15378		options: {
15379			tooltipClass: null
15380		},
15381		_tooltip: function() {
15382			var tooltipData = this._superApply( arguments );
15383			if ( this.options.tooltipClass ) {
15384				tooltipData.tooltip.addClass( this.options.tooltipClass );
15385			}
15386			return tooltipData;
15387		}
15388	} );
15389}
15390
15391var widgetsTooltip = $.ui.tooltip;
15392
15393
15394/*!
15395 * jQuery UI Effects 1.12.1
15396 * http://jqueryui.com
15397 *
15398 * Copyright jQuery Foundation and other contributors
15399 * Released under the MIT license.
15400 * http://jquery.org/license
15401 */
15402
15403//>>label: Effects Core
15404//>>group: Effects
15405// jscs:disable maximumLineLength
15406//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
15407// jscs:enable maximumLineLength
15408//>>docs: http://api.jqueryui.com/category/effects-core/
15409//>>demos: http://jqueryui.com/effect/
15410
15411
15412
15413var dataSpace = "ui-effects-",
15414	dataSpaceStyle = "ui-effects-style",
15415	dataSpaceAnimated = "ui-effects-animated",
15416
15417	// Create a local jQuery because jQuery Color relies on it and the
15418	// global may not exist with AMD and a custom build (#10199)
15419	jQuery = $;
15420
15421$.effects = {
15422	effect: {}
15423};
15424
15425/*!
15426 * jQuery Color Animations v2.1.2
15427 * https://github.com/jquery/jquery-color
15428 *
15429 * Copyright 2014 jQuery Foundation and other contributors
15430 * Released under the MIT license.
15431 * http://jquery.org/license
15432 *
15433 * Date: Wed Jan 16 08:47:09 2013 -0600
15434 */
15435( function( jQuery, undefined ) {
15436
15437	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
15438		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
15439
15440	// Plusequals test for += 100 -= 100
15441	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
15442
15443	// A set of RE's that can match strings and generate color tuples.
15444	stringParsers = [ {
15445			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
15446			parse: function( execResult ) {
15447				return [
15448					execResult[ 1 ],
15449					execResult[ 2 ],
15450					execResult[ 3 ],
15451					execResult[ 4 ]
15452				];
15453			}
15454		}, {
15455			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
15456			parse: function( execResult ) {
15457				return [
15458					execResult[ 1 ] * 2.55,
15459					execResult[ 2 ] * 2.55,
15460					execResult[ 3 ] * 2.55,
15461					execResult[ 4 ]
15462				];
15463			}
15464		}, {
15465
15466			// This regex ignores A-F because it's compared against an already lowercased string
15467			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
15468			parse: function( execResult ) {
15469				return [
15470					parseInt( execResult[ 1 ], 16 ),
15471					parseInt( execResult[ 2 ], 16 ),
15472					parseInt( execResult[ 3 ], 16 )
15473				];
15474			}
15475		}, {
15476
15477			// This regex ignores A-F because it's compared against an already lowercased string
15478			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
15479			parse: function( execResult ) {
15480				return [
15481					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
15482					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
15483					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
15484				];
15485			}
15486		}, {
15487			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
15488			space: "hsla",
15489			parse: function( execResult ) {
15490				return [
15491					execResult[ 1 ],
15492					execResult[ 2 ] / 100,
15493					execResult[ 3 ] / 100,
15494					execResult[ 4 ]
15495				];
15496			}
15497		} ],
15498
15499	// JQuery.Color( )
15500	color = jQuery.Color = function( color, green, blue, alpha ) {
15501		return new jQuery.Color.fn.parse( color, green, blue, alpha );
15502	},
15503	spaces = {
15504		rgba: {
15505			props: {
15506				red: {
15507					idx: 0,
15508					type: "byte"
15509				},
15510				green: {
15511					idx: 1,
15512					type: "byte"
15513				},
15514				blue: {
15515					idx: 2,
15516					type: "byte"
15517				}
15518			}
15519		},
15520
15521		hsla: {
15522			props: {
15523				hue: {
15524					idx: 0,
15525					type: "degrees"
15526				},
15527				saturation: {
15528					idx: 1,
15529					type: "percent"
15530				},
15531				lightness: {
15532					idx: 2,
15533					type: "percent"
15534				}
15535			}
15536		}
15537	},
15538	propTypes = {
15539		"byte": {
15540			floor: true,
15541			max: 255
15542		},
15543		"percent": {
15544			max: 1
15545		},
15546		"degrees": {
15547			mod: 360,
15548			floor: true
15549		}
15550	},
15551	support = color.support = {},
15552
15553	// Element for support tests
15554	supportElem = jQuery( "<p>" )[ 0 ],
15555
15556	// Colors = jQuery.Color.names
15557	colors,
15558
15559	// Local aliases of functions called often
15560	each = jQuery.each;
15561
15562// Determine rgba support immediately
15563supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
15564support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
15565
15566// Define cache name and alpha properties
15567// for rgba and hsla spaces
15568each( spaces, function( spaceName, space ) {
15569	space.cache = "_" + spaceName;
15570	space.props.alpha = {
15571		idx: 3,
15572		type: "percent",
15573		def: 1
15574	};
15575} );
15576
15577function clamp( value, prop, allowEmpty ) {
15578	var type = propTypes[ prop.type ] || {};
15579
15580	if ( value == null ) {
15581		return ( allowEmpty || !prop.def ) ? null : prop.def;
15582	}
15583
15584	// ~~ is an short way of doing floor for positive numbers
15585	value = type.floor ? ~~value : parseFloat( value );
15586
15587	// IE will pass in empty strings as value for alpha,
15588	// which will hit this case
15589	if ( isNaN( value ) ) {
15590		return prop.def;
15591	}
15592
15593	if ( type.mod ) {
15594
15595		// We add mod before modding to make sure that negatives values
15596		// get converted properly: -10 -> 350
15597		return ( value + type.mod ) % type.mod;
15598	}
15599
15600	// For now all property types without mod have min and max
15601	return 0 > value ? 0 : type.max < value ? type.max : value;
15602}
15603
15604function stringParse( string ) {
15605	var inst = color(),
15606		rgba = inst._rgba = [];
15607
15608	string = string.toLowerCase();
15609
15610	each( stringParsers, function( i, parser ) {
15611		var parsed,
15612			match = parser.re.exec( string ),
15613			values = match && parser.parse( match ),
15614			spaceName = parser.space || "rgba";
15615
15616		if ( values ) {
15617			parsed = inst[ spaceName ]( values );
15618
15619			// If this was an rgba parse the assignment might happen twice
15620			// oh well....
15621			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
15622			rgba = inst._rgba = parsed._rgba;
15623
15624			// Exit each( stringParsers ) here because we matched
15625			return false;
15626		}
15627	} );
15628
15629	// Found a stringParser that handled it
15630	if ( rgba.length ) {
15631
15632		// If this came from a parsed string, force "transparent" when alpha is 0
15633		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
15634		if ( rgba.join() === "0,0,0,0" ) {
15635			jQuery.extend( rgba, colors.transparent );
15636		}
15637		return inst;
15638	}
15639
15640	// Named colors
15641	return colors[ string ];
15642}
15643
15644color.fn = jQuery.extend( color.prototype, {
15645	parse: function( red, green, blue, alpha ) {
15646		if ( red === undefined ) {
15647			this._rgba = [ null, null, null, null ];
15648			return this;
15649		}
15650		if ( red.jquery || red.nodeType ) {
15651			red = jQuery( red ).css( green );
15652			green = undefined;
15653		}
15654
15655		var inst = this,
15656			type = jQuery.type( red ),
15657			rgba = this._rgba = [];
15658
15659		// More than 1 argument specified - assume ( red, green, blue, alpha )
15660		if ( green !== undefined ) {
15661			red = [ red, green, blue, alpha ];
15662			type = "array";
15663		}
15664
15665		if ( type === "string" ) {
15666			return this.parse( stringParse( red ) || colors._default );
15667		}
15668
15669		if ( type === "array" ) {
15670			each( spaces.rgba.props, function( key, prop ) {
15671				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
15672			} );
15673			return this;
15674		}
15675
15676		if ( type === "object" ) {
15677			if ( red instanceof color ) {
15678				each( spaces, function( spaceName, space ) {
15679					if ( red[ space.cache ] ) {
15680						inst[ space.cache ] = red[ space.cache ].slice();
15681					}
15682				} );
15683			} else {
15684				each( spaces, function( spaceName, space ) {
15685					var cache = space.cache;
15686					each( space.props, function( key, prop ) {
15687
15688						// If the cache doesn't exist, and we know how to convert
15689						if ( !inst[ cache ] && space.to ) {
15690
15691							// If the value was null, we don't need to copy it
15692							// if the key was alpha, we don't need to copy it either
15693							if ( key === "alpha" || red[ key ] == null ) {
15694								return;
15695							}
15696							inst[ cache ] = space.to( inst._rgba );
15697						}
15698
15699						// This is the only case where we allow nulls for ALL properties.
15700						// call clamp with alwaysAllowEmpty
15701						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
15702					} );
15703
15704					// Everything defined but alpha?
15705					if ( inst[ cache ] &&
15706							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
15707
15708						// Use the default of 1
15709						inst[ cache ][ 3 ] = 1;
15710						if ( space.from ) {
15711							inst._rgba = space.from( inst[ cache ] );
15712						}
15713					}
15714				} );
15715			}
15716			return this;
15717		}
15718	},
15719	is: function( compare ) {
15720		var is = color( compare ),
15721			same = true,
15722			inst = this;
15723
15724		each( spaces, function( _, space ) {
15725			var localCache,
15726				isCache = is[ space.cache ];
15727			if ( isCache ) {
15728				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
15729				each( space.props, function( _, prop ) {
15730					if ( isCache[ prop.idx ] != null ) {
15731						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
15732						return same;
15733					}
15734				} );
15735			}
15736			return same;
15737		} );
15738		return same;
15739	},
15740	_space: function() {
15741		var used = [],
15742			inst = this;
15743		each( spaces, function( spaceName, space ) {
15744			if ( inst[ space.cache ] ) {
15745				used.push( spaceName );
15746			}
15747		} );
15748		return used.pop();
15749	},
15750	transition: function( other, distance ) {
15751		var end = color( other ),
15752			spaceName = end._space(),
15753			space = spaces[ spaceName ],
15754			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
15755			start = startColor[ space.cache ] || space.to( startColor._rgba ),
15756			result = start.slice();
15757
15758		end = end[ space.cache ];
15759		each( space.props, function( key, prop ) {
15760			var index = prop.idx,
15761				startValue = start[ index ],
15762				endValue = end[ index ],
15763				type = propTypes[ prop.type ] || {};
15764
15765			// If null, don't override start value
15766			if ( endValue === null ) {
15767				return;
15768			}
15769
15770			// If null - use end
15771			if ( startValue === null ) {
15772				result[ index ] = endValue;
15773			} else {
15774				if ( type.mod ) {
15775					if ( endValue - startValue > type.mod / 2 ) {
15776						startValue += type.mod;
15777					} else if ( startValue - endValue > type.mod / 2 ) {
15778						startValue -= type.mod;
15779					}
15780				}
15781				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
15782			}
15783		} );
15784		return this[ spaceName ]( result );
15785	},
15786	blend: function( opaque ) {
15787
15788		// If we are already opaque - return ourself
15789		if ( this._rgba[ 3 ] === 1 ) {
15790			return this;
15791		}
15792
15793		var rgb = this._rgba.slice(),
15794			a = rgb.pop(),
15795			blend = color( opaque )._rgba;
15796
15797		return color( jQuery.map( rgb, function( v, i ) {
15798			return ( 1 - a ) * blend[ i ] + a * v;
15799		} ) );
15800	},
15801	toRgbaString: function() {
15802		var prefix = "rgba(",
15803			rgba = jQuery.map( this._rgba, function( v, i ) {
15804				return v == null ? ( i > 2 ? 1 : 0 ) : v;
15805			} );
15806
15807		if ( rgba[ 3 ] === 1 ) {
15808			rgba.pop();
15809			prefix = "rgb(";
15810		}
15811
15812		return prefix + rgba.join() + ")";
15813	},
15814	toHslaString: function() {
15815		var prefix = "hsla(",
15816			hsla = jQuery.map( this.hsla(), function( v, i ) {
15817				if ( v == null ) {
15818					v = i > 2 ? 1 : 0;
15819				}
15820
15821				// Catch 1 and 2
15822				if ( i && i < 3 ) {
15823					v = Math.round( v * 100 ) + "%";
15824				}
15825				return v;
15826			} );
15827
15828		if ( hsla[ 3 ] === 1 ) {
15829			hsla.pop();
15830			prefix = "hsl(";
15831		}
15832		return prefix + hsla.join() + ")";
15833	},
15834	toHexString: function( includeAlpha ) {
15835		var rgba = this._rgba.slice(),
15836			alpha = rgba.pop();
15837
15838		if ( includeAlpha ) {
15839			rgba.push( ~~( alpha * 255 ) );
15840		}
15841
15842		return "#" + jQuery.map( rgba, function( v ) {
15843
15844			// Default to 0 when nulls exist
15845			v = ( v || 0 ).toString( 16 );
15846			return v.length === 1 ? "0" + v : v;
15847		} ).join( "" );
15848	},
15849	toString: function() {
15850		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
15851	}
15852} );
15853color.fn.parse.prototype = color.fn;
15854
15855// Hsla conversions adapted from:
15856// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
15857
15858function hue2rgb( p, q, h ) {
15859	h = ( h + 1 ) % 1;
15860	if ( h * 6 < 1 ) {
15861		return p + ( q - p ) * h * 6;
15862	}
15863	if ( h * 2 < 1 ) {
15864		return q;
15865	}
15866	if ( h * 3 < 2 ) {
15867		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
15868	}
15869	return p;
15870}
15871
15872spaces.hsla.to = function( rgba ) {
15873	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
15874		return [ null, null, null, rgba[ 3 ] ];
15875	}
15876	var r = rgba[ 0 ] / 255,
15877		g = rgba[ 1 ] / 255,
15878		b = rgba[ 2 ] / 255,
15879		a = rgba[ 3 ],
15880		max = Math.max( r, g, b ),
15881		min = Math.min( r, g, b ),
15882		diff = max - min,
15883		add = max + min,
15884		l = add * 0.5,
15885		h, s;
15886
15887	if ( min === max ) {
15888		h = 0;
15889	} else if ( r === max ) {
15890		h = ( 60 * ( g - b ) / diff ) + 360;
15891	} else if ( g === max ) {
15892		h = ( 60 * ( b - r ) / diff ) + 120;
15893	} else {
15894		h = ( 60 * ( r - g ) / diff ) + 240;
15895	}
15896
15897	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
15898	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
15899	if ( diff === 0 ) {
15900		s = 0;
15901	} else if ( l <= 0.5 ) {
15902		s = diff / add;
15903	} else {
15904		s = diff / ( 2 - add );
15905	}
15906	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
15907};
15908
15909spaces.hsla.from = function( hsla ) {
15910	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
15911		return [ null, null, null, hsla[ 3 ] ];
15912	}
15913	var h = hsla[ 0 ] / 360,
15914		s = hsla[ 1 ],
15915		l = hsla[ 2 ],
15916		a = hsla[ 3 ],
15917		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
15918		p = 2 * l - q;
15919
15920	return [
15921		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
15922		Math.round( hue2rgb( p, q, h ) * 255 ),
15923		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
15924		a
15925	];
15926};
15927
15928each( spaces, function( spaceName, space ) {
15929	var props = space.props,
15930		cache = space.cache,
15931		to = space.to,
15932		from = space.from;
15933
15934	// Makes rgba() and hsla()
15935	color.fn[ spaceName ] = function( value ) {
15936
15937		// Generate a cache for this space if it doesn't exist
15938		if ( to && !this[ cache ] ) {
15939			this[ cache ] = to( this._rgba );
15940		}
15941		if ( value === undefined ) {
15942			return this[ cache ].slice();
15943		}
15944
15945		var ret,
15946			type = jQuery.type( value ),
15947			arr = ( type === "array" || type === "object" ) ? value : arguments,
15948			local = this[ cache ].slice();
15949
15950		each( props, function( key, prop ) {
vendor: 50,833 bytes, lines 15951-17936
15951			var val = arr[ type === "object" ? key : prop.idx ];
15952			if ( val == null ) {
15953				val = local[ prop.idx ];
15954			}
15955			local[ prop.idx ] = clamp( val, prop );
15956		} );
15957
15958		if ( from ) {
15959			ret = color( from( local ) );
15960			ret[ cache ] = local;
15961			return ret;
15962		} else {
15963			return color( local );
15964		}
15965	};
15966
15967	// Makes red() green() blue() alpha() hue() saturation() lightness()
15968	each( props, function( key, prop ) {
15969
15970		// Alpha is included in more than one space
15971		if ( color.fn[ key ] ) {
15972			return;
15973		}
15974		color.fn[ key ] = function( value ) {
15975			var vtype = jQuery.type( value ),
15976				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
15977				local = this[ fn ](),
15978				cur = local[ prop.idx ],
15979				match;
15980
15981			if ( vtype === "undefined" ) {
15982				return cur;
15983			}
15984
15985			if ( vtype === "function" ) {
15986				value = value.call( this, cur );
15987				vtype = jQuery.type( value );
15988			}
15989			if ( value == null && prop.empty ) {
15990				return this;
15991			}
15992			if ( vtype === "string" ) {
15993				match = rplusequals.exec( value );
15994				if ( match ) {
15995					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
15996				}
15997			}
15998			local[ prop.idx ] = value;
15999			return this[ fn ]( local );
16000		};
16001	} );
16002} );
16003
16004// Add cssHook and .fx.step function for each named hook.
16005// accept a space separated string of properties
16006color.hook = function( hook ) {
16007	var hooks = hook.split( " " );
16008	each( hooks, function( i, hook ) {
16009		jQuery.cssHooks[ hook ] = {
16010			set: function( elem, value ) {
16011				var parsed, curElem,
16012					backgroundColor = "";
16013
16014				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
16015						( parsed = stringParse( value ) ) ) ) {
16016					value = color( parsed || value );
16017					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
16018						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
16019						while (
16020							( backgroundColor === "" || backgroundColor === "transparent" ) &&
16021							curElem && curElem.style
16022						) {
16023							try {
16024								backgroundColor = jQuery.css( curElem, "backgroundColor" );
16025								curElem = curElem.parentNode;
16026							} catch ( e ) {
16027							}
16028						}
16029
16030						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
16031							backgroundColor :
16032							"_default" );
16033					}
16034
16035					value = value.toRgbaString();
16036				}
16037				try {
16038					elem.style[ hook ] = value;
16039				} catch ( e ) {
16040
16041					// Wrapped to prevent IE from throwing errors on "invalid" values like
16042					// 'auto' or 'inherit'
16043				}
16044			}
16045		};
16046		jQuery.fx.step[ hook ] = function( fx ) {
16047			if ( !fx.colorInit ) {
16048				fx.start = color( fx.elem, hook );
16049				fx.end = color( fx.end );
16050				fx.colorInit = true;
16051			}
16052			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
16053		};
16054	} );
16055
16056};
16057
16058color.hook( stepHooks );
16059
16060jQuery.cssHooks.borderColor = {
16061	expand: function( value ) {
16062		var expanded = {};
16063
16064		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
16065			expanded[ "border" + part + "Color" ] = value;
16066		} );
16067		return expanded;
16068	}
16069};
16070
16071// Basic color names only.
16072// Usage of any of the other color names requires adding yourself or including
16073// jquery.color.svg-names.js.
16074colors = jQuery.Color.names = {
16075
16076	// 4.1. Basic color keywords
16077	aqua: "#00ffff",
16078	black: "#000000",
16079	blue: "#0000ff",
16080	fuchsia: "#ff00ff",
16081	gray: "#808080",
16082	green: "#008000",
16083	lime: "#00ff00",
16084	maroon: "#800000",
16085	navy: "#000080",
16086	olive: "#808000",
16087	purple: "#800080",
16088	red: "#ff0000",
16089	silver: "#c0c0c0",
16090	teal: "#008080",
16091	white: "#ffffff",
16092	yellow: "#ffff00",
16093
16094	// 4.2.3. "transparent" color keyword
16095	transparent: [ null, null, null, 0 ],
16096
16097	_default: "#ffffff"
16098};
16099
16100} )( jQuery );
16101
16102/******************************************************************************/
16103/****************************** CLASS ANIMATIONS ******************************/
16104/******************************************************************************/
16105( function() {
16106
16107var classAnimationActions = [ "add", "remove", "toggle" ],
16108	shorthandStyles = {
16109		border: 1,
16110		borderBottom: 1,
16111		borderColor: 1,
16112		borderLeft: 1,
16113		borderRight: 1,
16114		borderTop: 1,
16115		borderWidth: 1,
16116		margin: 1,
16117		padding: 1
16118	};
16119
16120$.each(
16121	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
16122	function( _, prop ) {
16123		$.fx.step[ prop ] = function( fx ) {
16124			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
16125				jQuery.style( fx.elem, prop, fx.end );
16126				fx.setAttr = true;
16127			}
16128		};
16129	}
16130);
16131
16132function getElementStyles( elem ) {
16133	var key, len,
16134		style = elem.ownerDocument.defaultView ?
16135			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
16136			elem.currentStyle,
16137		styles = {};
16138
16139	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
16140		len = style.length;
16141		while ( len-- ) {
16142			key = style[ len ];
16143			if ( typeof style[ key ] === "string" ) {
16144				styles[ $.camelCase( key ) ] = style[ key ];
16145			}
16146		}
16147
16148	// Support: Opera, IE <9
16149	} else {
16150		for ( key in style ) {
16151			if ( typeof style[ key ] === "string" ) {
16152				styles[ key ] = style[ key ];
16153			}
16154		}
16155	}
16156
16157	return styles;
16158}
16159
16160function styleDifference( oldStyle, newStyle ) {
16161	var diff = {},
16162		name, value;
16163
16164	for ( name in newStyle ) {
16165		value = newStyle[ name ];
16166		if ( oldStyle[ name ] !== value ) {
16167			if ( !shorthandStyles[ name ] ) {
16168				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
16169					diff[ name ] = value;
16170				}
16171			}
16172		}
16173	}
16174
16175	return diff;
16176}
16177
16178// Support: jQuery <1.8
16179if ( !$.fn.addBack ) {
16180	$.fn.addBack = function( selector ) {
16181		return this.add( selector == null ?
16182			this.prevObject : this.prevObject.filter( selector )
16183		);
16184	};
16185}
16186
16187$.effects.animateClass = function( value, duration, easing, callback ) {
16188	var o = $.speed( duration, easing, callback );
16189
16190	return this.queue( function() {
16191		var animated = $( this ),
16192			baseClass = animated.attr( "class" ) || "",
16193			applyClassChange,
16194			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
16195
16196		// Map the animated objects to store the original styles.
16197		allAnimations = allAnimations.map( function() {
16198			var el = $( this );
16199			return {
16200				el: el,
16201				start: getElementStyles( this )
16202			};
16203		} );
16204
16205		// Apply class change
16206		applyClassChange = function() {
16207			$.each( classAnimationActions, function( i, action ) {
16208				if ( value[ action ] ) {
16209					animated[ action + "Class" ]( value[ action ] );
16210				}
16211			} );
16212		};
16213		applyClassChange();
16214
16215		// Map all animated objects again - calculate new styles and diff
16216		allAnimations = allAnimations.map( function() {
16217			this.end = getElementStyles( this.el[ 0 ] );
16218			this.diff = styleDifference( this.start, this.end );
16219			return this;
16220		} );
16221
16222		// Apply original class
16223		animated.attr( "class", baseClass );
16224
16225		// Map all animated objects again - this time collecting a promise
16226		allAnimations = allAnimations.map( function() {
16227			var styleInfo = this,
16228				dfd = $.Deferred(),
16229				opts = $.extend( {}, o, {
16230					queue: false,
16231					complete: function() {
16232						dfd.resolve( styleInfo );
16233					}
16234				} );
16235
16236			this.el.animate( this.diff, opts );
16237			return dfd.promise();
16238		} );
16239
16240		// Once all animations have completed:
16241		$.when.apply( $, allAnimations.get() ).done( function() {
16242
16243			// Set the final class
16244			applyClassChange();
16245
16246			// For each animated element,
16247			// clear all css properties that were animated
16248			$.each( arguments, function() {
16249				var el = this.el;
16250				$.each( this.diff, function( key ) {
16251					el.css( key, "" );
16252				} );
16253			} );
16254
16255			// This is guarnteed to be there if you use jQuery.speed()
16256			// it also handles dequeuing the next anim...
16257			o.complete.call( animated[ 0 ] );
16258		} );
16259	} );
16260};
16261
16262$.fn.extend( {
16263	addClass: ( function( orig ) {
16264		return function( classNames, speed, easing, callback ) {
16265			return speed ?
16266				$.effects.animateClass.call( this,
16267					{ add: classNames }, speed, easing, callback ) :
16268				orig.apply( this, arguments );
16269		};
16270	} )( $.fn.addClass ),
16271
16272	removeClass: ( function( orig ) {
16273		return function( classNames, speed, easing, callback ) {
16274			return arguments.length > 1 ?
16275				$.effects.animateClass.call( this,
16276					{ remove: classNames }, speed, easing, callback ) :
16277				orig.apply( this, arguments );
16278		};
16279	} )( $.fn.removeClass ),
16280
16281	toggleClass: ( function( orig ) {
16282		return function( classNames, force, speed, easing, callback ) {
16283			if ( typeof force === "boolean" || force === undefined ) {
16284				if ( !speed ) {
16285
16286					// Without speed parameter
16287					return orig.apply( this, arguments );
16288				} else {
16289					return $.effects.animateClass.call( this,
16290						( force ? { add: classNames } : { remove: classNames } ),
16291						speed, easing, callback );
16292				}
16293			} else {
16294
16295				// Without force parameter
16296				return $.effects.animateClass.call( this,
16297					{ toggle: classNames }, force, speed, easing );
16298			}
16299		};
16300	} )( $.fn.toggleClass ),
16301
16302	switchClass: function( remove, add, speed, easing, callback ) {
16303		return $.effects.animateClass.call( this, {
16304			add: add,
16305			remove: remove
16306		}, speed, easing, callback );
16307	}
16308} );
16309
16310} )();
16311
16312/******************************************************************************/
16313/*********************************** EFFECTS **********************************/
16314/******************************************************************************/
16315
16316( function() {
16317
16318if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
16319	$.expr.filters.animated = ( function( orig ) {
16320		return function( elem ) {
16321			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
16322		};
16323	} )( $.expr.filters.animated );
16324}
16325
16326if ( $.uiBackCompat !== false ) {
16327	$.extend( $.effects, {
16328
16329		// Saves a set of properties in a data storage
16330		save: function( element, set ) {
16331			var i = 0, length = set.length;
16332			for ( ; i < length; i++ ) {
16333				if ( set[ i ] !== null ) {
16334					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
16335				}
16336			}
16337		},
16338
16339		// Restores a set of previously saved properties from a data storage
16340		restore: function( element, set ) {
16341			var val, i = 0, length = set.length;
16342			for ( ; i < length; i++ ) {
16343				if ( set[ i ] !== null ) {
16344					val = element.data( dataSpace + set[ i ] );
16345					element.css( set[ i ], val );
16346				}
16347			}
16348		},
16349
16350		setMode: function( el, mode ) {
16351			if ( mode === "toggle" ) {
16352				mode = el.is( ":hidden" ) ? "show" : "hide";
16353			}
16354			return mode;
16355		},
16356
16357		// Wraps the element around a wrapper that copies position properties
16358		createWrapper: function( element ) {
16359
16360			// If the element is already wrapped, return it
16361			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
16362				return element.parent();
16363			}
16364
16365			// Wrap the element
16366			var props = {
16367					width: element.outerWidth( true ),
16368					height: element.outerHeight( true ),
16369					"float": element.css( "float" )
16370				},
16371				wrapper = $( "<div></div>" )
16372					.addClass( "ui-effects-wrapper" )
16373					.css( {
16374						fontSize: "100%",
16375						background: "transparent",
16376						border: "none",
16377						margin: 0,
16378						padding: 0
16379					} ),
16380
16381				// Store the size in case width/height are defined in % - Fixes #5245
16382				size = {
16383					width: element.width(),
16384					height: element.height()
16385				},
16386				active = document.activeElement;
16387
16388			// Support: Firefox
16389			// Firefox incorrectly exposes anonymous content
16390			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
16391			try {
16392				active.id;
16393			} catch ( e ) {
16394				active = document.body;
16395			}
16396
16397			element.wrap( wrapper );
16398
16399			// Fixes #7595 - Elements lose focus when wrapped.
16400			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
16401				$( active ).trigger( "focus" );
16402			}
16403
16404			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
16405			// lose the reference to the wrapped element
16406			wrapper = element.parent();
16407
16408			// Transfer positioning properties to the wrapper
16409			if ( element.css( "position" ) === "static" ) {
16410				wrapper.css( { position: "relative" } );
16411				element.css( { position: "relative" } );
16412			} else {
16413				$.extend( props, {
16414					position: element.css( "position" ),
16415					zIndex: element.css( "z-index" )
16416				} );
16417				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
16418					props[ pos ] = element.css( pos );
16419					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
16420						props[ pos ] = "auto";
16421					}
16422				} );
16423				element.css( {
16424					position: "relative",
16425					top: 0,
16426					left: 0,
16427					right: "auto",
16428					bottom: "auto"
16429				} );
16430			}
16431			element.css( size );
16432
16433			return wrapper.css( props ).show();
16434		},
16435
16436		removeWrapper: function( element ) {
16437			var active = document.activeElement;
16438
16439			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
16440				element.parent().replaceWith( element );
16441
16442				// Fixes #7595 - Elements lose focus when wrapped.
16443				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
16444					$( active ).trigger( "focus" );
16445				}
16446			}
16447
16448			return element;
16449		}
16450	} );
16451}
16452
16453$.extend( $.effects, {
16454	version: "1.12.1",
16455
16456	define: function( name, mode, effect ) {
16457		if ( !effect ) {
16458			effect = mode;
16459			mode = "effect";
16460		}
16461
16462		$.effects.effect[ name ] = effect;
16463		$.effects.effect[ name ].mode = mode;
16464
16465		return effect;
16466	},
16467
16468	scaledDimensions: function( element, percent, direction ) {
16469		if ( percent === 0 ) {
16470			return {
16471				height: 0,
16472				width: 0,
16473				outerHeight: 0,
16474				outerWidth: 0
16475			};
16476		}
16477
16478		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
16479			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
16480
16481		return {
16482			height: element.height() * y,
16483			width: element.width() * x,
16484			outerHeight: element.outerHeight() * y,
16485			outerWidth: element.outerWidth() * x
16486		};
16487
16488	},
16489
16490	clipToBox: function( animation ) {
16491		return {
16492			width: animation.clip.right - animation.clip.left,
16493			height: animation.clip.bottom - animation.clip.top,
16494			left: animation.clip.left,
16495			top: animation.clip.top
16496		};
16497	},
16498
16499	// Injects recently queued functions to be first in line (after "inprogress")
16500	unshift: function( element, queueLength, count ) {
16501		var queue = element.queue();
16502
16503		if ( queueLength > 1 ) {
16504			queue.splice.apply( queue,
16505				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
16506		}
16507		element.dequeue();
16508	},
16509
16510	saveStyle: function( element ) {
16511		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
16512	},
16513
16514	restoreStyle: function( element ) {
16515		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
16516		element.removeData( dataSpaceStyle );
16517	},
16518
16519	mode: function( element, mode ) {
16520		var hidden = element.is( ":hidden" );
16521
16522		if ( mode === "toggle" ) {
16523			mode = hidden ? "show" : "hide";
16524		}
16525		if ( hidden ? mode === "hide" : mode === "show" ) {
16526			mode = "none";
16527		}
16528		return mode;
16529	},
16530
16531	// Translates a [top,left] array into a baseline value
16532	getBaseline: function( origin, original ) {
16533		var y, x;
16534
16535		switch ( origin[ 0 ] ) {
16536		case "top":
16537			y = 0;
16538			break;
16539		case "middle":
16540			y = 0.5;
16541			break;
16542		case "bottom":
16543			y = 1;
16544			break;
16545		default:
16546			y = origin[ 0 ] / original.height;
16547		}
16548
16549		switch ( origin[ 1 ] ) {
16550		case "left":
16551			x = 0;
16552			break;
16553		case "center":
16554			x = 0.5;
16555			break;
16556		case "right":
16557			x = 1;
16558			break;
16559		default:
16560			x = origin[ 1 ] / original.width;
16561		}
16562
16563		return {
16564			x: x,
16565			y: y
16566		};
16567	},
16568
16569	// Creates a placeholder element so that the original element can be made absolute
16570	createPlaceholder: function( element ) {
16571		var placeholder,
16572			cssPosition = element.css( "position" ),
16573			position = element.position();
16574
16575		// Lock in margins first to account for form elements, which
16576		// will change margin if you explicitly set height
16577		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
16578		// Support: Safari
16579		element.css( {
16580			marginTop: element.css( "marginTop" ),
16581			marginBottom: element.css( "marginBottom" ),
16582			marginLeft: element.css( "marginLeft" ),
16583			marginRight: element.css( "marginRight" )
16584		} )
16585		.outerWidth( element.outerWidth() )
16586		.outerHeight( element.outerHeight() );
16587
16588		if ( /^(static|relative)/.test( cssPosition ) ) {
16589			cssPosition = "absolute";
16590
16591			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
16592
16593				// Convert inline to inline block to account for inline elements
16594				// that turn to inline block based on content (like img)
16595				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
16596					"inline-block" :
16597					"block",
16598				visibility: "hidden",
16599
16600				// Margins need to be set to account for margin collapse
16601				marginTop: element.css( "marginTop" ),
16602				marginBottom: element.css( "marginBottom" ),
16603				marginLeft: element.css( "marginLeft" ),
16604				marginRight: element.css( "marginRight" ),
16605				"float": element.css( "float" )
16606			} )
16607			.outerWidth( element.outerWidth() )
16608			.outerHeight( element.outerHeight() )
16609			.addClass( "ui-effects-placeholder" );
16610
16611			element.data( dataSpace + "placeholder", placeholder );
16612		}
16613
16614		element.css( {
16615			position: cssPosition,
16616			left: position.left,
16617			top: position.top
16618		} );
16619
16620		return placeholder;
16621	},
16622
16623	removePlaceholder: function( element ) {
16624		var dataKey = dataSpace + "placeholder",
16625				placeholder = element.data( dataKey );
16626
16627		if ( placeholder ) {
16628			placeholder.remove();
16629			element.removeData( dataKey );
16630		}
16631	},
16632
16633	// Removes a placeholder if it exists and restores
16634	// properties that were modified during placeholder creation
16635	cleanUp: function( element ) {
16636		$.effects.restoreStyle( element );
16637		$.effects.removePlaceholder( element );
16638	},
16639
16640	setTransition: function( element, list, factor, value ) {
16641		value = value || {};
16642		$.each( list, function( i, x ) {
16643			var unit = element.cssUnit( x );
16644			if ( unit[ 0 ] > 0 ) {
16645				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
16646			}
16647		} );
16648		return value;
16649	}
16650} );
16651
16652// Return an effect options object for the given parameters:
16653function _normalizeArguments( effect, options, speed, callback ) {
16654
16655	// Allow passing all options as the first parameter
16656	if ( $.isPlainObject( effect ) ) {
16657		options = effect;
16658		effect = effect.effect;
16659	}
16660
16661	// Convert to an object
16662	effect = { effect: effect };
16663
16664	// Catch (effect, null, ...)
16665	if ( options == null ) {
16666		options = {};
16667	}
16668
16669	// Catch (effect, callback)
16670	if ( $.isFunction( options ) ) {
16671		callback = options;
16672		speed = null;
16673		options = {};
16674	}
16675
16676	// Catch (effect, speed, ?)
16677	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
16678		callback = speed;
16679		speed = options;
16680		options = {};
16681	}
16682
16683	// Catch (effect, options, callback)
16684	if ( $.isFunction( speed ) ) {
16685		callback = speed;
16686		speed = null;
16687	}
16688
16689	// Add options to effect
16690	if ( options ) {
16691		$.extend( effect, options );
16692	}
16693
16694	speed = speed || options.duration;
16695	effect.duration = $.fx.off ? 0 :
16696		typeof speed === "number" ? speed :
16697		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
16698		$.fx.speeds._default;
16699
16700	effect.complete = callback || options.complete;
16701
16702	return effect;
16703}
16704
16705function standardAnimationOption( option ) {
16706
16707	// Valid standard speeds (nothing, number, named speed)
16708	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
16709		return true;
16710	}
16711
16712	// Invalid strings - treat as "normal" speed
16713	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
16714		return true;
16715	}
16716
16717	// Complete callback
16718	if ( $.isFunction( option ) ) {
16719		return true;
16720	}
16721
16722	// Options hash (but not naming an effect)
16723	if ( typeof option === "object" && !option.effect ) {
16724		return true;
16725	}
16726
16727	// Didn't match any standard API
16728	return false;
16729}
16730
16731$.fn.extend( {
16732	effect: function( /* effect, options, speed, callback */ ) {
16733		var args = _normalizeArguments.apply( this, arguments ),
16734			effectMethod = $.effects.effect[ args.effect ],
16735			defaultMode = effectMethod.mode,
16736			queue = args.queue,
16737			queueName = queue || "fx",
16738			complete = args.complete,
16739			mode = args.mode,
16740			modes = [],
16741			prefilter = function( next ) {
16742				var el = $( this ),
16743					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
16744
16745				// Sentinel for duck-punching the :animated psuedo-selector
16746				el.data( dataSpaceAnimated, true );
16747
16748				// Save effect mode for later use,
16749				// we can't just call $.effects.mode again later,
16750				// as the .show() below destroys the initial state
16751				modes.push( normalizedMode );
16752
16753				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
16754				if ( defaultMode && ( normalizedMode === "show" ||
16755						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
16756					el.show();
16757				}
16758
16759				if ( !defaultMode || normalizedMode !== "none" ) {
16760					$.effects.saveStyle( el );
16761				}
16762
16763				if ( $.isFunction( next ) ) {
16764					next();
16765				}
16766			};
16767
16768		if ( $.fx.off || !effectMethod ) {
16769
16770			// Delegate to the original method (e.g., .show()) if possible
16771			if ( mode ) {
16772				return this[ mode ]( args.duration, complete );
16773			} else {
16774				return this.each( function() {
16775					if ( complete ) {
16776						complete.call( this );
16777					}
16778				} );
16779			}
16780		}
16781
16782		function run( next ) {
16783			var elem = $( this );
16784
16785			function cleanup() {
16786				elem.removeData( dataSpaceAnimated );
16787
16788				$.effects.cleanUp( elem );
16789
16790				if ( args.mode === "hide" ) {
16791					elem.hide();
16792				}
16793
16794				done();
16795			}
16796
16797			function done() {
16798				if ( $.isFunction( complete ) ) {
16799					complete.call( elem[ 0 ] );
16800				}
16801
16802				if ( $.isFunction( next ) ) {
16803					next();
16804				}
16805			}
16806
16807			// Override mode option on a per element basis,
16808			// as toggle can be either show or hide depending on element state
16809			args.mode = modes.shift();
16810
16811			if ( $.uiBackCompat !== false && !defaultMode ) {
16812				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
16813
16814					// Call the core method to track "olddisplay" properly
16815					elem[ mode ]();
16816					done();
16817				} else {
16818					effectMethod.call( elem[ 0 ], args, done );
16819				}
16820			} else {
16821				if ( args.mode === "none" ) {
16822
16823					// Call the core method to track "olddisplay" properly
16824					elem[ mode ]();
16825					done();
16826				} else {
16827					effectMethod.call( elem[ 0 ], args, cleanup );
16828				}
16829			}
16830		}
16831
16832		// Run prefilter on all elements first to ensure that
16833		// any showing or hiding happens before placeholder creation,
16834		// which ensures that any layout changes are correctly captured.
16835		return queue === false ?
16836			this.each( prefilter ).each( run ) :
16837			this.queue( queueName, prefilter ).queue( queueName, run );
16838	},
16839
16840	show: ( function( orig ) {
16841		return function( option ) {
16842			if ( standardAnimationOption( option ) ) {
16843				return orig.apply( this, arguments );
16844			} else {
16845				var args = _normalizeArguments.apply( this, arguments );
16846				args.mode = "show";
16847				return this.effect.call( this, args );
16848			}
16849		};
16850	} )( $.fn.show ),
16851
16852	hide: ( function( orig ) {
16853		return function( option ) {
16854			if ( standardAnimationOption( option ) ) {
16855				return orig.apply( this, arguments );
16856			} else {
16857				var args = _normalizeArguments.apply( this, arguments );
16858				args.mode = "hide";
16859				return this.effect.call( this, args );
16860			}
16861		};
16862	} )( $.fn.hide ),
16863
16864	toggle: ( function( orig ) {
16865		return function( option ) {
16866			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
16867				return orig.apply( this, arguments );
16868			} else {
16869				var args = _normalizeArguments.apply( this, arguments );
16870				args.mode = "toggle";
16871				return this.effect.call( this, args );
16872			}
16873		};
16874	} )( $.fn.toggle ),
16875
16876	cssUnit: function( key ) {
16877		var style = this.css( key ),
16878			val = [];
16879
16880		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
16881			if ( style.indexOf( unit ) > 0 ) {
16882				val = [ parseFloat( style ), unit ];
16883			}
16884		} );
16885		return val;
16886	},
16887
16888	cssClip: function( clipObj ) {
16889		if ( clipObj ) {
16890			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
16891				clipObj.bottom + "px " + clipObj.left + "px)" );
16892		}
16893		return parseClip( this.css( "clip" ), this );
16894	},
16895
16896	transfer: function( options, done ) {
16897		var element = $( this ),
16898			target = $( options.to ),
16899			targetFixed = target.css( "position" ) === "fixed",
16900			body = $( "body" ),
16901			fixTop = targetFixed ? body.scrollTop() : 0,
16902			fixLeft = targetFixed ? body.scrollLeft() : 0,
16903			endPosition = target.offset(),
16904			animation = {
16905				top: endPosition.top - fixTop,
16906				left: endPosition.left - fixLeft,
16907				height: target.innerHeight(),
16908				width: target.innerWidth()
16909			},
16910			startPosition = element.offset(),
16911			transfer = $( "<div class='ui-effects-transfer'></div>" )
16912				.appendTo( "body" )
16913				.addClass( options.className )
16914				.css( {
16915					top: startPosition.top - fixTop,
16916					left: startPosition.left - fixLeft,
16917					height: element.innerHeight(),
16918					width: element.innerWidth(),
16919					position: targetFixed ? "fixed" : "absolute"
16920				} )
16921				.animate( animation, options.duration, options.easing, function() {
16922					transfer.remove();
16923					if ( $.isFunction( done ) ) {
16924						done();
16925					}
16926				} );
16927	}
16928} );
16929
16930function parseClip( str, element ) {
16931		var outerWidth = element.outerWidth(),
16932			outerHeight = element.outerHeight(),
16933			clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
16934			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
16935
16936		return {
16937			top: parseFloat( values[ 1 ] ) || 0,
16938			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
16939			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
16940			left: parseFloat( values[ 4 ] ) || 0
16941		};
16942}
16943
16944$.fx.step.clip = function( fx ) {
16945	if ( !fx.clipInit ) {
16946		fx.start = $( fx.elem ).cssClip();
16947		if ( typeof fx.end === "string" ) {
16948			fx.end = parseClip( fx.end, fx.elem );
16949		}
16950		fx.clipInit = true;
16951	}
16952
16953	$( fx.elem ).cssClip( {
16954		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
16955		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
16956		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
16957		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
16958	} );
16959};
16960
16961} )();
16962
16963/******************************************************************************/
16964/*********************************** EASING ***********************************/
16965/******************************************************************************/
16966
16967( function() {
16968
16969// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
16970
16971var baseEasings = {};
16972
16973$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
16974	baseEasings[ name ] = function( p ) {
16975		return Math.pow( p, i + 2 );
16976	};
16977} );
16978
16979$.extend( baseEasings, {
16980	Sine: function( p ) {
16981		return 1 - Math.cos( p * Math.PI / 2 );
16982	},
16983	Circ: function( p ) {
16984		return 1 - Math.sqrt( 1 - p * p );
16985	},
16986	Elastic: function( p ) {
16987		return p === 0 || p === 1 ? p :
16988			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
16989	},
16990	Back: function( p ) {
16991		return p * p * ( 3 * p - 2 );
16992	},
16993	Bounce: function( p ) {
16994		var pow2,
16995			bounce = 4;
16996
16997		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
16998		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
16999	}
17000} );
17001
17002$.each( baseEasings, function( name, easeIn ) {
17003	$.easing[ "easeIn" + name ] = easeIn;
17004	$.easing[ "easeOut" + name ] = function( p ) {
17005		return 1 - easeIn( 1 - p );
17006	};
17007	$.easing[ "easeInOut" + name ] = function( p ) {
17008		return p < 0.5 ?
17009			easeIn( p * 2 ) / 2 :
17010			1 - easeIn( p * -2 + 2 ) / 2;
17011	};
17012} );
17013
17014} )();
17015
17016var effect = $.effects;
17017
17018
17019/*!
17020 * jQuery UI Effects Blind 1.12.1
17021 * http://jqueryui.com
17022 *
17023 * Copyright jQuery Foundation and other contributors
17024 * Released under the MIT license.
17025 * http://jquery.org/license
17026 */
17027
17028//>>label: Blind Effect
17029//>>group: Effects
17030//>>description: Blinds the element.
17031//>>docs: http://api.jqueryui.com/blind-effect/
17032//>>demos: http://jqueryui.com/effect/
17033
17034
17035
17036var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
17037	var map = {
17038			up: [ "bottom", "top" ],
17039			vertical: [ "bottom", "top" ],
17040			down: [ "top", "bottom" ],
17041			left: [ "right", "left" ],
17042			horizontal: [ "right", "left" ],
17043			right: [ "left", "right" ]
17044		},
17045		element = $( this ),
17046		direction = options.direction || "up",
17047		start = element.cssClip(),
17048		animate = { clip: $.extend( {}, start ) },
17049		placeholder = $.effects.createPlaceholder( element );
17050
17051	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
17052
17053	if ( options.mode === "show" ) {
17054		element.cssClip( animate.clip );
17055		if ( placeholder ) {
17056			placeholder.css( $.effects.clipToBox( animate ) );
17057		}
17058
17059		animate.clip = start;
17060	}
17061
17062	if ( placeholder ) {
17063		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
17064	}
17065
17066	element.animate( animate, {
17067		queue: false,
17068		duration: options.duration,
17069		easing: options.easing,
17070		complete: done
17071	} );
17072} );
17073
17074
17075/*!
17076 * jQuery UI Effects Bounce 1.12.1
17077 * http://jqueryui.com
17078 *
17079 * Copyright jQuery Foundation and other contributors
17080 * Released under the MIT license.
17081 * http://jquery.org/license
17082 */
17083
17084//>>label: Bounce Effect
17085//>>group: Effects
17086//>>description: Bounces an element horizontally or vertically n times.
17087//>>docs: http://api.jqueryui.com/bounce-effect/
17088//>>demos: http://jqueryui.com/effect/
17089
17090
17091
17092var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
17093	var upAnim, downAnim, refValue,
17094		element = $( this ),
17095
17096		// Defaults:
17097		mode = options.mode,
17098		hide = mode === "hide",
17099		show = mode === "show",
17100		direction = options.direction || "up",
17101		distance = options.distance,
17102		times = options.times || 5,
17103
17104		// Number of internal animations
17105		anims = times * 2 + ( show || hide ? 1 : 0 ),
17106		speed = options.duration / anims,
17107		easing = options.easing,
17108
17109		// Utility:
17110		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17111		motion = ( direction === "up" || direction === "left" ),
17112		i = 0,
17113
17114		queuelen = element.queue().length;
17115
17116	$.effects.createPlaceholder( element );
17117
17118	refValue = element.css( ref );
17119
17120	// Default distance for the BIGGEST bounce is the outer Distance / 3
17121	if ( !distance ) {
17122		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
17123	}
17124
17125	if ( show ) {
17126		downAnim = { opacity: 1 };
17127		downAnim[ ref ] = refValue;
17128
17129		// If we are showing, force opacity 0 and set the initial position
17130		// then do the "first" animation
17131		element
17132			.css( "opacity", 0 )
17133			.css( ref, motion ? -distance * 2 : distance * 2 )
17134			.animate( downAnim, speed, easing );
17135	}
17136
17137	// Start at the smallest distance if we are hiding
17138	if ( hide ) {
17139		distance = distance / Math.pow( 2, times - 1 );
17140	}
17141
17142	downAnim = {};
17143	downAnim[ ref ] = refValue;
17144
17145	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
17146	for ( ; i < times; i++ ) {
17147		upAnim = {};
17148		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
17149
17150		element
17151			.animate( upAnim, speed, easing )
17152			.animate( downAnim, speed, easing );
17153
17154		distance = hide ? distance * 2 : distance / 2;
17155	}
17156
17157	// Last Bounce when Hiding
17158	if ( hide ) {
17159		upAnim = { opacity: 0 };
17160		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
17161
17162		element.animate( upAnim, speed, easing );
17163	}
17164
17165	element.queue( done );
17166
17167	$.effects.unshift( element, queuelen, anims + 1 );
17168} );
17169
17170
17171/*!
17172 * jQuery UI Effects Clip 1.12.1
17173 * http://jqueryui.com
17174 *
17175 * Copyright jQuery Foundation and other contributors
17176 * Released under the MIT license.
17177 * http://jquery.org/license
17178 */
17179
17180//>>label: Clip Effect
17181//>>group: Effects
17182//>>description: Clips the element on and off like an old TV.
17183//>>docs: http://api.jqueryui.com/clip-effect/
17184//>>demos: http://jqueryui.com/effect/
17185
17186
17187
17188var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
17189	var start,
17190		animate = {},
17191		element = $( this ),
17192		direction = options.direction || "vertical",
17193		both = direction === "both",
17194		horizontal = both || direction === "horizontal",
17195		vertical = both || direction === "vertical";
17196
17197	start = element.cssClip();
17198	animate.clip = {
17199		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
17200		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
17201		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
17202		left: horizontal ? ( start.right - start.left ) / 2 : start.left
17203	};
17204
17205	$.effects.createPlaceholder( element );
17206
17207	if ( options.mode === "show" ) {
17208		element.cssClip( animate.clip );
17209		animate.clip = start;
17210	}
17211
17212	element.animate( animate, {
17213		queue: false,
17214		duration: options.duration,
17215		easing: options.easing,
17216		complete: done
17217	} );
17218
17219} );
17220
17221
17222/*!
17223 * jQuery UI Effects Drop 1.12.1
17224 * http://jqueryui.com
17225 *
17226 * Copyright jQuery Foundation and other contributors
17227 * Released under the MIT license.
17228 * http://jquery.org/license
17229 */
17230
17231//>>label: Drop Effect
17232//>>group: Effects
17233//>>description: Moves an element in one direction and hides it at the same time.
17234//>>docs: http://api.jqueryui.com/drop-effect/
17235//>>demos: http://jqueryui.com/effect/
17236
17237
17238
17239var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
17240
17241	var distance,
17242		element = $( this ),
17243		mode = options.mode,
17244		show = mode === "show",
17245		direction = options.direction || "left",
17246		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17247		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
17248		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
17249		animation = {
17250			opacity: 0
17251		};
17252
17253	$.effects.createPlaceholder( element );
17254
17255	distance = options.distance ||
17256		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
17257
17258	animation[ ref ] = motion + distance;
17259
17260	if ( show ) {
17261		element.css( animation );
17262
17263		animation[ ref ] = oppositeMotion + distance;
17264		animation.opacity = 1;
17265	}
17266
17267	// Animate
17268	element.animate( animation, {
17269		queue: false,
17270		duration: options.duration,
17271		easing: options.easing,
17272		complete: done
17273	} );
17274} );
17275
17276
17277/*!
17278 * jQuery UI Effects Explode 1.12.1
17279 * http://jqueryui.com
17280 *
17281 * Copyright jQuery Foundation and other contributors
17282 * Released under the MIT license.
17283 * http://jquery.org/license
17284 */
17285
17286//>>label: Explode Effect
17287//>>group: Effects
17288// jscs:disable maximumLineLength
17289//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
17290// jscs:enable maximumLineLength
17291//>>docs: http://api.jqueryui.com/explode-effect/
17292//>>demos: http://jqueryui.com/effect/
17293
17294
17295
17296var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
17297
17298	var i, j, left, top, mx, my,
17299		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
17300		cells = rows,
17301		element = $( this ),
17302		mode = options.mode,
17303		show = mode === "show",
17304
17305		// Show and then visibility:hidden the element before calculating offset
17306		offset = element.show().css( "visibility", "hidden" ).offset(),
17307
17308		// Width and height of a piece
17309		width = Math.ceil( element.outerWidth() / cells ),
17310		height = Math.ceil( element.outerHeight() / rows ),
17311		pieces = [];
17312
17313	// Children animate complete:
17314	function childComplete() {
17315		pieces.push( this );
17316		if ( pieces.length === rows * cells ) {
17317			animComplete();
17318		}
17319	}
17320
17321	// Clone the element for each row and cell.
17322	for ( i = 0; i < rows; i++ ) { // ===>
17323		top = offset.top + i * height;
17324		my = i - ( rows - 1 ) / 2;
17325
17326		for ( j = 0; j < cells; j++ ) { // |||
17327			left = offset.left + j * width;
17328			mx = j - ( cells - 1 ) / 2;
17329
17330			// Create a clone of the now hidden main element that will be absolute positioned
17331			// within a wrapper div off the -left and -top equal to size of our pieces
17332			element
17333				.clone()
17334				.appendTo( "body" )
17335				.wrap( "<div></div>" )
17336				.css( {
17337					position: "absolute",
17338					visibility: "visible",
17339					left: -j * width,
17340					top: -i * height
17341				} )
17342
17343				// Select the wrapper - make it overflow: hidden and absolute positioned based on
17344				// where the original was located +left and +top equal to the size of pieces
17345				.parent()
17346					.addClass( "ui-effects-explode" )
17347					.css( {
17348						position: "absolute",
17349						overflow: "hidden",
17350						width: width,
17351						height: height,
17352						left: left + ( show ? mx * width : 0 ),
17353						top: top + ( show ? my * height : 0 ),
17354						opacity: show ? 0 : 1
17355					} )
17356					.animate( {
17357						left: left + ( show ? 0 : mx * width ),
17358						top: top + ( show ? 0 : my * height ),
17359						opacity: show ? 1 : 0
17360					}, options.duration || 500, options.easing, childComplete );
17361		}
17362	}
17363
17364	function animComplete() {
17365		element.css( {
17366			visibility: "visible"
17367		} );
17368		$( pieces ).remove();
17369		done();
17370	}
17371} );
17372
17373
17374/*!
17375 * jQuery UI Effects Fade 1.12.1
17376 * http://jqueryui.com
17377 *
17378 * Copyright jQuery Foundation and other contributors
17379 * Released under the MIT license.
17380 * http://jquery.org/license
17381 */
17382
17383//>>label: Fade Effect
17384//>>group: Effects
17385//>>description: Fades the element.
17386//>>docs: http://api.jqueryui.com/fade-effect/
17387//>>demos: http://jqueryui.com/effect/
17388
17389
17390
17391var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
17392	var show = options.mode === "show";
17393
17394	$( this )
17395		.css( "opacity", show ? 0 : 1 )
17396		.animate( {
17397			opacity: show ? 1 : 0
17398		}, {
17399			queue: false,
17400			duration: options.duration,
17401			easing: options.easing,
17402			complete: done
17403		} );
17404} );
17405
17406
17407/*!
17408 * jQuery UI Effects Fold 1.12.1
17409 * http://jqueryui.com
17410 *
17411 * Copyright jQuery Foundation and other contributors
17412 * Released under the MIT license.
17413 * http://jquery.org/license
17414 */
17415
17416//>>label: Fold Effect
17417//>>group: Effects
17418//>>description: Folds an element first horizontally and then vertically.
17419//>>docs: http://api.jqueryui.com/fold-effect/
17420//>>demos: http://jqueryui.com/effect/
17421
17422
17423
17424var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
17425
17426	// Create element
17427	var element = $( this ),
17428		mode = options.mode,
17429		show = mode === "show",
17430		hide = mode === "hide",
17431		size = options.size || 15,
17432		percent = /([0-9]+)%/.exec( size ),
17433		horizFirst = !!options.horizFirst,
17434		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
17435		duration = options.duration / 2,
17436
17437		placeholder = $.effects.createPlaceholder( element ),
17438
17439		start = element.cssClip(),
17440		animation1 = { clip: $.extend( {}, start ) },
17441		animation2 = { clip: $.extend( {}, start ) },
17442
17443		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
17444
17445		queuelen = element.queue().length;
17446
17447	if ( percent ) {
17448		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
17449	}
17450	animation1.clip[ ref[ 0 ] ] = size;
17451	animation2.clip[ ref[ 0 ] ] = size;
17452	animation2.clip[ ref[ 1 ] ] = 0;
17453
17454	if ( show ) {
17455		element.cssClip( animation2.clip );
17456		if ( placeholder ) {
17457			placeholder.css( $.effects.clipToBox( animation2 ) );
17458		}
17459
17460		animation2.clip = start;
17461	}
17462
17463	// Animate
17464	element
17465		.queue( function( next ) {
17466			if ( placeholder ) {
17467				placeholder
17468					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
17469					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
17470			}
17471
17472			next();
17473		} )
17474		.animate( animation1, duration, options.easing )
17475		.animate( animation2, duration, options.easing )
17476		.queue( done );
17477
17478	$.effects.unshift( element, queuelen, 4 );
17479} );
17480
17481
17482/*!
17483 * jQuery UI Effects Highlight 1.12.1
17484 * http://jqueryui.com
17485 *
17486 * Copyright jQuery Foundation and other contributors
17487 * Released under the MIT license.
17488 * http://jquery.org/license
17489 */
17490
17491//>>label: Highlight Effect
17492//>>group: Effects
17493//>>description: Highlights the background of an element in a defined color for a custom duration.
17494//>>docs: http://api.jqueryui.com/highlight-effect/
17495//>>demos: http://jqueryui.com/effect/
17496
17497
17498
17499var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
17500	var element = $( this ),
17501		animation = {
17502			backgroundColor: element.css( "backgroundColor" )
17503		};
17504
17505	if ( options.mode === "hide" ) {
17506		animation.opacity = 0;
17507	}
17508
17509	$.effects.saveStyle( element );
17510
17511	element
17512		.css( {
17513			backgroundImage: "none",
17514			backgroundColor: options.color || "#ffff99"
17515		} )
17516		.animate( animation, {
17517			queue: false,
17518			duration: options.duration,
17519			easing: options.easing,
17520			complete: done
17521		} );
17522} );
17523
17524
17525/*!
17526 * jQuery UI Effects Size 1.12.1
17527 * http://jqueryui.com
17528 *
17529 * Copyright jQuery Foundation and other contributors
17530 * Released under the MIT license.
17531 * http://jquery.org/license
17532 */
17533
17534//>>label: Size Effect
17535//>>group: Effects
17536//>>description: Resize an element to a specified width and height.
17537//>>docs: http://api.jqueryui.com/size-effect/
17538//>>demos: http://jqueryui.com/effect/
17539
17540
17541
17542var effectsEffectSize = $.effects.define( "size", function( options, done ) {
17543
17544	// Create element
17545	var baseline, factor, temp,
17546		element = $( this ),
17547
17548		// Copy for children
17549		cProps = [ "fontSize" ],
17550		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
17551		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
17552
17553		// Set options
17554		mode = options.mode,
17555		restore = mode !== "effect",
17556		scale = options.scale || "both",
17557		origin = options.origin || [ "middle", "center" ],
17558		position = element.css( "position" ),
17559		pos = element.position(),
17560		original = $.effects.scaledDimensions( element ),
17561		from = options.from || original,
17562		to = options.to || $.effects.scaledDimensions( element, 0 );
17563
17564	$.effects.createPlaceholder( element );
17565
17566	if ( mode === "show" ) {
17567		temp = from;
17568		from = to;
17569		to = temp;
17570	}
17571
17572	// Set scaling factor
17573	factor = {
17574		from: {
17575			y: from.height / original.height,
17576			x: from.width / original.width
17577		},
17578		to: {
17579			y: to.height / original.height,
17580			x: to.width / original.width
17581		}
17582	};
17583
17584	// Scale the css box
17585	if ( scale === "box" || scale === "both" ) {
17586
17587		// Vertical props scaling
17588		if ( factor.from.y !== factor.to.y ) {
17589			from = $.effects.setTransition( element, vProps, factor.from.y, from );
17590			to = $.effects.setTransition( element, vProps, factor.to.y, to );
17591		}
17592
17593		// Horizontal props scaling
17594		if ( factor.from.x !== factor.to.x ) {
17595			from = $.effects.setTransition( element, hProps, factor.from.x, from );
17596			to = $.effects.setTransition( element, hProps, factor.to.x, to );
17597		}
17598	}
17599
17600	// Scale the content
17601	if ( scale === "content" || scale === "both" ) {
17602
17603		// Vertical props scaling
17604		if ( factor.from.y !== factor.to.y ) {
17605			from = $.effects.setTransition( element, cProps, factor.from.y, from );
17606			to = $.effects.setTransition( element, cProps, factor.to.y, to );
17607		}
17608	}
17609
17610	// Adjust the position properties based on the provided origin points
17611	if ( origin ) {
17612		baseline = $.effects.getBaseline( origin, original );
17613		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
17614		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
17615		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
17616		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
17617	}
17618	element.css( from );
17619
17620	// Animate the children if desired
17621	if ( scale === "content" || scale === "both" ) {
17622
17623		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
17624		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
17625
17626		// Only animate children with width attributes specified
17627		// TODO: is this right? should we include anything with css width specified as well
17628		element.find( "*[width]" ).each( function() {
17629			var child = $( this ),
17630				childOriginal = $.effects.scaledDimensions( child ),
17631				childFrom = {
17632					height: childOriginal.height * factor.from.y,
17633					width: childOriginal.width * factor.from.x,
17634					outerHeight: childOriginal.outerHeight * factor.from.y,
17635					outerWidth: childOriginal.outerWidth * factor.from.x
17636				},
17637				childTo = {
17638					height: childOriginal.height * factor.to.y,
17639					width: childOriginal.width * factor.to.x,
17640					outerHeight: childOriginal.height * factor.to.y,
17641					outerWidth: childOriginal.width * factor.to.x
17642				};
17643
17644			// Vertical props scaling
17645			if ( factor.from.y !== factor.to.y ) {
17646				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
17647				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
17648			}
17649
17650			// Horizontal props scaling
17651			if ( factor.from.x !== factor.to.x ) {
17652				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
17653				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
17654			}
17655
17656			if ( restore ) {
17657				$.effects.saveStyle( child );
17658			}
17659
17660			// Animate children
17661			child.css( childFrom );
17662			child.animate( childTo, options.duration, options.easing, function() {
17663
17664				// Restore children
17665				if ( restore ) {
17666					$.effects.restoreStyle( child );
17667				}
17668			} );
17669		} );
17670	}
17671
17672	// Animate
17673	element.animate( to, {
17674		queue: false,
17675		duration: options.duration,
17676		easing: options.easing,
17677		complete: function() {
17678
17679			var offset = element.offset();
17680
17681			if ( to.opacity === 0 ) {
17682				element.css( "opacity", from.opacity );
17683			}
17684
17685			if ( !restore ) {
17686				element
17687					.css( "position", position === "static" ? "relative" : position )
17688					.offset( offset );
17689
17690				// Need to save style here so that automatic style restoration
17691				// doesn't restore to the original styles from before the animation.
17692				$.effects.saveStyle( element );
17693			}
17694
17695			done();
17696		}
17697	} );
17698
17699} );
17700
17701
17702/*!
17703 * jQuery UI Effects Scale 1.12.1
17704 * http://jqueryui.com
17705 *
17706 * Copyright jQuery Foundation and other contributors
17707 * Released under the MIT license.
17708 * http://jquery.org/license
17709 */
17710
17711//>>label: Scale Effect
17712//>>group: Effects
17713//>>description: Grows or shrinks an element and its content.
17714//>>docs: http://api.jqueryui.com/scale-effect/
17715//>>demos: http://jqueryui.com/effect/
17716
17717
17718
17719var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
17720
17721	// Create element
17722	var el = $( this ),
17723		mode = options.mode,
17724		percent = parseInt( options.percent, 10 ) ||
17725			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
17726
17727		newOptions = $.extend( true, {
17728			from: $.effects.scaledDimensions( el ),
17729			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
17730			origin: options.origin || [ "middle", "center" ]
17731		}, options );
17732
17733	// Fade option to support puff
17734	if ( options.fade ) {
17735		newOptions.from.opacity = 1;
17736		newOptions.to.opacity = 0;
17737	}
17738
17739	$.effects.effect.size.call( this, newOptions, done );
17740} );
17741
17742
17743/*!
17744 * jQuery UI Effects Puff 1.12.1
17745 * http://jqueryui.com
17746 *
17747 * Copyright jQuery Foundation and other contributors
17748 * Released under the MIT license.
17749 * http://jquery.org/license
17750 */
17751
17752//>>label: Puff Effect
17753//>>group: Effects
17754//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
17755//>>docs: http://api.jqueryui.com/puff-effect/
17756//>>demos: http://jqueryui.com/effect/
17757
17758
17759
17760var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
17761	var newOptions = $.extend( true, {}, options, {
17762		fade: true,
17763		percent: parseInt( options.percent, 10 ) || 150
17764	} );
17765
17766	$.effects.effect.scale.call( this, newOptions, done );
17767} );
17768
17769
17770/*!
17771 * jQuery UI Effects Pulsate 1.12.1
17772 * http://jqueryui.com
17773 *
17774 * Copyright jQuery Foundation and other contributors
17775 * Released under the MIT license.
17776 * http://jquery.org/license
17777 */
17778
17779//>>label: Pulsate Effect
17780//>>group: Effects
17781//>>description: Pulsates an element n times by changing the opacity to zero and back.
17782//>>docs: http://api.jqueryui.com/pulsate-effect/
17783//>>demos: http://jqueryui.com/effect/
17784
17785
17786
17787var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
17788	var element = $( this ),
17789		mode = options.mode,
17790		show = mode === "show",
17791		hide = mode === "hide",
17792		showhide = show || hide,
17793
17794		// Showing or hiding leaves off the "last" animation
17795		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
17796		duration = options.duration / anims,
17797		animateTo = 0,
17798		i = 1,
17799		queuelen = element.queue().length;
17800
17801	if ( show || !element.is( ":visible" ) ) {
17802		element.css( "opacity", 0 ).show();
17803		animateTo = 1;
17804	}
17805
17806	// Anims - 1 opacity "toggles"
17807	for ( ; i < anims; i++ ) {
17808		element.animate( { opacity: animateTo }, duration, options.easing );
17809		animateTo = 1 - animateTo;
17810	}
17811
17812	element.animate( { opacity: animateTo }, duration, options.easing );
17813
17814	element.queue( done );
17815
17816	$.effects.unshift( element, queuelen, anims + 1 );
17817} );
17818
17819
17820/*!
17821 * jQuery UI Effects Shake 1.12.1
17822 * http://jqueryui.com
17823 *
17824 * Copyright jQuery Foundation and other contributors
17825 * Released under the MIT license.
17826 * http://jquery.org/license
17827 */
17828
17829//>>label: Shake Effect
17830//>>group: Effects
17831//>>description: Shakes an element horizontally or vertically n times.
17832//>>docs: http://api.jqueryui.com/shake-effect/
17833//>>demos: http://jqueryui.com/effect/
17834
17835
17836
17837var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
17838
17839	var i = 1,
17840		element = $( this ),
17841		direction = options.direction || "left",
17842		distance = options.distance || 20,
17843		times = options.times || 3,
17844		anims = times * 2 + 1,
17845		speed = Math.round( options.duration / anims ),
17846		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17847		positiveMotion = ( direction === "up" || direction === "left" ),
17848		animation = {},
17849		animation1 = {},
17850		animation2 = {},
17851
17852		queuelen = element.queue().length;
17853
17854	$.effects.createPlaceholder( element );
17855
17856	// Animation
17857	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
17858	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
17859	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
17860
17861	// Animate
17862	element.animate( animation, speed, options.easing );
17863
17864	// Shakes
17865	for ( ; i < times; i++ ) {
17866		element
17867			.animate( animation1, speed, options.easing )
17868			.animate( animation2, speed, options.easing );
17869	}
17870
17871	element
17872		.animate( animation1, speed, options.easing )
17873		.animate( animation, speed / 2, options.easing )
17874		.queue( done );
17875
17876	$.effects.unshift( element, queuelen, anims + 1 );
17877} );
17878
17879
17880/*!
17881 * jQuery UI Effects Slide 1.12.1
17882 * http://jqueryui.com
17883 *
17884 * Copyright jQuery Foundation and other contributors
17885 * Released under the MIT license.
17886 * http://jquery.org/license
17887 */
17888
17889//>>label: Slide Effect
17890//>>group: Effects
17891//>>description: Slides an element in and out of the viewport.
17892//>>docs: http://api.jqueryui.com/slide-effect/
17893//>>demos: http://jqueryui.com/effect/
17894
17895
17896
17897var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
17898	var startClip, startRef,
17899		element = $( this ),
17900		map = {
17901			up: [ "bottom", "top" ],
17902			down: [ "top", "bottom" ],
17903			left: [ "right", "left" ],
17904			right: [ "left", "right" ]
17905		},
17906		mode = options.mode,
17907		direction = options.direction || "left",
17908		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17909		positiveMotion = ( direction === "up" || direction === "left" ),
17910		distance = options.distance ||
17911			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
17912		animation = {};
17913
17914	$.effects.createPlaceholder( element );
17915
17916	startClip = element.cssClip();
17917	startRef = element.position()[ ref ];
17918
17919	// Define hide animation
17920	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
17921	animation.clip = element.cssClip();
17922	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
17923
17924	// Reverse the animation if we're showing
17925	if ( mode === "show" ) {
17926		element.cssClip( animation.clip );
17927		element.css( ref, animation[ ref ] );
17928		animation.clip = startClip;
17929		animation[ ref ] = startRef;
17930	}
17931
17932	// Actually animate
17933	element.animate( animation, {
17934		queue: false,
17935		duration: options.duration,
17936		easing: options.easing,
vendor: 637 bytes, lines 17937-17970
17937		complete: done
17938	} );
17939} );
17940
17941
17942/*!
17943 * jQuery UI Effects Transfer 1.12.1
17944 * http://jqueryui.com
17945 *
17946 * Copyright jQuery Foundation and other contributors
17947 * Released under the MIT license.
17948 * http://jquery.org/license
17949 */
17950
17951//>>label: Transfer Effect
17952//>>group: Effects
17953//>>description: Displays a transfer effect from one element to another.
17954//>>docs: http://api.jqueryui.com/transfer-effect/
17955//>>demos: http://jqueryui.com/effect/
17956
17957
17958
17959var effect;
17960if ( $.uiBackCompat !== false ) {
17961	effect = $.effects.define( "transfer", function( options, done ) {
17962		$( this ).transfer( options, done );
17963	} );
17964}
17965var effectsEffectTransfer = effect;
17966
17967
17968
17969
17970}));

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.