PageSourceSearch

https://www.barnetband.org/brostools/jquery/jqueryui/js/jquery-ui.js?ver=522454

js barnetband.org collected 2026-10-02 00:12:33 UTC 522,454 bytes, 18,844 lines download raw bytes

1/*! jQuery UI - v1.14.2 - 2026-02-23
2* https://jqueryui.com
3* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-patch.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/slider.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: 25,280 bytes, lines 3-943
3.js
4* Copyright OpenJS Foundation and other contributors; Licensed MIT */
5
6( function( factory ) {
7	"use strict";
8
9	if ( typeof define === "function" && define.amd ) {
10
11		// AMD. Register as an anonymous module.
12		define( [ "jquery" ], factory );
13	} else {
14
15		// Browser globals
16		factory( jQuery );
17	}
18} )( function( $ ) {
19"use strict";
20
21$.ui = $.ui || {};
22
23var version = $.ui.version = "1.14.2";
24
25
26/*!
27 * jQuery UI Widget 1.14.2
28 * https://jqueryui.com
29 *
30 * Copyright OpenJS Foundation and other contributors
31 * Released under the MIT license.
32 * https://jquery.org/license
33 */
34
35//>>label: Widget
36//>>group: Core
37//>>description: Provides a factory for creating stateful widgets with a common API.
38//>>docs: https://api.jqueryui.com/jQuery.widget/
39//>>demos: https://jqueryui.com/widget/
40
41
42var widgetUuid = 0;
43var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
44var widgetSlice = Array.prototype.slice;
45
46$.cleanData = ( function( orig ) {
47	return function( elems ) {
48		var events, elem, i;
49		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
50
51			// Only trigger remove when necessary to save time
52			events = $._data( elem, "events" );
53			if ( events && events.remove ) {
54				$( elem ).triggerHandler( "remove" );
55			}
56		}
57		orig( elems );
58	};
59} )( $.cleanData );
60
61$.widget = function( name, base, prototype ) {
62	var existingConstructor, constructor, basePrototype;
63
64	// ProxiedPrototype allows the provided prototype to remain unmodified
65	// so that it can be used as a mixin for multiple widgets (#8876)
66	var proxiedPrototype = {};
67
68	var namespace = name.split( "." )[ 0 ];
69	name = name.split( "." )[ 1 ];
70	if ( name === "__proto__" || name === "constructor" ) {
71		return $.error( "Invalid widget name: " + name );
72	}
73	var fullName = namespace + "-" + name;
74
75	if ( !prototype ) {
76		prototype = base;
77		base = $.Widget;
78	}
79
80	if ( Array.isArray( prototype ) ) {
81		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
82	}
83
84	// Create selector for plugin
85	$.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
86		return !!$.data( elem, fullName );
87	};
88
89	$[ namespace ] = $[ namespace ] || {};
90	existingConstructor = $[ namespace ][ name ];
91	constructor = $[ namespace ][ name ] = function( options, element ) {
92
93		// Allow instantiation without "new" keyword
94		if ( !this || !this._createWidget ) {
95			return new constructor( options, element );
96		}
97
98		// Allow instantiation without initializing for simple inheritance
99		// must use "new" keyword (the code above always passes args)
100		if ( arguments.length ) {
101			this._createWidget( options, element );
102		}
103	};
104
105	// Extend with the existing constructor to carry over any static properties
106	$.extend( constructor, existingConstructor, {
107		version: prototype.version,
108
109		// Copy the object used to create the prototype in case we need to
110		// redefine the widget later
111		_proto: $.extend( {}, prototype ),
112
113		// Track widgets that inherit from this widget in case this widget is
114		// redefined after a widget inherits from it
115		_childConstructors: []
116	} );
117
118	basePrototype = new base();
119
120	// We need to make the options hash a property directly on the new instance
121	// otherwise we'll modify the options hash on the prototype that we're
122	// inheriting from
123	basePrototype.options = $.widget.extend( {}, basePrototype.options );
124	$.each( prototype, function( prop, value ) {
125		if ( typeof value !== "function" ) {
126			proxiedPrototype[ prop ] = value;
127			return;
128		}
129		proxiedPrototype[ prop ] = ( function() {
130			function _super() {
131				return base.prototype[ prop ].apply( this, arguments );
132			}
133
134			function _superApply( args ) {
135				return base.prototype[ prop ].apply( this, args );
136			}
137
138			return function() {
139				var __super = this._super;
140				var __superApply = this._superApply;
141				var returnValue;
142
143				this._super = _super;
144				this._superApply = _superApply;
145
146				returnValue = value.apply( this, arguments );
147
148				this._super = __super;
149				this._superApply = __superApply;
150
151				return returnValue;
152			};
153		} )();
154	} );
155	constructor.prototype = $.widget.extend( basePrototype, {
156
157		// TODO: remove support for widgetEventPrefix
158		// always use the name + a colon as the prefix, e.g., draggable:start
159		// don't prefix for widgets that aren't DOM-based
160		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
161	}, proxiedPrototype, {
162		constructor: constructor,
163		namespace: namespace,
164		widgetName: name,
165		widgetFullName: fullName
166	} );
167
168	// If this widget is being redefined then we need to find all widgets that
169	// are inheriting from it and redefine all of them so that they inherit from
170	// the new version of this widget. We're essentially trying to replace one
171	// level in the prototype chain.
172	if ( existingConstructor ) {
173		$.each( existingConstructor._childConstructors, function( i, child ) {
174			var childPrototype = child.prototype;
175
176			// Redefine the child widget using the same prototype that was
177			// originally used, but inherit from the new version of the base
178			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
179				child._proto );
180		} );
181
182		// Remove the list of existing child constructors from the old constructor
183		// so the old child constructors can be garbage collected
184		delete existingConstructor._childConstructors;
185	} else {
186		base._childConstructors.push( constructor );
187	}
188
189	$.widget.bridge( name, constructor );
190
191	return constructor;
192};
193
194$.widget.extend = function( target ) {
195	var input = widgetSlice.call( arguments, 1 );
196	var inputIndex = 0;
197	var inputLength = input.length;
198	var key;
199	var value;
200
201	for ( ; inputIndex < inputLength; inputIndex++ ) {
202		for ( key in input[ inputIndex ] ) {
203			value = input[ inputIndex ][ key ];
204			if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
205
206				// Clone objects
207				if ( $.isPlainObject( value ) ) {
208					target[ key ] = $.isPlainObject( target[ key ] ) ?
209						$.widget.extend( {}, target[ key ], value ) :
210
211						// Don't extend strings, arrays, etc. with objects
212						$.widget.extend( {}, value );
213
214				// Copy everything else by reference
215				} else {
216					target[ key ] = value;
217				}
218			}
219		}
220	}
221	return target;
222};
223
224$.widget.bridge = function( name, object ) {
225	var fullName = object.prototype.widgetFullName || name;
226	$.fn[ name ] = function( options ) {
227		var isMethodCall = typeof options === "string";
228		var args = widgetSlice.call( arguments, 1 );
229		var returnValue = this;
230
231		if ( isMethodCall ) {
232
233			// If this is an empty collection, we need to have the instance method
234			// return undefined instead of the jQuery instance
235			if ( !this.length && options === "instance" ) {
236				returnValue = undefined;
237			} else {
238				this.each( function() {
239					var methodValue;
240					var instance = $.data( this, fullName );
241
242					if ( options === "instance" ) {
243						returnValue = instance;
244						return false;
245					}
246
247					if ( !instance ) {
248						return $.error( "cannot call methods on " + name +
249							" prior to initialization; " +
250							"attempted to call method '" + options + "'" );
251					}
252
253					if ( typeof instance[ options ] !== "function" ||
254						options.charAt( 0 ) === "_" ) {
255						return $.error( "no such method '" + options + "' for " + name +
256							" widget instance" );
257					}
258
259					methodValue = instance[ options ].apply( instance, args );
260
261					if ( methodValue !== instance && methodValue !== undefined ) {
262						returnValue = methodValue && methodValue.jquery ?
263							returnValue.pushStack( methodValue.get() ) :
264							methodValue;
265						return false;
266					}
267				} );
268			}
269		} else {
270
271			// Allow multiple hashes to be passed on init
272			if ( args.length ) {
273				options = $.widget.extend.apply( null, [ options ].concat( args ) );
274			}
275
276			this.each( function() {
277				var instance = $.data( this, fullName );
278				if ( instance ) {
279					instance.option( options || {} );
280					if ( instance._init ) {
281						instance._init();
282					}
283				} else {
284					$.data( this, fullName, new object( options, this ) );
285				}
286			} );
287		}
288
289		return returnValue;
290	};
291};
292
293$.Widget = function( /* options, element */ ) {};
294$.Widget._childConstructors = [];
295
296$.Widget.prototype = {
297	widgetName: "widget",
298	widgetEventPrefix: "",
299	defaultElement: "<div>",
300
301	options: {
302		classes: {},
303		disabled: false,
304
305		// Callbacks
306		create: null
307	},
308
309	_createWidget: function( options, element ) {
310		element = $( element || this.defaultElement || this )[ 0 ];
311		this.element = $( element );
312		this.uuid = widgetUuid++;
313		this.eventNamespace = "." + this.widgetName + this.uuid;
314
315		this.bindings = $();
316		this.hoverable = $();
317		this.focusable = $();
318		this.classesElementLookup = {};
319
320		if ( element !== this ) {
321			$.data( element, this.widgetFullName, this );
322			this._on( true, this.element, {
323				remove: function( event ) {
324					if ( event.target === element ) {
325						this.destroy();
326					}
327				}
328			} );
329			this.document = $( element.style ?
330
331				// Element within the document
332				element.ownerDocument :
333
334				// Element is window or document
335				element.document || element );
336			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
337		}
338
339		this.options = $.widget.extend( {},
340			this.options,
341			this._getCreateOptions(),
342			options );
343
344		this._create();
345
346		if ( this.options.disabled ) {
347			this._setOptionDisabled( this.options.disabled );
348		}
349
350		this._trigger( "create", null, this._getCreateEventData() );
351		this._init();
352	},
353
354	_getCreateOptions: function() {
355		return {};
356	},
357
358	_getCreateEventData: $.noop,
359
360	_create: $.noop,
361
362	_init: $.noop,
363
364	destroy: function() {
365		var that = this;
366
367		this._destroy();
368		$.each( this.classesElementLookup, function( key, value ) {
369			that._removeClass( value, key );
370		} );
371
372		// We can probably remove the unbind calls in 2.0
373		// all event bindings should go through this._on()
374		this.element
375			.off( this.eventNamespace )
376			.removeData( this.widgetFullName );
377		this.widget()
378			.off( this.eventNamespace )
379			.removeAttr( "aria-disabled" );
380
381		// Clean up events and states
382		this.bindings.off( this.eventNamespace );
383	},
384
385	_destroy: $.noop,
386
387	widget: function() {
388		return this.element;
389	},
390
391	option: function( key, value ) {
392		var options = key;
393		var parts;
394		var curOption;
395		var i;
396
397		if ( arguments.length === 0 ) {
398
399			// Don't return a reference to the internal hash
400			return $.widget.extend( {}, this.options );
401		}
402
403		if ( typeof key === "string" ) {
404
405			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
406			options = {};
407			parts = key.split( "." );
408			key = parts.shift();
409			if ( parts.length ) {
410				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
411				for ( i = 0; i < parts.length - 1; i++ ) {
412					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
413					curOption = curOption[ parts[ i ] ];
414				}
415				key = parts.pop();
416				if ( arguments.length === 1 ) {
417					return curOption[ key ] === undefined ? null : curOption[ key ];
418				}
419				curOption[ key ] = value;
420			} else {
421				if ( arguments.length === 1 ) {
422					return this.options[ key ] === undefined ? null : this.options[ key ];
423				}
424				options[ key ] = value;
425			}
426		}
427
428		this._setOptions( options );
429
430		return this;
431	},
432
433	_setOptions: function( options ) {
434		var key;
435
436		for ( key in options ) {
437			this._setOption( key, options[ key ] );
438		}
439
440		return this;
441	},
442
443	_setOption: function( key, value ) {
444		if ( key === "classes" ) {
445			this._setOptionClasses( value );
446		}
447
448		this.options[ key ] = value;
449
450		if ( key === "disabled" ) {
451			this._setOptionDisabled( value );
452		}
453
454		return this;
455	},
456
457	_setOptionClasses: function( value ) {
458		var classKey, elements, currentElements;
459
460		for ( classKey in value ) {
461			currentElements = this.classesElementLookup[ classKey ];
462			if ( value[ classKey ] === this.options.classes[ classKey ] ||
463					!currentElements ||
464					!currentElements.length ) {
465				continue;
466			}
467
468			// We are doing this to create a new jQuery object because the _removeClass() call
469			// on the next line is going to destroy the reference to the current elements being
470			// tracked. We need to save a copy of this collection so that we can add the new classes
471			// below.
472			elements = $( currentElements.get() );
473			this._removeClass( currentElements, classKey );
474
475			// We don't use _addClass() here, because that uses this.options.classes
476			// for generating the string of classes. We want to use the value passed in from
477			// _setOption(), this is the new value of the classes option which was passed to
478			// _setOption(). We pass this value directly to _classes().
479			elements.addClass( this._classes( {
480				element: elements,
481				keys: classKey,
482				classes: value,
483				add: true
484			} ) );
485		}
486	},
487
488	_setOptionDisabled: function( value ) {
489		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
490
491		// If the widget is becoming disabled, then nothing is interactive
492		if ( value ) {
493			this._removeClass( this.hoverable, null, "ui-state-hover" );
494			this._removeClass( this.focusable, null, "ui-state-focus" );
495		}
496	},
497
498	enable: function() {
499		return this._setOptions( { disabled: false } );
500	},
501
502	disable: function() {
503		return this._setOptions( { disabled: true } );
504	},
505
506	_classes: function( options ) {
507		var full = [];
508		var that = this;
509
510		options = $.extend( {
511			element: this.element,
512			classes: this.options.classes || {}
513		}, options );
514
515		function bindRemoveEvent() {
516			var nodesToBind = [];
517
518			options.element.each( function( _, element ) {
519				var isTracked = $.map( that.classesElementLookup, function( elements ) {
520					return elements;
521				} )
522					.some( function( elements ) {
523						return elements.is( element );
524					} );
525
526				if ( !isTracked ) {
527					nodesToBind.push( element );
528				}
529			} );
530
531			that._on( $( nodesToBind ), {
532				remove: "_untrackClassesElement"
533			} );
534		}
535
536		function processClassString( classes, checkOption ) {
537			var current, i;
538			for ( i = 0; i < classes.length; i++ ) {
539				current = that.classesElementLookup[ classes[ i ] ] || $();
540				if ( options.add ) {
541					bindRemoveEvent();
542					current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
543				} else {
544					current = $( current.not( options.element ).get() );
545				}
546				that.classesElementLookup[ classes[ i ] ] = current;
547				full.push( classes[ i ] );
548				if ( checkOption && options.classes[ classes[ i ] ] ) {
549					full.push( options.classes[ classes[ i ] ] );
550				}
551			}
552		}
553
554		if ( options.keys ) {
555			processClassString( options.keys.match( /\S+/g ) || [], true );
556		}
557		if ( options.extra ) {
558			processClassString( options.extra.match( /\S+/g ) || [] );
559		}
560
561		return full.join( " " );
562	},
563
564	_untrackClassesElement: function( event ) {
565		var that = this;
566		$.each( that.classesElementLookup, function( key, value ) {
567			if ( $.inArray( event.target, value ) !== -1 ) {
568				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
569			}
570		} );
571
572		this._off( $( event.target ) );
573	},
574
575	_removeClass: function( element, keys, extra ) {
576		return this._toggleClass( element, keys, extra, false );
577	},
578
579	_addClass: function( element, keys, extra ) {
580		return this._toggleClass( element, keys, extra, true );
581	},
582
583	_toggleClass: function( element, keys, extra, add ) {
584		add = ( typeof add === "boolean" ) ? add : extra;
585		var shift = ( typeof element === "string" || element === null ),
586			options = {
587				extra: shift ? keys : extra,
588				keys: shift ? element : keys,
589				element: shift ? this.element : element,
590				add: add
591			};
592		options.element.toggleClass( this._classes( options ), add );
593		return this;
594	},
595
596	_on: function( suppressDisabledCheck, element, handlers ) {
597		var delegateElement;
598		var instance = this;
599
600		// No suppressDisabledCheck flag, shuffle arguments
601		if ( typeof suppressDisabledCheck !== "boolean" ) {
602			handlers = element;
603			element = suppressDisabledCheck;
604			suppressDisabledCheck = false;
605		}
606
607		// No element argument, shuffle and use this.element
608		if ( !handlers ) {
609			handlers = element;
610			element = this.element;
611			delegateElement = this.widget();
612		} else {
613			element = delegateElement = $( element );
614			this.bindings = this.bindings.add( element );
615		}
616
617		$.each( handlers, function( event, handler ) {
618			function handlerProxy() {
619
620				// Allow widgets to customize the disabled handling
621				// - disabled as an array instead of boolean
622				// - disabled class as method for disabling individual parts
623				if ( !suppressDisabledCheck &&
624						( instance.options.disabled === true ||
625						$( this ).hasClass( "ui-state-disabled" ) ) ) {
626					return;
627				}
628				return ( typeof handler === "string" ? instance[ handler ] : handler )
629					.apply( instance, arguments );
630			}
631
632			// Copy the guid so direct unbinding works
633			if ( typeof handler !== "string" ) {
634				handlerProxy.guid = handler.guid =
635					handler.guid || handlerProxy.guid || $.guid++;
636			}
637
638			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
639			var eventName = match[ 1 ] + instance.eventNamespace;
640			var selector = match[ 2 ];
641
642			if ( selector ) {
643				delegateElement.on( eventName, selector, handlerProxy );
644			} else {
645				element.on( eventName, handlerProxy );
646			}
647		} );
648	},
649
650	_off: function( element, eventName ) {
651		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
652			this.eventNamespace;
653		element.off( eventName );
654
655		// Clear the stack to avoid memory leaks (#10056)
656		this.bindings = $( this.bindings.not( element ).get() );
657		this.focusable = $( this.focusable.not( element ).get() );
658		this.hoverable = $( this.hoverable.not( element ).get() );
659	},
660
661	_delay: function( handler, delay ) {
662		function handlerProxy() {
663			return ( typeof handler === "string" ? instance[ handler ] : handler )
664				.apply( instance, arguments );
665		}
666		var instance = this;
667		return setTimeout( handlerProxy, delay || 0 );
668	},
669
670	_hoverable: function( element ) {
671		this.hoverable = this.hoverable.add( element );
672		this._on( element, {
673			mouseenter: function( event ) {
674				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
675			},
676			mouseleave: function( event ) {
677				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
678			}
679		} );
680	},
681
682	_focusable: function( element ) {
683		this.focusable = this.focusable.add( element );
684		this._on( element, {
685			focusin: function( event ) {
686				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
687			},
688			focusout: function( event ) {
689				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
690			}
691		} );
692	},
693
694	_trigger: function( type, event, data ) {
695		var prop, orig;
696		var callback = this.options[ type ];
697
698		data = data || {};
699		event = $.Event( event );
700		event.type = ( type === this.widgetEventPrefix ?
701			type :
702			this.widgetEventPrefix + type ).toLowerCase();
703
704		// The original event may come from any element
705		// so we need to reset the target on the new event
706		event.target = this.element[ 0 ];
707
708		// Copy original event properties over to the new event
709		orig = event.originalEvent;
710		if ( orig ) {
711			for ( prop in orig ) {
712				if ( !( prop in event ) ) {
713					event[ prop ] = orig[ prop ];
714				}
715			}
716		}
717
718		this.element.trigger( event, data );
719		return !( typeof callback === "function" &&
720			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
721			event.isDefaultPrevented() );
722	}
723};
724
725$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
726	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
727		if ( typeof options === "string" ) {
728			options = { effect: options };
729		}
730
731		var hasOptions;
732		var effectName = !options ?
733			method :
734			options === true || typeof options === "number" ?
735				defaultEffect :
736				options.effect || defaultEffect;
737
738		options = options || {};
739		if ( typeof options === "number" ) {
740			options = { duration: options };
741		} else if ( options === true ) {
742			options = {};
743		}
744
745		hasOptions = !$.isEmptyObject( options );
746		options.complete = callback;
747
748		if ( options.delay ) {
749			element.delay( options.delay );
750		}
751
752		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
753			element[ method ]( options );
754		} else if ( effectName !== method && element[ effectName ] ) {
755			element[ effectName ]( options.duration, options.easing, callback );
756		} else {
757			element.queue( function( next ) {
758				$( this )[ method ]();
759				if ( callback ) {
760					callback.call( element[ 0 ] );
761				}
762				next();
763			} );
764		}
765	};
766} );
767
768var widget = $.widget;
769
770
771/*!
772 * jQuery UI Position 1.14.2
773 * https://jqueryui.com
774 *
775 * Copyright OpenJS Foundation and other contributors
776 * Released under the MIT license.
777 * https://jquery.org/license
778 *
779 * https://api.jqueryui.com/position/
780 */
781
782//>>label: Position
783//>>group: Core
784//>>description: Positions elements relative to other elements.
785//>>docs: https://api.jqueryui.com/position/
786//>>demos: https://jqueryui.com/position/
787
788
789( function() {
790var cachedScrollbarWidth,
791	max = Math.max,
792	abs = Math.abs,
793	rhorizontal = /left|center|right/,
794	rvertical = /top|center|bottom/,
795	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
796	rposition = /^\w+/,
797	rpercent = /%$/,
798	_position = $.fn.position;
799
800function getOffsets( offsets, width, height ) {
801	return [
802		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
803		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
804	];
805}
806
807function parseCss( element, property ) {
808	return parseInt( $.css( element, property ), 10 ) || 0;
809}
810
811function isWindow( obj ) {
812	return obj != null && obj === obj.window;
813}
814
815function getDimensions( elem ) {
816	var raw = elem[ 0 ];
817	if ( raw.nodeType === 9 ) {
818		return {
819			width: elem.width(),
820			height: elem.height(),
821			offset: { top: 0, left: 0 }
822		};
823	}
824	if ( isWindow( raw ) ) {
825		return {
826			width: elem.width(),
827			height: elem.height(),
828			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
829		};
830	}
831	if ( raw.preventDefault ) {
832		return {
833			width: 0,
834			height: 0,
835			offset: { top: raw.pageY, left: raw.pageX }
836		};
837	}
838	return {
839		width: elem.outerWidth(),
840		height: elem.outerHeight(),
841		offset: elem.offset()
842	};
843}
844
845$.position = {
846	scrollbarWidth: function() {
847		if ( cachedScrollbarWidth !== undefined ) {
848			return cachedScrollbarWidth;
849		}
850		var w1, w2,
851			div = $( "<div style=" +
852				"'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" +
853				"<div style='height:300px;width:auto;'></div></div>" ),
854			innerDiv = div.children()[ 0 ];
855
856		$( "body" ).append( div );
857		w1 = innerDiv.offsetWidth;
858		div.css( "overflow", "scroll" );
859
860		w2 = innerDiv.offsetWidth;
861
862		if ( w1 === w2 ) {
863			w2 = div[ 0 ].clientWidth;
864		}
865
866		div.remove();
867
868		return ( cachedScrollbarWidth = w1 - w2 );
869	},
870	getScrollInfo: function( within ) {
871		var overflowX = within.isWindow || within.isDocument ? "" :
872				within.element.css( "overflow-x" ),
873			overflowY = within.isWindow || within.isDocument ? "" :
874				within.element.css( "overflow-y" ),
875			hasOverflowX = overflowX === "scroll" ||
876				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
877			hasOverflowY = overflowY === "scroll" ||
878				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
879		return {
880			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
881			height: hasOverflowX ? $.position.scrollbarWidth() : 0
882		};
883	},
884	getWithinInfo: function( element ) {
885		var withinElement = $( element || window ),
886			isElemWindow = isWindow( withinElement[ 0 ] ),
887			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
888			hasOffset = !isElemWindow && !isDocument;
889		return {
890			element: withinElement,
891			isWindow: isElemWindow,
892			isDocument: isDocument,
893			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
894			scrollLeft: withinElement.scrollLeft(),
895			scrollTop: withinElement.scrollTop(),
896			width: withinElement.outerWidth(),
897			height: withinElement.outerHeight()
898		};
899	}
900};
901
902$.fn.position = function( options ) {
903	if ( !options || !options.of ) {
904		return _position.apply( this, arguments );
905	}
906
907	// Make a copy, we don't want to modify arguments
908	options = $.extend( {}, options );
909
910	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
911
912		// Make sure string options are treated as CSS selectors
913		target = typeof options.of === "string" ?
914			$( document ).find( options.of ) :
915			$( options.of ),
916
917		within = $.position.getWithinInfo( options.within ),
918		scrollInfo = $.position.getScrollInfo( within ),
919		collision = ( options.collision || "flip" ).split( " " ),
920		offsets = {};
921
922	dimensions = getDimensions( target );
923	if ( target[ 0 ].preventDefault ) {
924
925		// Force left top to allow flipping
926		options.at = "left top";
927	}
928	targetWidth = dimensions.width;
929	targetHeight = dimensions.height;
930	targetOffset = dimensions.offset;
931
932	// Clone to reuse original targetOffset later
933	basePosition = $.extend( {}, targetOffset );
934
935	// Force my and at to have valid horizontal and vertical positions
936	// if a value is missing or invalid, it will be converted to center
937	$.each( [ "my", "at" ], function() {
938		var pos = ( options[ this ] || "" ).split( " " ),
939			horizontalOffset,
940			verticalOffset;
941
942		if ( pos.length === 1 ) {
943			pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 4,599 bytes, lines 944-1096
944				pos.concat( [ "center" ] ) :
945				rvertical.test( pos[ 0 ] ) ?
946					[ "center" ].concat( pos ) :
947					[ "center", "center" ];
948		}
949		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
950		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
951
952		// Calculate offsets
953		horizontalOffset = roffset.exec( pos[ 0 ] );
954		verticalOffset = roffset.exec( pos[ 1 ] );
955		offsets[ this ] = [
956			horizontalOffset ? horizontalOffset[ 0 ] : 0,
957			verticalOffset ? verticalOffset[ 0 ] : 0
958		];
959
960		// Reduce to just the positions without the offsets
961		options[ this ] = [
962			rposition.exec( pos[ 0 ] )[ 0 ],
963			rposition.exec( pos[ 1 ] )[ 0 ]
964		];
965	} );
966
967	// Normalize collision option
968	if ( collision.length === 1 ) {
969		collision[ 1 ] = collision[ 0 ];
970	}
971
972	if ( options.at[ 0 ] === "right" ) {
973		basePosition.left += targetWidth;
974	} else if ( options.at[ 0 ] === "center" ) {
975		basePosition.left += targetWidth / 2;
976	}
977
978	if ( options.at[ 1 ] === "bottom" ) {
979		basePosition.top += targetHeight;
980	} else if ( options.at[ 1 ] === "center" ) {
981		basePosition.top += targetHeight / 2;
982	}
983
984	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
985	basePosition.left += atOffset[ 0 ];
986	basePosition.top += atOffset[ 1 ];
987
988	return this.each( function() {
989		var collisionPosition, using,
990			elem = $( this ),
991			elemWidth = elem.outerWidth(),
992			elemHeight = elem.outerHeight(),
993			marginLeft = parseCss( this, "marginLeft" ),
994			marginTop = parseCss( this, "marginTop" ),
995			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
996				scrollInfo.width,
997			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
998				scrollInfo.height,
999			position = $.extend( {}, basePosition ),
1000			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1001
1002		if ( options.my[ 0 ] === "right" ) {
1003			position.left -= elemWidth;
1004		} else if ( options.my[ 0 ] === "center" ) {
1005			position.left -= elemWidth / 2;
1006		}
1007
1008		if ( options.my[ 1 ] === "bottom" ) {
1009			position.top -= elemHeight;
1010		} else if ( options.my[ 1 ] === "center" ) {
1011			position.top -= elemHeight / 2;
1012		}
1013
1014		position.left += myOffset[ 0 ];
1015		position.top += myOffset[ 1 ];
1016
1017		collisionPosition = {
1018			marginLeft: marginLeft,
1019			marginTop: marginTop
1020		};
1021
1022		$.each( [ "left", "top" ], function( i, dir ) {
1023			if ( $.ui.position[ collision[ i ] ] ) {
1024				$.ui.position[ collision[ i ] ][ dir ]( position, {
1025					targetWidth: targetWidth,
1026					targetHeight: targetHeight,
1027					elemWidth: elemWidth,
1028					elemHeight: elemHeight,
1029					collisionPosition: collisionPosition,
1030					collisionWidth: collisionWidth,
1031					collisionHeight: collisionHeight,
1032					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1033					my: options.my,
1034					at: options.at,
1035					within: within,
1036					elem: elem
1037				} );
1038			}
1039		} );
1040
1041		if ( options.using ) {
1042
1043			// Adds feedback as second argument to using callback, if present
1044			using = function( props ) {
1045				var left = targetOffset.left - position.left,
1046					right = left + targetWidth - elemWidth,
1047					top = targetOffset.top - position.top,
1048					bottom = top + targetHeight - elemHeight,
1049					feedback = {
1050						target: {
1051							element: target,
1052							left: targetOffset.left,
1053							top: targetOffset.top,
1054							width: targetWidth,
1055							height: targetHeight
1056						},
1057						element: {
1058							element: elem,
1059							left: position.left,
1060							top: position.top,
1061							width: elemWidth,
1062							height: elemHeight
1063						},
1064						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1065						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1066					};
1067				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1068					feedback.horizontal = "center";
1069				}
1070				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1071					feedback.vertical = "middle";
1072				}
1073				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1074					feedback.important = "horizontal";
1075				} else {
1076					feedback.important = "vertical";
1077				}
1078				options.using.call( this, props, feedback );
1079			};
1080		}
1081
1082		elem.offset( $.extend( position, { using: using } ) );
1083	} );
1084};
1085
1086$.ui.position = {
1087	fit: {
1088		left: function( position, data ) {
1089			var within = data.within,
1090				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1091				outerWidth = within.width,
1092				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1093				overLeft = withinOffset - collisionPosLeft,
1094				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1095				newOverRight;
1096
vendor: 6,851 bytes, lines 1097-1325
1097			// Element is wider than within
1098			if ( data.collisionWidth > outerWidth ) {
1099
1100				// Element is initially over the left side of within
1101				if ( overLeft > 0 && overRight <= 0 ) {
1102					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1103						withinOffset;
1104					position.left += overLeft - newOverRight;
1105
1106				// Element is initially over right side of within
1107				} else if ( overRight > 0 && overLeft <= 0 ) {
1108					position.left = withinOffset;
1109
1110				// Element is initially over both left and right sides of within
1111				} else {
1112					if ( overLeft > overRight ) {
1113						position.left = withinOffset + outerWidth - data.collisionWidth;
1114					} else {
1115						position.left = withinOffset;
1116					}
1117				}
1118
1119			// Too far left -> align with left edge
1120			} else if ( overLeft > 0 ) {
1121				position.left += overLeft;
1122
1123			// Too far right -> align with right edge
1124			} else if ( overRight > 0 ) {
1125				position.left -= overRight;
1126
1127			// Adjust based on position and margin
1128			} else {
1129				position.left = max( position.left - collisionPosLeft, position.left );
1130			}
1131		},
1132		top: function( position, data ) {
1133			var within = data.within,
1134				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1135				outerHeight = data.within.height,
1136				collisionPosTop = position.top - data.collisionPosition.marginTop,
1137				overTop = withinOffset - collisionPosTop,
1138				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1139				newOverBottom;
1140
1141			// Element is taller than within
1142			if ( data.collisionHeight > outerHeight ) {
1143
1144				// Element is initially over the top of within
1145				if ( overTop > 0 && overBottom <= 0 ) {
1146					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1147						withinOffset;
1148					position.top += overTop - newOverBottom;
1149
1150				// Element is initially over bottom of within
1151				} else if ( overBottom > 0 && overTop <= 0 ) {
1152					position.top = withinOffset;
1153
1154				// Element is initially over both top and bottom of within
1155				} else {
1156					if ( overTop > overBottom ) {
1157						position.top = withinOffset + outerHeight - data.collisionHeight;
1158					} else {
1159						position.top = withinOffset;
1160					}
1161				}
1162
1163			// Too far up -> align with top
1164			} else if ( overTop > 0 ) {
1165				position.top += overTop;
1166
1167			// Too far down -> align with bottom edge
1168			} else if ( overBottom > 0 ) {
1169				position.top -= overBottom;
1170
1171			// Adjust based on position and margin
1172			} else {
1173				position.top = max( position.top - collisionPosTop, position.top );
1174			}
1175		}
1176	},
1177	flip: {
1178		left: function( position, data ) {
1179			var within = data.within,
1180				withinOffset = within.offset.left + within.scrollLeft,
1181				outerWidth = within.width,
1182				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1183				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1184				overLeft = collisionPosLeft - offsetLeft,
1185				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1186				myOffset = data.my[ 0 ] === "left" ?
1187					-data.elemWidth :
1188					data.my[ 0 ] === "right" ?
1189						data.elemWidth :
1190						0,
1191				atOffset = data.at[ 0 ] === "left" ?
1192					data.targetWidth :
1193					data.at[ 0 ] === "right" ?
1194						-data.targetWidth :
1195						0,
1196				offset = -2 * data.offset[ 0 ],
1197				newOverRight,
1198				newOverLeft;
1199
1200			if ( overLeft < 0 ) {
1201				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1202					outerWidth - withinOffset;
1203				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1204					position.left += myOffset + atOffset + offset;
1205				}
1206			} else if ( overRight > 0 ) {
1207				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1208					atOffset + offset - offsetLeft;
1209				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1210					position.left += myOffset + atOffset + offset;
1211				}
1212			}
1213		},
1214		top: function( position, data ) {
1215			var within = data.within,
1216				withinOffset = within.offset.top + within.scrollTop,
1217				outerHeight = within.height,
1218				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1219				collisionPosTop = position.top - data.collisionPosition.marginTop,
1220				overTop = collisionPosTop - offsetTop,
1221				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1222				top = data.my[ 1 ] === "top",
1223				myOffset = top ?
1224					-data.elemHeight :
1225					data.my[ 1 ] === "bottom" ?
1226						data.elemHeight :
1227						0,
1228				atOffset = data.at[ 1 ] === "top" ?
1229					data.targetHeight :
1230					data.at[ 1 ] === "bottom" ?
1231						-data.targetHeight :
1232						0,
1233				offset = -2 * data.offset[ 1 ],
1234				newOverTop,
1235				newOverBottom;
1236			if ( overTop < 0 ) {
1237				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1238					outerHeight - withinOffset;
1239				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1240					position.top += myOffset + atOffset + offset;
1241				}
1242			} else if ( overBottom > 0 ) {
1243				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1244					offset - offsetTop;
1245				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1246					position.top += myOffset + atOffset + offset;
1247				}
1248			}
1249		}
1250	},
1251	flipfit: {
1252		left: function() {
1253			$.ui.position.flip.left.apply( this, arguments );
1254			$.ui.position.fit.left.apply( this, arguments );
1255		},
1256		top: function() {
1257			$.ui.position.flip.top.apply( this, arguments );
1258			$.ui.position.fit.top.apply( this, arguments );
1259		}
1260	}
1261};
1262
1263} )();
1264
1265var position = $.ui.position;
1266
1267
1268/*!
1269 * jQuery UI :data 1.14.2
1270 * https://jqueryui.com
1271 *
1272 * Copyright OpenJS Foundation and other contributors
1273 * Released under the MIT license.
1274 * https://jquery.org/license
1275 */
1276
1277//>>label: :data Selector
1278//>>group: Core
1279//>>description: Selects elements which have data stored under the specified key.
1280//>>docs: https://api.jqueryui.com/data-selector/
1281
1282
1283var data = $.extend( $.expr.pseudos, {
1284	data: $.expr.createPseudo( function( dataName ) {
1285		return function( elem ) {
1286			return !!$.data( elem, dataName );
1287		};
1288	} )
1289} );
1290
1291/*!
1292 * jQuery UI Disable Selection 1.14.2
1293 * https://jqueryui.com
1294 *
1295 * Copyright OpenJS Foundation and other contributors
1296 * Released under the MIT license.
1297 * https://jquery.org/license
1298 */
1299
1300//>>label: disableSelection
1301//>>group: Core
1302//>>description: Disable selection of text content within the set of matched elements.
1303//>>docs: https://api.jqueryui.com/disableSelection/
1304
1305// This file is deprecated
1306
1307var disableSelection = $.fn.extend( {
1308	disableSelection: ( function() {
1309		var eventType = "onselectstart" in document.createElement( "div" ) ?
1310			"selectstart" :
1311			"mousedown";
1312
1313		return function() {
1314			return this.on( eventType + ".ui-disableSelection", function( event ) {
1315				event.preventDefault();
1316			} );
1317		};
1318	} )(),
1319
1320	enableSelection: function() {
1321		return this.off( ".ui-disableSelection" );
1322	}
1323} );
1324
1325
vendor: 8,547 bytes, lines 1326-1675
1326/*!
1327 * jQuery UI Focusable 1.14.2
1328 * https://jqueryui.com
1329 *
1330 * Copyright OpenJS Foundation and other contributors
1331 * Released under the MIT license.
1332 * https://jquery.org/license
1333 */
1334
1335//>>label: :focusable Selector
1336//>>group: Core
1337//>>description: Selects elements which can be focused.
1338//>>docs: https://api.jqueryui.com/focusable-selector/
1339
1340
1341// Selectors
1342$.ui.focusable = function( element, hasTabindex ) {
1343	var map, mapName, img, focusableIfVisible, fieldset,
1344		nodeName = element.nodeName.toLowerCase();
1345
1346	if ( "area" === nodeName ) {
1347		map = element.parentNode;
1348		mapName = map.name;
1349		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
1350			return false;
1351		}
1352		img = $( "img[usemap='#" + mapName + "']" );
1353		return img.length > 0 && img.is( ":visible" );
1354	}
1355
1356	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
1357		focusableIfVisible = !element.disabled;
1358
1359		if ( focusableIfVisible ) {
1360
1361			// Form controls within a disabled fieldset are disabled.
1362			// However, controls within the fieldset's legend do not get disabled.
1363			// Since controls generally aren't placed inside legends, we skip
1364			// this portion of the check.
1365			fieldset = $( element ).closest( "fieldset" )[ 0 ];
1366			if ( fieldset ) {
1367				focusableIfVisible = !fieldset.disabled;
1368			}
1369		}
1370	} else if ( "a" === nodeName ) {
1371		focusableIfVisible = element.href || hasTabindex;
1372	} else {
1373		focusableIfVisible = hasTabindex;
1374	}
1375
1376	return focusableIfVisible && $( element ).is( ":visible" ) &&
1377		$( element ).css( "visibility" ) === "visible";
1378};
1379
1380$.extend( $.expr.pseudos, {
1381	focusable: function( element ) {
1382		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
1383	}
1384} );
1385
1386var focusable = $.ui.focusable;
1387
1388
1389/*!
1390 * jQuery UI Form Reset Mixin 1.14.2
1391 * https://jqueryui.com
1392 *
1393 * Copyright OpenJS Foundation and other contributors
1394 * Released under the MIT license.
1395 * https://jquery.org/license
1396 */
1397
1398//>>label: Form Reset Mixin
1399//>>group: Core
1400//>>description: Refresh input widgets when their form is reset
1401//>>docs: https://api.jqueryui.com/form-reset-mixin/
1402
1403
1404var formResetMixin = $.ui.formResetMixin = {
1405	_formResetHandler: function() {
1406		var form = $( this );
1407
1408		// Wait for the form reset to actually happen before refreshing
1409		setTimeout( function() {
1410			var instances = form.data( "ui-form-reset-instances" );
1411			$.each( instances, function() {
1412				this.refresh();
1413			} );
1414		} );
1415	},
1416
1417	_bindFormResetHandler: function() {
1418		this.form = $( this.element.prop( "form" ) );
1419		if ( !this.form.length ) {
1420			return;
1421		}
1422
1423		var instances = this.form.data( "ui-form-reset-instances" ) || [];
1424		if ( !instances.length ) {
1425
1426			// We don't use _on() here because we use a single event handler per form
1427			this.form.on( "reset.ui-form-reset", this._formResetHandler );
1428		}
1429		instances.push( this );
1430		this.form.data( "ui-form-reset-instances", instances );
1431	},
1432
1433	_unbindFormResetHandler: function() {
1434		if ( !this.form.length ) {
1435			return;
1436		}
1437
1438		var instances = this.form.data( "ui-form-reset-instances" );
1439		instances.splice( $.inArray( this, instances ), 1 );
1440		if ( instances.length ) {
1441			this.form.data( "ui-form-reset-instances", instances );
1442		} else {
1443			this.form
1444				.removeData( "ui-form-reset-instances" )
1445				.off( "reset.ui-form-reset" );
1446		}
1447	}
1448};
1449
1450
1451/*!
1452 * jQuery UI Legacy jQuery Core patches 1.14.2
1453 * https://jqueryui.com
1454 *
1455 * Copyright OpenJS Foundation and other contributors
1456 * Released under the MIT license.
1457 * https://jquery.org/license
1458 *
1459 */
1460
1461//>>label: Legacy jQuery Core patches
1462//>>group: Core
1463//>>description: Backport `.even()`, `.odd()` and `$.escapeSelector` to older jQuery Core versions (deprecated)
1464
1465
1466// Support: jQuery 2.2.x or older.
1467// This method has been defined in jQuery 3.0.0.
1468// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js
1469if ( !$.escapeSelector ) {
1470	$.escapeSelector = function( id ) {
1471		return CSS.escape( id + "" );
1472	};
1473}
1474
1475// Support: jQuery 3.4.x or older
1476// These methods have been defined in jQuery 3.5.0.
1477if ( !$.fn.even || !$.fn.odd ) {
1478	$.fn.extend( {
1479		even: function() {
1480			return this.filter( function( i ) {
1481				return i % 2 === 0;
1482			} );
1483		},
1484		odd: function() {
1485			return this.filter( function( i ) {
1486				return i % 2 === 1;
1487			} );
1488		}
1489	} );
1490}
1491
1492;
1493/*!
1494 * jQuery UI Keycode 1.14.2
1495 * https://jqueryui.com
1496 *
1497 * Copyright OpenJS Foundation and other contributors
1498 * Released under the MIT license.
1499 * https://jquery.org/license
1500 */
1501
1502//>>label: Keycode
1503//>>group: Core
1504//>>description: Provide keycodes as keynames
1505//>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/
1506
1507
1508var keycode = $.ui.keyCode = {
1509	BACKSPACE: 8,
1510	COMMA: 188,
1511	DELETE: 46,
1512	DOWN: 40,
1513	END: 35,
1514	ENTER: 13,
1515	ESCAPE: 27,
1516	HOME: 36,
1517	LEFT: 37,
1518	PAGE_DOWN: 34,
1519	PAGE_UP: 33,
1520	PERIOD: 190,
1521	RIGHT: 39,
1522	SPACE: 32,
1523	TAB: 9,
1524	UP: 38
1525};
1526
1527
1528/*!
1529 * jQuery UI Labels 1.14.2
1530 * https://jqueryui.com
1531 *
1532 * Copyright OpenJS Foundation and other contributors
1533 * Released under the MIT license.
1534 * https://jquery.org/license
1535 */
1536
1537//>>label: labels
1538//>>group: Core
1539//>>description: Find all the labels associated with a given input
1540//>>docs: https://api.jqueryui.com/labels/
1541
1542
1543var labels = $.fn.labels = function() {
1544	var ancestor, selector, id, labels, ancestors;
1545
1546	if ( !this.length ) {
1547		return this.pushStack( [] );
1548	}
1549
1550	// Check control.labels first
1551	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
1552		return this.pushStack( this[ 0 ].labels );
1553	}
1554
1555	// If `control.labels` is empty - e.g. inside of document fragments - find
1556	// the labels manually
1557	labels = this.eq( 0 ).parents( "label" );
1558
1559	// Look for the label based on the id
1560	id = this.attr( "id" );
1561	if ( id ) {
1562
1563		// We don't search against the document in case the element
1564		// is disconnected from the DOM
1565		ancestor = this.eq( 0 ).parents().last();
1566
1567		// Get a full set of top level ancestors
1568		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
1569
1570		// Create a selector for the label based on the id
1571		selector = "label[for='" + CSS.escape( id ) + "']";
1572
1573		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
1574
1575	}
1576
1577	// Return whatever we have found for labels
1578	return this.pushStack( labels );
1579};
1580
1581
1582/*!
1583 * jQuery UI Scroll Parent 1.14.2
1584 * https://jqueryui.com
1585 *
1586 * Copyright OpenJS Foundation and other contributors
1587 * Released under the MIT license.
1588 * https://jquery.org/license
1589 */
1590
1591//>>label: scrollParent
1592//>>group: Core
1593//>>description: Get the closest ancestor element that is scrollable.
1594//>>docs: https://api.jqueryui.com/scrollParent/
1595
1596
1597var scrollParent = $.fn.scrollParent = function( includeHidden ) {
1598	var position = this.css( "position" ),
1599		excludeStaticParent = position === "absolute",
1600		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
1601		scrollParent = this.parents().filter( function() {
1602			var parent = $( this );
1603			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
1604				return false;
1605			}
1606			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
1607				parent.css( "overflow-x" ) );
1608		} ).eq( 0 );
1609
1610	return position === "fixed" || !scrollParent.length ?
1611		$( this[ 0 ].ownerDocument || document ) :
1612		scrollParent;
1613};
1614
1615
1616/*!
1617 * jQuery UI Tabbable 1.14.2
1618 * https://jqueryui.com
1619 *
1620 * Copyright OpenJS Foundation and other contributors
1621 * Released under the MIT license.
1622 * https://jquery.org/license
1623 */
1624
1625//>>label: :tabbable Selector
1626//>>group: Core
1627//>>description: Selects elements which can be tabbed to.
1628//>>docs: https://api.jqueryui.com/tabbable-selector/
1629
1630
1631var tabbable = $.extend( $.expr.pseudos, {
1632	tabbable: function( element ) {
1633		var tabIndex = $.attr( element, "tabindex" ),
1634			hasTabindex = tabIndex != null;
1635		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
1636	}
1637} );
1638
1639
1640/*!
1641 * jQuery UI Unique ID 1.14.2
1642 * https://jqueryui.com
1643 *
1644 * Copyright OpenJS Foundation and other contributors
1645 * Released under the MIT license.
1646 * https://jquery.org/license
1647 */
1648
1649//>>label: uniqueId
1650//>>group: Core
1651//>>description: Functions to generate and remove uniqueId's
1652//>>docs: https://api.jqueryui.com/uniqueId/
1653
1654
1655var uniqueId = $.fn.extend( {
1656	uniqueId: ( function() {
1657		var uuid = 0;
1658
1659		return function() {
1660			return this.each( function() {
1661				if ( !this.id ) {
1662					this.id = "ui-id-" + ( ++uuid );
1663				}
1664			} );
1665		};
1666	} )(),
1667
1668	removeUniqueId: function() {
1669		return this.each( function() {
1670			if ( /^ui-id-\d+$/.test( this.id ) ) {
1671				$( this ).removeAttr( "id" );
1672			}
1673		} );
1674	}
1675} )
vendor: 19,830 bytes, lines 1675-2427
1675;
1676
1677
1678/*!
1679 * jQuery UI Mouse 1.14.2
1680 * https://jqueryui.com
1681 *
1682 * Copyright OpenJS Foundation and other contributors
1683 * Released under the MIT license.
1684 * https://jquery.org/license
1685 */
1686
1687//>>label: Mouse
1688//>>group: Widgets
1689//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
1690//>>docs: https://api.jqueryui.com/mouse/
1691
1692
1693var mouseHandled = false;
1694$( document ).on( "mouseup", function() {
1695	mouseHandled = false;
1696} );
1697
1698var widgetsMouse = $.widget( "ui.mouse", {
1699	version: "1.14.2",
1700	options: {
1701		cancel: "input, textarea, button, select, option",
1702		distance: 1,
1703		delay: 0
1704	},
1705	_mouseInit: function() {
1706		var that = this;
1707
1708		this.element
1709			.on( "mousedown." + this.widgetName, function( event ) {
1710				return that._mouseDown( event );
1711			} )
1712			.on( "click." + this.widgetName, function( event ) {
1713				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
1714					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
1715					event.stopImmediatePropagation();
1716					return false;
1717				}
1718			} );
1719
1720		this.started = false;
1721	},
1722
1723	// TODO: make sure destroying one instance of mouse doesn't mess with
1724	// other instances of mouse
1725	_mouseDestroy: function() {
1726		this.element.off( "." + this.widgetName );
1727		if ( this._mouseMoveDelegate ) {
1728			this.document
1729				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1730				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1731		}
1732	},
1733
1734	_mouseDown: function( event ) {
1735
1736		// don't let more than one widget handle mouseStart
1737		if ( mouseHandled ) {
1738			return;
1739		}
1740
1741		this._mouseMoved = false;
1742
1743		// We may have missed mouseup (out of window)
1744		if ( this._mouseStarted ) {
1745			this._mouseUp( event );
1746		}
1747
1748		this._mouseDownEvent = event;
1749
1750		var that = this,
1751			btnIsLeft = event.which === 1,
1752			elIsCancel = typeof this.options.cancel === "string" ?
1753				$( event.target ).closest( this.options.cancel ).length :
1754				false;
1755		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
1756			return true;
1757		}
1758
1759		this.mouseDelayMet = !this.options.delay;
1760		if ( !this.mouseDelayMet ) {
1761			this._mouseDelayTimer = setTimeout( function() {
1762				that.mouseDelayMet = true;
1763			}, this.options.delay );
1764		}
1765
1766		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1767			this._mouseStarted = ( this._mouseStart( event ) !== false );
1768			if ( !this._mouseStarted ) {
1769				event.preventDefault();
1770				return true;
1771			}
1772		}
1773
1774		// Click event may never have fired (Gecko & Opera)
1775		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
1776			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
1777		}
1778
1779		// These delegates are required to keep context
1780		this._mouseMoveDelegate = function( event ) {
1781			return that._mouseMove( event );
1782		};
1783		this._mouseUpDelegate = function( event ) {
1784			return that._mouseUp( event );
1785		};
1786
1787		this.document
1788			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1789			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
1790
1791		event.preventDefault();
1792
1793		mouseHandled = true;
1794		return true;
1795	},
1796
1797	_mouseMove: function( event ) {
1798
1799		// Only check for mouseups outside the document if you've moved inside the document
1800		// at least once.
1801		if ( this._mouseMoved && !event.which ) {
1802
1803			// Support: Safari <=8 - 9
1804			// Safari sets which to 0 if you press any of the following keys
1805			// during a drag (#14461)
1806			if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
1807					event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
1808				this.ignoreMissingWhich = true;
1809			} else if ( !this.ignoreMissingWhich ) {
1810				return this._mouseUp( event );
1811			}
1812		}
1813
1814		if ( event.which || event.button ) {
1815			this._mouseMoved = true;
1816		}
1817
1818		if ( this._mouseStarted ) {
1819			this._mouseDrag( event );
1820			return event.preventDefault();
1821		}
1822
1823		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1824			this._mouseStarted =
1825				( this._mouseStart( this._mouseDownEvent, event ) !== false );
1826			if ( this._mouseStarted ) {
1827				this._mouseDrag( event );
1828			} else {
1829				this._mouseUp( event );
1830			}
1831		}
1832
1833		return !this._mouseStarted;
1834	},
1835
1836	_mouseUp: function( event ) {
1837		this.document
1838			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1839			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1840
1841		if ( this._mouseStarted ) {
1842			this._mouseStarted = false;
1843
1844			if ( event.target === this._mouseDownEvent.target ) {
1845				$.data( event.target, this.widgetName + ".preventClickEvent", true );
1846			}
1847
1848			this._mouseStop( event );
1849		}
1850
1851		if ( this._mouseDelayTimer ) {
1852			clearTimeout( this._mouseDelayTimer );
1853			delete this._mouseDelayTimer;
1854		}
1855
1856		this.ignoreMissingWhich = false;
1857		mouseHandled = false;
1858		event.preventDefault();
1859	},
1860
1861	_mouseDistanceMet: function( event ) {
1862		return ( Math.max(
1863				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
1864				Math.abs( this._mouseDownEvent.pageY - event.pageY )
1865			) >= this.options.distance
1866		);
1867	},
1868
1869	_mouseDelayMet: function( /* event */ ) {
1870		return this.mouseDelayMet;
1871	},
1872
1873	// These are placeholder methods, to be overriden by extending plugin
1874	_mouseStart: function( /* event */ ) {},
1875	_mouseDrag: function( /* event */ ) {},
1876	_mouseStop: function( /* event */ ) {},
1877	_mouseCapture: function( /* event */ ) {
1878		return true;
1879	}
1880} );
1881
1882
1883
1884// $.ui.plugin is deprecated. Use $.widget() extensions instead.
1885var plugin = $.ui.plugin = {
1886	add: function( module, option, set ) {
1887		var i,
1888			proto = $.ui[ module ].prototype;
1889		for ( i in set ) {
1890			proto.plugins[ i ] = proto.plugins[ i ] || [];
1891			proto.plugins[ i ].push( [ option, set[ i ] ] );
1892		}
1893	},
1894	call: function( instance, name, args, allowDisconnected ) {
1895		var i,
1896			set = instance.plugins[ name ];
1897
1898		if ( !set ) {
1899			return;
1900		}
1901
1902		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
1903				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
1904			return;
1905		}
1906
1907		for ( i = 0; i < set.length; i++ ) {
1908			if ( instance.options[ set[ i ][ 0 ] ] ) {
1909				set[ i ][ 1 ].apply( instance.element, args );
1910			}
1911		}
1912	}
1913};
1914
1915
1916/*!
1917 * jQuery UI Draggable 1.14.2
1918 * https://jqueryui.com
1919 *
1920 * Copyright OpenJS Foundation and other contributors
1921 * Released under the MIT license.
1922 * https://jquery.org/license
1923 */
1924
1925//>>label: Draggable
1926//>>group: Interactions
1927//>>description: Enables dragging functionality for any element.
1928//>>docs: https://api.jqueryui.com/draggable/
1929//>>demos: https://jqueryui.com/draggable/
1930//>>css.structure: ../../themes/base/draggable.css
1931
1932
1933$.widget( "ui.draggable", $.ui.mouse, {
1934	version: "1.14.2",
1935	widgetEventPrefix: "drag",
1936	options: {
1937		addClasses: true,
1938		appendTo: "parent",
1939		axis: false,
1940		connectToSortable: false,
1941		containment: false,
1942		cursor: "auto",
1943		cursorAt: false,
1944		grid: false,
1945		handle: false,
1946		helper: "original",
1947		iframeFix: false,
1948		opacity: false,
1949		refreshPositions: false,
1950		revert: false,
1951		revertDuration: 500,
1952		scope: "default",
1953		scroll: true,
1954		scrollSensitivity: 20,
1955		scrollSpeed: 20,
1956		snap: false,
1957		snapMode: "both",
1958		snapTolerance: 20,
1959		stack: false,
1960		zIndex: false,
1961
1962		// Callbacks
1963		drag: null,
1964		start: null,
1965		stop: null
1966	},
1967	_create: function() {
1968
1969		if ( this.options.helper === "original" ) {
1970			this._setPositionRelative();
1971		}
1972		if ( this.options.addClasses ) {
1973			this._addClass( "ui-draggable" );
1974		}
1975		this._setHandleClassName();
1976
1977		this._mouseInit();
1978	},
1979
1980	_setOption: function( key, value ) {
1981		this._super( key, value );
1982		if ( key === "handle" ) {
1983			this._removeHandleClassName();
1984			this._setHandleClassName();
1985		}
1986	},
1987
1988	_destroy: function() {
1989		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1990			this.destroyOnClear = true;
1991			return;
1992		}
1993		this._removeHandleClassName();
1994		this._mouseDestroy();
1995	},
1996
1997	_mouseCapture: function( event ) {
1998		var o = this.options;
1999
2000		// Among others, prevent a drag on a resizable-handle
2001		if ( this.helper || o.disabled ||
2002				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
2003			return false;
2004		}
2005
2006		//Quit if we're not on a valid handle
2007		this.handle = this._getHandle( event );
2008		if ( !this.handle ) {
2009			return false;
2010		}
2011
2012		this._blurActiveElement( event );
2013
2014		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
2015
2016		return true;
2017
2018	},
2019
2020	_blockFrames: function( selector ) {
2021		this.iframeBlocks = this.document.find( selector ).map( function() {
2022			var iframe = $( this );
2023
2024			return $( "<div>" )
2025				.css( "position", "absolute" )
2026				.appendTo( iframe.parent() )
2027				.outerWidth( iframe.outerWidth() )
2028				.outerHeight( iframe.outerHeight() )
2029				.offset( iframe.offset() )[ 0 ];
2030		} );
2031	},
2032
2033	_unblockFrames: function() {
2034		if ( this.iframeBlocks ) {
2035			this.iframeBlocks.remove();
2036			delete this.iframeBlocks;
2037		}
2038	},
2039
2040	_blurActiveElement: function( event ) {
2041		var activeElement = this.document[ 0 ].activeElement,
2042			target = $( event.target );
2043
2044		// Don't blur if the event occurred on an element that is within
2045		// the currently focused element
2046		// See #10527, #12472
2047		if ( target.closest( activeElement ).length ) {
2048			return;
2049		}
2050
2051		// Blur any element that currently has focus, see #4261
2052		$( activeElement ).trigger( "blur" );
2053	},
2054
2055	_mouseStart: function( event ) {
2056
2057		var o = this.options;
2058
2059		//Create and append the visible helper
2060		this.helper = this._createHelper( event );
2061
2062		this._addClass( this.helper, "ui-draggable-dragging" );
2063
2064		//Cache the helper size
2065		this._cacheHelperProportions();
2066
2067		//If ddmanager is used for droppables, set the global draggable
2068		if ( $.ui.ddmanager ) {
2069			$.ui.ddmanager.current = this;
2070		}
2071
2072		/*
2073		 * - Position generation -
2074		 * This block generates everything position related - it's the core of draggables.
2075		 */
2076
2077		//Cache the margins of the original element
2078		this._cacheMargins();
2079
2080		//Store the helper's css position
2081		this.cssPosition = this.helper.css( "position" );
2082		this.scrollParent = this.helper.scrollParent( true );
2083		this.offsetParent = this.helper.offsetParent();
2084		this.hasFixedAncestor = this.helper.parents().filter( function() {
2085				return $( this ).css( "position" ) === "fixed";
2086			} ).length > 0;
2087
2088		//The element's absolute position on the page minus margins
2089		this.positionAbs = this.element.offset();
2090		this._refreshOffsets( event );
2091
2092		//Generate the original position
2093		this.originalPosition = this.position = this._generatePosition( event, false );
2094		this.originalPageX = event.pageX;
2095		this.originalPageY = event.pageY;
2096
2097		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
2098		if ( o.cursorAt ) {
2099			this._adjustOffsetFromHelper( o.cursorAt );
2100		}
2101
2102		//Set a containment if given in the options
2103		this._setContainment();
2104
2105		//Trigger event + callbacks
2106		if ( this._trigger( "start", event ) === false ) {
2107			this._clear();
2108			return false;
2109		}
2110
2111		//Recache the helper size
2112		this._cacheHelperProportions();
2113
2114		//Prepare the droppable offsets
2115		if ( $.ui.ddmanager && !o.dropBehaviour ) {
2116			$.ui.ddmanager.prepareOffsets( this, event );
2117		}
2118
2119		// Execute the drag once - this causes the helper not to be visible before getting its
2120		// correct position
2121		this._mouseDrag( event, true );
2122
2123		// If the ddmanager is used for droppables, inform the manager that dragging has started
2124		// (see #5003)
2125		if ( $.ui.ddmanager ) {
2126			$.ui.ddmanager.dragStart( this, event );
2127		}
2128
2129		return true;
2130	},
2131
2132	_refreshOffsets: function( event ) {
2133		this.offset = {
2134			top: this.positionAbs.top - this.margins.top,
2135			left: this.positionAbs.left - this.margins.left,
2136			scroll: false,
2137			parent: this._getParentOffset(),
2138			relative: this._getRelativeOffset()
2139		};
2140
2141		this.offset.click = {
2142			left: event.pageX - this.offset.left,
2143			top: event.pageY - this.offset.top
2144		};
2145	},
2146
2147	_mouseDrag: function( event, noPropagation ) {
2148
2149		// reset any necessary cached properties (see #5009)
2150		if ( this.hasFixedAncestor ) {
2151			this.offset.parent = this._getParentOffset();
2152		}
2153
2154		//Compute the helpers position
2155		this.position = this._generatePosition( event, true );
2156		this.positionAbs = this._convertPositionTo( "absolute" );
2157
2158		//Call plugins and callbacks and use the resulting position if something is returned
2159		if ( !noPropagation ) {
2160			var ui = this._uiHash();
2161			if ( this._trigger( "drag", event, ui ) === false ) {
2162				this._mouseUp( new $.Event( "mouseup", event ) );
2163				return false;
2164			}
2165			this.position = ui.position;
2166		}
2167
2168		this.helper[ 0 ].style.left = this.position.left + "px";
2169		this.helper[ 0 ].style.top = this.position.top + "px";
2170
2171		if ( $.ui.ddmanager ) {
2172			$.ui.ddmanager.drag( this, event );
2173		}
2174
2175		return false;
2176	},
2177
2178	_mouseStop: function( event ) {
2179
2180		//If we are using droppables, inform the manager about the drop
2181		var that = this,
2182			dropped = false;
2183		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
2184			dropped = $.ui.ddmanager.drop( this, event );
2185		}
2186
2187		//if a drop comes from outside (a sortable)
2188		if ( this.dropped ) {
2189			dropped = this.dropped;
2190			this.dropped = false;
2191		}
2192
2193		if ( ( this.options.revert === "invalid" && !dropped ) ||
2194				( this.options.revert === "valid" && dropped ) ||
2195				this.options.revert === true || ( typeof this.options.revert === "function" &&
2196				this.options.revert.call( this.element, dropped ) )
2197		) {
2198			$( this.helper ).animate(
2199				this.originalPosition,
2200				parseInt( this.options.revertDuration, 10 ),
2201				function() {
2202					if ( that._trigger( "stop", event ) !== false ) {
2203						that._clear();
2204					}
2205				}
2206			);
2207		} else {
2208			if ( this._trigger( "stop", event ) !== false ) {
2209				this._clear();
2210			}
2211		}
2212
2213		return false;
2214	},
2215
2216	_mouseUp: function( event ) {
2217		this._unblockFrames();
2218
2219		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
2220		// (see #5003)
2221		if ( $.ui.ddmanager ) {
2222			$.ui.ddmanager.dragStop( this, event );
2223		}
2224
2225		// Only need to focus if the event occurred on the draggable itself, see #10527
2226		if ( this.handleElement.is( event.target ) ) {
2227
2228			// The interaction is over; whether or not the click resulted in a drag,
2229			// focus the element
2230			this.element.trigger( "focus" );
2231		}
2232
2233		return $.ui.mouse.prototype._mouseUp.call( this, event );
2234	},
2235
2236	cancel: function() {
2237
2238		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
2239			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
2240		} else {
2241			this._clear();
2242		}
2243
2244		return this;
2245
2246	},
2247
2248	_getHandle: function( event ) {
2249		return this.options.handle ?
2250			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
2251			true;
2252	},
2253
2254	_setHandleClassName: function() {
2255		this.handleElement = this.options.handle ?
2256			this.element.find( this.options.handle ) : this.element;
2257		this._addClass( this.handleElement, "ui-draggable-handle" );
2258	},
2259
2260	_removeHandleClassName: function() {
2261		this._removeClass( this.handleElement, "ui-draggable-handle" );
2262	},
2263
2264	_createHelper: function( event ) {
2265
2266		var o = this.options,
2267			helperIsFunction = typeof o.helper === "function",
2268			helper = helperIsFunction ?
2269				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
2270				( o.helper === "clone" ?
2271					this.element.clone().removeAttr( "id" ) :
2272					this.element );
2273
2274		if ( !helper.parents( "body" ).length ) {
2275			helper.appendTo( ( o.appendTo === "parent" ?
2276				this.element[ 0 ].parentNode :
2277				o.appendTo ) );
2278		}
2279
2280		// https://bugs.jqueryui.com/ticket/9446
2281		// a helper function can return the original element
2282		// which wouldn't have been set to relative in _create
2283		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
2284			this._setPositionRelative();
2285		}
2286
2287		if ( helper[ 0 ] !== this.element[ 0 ] &&
2288				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
2289			helper.css( "position", "absolute" );
2290		}
2291
2292		return helper;
2293
2294	},
2295
2296	_setPositionRelative: function() {
2297		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
2298			this.element[ 0 ].style.position = "relative";
2299		}
2300	},
2301
2302	_adjustOffsetFromHelper: function( obj ) {
2303		if ( typeof obj === "string" ) {
2304			obj = obj.split( " " );
2305		}
2306		if ( Array.isArray( obj ) ) {
2307			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
2308		}
2309		if ( "left" in obj ) {
2310			this.offset.click.left = obj.left + this.margins.left;
2311		}
2312		if ( "right" in obj ) {
2313			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
2314		}
2315		if ( "top" in obj ) {
2316			this.offset.click.top = obj.top + this.margins.top;
2317		}
2318		if ( "bottom" in obj ) {
2319			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
2320		}
2321	},
2322
2323	_isRootNode: function( element ) {
2324		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
2325	},
2326
2327	_getParentOffset: function() {
2328
2329		//Get the offsetParent and cache its position
2330		var po = this.offsetParent.offset(),
2331			document = this.document[ 0 ];
2332
2333		// This is a special case where we need to modify a offset calculated on start, since the
2334		// following happened:
2335		// 1. The position of the helper is absolute, so it's position is calculated based on the
2336		// next positioned parent
2337		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
2338		// the document, which means that the scroll is included in the initial calculation of the
2339		// offset of the parent, and never recalculated upon drag
2340		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
2341				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
2342			po.left += this.scrollParent.scrollLeft();
2343			po.top += this.scrollParent.scrollTop();
2344		}
2345
2346		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
2347			po = { top: 0, left: 0 };
2348		}
2349
2350		return {
2351			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
2352			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
2353		};
2354
2355	},
2356
2357	_getRelativeOffset: function() {
2358		if ( this.cssPosition !== "relative" ) {
2359			return { top: 0, left: 0 };
2360		}
2361
2362		var p = this.element.position(),
2363			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2364
2365		return {
2366			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
2367				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
2368			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
2369				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
2370		};
2371
2372	},
2373
2374	_cacheMargins: function() {
2375		this.margins = {
2376			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
2377			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
2378			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
2379			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
2380		};
2381	},
2382
2383	_cacheHelperProportions: function() {
2384		this.helperProportions = {
2385			width: this.helper.outerWidth(),
2386			height: this.helper.outerHeight()
2387		};
2388	},
2389
2390	_setContainment: function() {
2391
2392		var isUserScrollable, c, ce,
2393			o = this.options,
2394			document = this.document[ 0 ];
2395
2396		this.relativeContainer = null;
2397
2398		if ( !o.containment ) {
2399			this.containment = null;
2400			return;
2401		}
2402
2403		if ( o.containment === "window" ) {
2404			this.containment = [
2405				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2406				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2407				$( window ).scrollLeft() + $( window ).width() -
2408					this.helperProportions.width - this.margins.left,
2409				$( window ).scrollTop() +
2410					( $( window ).height() || document.body.parentNode.scrollHeight ) -
2411					this.helperProportions.height - this.margins.top
2412			];
2413			return;
2414		}
2415
2416		if ( o.containment === "document" ) {
2417			this.containment = [
2418				0,
2419				0,
2420				$( document ).width() - this.helperProportions.width - this.margins.left,
2421				( $( document ).height() || document.body.parentNode.scrollHeight ) -
2422					this.helperProportions.height - this.margins.top
2423			];
2424			return;
2425		}
2426
2427		if ( o.containment.constructor === Array ) {
vendor: 10,369 bytes, lines 2428-2774
2428			this.containment = o.containment;
2429			return;
2430		}
2431
2432		if ( o.containment === "parent" ) {
2433			o.containment = this.helper[ 0 ].parentNode;
2434		}
2435
2436		c = $( o.containment );
2437		ce = c[ 0 ];
2438
2439		if ( !ce ) {
2440			return;
2441		}
2442
2443		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2444
2445		this.containment = [
2446			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
2447				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2448			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
2449				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2450			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2451				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2452				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2453				this.helperProportions.width -
2454				this.margins.left -
2455				this.margins.right,
2456			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2457				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2458				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2459				this.helperProportions.height -
2460				this.margins.top -
2461				this.margins.bottom
2462		];
2463		this.relativeContainer = c;
2464	},
2465
2466	_convertPositionTo: function( d, pos ) {
2467
2468		if ( !pos ) {
2469			pos = this.position;
2470		}
2471
2472		var mod = d === "absolute" ? 1 : -1,
2473			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2474
2475		return {
2476			top: (
2477
2478				// The absolute mouse position
2479				pos.top	+
2480
2481				// Only for relative positioned nodes: Relative offset from element to offset parent
2482				this.offset.relative.top * mod +
2483
2484				// The offsetParent's offset without borders (offset + border)
2485				this.offset.parent.top * mod -
2486				( ( this.cssPosition === "fixed" ?
2487					-this.offset.scroll.top :
2488					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
2489			),
2490			left: (
2491
2492				// The absolute mouse position
2493				pos.left +
2494
2495				// Only for relative positioned nodes: Relative offset from element to offset parent
2496				this.offset.relative.left * mod +
2497
2498				// The offsetParent's offset without borders (offset + border)
2499				this.offset.parent.left * mod	-
2500				( ( this.cssPosition === "fixed" ?
2501					-this.offset.scroll.left :
2502					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
2503			)
2504		};
2505
2506	},
2507
2508	_generatePosition: function( event, constrainPosition ) {
2509
2510		var containment, co, top, left,
2511			o = this.options,
2512			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2513			pageX = event.pageX,
2514			pageY = event.pageY;
2515
2516		// Cache the scroll
2517		if ( !scrollIsRootNode || !this.offset.scroll ) {
2518			this.offset.scroll = {
2519				top: this.scrollParent.scrollTop(),
2520				left: this.scrollParent.scrollLeft()
2521			};
2522		}
2523
2524		/*
2525		 * - Position constraining -
2526		 * Constrain the position to a mix of grid, containment.
2527		 */
2528
2529		// If we are not dragging yet, we won't check for options
2530		if ( constrainPosition ) {
2531			if ( this.containment ) {
2532				if ( this.relativeContainer ) {
2533					co = this.relativeContainer.offset();
2534					containment = [
2535						this.containment[ 0 ] + co.left,
2536						this.containment[ 1 ] + co.top,
2537						this.containment[ 2 ] + co.left,
2538						this.containment[ 3 ] + co.top
2539					];
2540				} else {
2541					containment = this.containment;
2542				}
2543
2544				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
2545					pageX = containment[ 0 ] + this.offset.click.left;
2546				}
2547				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
2548					pageY = containment[ 1 ] + this.offset.click.top;
2549				}
2550				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
2551					pageX = containment[ 2 ] + this.offset.click.left;
2552				}
2553				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
2554					pageY = containment[ 3 ] + this.offset.click.top;
2555				}
2556			}
2557
2558			if ( o.grid ) {
2559
2560				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
2561				// argument errors in IE (see ticket #6950)
2562				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
2563					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
2564				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
2565					top - this.offset.click.top > containment[ 3 ] ) ?
2566						top :
2567						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
2568							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
2569
2570				left = o.grid[ 0 ] ? this.originalPageX +
2571					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
2572					this.originalPageX;
2573				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
2574					left - this.offset.click.left > containment[ 2 ] ) ?
2575						left :
2576						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
2577							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
2578			}
2579
2580			if ( o.axis === "y" ) {
2581				pageX = this.originalPageX;
2582			}
2583
2584			if ( o.axis === "x" ) {
2585				pageY = this.originalPageY;
2586			}
2587		}
2588
2589		return {
2590			top: (
2591
2592				// The absolute mouse position
2593				pageY -
2594
2595				// Click offset (relative to the element)
2596				this.offset.click.top -
2597
2598				// Only for relative positioned nodes: Relative offset from element to offset parent
2599				this.offset.relative.top -
2600
2601				// The offsetParent's offset without borders (offset + border)
2602				this.offset.parent.top +
2603				( this.cssPosition === "fixed" ?
2604					-this.offset.scroll.top :
2605					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2606			),
2607			left: (
2608
2609				// The absolute mouse position
2610				pageX -
2611
2612				// Click offset (relative to the element)
2613				this.offset.click.left -
2614
2615				// Only for relative positioned nodes: Relative offset from element to offset parent
2616				this.offset.relative.left -
2617
2618				// The offsetParent's offset without borders (offset + border)
2619				this.offset.parent.left +
2620				( this.cssPosition === "fixed" ?
2621					-this.offset.scroll.left :
2622					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2623			)
2624		};
2625
2626	},
2627
2628	_clear: function() {
2629		this._removeClass( this.helper, "ui-draggable-dragging" );
2630		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
2631			this.helper.remove();
2632		}
2633		this.helper = null;
2634		this.cancelHelperRemoval = false;
2635		if ( this.destroyOnClear ) {
2636			this.destroy();
2637		}
2638	},
2639
2640	// From now on bulk stuff - mainly helpers
2641
2642	_trigger: function( type, event, ui ) {
2643		ui = ui || this._uiHash();
2644		$.ui.plugin.call( this, type, [ event, ui, this ], true );
2645
2646		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
2647		if ( /^(drag|start|stop)/.test( type ) ) {
2648			this.positionAbs = this._convertPositionTo( "absolute" );
2649			ui.offset = this.positionAbs;
2650		}
2651		return $.Widget.prototype._trigger.call( this, type, event, ui );
2652	},
2653
2654	plugins: {},
2655
2656	_uiHash: function() {
2657		return {
2658			helper: this.helper,
2659			position: this.position,
2660			originalPosition: this.originalPosition,
2661			offset: this.positionAbs
2662		};
2663	}
2664
2665} );
2666
2667$.ui.plugin.add( "draggable", "connectToSortable", {
2668	start: function( event, ui, draggable ) {
2669		var uiSortable = $.extend( {}, ui, {
2670			item: draggable.element
2671		} );
2672
2673		draggable.sortables = [];
2674		$( draggable.options.connectToSortable ).each( function() {
2675			var sortable = $( this ).sortable( "instance" );
2676
2677			if ( sortable && !sortable.options.disabled ) {
2678				draggable.sortables.push( sortable );
2679
2680				// RefreshPositions is called at drag start to refresh the containerCache
2681				// which is used in drag. This ensures it's initialized and synchronized
2682				// with any changes that might have happened on the page since initialization.
2683				sortable.refreshPositions();
2684				sortable._trigger( "activate", event, uiSortable );
2685			}
2686		} );
2687	},
2688	stop: function( event, ui, draggable ) {
2689		var uiSortable = $.extend( {}, ui, {
2690			item: draggable.element
2691		} );
2692
2693		draggable.cancelHelperRemoval = false;
2694
2695		$.each( draggable.sortables, function() {
2696			var sortable = this;
2697
2698			if ( sortable.isOver ) {
2699				sortable.isOver = 0;
2700
2701				// Allow this sortable to handle removing the helper
2702				draggable.cancelHelperRemoval = true;
2703				sortable.cancelHelperRemoval = false;
2704
2705				// Use _storedCSS To restore properties in the sortable,
2706				// as this also handles revert (#9675) since the draggable
2707				// may have modified them in unexpected ways (#8809)
2708				sortable._storedCSS = {
2709					position: sortable.placeholder.css( "position" ),
2710					top: sortable.placeholder.css( "top" ),
2711					left: sortable.placeholder.css( "left" )
2712				};
2713
2714				sortable._mouseStop( event );
2715
2716				// Once drag has ended, the sortable should return to using
2717				// its original helper, not the shared helper from draggable
2718				sortable.options.helper = sortable.options._helper;
2719			} else {
2720
2721				// Prevent this Sortable from removing the helper.
2722				// However, don't set the draggable to remove the helper
2723				// either as another connected Sortable may yet handle the removal.
2724				sortable.cancelHelperRemoval = true;
2725
2726				sortable._trigger( "deactivate", event, uiSortable );
2727			}
2728		} );
2729	},
2730	drag: function( event, ui, draggable ) {
2731		$.each( draggable.sortables, function() {
2732			var innermostIntersecting = false,
2733				sortable = this;
2734
2735			// Copy over variables that sortable's _intersectsWith uses
2736			sortable.positionAbs = draggable.positionAbs;
2737			sortable.helperProportions = draggable.helperProportions;
2738			sortable.offset.click = draggable.offset.click;
2739
2740			if ( sortable._intersectsWith( sortable.containerCache ) ) {
2741				innermostIntersecting = true;
2742
2743				$.each( draggable.sortables, function() {
2744
2745					// Copy over variables that sortable's _intersectsWith uses
2746					this.positionAbs = draggable.positionAbs;
2747					this.helperProportions = draggable.helperProportions;
2748					this.offset.click = draggable.offset.click;
2749
2750					if ( this !== sortable &&
2751							this._intersectsWith( this.containerCache ) &&
2752							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2753						innermostIntersecting = false;
2754					}
2755
2756					return innermostIntersecting;
2757				} );
2758			}
2759
2760			if ( innermostIntersecting ) {
2761
2762				// If it intersects, we use a little isOver variable and set it once,
2763				// so that the move-in stuff gets fired only once.
2764				if ( !sortable.isOver ) {
2765					sortable.isOver = 1;
2766
2767					// Store draggable's parent in case we need to reappend to it later.
2768					draggable._parent = ui.helper.parent();
2769
2770					sortable.currentItem = ui.helper
2771						.appendTo( sortable.element )
2772						.data( "ui-sortable-item", true );
2773
2774					// Store helper option to later restore it
vendor: 55,332 bytes, lines 2775-4889
2775					sortable.options._helper = sortable.options.helper;
2776
2777					sortable.options.helper = function() {
2778						return ui.helper[ 0 ];
2779					};
2780
2781					// Fire the start events of the sortable with our passed browser event,
2782					// and our own helper (so it doesn't create a new one)
2783					event.target = sortable.currentItem[ 0 ];
2784					sortable._mouseCapture( event, true );
2785					sortable._mouseStart( event, true, true );
2786
2787					// Because the browser event is way off the new appended portlet,
2788					// modify necessary variables to reflect the changes
2789					sortable.offset.click.top = draggable.offset.click.top;
2790					sortable.offset.click.left = draggable.offset.click.left;
2791					sortable.offset.parent.left -= draggable.offset.parent.left -
2792						sortable.offset.parent.left;
2793					sortable.offset.parent.top -= draggable.offset.parent.top -
2794						sortable.offset.parent.top;
2795
2796					draggable._trigger( "toSortable", event );
2797
2798					// Inform draggable that the helper is in a valid drop zone,
2799					// used solely in the revert option to handle "valid/invalid".
2800					draggable.dropped = sortable.element;
2801
2802					// Need to refreshPositions of all sortables in the case that
2803					// adding to one sortable changes the location of the other sortables (#9675)
2804					$.each( draggable.sortables, function() {
2805						this.refreshPositions();
2806					} );
2807
2808					// Hack so receive/update callbacks work (mostly)
2809					draggable.currentItem = draggable.element;
2810					sortable.fromOutside = draggable;
2811				}
2812
2813				if ( sortable.currentItem ) {
2814					sortable._mouseDrag( event );
2815
2816					// Copy the sortable's position because the draggable's can potentially reflect
2817					// a relative position, while sortable is always absolute, which the dragged
2818					// element has now become. (#8809)
2819					ui.position = sortable.position;
2820				}
2821			} else {
2822
2823				// If it doesn't intersect with the sortable, and it intersected before,
2824				// we fake the drag stop of the sortable, but make sure it doesn't remove
2825				// the helper by using cancelHelperRemoval.
2826				if ( sortable.isOver ) {
2827
2828					sortable.isOver = 0;
2829					sortable.cancelHelperRemoval = true;
2830
2831					// Calling sortable's mouseStop would trigger a revert,
2832					// so revert must be temporarily false until after mouseStop is called.
2833					sortable.options._revert = sortable.options.revert;
2834					sortable.options.revert = false;
2835
2836					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2837					sortable._mouseStop( event, true );
2838
2839					// Restore sortable behaviors that were modfied
2840					// when the draggable entered the sortable area (#9481)
2841					sortable.options.revert = sortable.options._revert;
2842					sortable.options.helper = sortable.options._helper;
2843
2844					if ( sortable.placeholder ) {
2845						sortable.placeholder.remove();
2846					}
2847
2848					// Restore and recalculate the draggable's offset considering the sortable
2849					// may have modified them in unexpected ways. (#8809, #10669)
2850					ui.helper.appendTo( draggable._parent );
2851					draggable._refreshOffsets( event );
2852					ui.position = draggable._generatePosition( event, true );
2853
2854					draggable._trigger( "fromSortable", event );
2855
2856					// Inform draggable that the helper is no longer in a valid drop zone
2857					draggable.dropped = false;
2858
2859					// Need to refreshPositions of all sortables just in case removing
2860					// from one sortable changes the location of other sortables (#9675)
2861					$.each( draggable.sortables, function() {
2862						this.refreshPositions();
2863					} );
2864				}
2865			}
2866		} );
2867	}
2868} );
2869
2870$.ui.plugin.add( "draggable", "cursor", {
2871	start: function( event, ui, instance ) {
2872		var t = $( "body" ),
2873			o = instance.options;
2874
2875		if ( t.css( "cursor" ) ) {
2876			o._cursor = t.css( "cursor" );
2877		}
2878		t.css( "cursor", o.cursor );
2879	},
2880	stop: function( event, ui, instance ) {
2881		var o = instance.options;
2882		if ( o._cursor ) {
2883			$( "body" ).css( "cursor", o._cursor );
2884		}
2885	}
2886} );
2887
2888$.ui.plugin.add( "draggable", "opacity", {
2889	start: function( event, ui, instance ) {
2890		var t = $( ui.helper ),
2891			o = instance.options;
2892		if ( t.css( "opacity" ) ) {
2893			o._opacity = t.css( "opacity" );
2894		}
2895		t.css( "opacity", o.opacity );
2896	},
2897	stop: function( event, ui, instance ) {
2898		var o = instance.options;
2899		if ( o._opacity ) {
2900			$( ui.helper ).css( "opacity", o._opacity );
2901		}
2902	}
2903} );
2904
2905$.ui.plugin.add( "draggable", "scroll", {
2906	start: function( event, ui, i ) {
2907		if ( !i.scrollParentNotHidden ) {
2908			i.scrollParentNotHidden = i.helper.scrollParent( false );
2909		}
2910
2911		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
2912				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2913			i.overflowOffset = i.scrollParentNotHidden.offset();
2914		}
2915	},
2916	drag: function( event, ui, i  ) {
2917
2918		var o = i.options,
2919			scrolled = false,
2920			scrollParent = i.scrollParentNotHidden[ 0 ],
2921			document = i.document[ 0 ];
2922
2923		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2924			if ( !o.axis || o.axis !== "x" ) {
2925				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
2926						o.scrollSensitivity ) {
2927					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2928				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2929					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2930				}
2931			}
2932
2933			if ( !o.axis || o.axis !== "y" ) {
2934				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
2935						o.scrollSensitivity ) {
2936					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2937				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2938					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2939				}
2940			}
2941
2942		} else {
2943
2944			if ( !o.axis || o.axis !== "x" ) {
2945				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
2946					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
2947				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
2948						o.scrollSensitivity ) {
2949					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
2950				}
2951			}
2952
2953			if ( !o.axis || o.axis !== "y" ) {
2954				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
2955					scrolled = $( document ).scrollLeft(
2956						$( document ).scrollLeft() - o.scrollSpeed
2957					);
2958				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
2959						o.scrollSensitivity ) {
2960					scrolled = $( document ).scrollLeft(
2961						$( document ).scrollLeft() + o.scrollSpeed
2962					);
2963				}
2964			}
2965
2966		}
2967
2968		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
2969			$.ui.ddmanager.prepareOffsets( i, event );
2970		}
2971
2972	}
2973} );
2974
2975$.ui.plugin.add( "draggable", "snap", {
2976	start: function( event, ui, i ) {
2977
2978		var o = i.options;
2979
2980		i.snapElements = [];
2981
2982		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
2983			.each( function() {
2984				var $t = $( this ),
2985					$o = $t.offset();
2986				if ( this !== i.element[ 0 ] ) {
2987					i.snapElements.push( {
2988						item: this,
2989						width: $t.outerWidth(), height: $t.outerHeight(),
2990						top: $o.top, left: $o.left
2991					} );
2992				}
2993			} );
2994
2995	},
2996	drag: function( event, ui, inst ) {
2997
2998		var ts, bs, ls, rs, l, r, t, b, i, first,
2999			o = inst.options,
3000			d = o.snapTolerance,
3001			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
3002			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
3003
3004		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
3005
3006			l = inst.snapElements[ i ].left - inst.margins.left;
3007			r = l + inst.snapElements[ i ].width;
3008			t = inst.snapElements[ i ].top - inst.margins.top;
3009			b = t + inst.snapElements[ i ].height;
3010
3011			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
3012					!$.contains( inst.snapElements[ i ].item.ownerDocument,
3013					inst.snapElements[ i ].item ) ) {
3014				if ( inst.snapElements[ i ].snapping ) {
3015					if ( inst.options.snap.release ) {
3016						inst.options.snap.release.call(
3017							inst.element,
3018							event,
3019							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
3020						);
3021					}
3022				}
3023				inst.snapElements[ i ].snapping = false;
3024				continue;
3025			}
3026
3027			if ( o.snapMode !== "inner" ) {
3028				ts = Math.abs( t - y2 ) <= d;
3029				bs = Math.abs( b - y1 ) <= d;
3030				ls = Math.abs( l - x2 ) <= d;
3031				rs = Math.abs( r - x1 ) <= d;
3032				if ( ts ) {
3033					ui.position.top = inst._convertPositionTo( "relative", {
3034						top: t - inst.helperProportions.height,
3035						left: 0
3036					} ).top;
3037				}
3038				if ( bs ) {
3039					ui.position.top = inst._convertPositionTo( "relative", {
3040						top: b,
3041						left: 0
3042					} ).top;
3043				}
3044				if ( ls ) {
3045					ui.position.left = inst._convertPositionTo( "relative", {
3046						top: 0,
3047						left: l - inst.helperProportions.width
3048					} ).left;
3049				}
3050				if ( rs ) {
3051					ui.position.left = inst._convertPositionTo( "relative", {
3052						top: 0,
3053						left: r
3054					} ).left;
3055				}
3056			}
3057
3058			first = ( ts || bs || ls || rs );
3059
3060			if ( o.snapMode !== "outer" ) {
3061				ts = Math.abs( t - y1 ) <= d;
3062				bs = Math.abs( b - y2 ) <= d;
3063				ls = Math.abs( l - x1 ) <= d;
3064				rs = Math.abs( r - x2 ) <= d;
3065				if ( ts ) {
3066					ui.position.top = inst._convertPositionTo( "relative", {
3067						top: t,
3068						left: 0
3069					} ).top;
3070				}
3071				if ( bs ) {
3072					ui.position.top = inst._convertPositionTo( "relative", {
3073						top: b - inst.helperProportions.height,
3074						left: 0
3075					} ).top;
3076				}
3077				if ( ls ) {
3078					ui.position.left = inst._convertPositionTo( "relative", {
3079						top: 0,
3080						left: l
3081					} ).left;
3082				}
3083				if ( rs ) {
3084					ui.position.left = inst._convertPositionTo( "relative", {
3085						top: 0,
3086						left: r - inst.helperProportions.width
3087					} ).left;
3088				}
3089			}
3090
3091			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
3092				if ( inst.options.snap.snap ) {
3093					inst.options.snap.snap.call(
3094						inst.element,
3095						event,
3096						$.extend( inst._uiHash(), {
3097							snapItem: inst.snapElements[ i ].item
3098						} ) );
3099				}
3100			}
3101			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
3102
3103		}
3104
3105	}
3106} );
3107
3108$.ui.plugin.add( "draggable", "stack", {
3109	start: function( event, ui, instance ) {
3110		var min,
3111			o = instance.options,
3112			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
3113				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
3114					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
3115			} );
3116
3117		if ( !group.length ) {
3118			return;
3119		}
3120
3121		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
3122		$( group ).each( function( i ) {
3123			$( this ).css( "zIndex", min + i );
3124		} );
3125		this.css( "zIndex", ( min + group.length ) );
3126	}
3127} );
3128
3129$.ui.plugin.add( "draggable", "zIndex", {
3130	start: function( event, ui, instance ) {
3131		var t = $( ui.helper ),
3132			o = instance.options;
3133
3134		if ( t.css( "zIndex" ) ) {
3135			o._zIndex = t.css( "zIndex" );
3136		}
3137		t.css( "zIndex", o.zIndex );
3138	},
3139	stop: function( event, ui, instance ) {
3140		var o = instance.options;
3141
3142		if ( o._zIndex ) {
3143			$( ui.helper ).css( "zIndex", o._zIndex );
3144		}
3145	}
3146} );
3147
3148var widgetsDraggable = $.ui.draggable;
3149
3150
3151/*!
3152 * jQuery UI Droppable 1.14.2
3153 * https://jqueryui.com
3154 *
3155 * Copyright OpenJS Foundation and other contributors
3156 * Released under the MIT license.
3157 * https://jquery.org/license
3158 */
3159
3160//>>label: Droppable
3161//>>group: Interactions
3162//>>description: Enables drop targets for draggable elements.
3163//>>docs: https://api.jqueryui.com/droppable/
3164//>>demos: https://jqueryui.com/droppable/
3165
3166
3167$.widget( "ui.droppable", {
3168	version: "1.14.2",
3169	widgetEventPrefix: "drop",
3170	options: {
3171		accept: "*",
3172		addClasses: true,
3173		greedy: false,
3174		scope: "default",
3175		tolerance: "intersect",
3176
3177		// Callbacks
3178		activate: null,
3179		deactivate: null,
3180		drop: null,
3181		out: null,
3182		over: null
3183	},
3184	_create: function() {
3185
3186		var proportions,
3187			o = this.options,
3188			accept = o.accept;
3189
3190		this.isover = false;
3191		this.isout = true;
3192
3193		this.accept = typeof accept === "function" ? accept : function( d ) {
3194			return d.is( accept );
3195		};
3196
3197		this.proportions = function( /* valueToWrite */ ) {
3198			if ( arguments.length ) {
3199
3200				// Store the droppable's proportions
3201				proportions = arguments[ 0 ];
3202			} else {
3203
3204				// Retrieve or derive the droppable's proportions
3205				return proportions ?
3206					proportions :
3207					proportions = {
3208						width: this.element[ 0 ].offsetWidth,
3209						height: this.element[ 0 ].offsetHeight
3210					};
3211			}
3212		};
3213
3214		this._addToManager( o.scope );
3215
3216		if ( o.addClasses ) {
3217			this._addClass( "ui-droppable" );
3218		}
3219
3220	},
3221
3222	_addToManager: function( scope ) {
3223
3224		// Add the reference and positions to the manager
3225		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
3226		$.ui.ddmanager.droppables[ scope ].push( this );
3227	},
3228
3229	_splice: function( drop ) {
3230		var i = 0;
3231		for ( ; i < drop.length; i++ ) {
3232			if ( drop[ i ] === this ) {
3233				drop.splice( i, 1 );
3234			}
3235		}
3236	},
3237
3238	_destroy: function() {
3239		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
3240
3241		this._splice( drop );
3242	},
3243
3244	_setOption: function( key, value ) {
3245
3246		if ( key === "accept" ) {
3247			this.accept = typeof value === "function" ? value : function( d ) {
3248				return d.is( value );
3249			};
3250		} else if ( key === "scope" ) {
3251			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
3252
3253			this._splice( drop );
3254			this._addToManager( value );
3255		}
3256
3257		this._super( key, value );
3258	},
3259
3260	_activate: function( event ) {
3261		var draggable = $.ui.ddmanager.current;
3262
3263		this._addActiveClass();
3264		if ( draggable ) {
3265			this._trigger( "activate", event, this.ui( draggable ) );
3266		}
3267	},
3268
3269	_deactivate: function( event ) {
3270		var draggable = $.ui.ddmanager.current;
3271
3272		this._removeActiveClass();
3273		if ( draggable ) {
3274			this._trigger( "deactivate", event, this.ui( draggable ) );
3275		}
3276	},
3277
3278	_over: function( event ) {
3279
3280		var draggable = $.ui.ddmanager.current;
3281
3282		// Bail if draggable and droppable are same element
3283		if ( !draggable || ( draggable.currentItem ||
3284				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3285			return;
3286		}
3287
3288		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
3289				draggable.element ) ) ) {
3290			this._addHoverClass();
3291			this._trigger( "over", event, this.ui( draggable ) );
3292		}
3293
3294	},
3295
3296	_out: function( event ) {
3297
3298		var draggable = $.ui.ddmanager.current;
3299
3300		// Bail if draggable and droppable are same element
3301		if ( !draggable || ( draggable.currentItem ||
3302				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3303			return;
3304		}
3305
3306		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
3307				draggable.element ) ) ) {
3308			this._removeHoverClass();
3309			this._trigger( "out", event, this.ui( draggable ) );
3310		}
3311
3312	},
3313
3314	_drop: function( event, custom ) {
3315
3316		var draggable = custom || $.ui.ddmanager.current,
3317			childrenIntersection = false;
3318
3319		// Bail if draggable and droppable are same element
3320		if ( !draggable || ( draggable.currentItem ||
3321				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3322			return false;
3323		}
3324
3325		this.element
3326			.find( ":data(ui-droppable)" )
3327			.not( ".ui-draggable-dragging" )
3328			.each( function() {
3329				var inst = $( this ).droppable( "instance" );
3330				if (
3331					inst.options.greedy &&
3332					!inst.options.disabled &&
3333					inst.options.scope === draggable.options.scope &&
3334					inst.accept.call(
3335						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
3336					) &&
3337					$.ui.intersect(
3338						draggable,
3339						$.extend( inst, { offset: inst.element.offset() } ),
3340						inst.options.tolerance, event
3341					)
3342				) {
3343					childrenIntersection = true;
3344					return false;
3345				}
3346			} );
3347		if ( childrenIntersection ) {
3348			return false;
3349		}
3350
3351		if ( this.accept.call( this.element[ 0 ],
3352				( draggable.currentItem || draggable.element ) ) ) {
3353			this._removeActiveClass();
3354			this._removeHoverClass();
3355
3356			this._trigger( "drop", event, this.ui( draggable ) );
3357			return this.element;
3358		}
3359
3360		return false;
3361
3362	},
3363
3364	ui: function( c ) {
3365		return {
3366			draggable: ( c.currentItem || c.element ),
3367			helper: c.helper,
3368			position: c.position,
3369			offset: c.positionAbs
3370		};
3371	},
3372
3373	// Extension points just to make backcompat sane and avoid duplicating logic
3374	// TODO: Remove in 1.14 along with call to it below
3375	_addHoverClass: function() {
3376		this._addClass( "ui-droppable-hover" );
3377	},
3378
3379	_removeHoverClass: function() {
3380		this._removeClass( "ui-droppable-hover" );
3381	},
3382
3383	_addActiveClass: function() {
3384		this._addClass( "ui-droppable-active" );
3385	},
3386
3387	_removeActiveClass: function() {
3388		this._removeClass( "ui-droppable-active" );
3389	}
3390} );
3391
3392$.ui.intersect = ( function() {
3393	function isOverAxis( x, reference, size ) {
3394		return ( x >= reference ) && ( x < ( reference + size ) );
3395	}
3396
3397	return function( draggable, droppable, toleranceMode, event ) {
3398
3399		if ( !droppable.offset ) {
3400			return false;
3401		}
3402
3403		var x1 = ( draggable.positionAbs ||
3404				draggable.position.absolute ).left + draggable.margins.left,
3405			y1 = ( draggable.positionAbs ||
3406				draggable.position.absolute ).top + draggable.margins.top,
3407			x2 = x1 + draggable.helperProportions.width,
3408			y2 = y1 + draggable.helperProportions.height,
3409			l = droppable.offset.left,
3410			t = droppable.offset.top,
3411			r = l + droppable.proportions().width,
3412			b = t + droppable.proportions().height;
3413
3414		switch ( toleranceMode ) {
3415		case "fit":
3416			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
3417		case "intersect":
3418			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
3419				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
3420				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
3421				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
3422		case "pointer":
3423			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
3424				isOverAxis( event.pageX, l, droppable.proportions().width );
3425		case "touch":
3426			return (
3427				( y1 >= t && y1 <= b ) || // Top edge touching
3428				( y2 >= t && y2 <= b ) || // Bottom edge touching
3429				( y1 < t && y2 > b ) // Surrounded vertically
3430			) && (
3431				( x1 >= l && x1 <= r ) || // Left edge touching
3432				( x2 >= l && x2 <= r ) || // Right edge touching
3433				( x1 < l && x2 > r ) // Surrounded horizontally
3434			);
3435		default:
3436			return false;
3437		}
3438	};
3439} )();
3440
3441/*
3442	This manager tracks offsets of draggables and droppables
3443*/
3444$.ui.ddmanager = {
3445	current: null,
3446	droppables: { "default": [] },
3447	prepareOffsets: function( t, event ) {
3448
3449		var i, j,
3450			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
3451			type = event ? event.type : null, // workaround for #2317
3452			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
3453
3454		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
3455
3456			// No disabled and non-accepted
3457			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
3458					( t.currentItem || t.element ) ) ) ) {
3459				continue;
3460			}
3461
3462			// Filter out elements in the current dragged item
3463			for ( j = 0; j < list.length; j++ ) {
3464				if ( list[ j ] === m[ i ].element[ 0 ] ) {
3465					m[ i ].proportions().height = 0;
3466					continue droppablesLoop;
3467				}
3468			}
3469
3470			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
3471			if ( !m[ i ].visible ) {
3472				continue;
3473			}
3474
3475			// Activate the droppable if used directly from draggables
3476			if ( type === "mousedown" ) {
3477				m[ i ]._activate.call( m[ i ], event );
3478			}
3479
3480			m[ i ].offset = m[ i ].element.offset();
3481			m[ i ].proportions( {
3482				width: m[ i ].element[ 0 ].offsetWidth,
3483				height: m[ i ].element[ 0 ].offsetHeight
3484			} );
3485
3486		}
3487
3488	},
3489	drop: function( draggable, event ) {
3490
3491		var dropped = false;
3492
3493		// Create a copy of the droppables in case the list changes during the drop (#9116)
3494		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
3495
3496			if ( !this.options ) {
3497				return;
3498			}
3499			if ( !this.options.disabled && this.visible &&
3500					$.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
3501				dropped = this._drop.call( this, event ) || dropped;
3502			}
3503
3504			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
3505					( draggable.currentItem || draggable.element ) ) ) {
3506				this.isout = true;
3507				this.isover = false;
3508				this._deactivate.call( this, event );
3509			}
3510
3511		} );
3512		return dropped;
3513
3514	},
3515	dragStart: function( draggable, event ) {
3516
3517		// Listen for scrolling so that if the dragging causes scrolling the position of the
3518		// droppables can be recalculated (see #5003)
3519		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
3520			if ( !draggable.options.refreshPositions ) {
3521				$.ui.ddmanager.prepareOffsets( draggable, event );
3522			}
3523		} );
3524	},
3525	drag: function( draggable, event ) {
3526
3527		// If you have a highly dynamic page, you might try this option. It renders positions
3528		// every time you move the mouse.
3529		if ( draggable.options.refreshPositions ) {
3530			$.ui.ddmanager.prepareOffsets( draggable, event );
3531		}
3532
3533		// Run through all droppables and check their positions based on specific tolerance options
3534		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3535
3536			if ( this.options.disabled || this.greedyChild || !this.visible ) {
3537				return;
3538			}
3539
3540			var parentInstance, scope, parent,
3541				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
3542				c = !intersects && this.isover ?
3543					"isout" :
3544					( intersects && !this.isover ? "isover" : null );
3545			if ( !c ) {
3546				return;
3547			}
3548
3549			if ( this.options.greedy ) {
3550
3551				// find droppable parents with same scope
3552				scope = this.options.scope;
3553				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
3554					return $( this ).droppable( "instance" ).options.scope === scope;
3555				} );
3556
3557				if ( parent.length ) {
3558					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3559					parentInstance.greedyChild = ( c === "isover" );
3560				}
3561			}
3562
3563			// We just moved into a greedy child
3564			if ( parentInstance && c === "isover" ) {
3565				parentInstance.isover = false;
3566				parentInstance.isout = true;
3567				parentInstance._out.call( parentInstance, event );
3568			}
3569
3570			this[ c ] = true;
3571			this[ c === "isout" ? "isover" : "isout" ] = false;
3572			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
3573
3574			// We just moved out of a greedy child
3575			if ( parentInstance && c === "isout" ) {
3576				parentInstance.isout = false;
3577				parentInstance.isover = true;
3578				parentInstance._over.call( parentInstance, event );
3579			}
3580		} );
3581
3582	},
3583	dragStop: function( draggable, event ) {
3584		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
3585
3586		// Call prepareOffsets one final time since IE does not fire return scroll events when
3587		// overflow was caused by drag (see #5003)
3588		if ( !draggable.options.refreshPositions ) {
3589			$.ui.ddmanager.prepareOffsets( draggable, event );
3590		}
3591	}
3592};
3593
3594// DEPRECATED
3595// TODO: switch return back to widget declaration at top of file when this is removed
3596if ( $.uiBackCompat === true ) {
3597
3598	// Backcompat for activeClass and hoverClass options
3599	$.widget( "ui.droppable", $.ui.droppable, {
3600		options: {
3601			hoverClass: false,
3602			activeClass: false
3603		},
3604		_addActiveClass: function() {
3605			this._super();
3606			if ( this.options.activeClass ) {
3607				this.element.addClass( this.options.activeClass );
3608			}
3609		},
3610		_removeActiveClass: function() {
3611			this._super();
3612			if ( this.options.activeClass ) {
3613				this.element.removeClass( this.options.activeClass );
3614			}
3615		},
3616		_addHoverClass: function() {
3617			this._super();
3618			if ( this.options.hoverClass ) {
3619				this.element.addClass( this.options.hoverClass );
3620			}
3621		},
3622		_removeHoverClass: function() {
3623			this._super();
3624			if ( this.options.hoverClass ) {
3625				this.element.removeClass( this.options.hoverClass );
3626			}
3627		}
3628	} );
3629}
3630
3631var widgetsDroppable = $.ui.droppable;
3632
3633
3634/*!
3635 * jQuery UI Resizable 1.14.2
3636 * https://jqueryui.com
3637 *
3638 * Copyright OpenJS Foundation and other contributors
3639 * Released under the MIT license.
3640 * https://jquery.org/license
3641 */
3642
3643//>>label: Resizable
3644//>>group: Interactions
3645//>>description: Enables resize functionality for any element.
3646//>>docs: https://api.jqueryui.com/resizable/
3647//>>demos: https://jqueryui.com/resizable/
3648//>>css.structure: ../../themes/base/core.css
3649//>>css.structure: ../../themes/base/resizable.css
3650//>>css.theme: ../../themes/base/theme.css
3651
3652
3653$.widget( "ui.resizable", $.ui.mouse, {
3654	version: "1.14.2",
3655	widgetEventPrefix: "resize",
3656	options: {
3657		alsoResize: false,
3658		animate: false,
3659		animateDuration: "slow",
3660		animateEasing: "swing",
3661		aspectRatio: false,
3662		autoHide: false,
3663		classes: {
3664			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
3665		},
3666		containment: false,
3667		ghost: false,
3668		grid: false,
3669		handles: "e,s,se",
3670		helper: false,
3671		maxHeight: null,
3672		maxWidth: null,
3673		minHeight: 10,
3674		minWidth: 10,
3675
3676		// See #7960
3677		zIndex: 90,
3678
3679		// Callbacks
3680		resize: null,
3681		start: null,
3682		stop: null
3683	},
3684
3685	_num: function( value ) {
3686		return parseFloat( value ) || 0;
3687	},
3688
3689	_isNumber: function( value ) {
3690		return !isNaN( parseFloat( value ) );
3691	},
3692
3693	_hasScroll: function( el, a ) {
3694
3695		var scroll,
3696			has = false,
3697			overflow = $( el ).css( "overflow" );
3698
3699		if ( overflow === "hidden" ) {
3700			return false;
3701		}
3702		if ( overflow === "scroll" ) {
3703			return true;
3704		}
3705
3706		scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop";
3707
3708		if ( el[ scroll ] > 0 ) {
3709			return true;
3710		}
3711
3712		// TODO: determine which cases actually cause this to happen
3713		// if the element doesn't have the scroll set, see if it's possible to
3714		// set the scroll
3715		try {
3716			el[ scroll ] = 1;
3717			has = ( el[ scroll ] > 0 );
3718			el[ scroll ] = 0;
3719		} catch ( _e ) {
3720
3721			// `el` might be a string, then setting `scroll` will throw
3722			// an error in strict mode; ignore it.
3723		}
3724		return has;
3725	},
3726
3727	_create: function() {
3728
3729		var margins,
3730			o = this.options,
3731			that = this;
3732		this._addClass( "ui-resizable" );
3733
3734		$.extend( this, {
3735			_aspectRatio: !!( o.aspectRatio ),
3736			aspectRatio: o.aspectRatio,
3737			originalElement: this.element,
3738			_proportionallyResizeElements: [],
3739			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3740		} );
3741
3742		// Wrap the element if it cannot hold child nodes
3743		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
3744
3745			this.element.wrap(
3746				$( "<div class='ui-wrapper'></div>" ).css( {
3747					overflow: "hidden",
3748					position: this.element.css( "position" ),
3749					width: this.element.outerWidth(),
3750					height: this.element.outerHeight(),
3751					top: this.element.css( "top" ),
3752					left: this.element.css( "left" )
3753				} )
3754			);
3755
3756			this.element = this.element.parent().data(
3757				"ui-resizable", this.element.resizable( "instance" )
3758			);
3759
3760			this.elementIsWrapper = true;
3761
3762			margins = {
3763				marginTop: this.originalElement.css( "marginTop" ),
3764				marginRight: this.originalElement.css( "marginRight" ),
3765				marginBottom: this.originalElement.css( "marginBottom" ),
3766				marginLeft: this.originalElement.css( "marginLeft" )
3767			};
3768
3769			this.element.css( margins );
3770
3771			// Support: Safari
3772			// Prevent Safari textarea resize
3773			this.originalResizeStyle = this.originalElement.css( "resize" );
3774			this.originalElement.css( "resize", "none" );
3775
3776			this._proportionallyResizeElements.push( this.originalElement.css( {
3777				position: "static",
3778				zoom: 1,
3779				display: "block"
3780			} ) );
3781
3782			this._proportionallyResize();
3783		}
3784
3785		this._setupHandles();
3786
3787		if ( o.autoHide ) {
3788			$( this.element )
3789				.on( "mouseenter", function() {
3790					if ( o.disabled ) {
3791						return;
3792					}
3793					that._removeClass( "ui-resizable-autohide" );
3794					that._handles.show();
3795				} )
3796				.on( "mouseleave", function() {
3797					if ( o.disabled ) {
3798						return;
3799					}
3800					if ( !that.resizing ) {
3801						that._addClass( "ui-resizable-autohide" );
3802						that._handles.hide();
3803					}
3804				} );
3805		}
3806
3807		this._mouseInit();
3808	},
3809
3810	_destroy: function() {
3811
3812		this._mouseDestroy();
3813		this._addedHandles.remove();
3814
3815		var wrapper,
3816			_destroy = function( exp ) {
3817				$( exp )
3818					.removeData( "resizable" )
3819					.removeData( "ui-resizable" )
3820					.off( ".resizable" );
3821			};
3822
3823		// TODO: Unwrap at same DOM position
3824		if ( this.elementIsWrapper ) {
3825			_destroy( this.element );
3826			wrapper = this.element;
3827			this.originalElement.css( {
3828				position: wrapper.css( "position" ),
3829				width: wrapper.outerWidth(),
3830				height: wrapper.outerHeight(),
3831				top: wrapper.css( "top" ),
3832				left: wrapper.css( "left" )
3833			} ).insertAfter( wrapper );
3834			wrapper.remove();
3835		}
3836
3837		this.originalElement.css( "resize", this.originalResizeStyle );
3838		_destroy( this.originalElement );
3839
3840		return this;
3841	},
3842
3843	_setOption: function( key, value ) {
3844		this._super( key, value );
3845
3846		switch ( key ) {
3847		case "handles":
3848			this._removeHandles();
3849			this._setupHandles();
3850			break;
3851		case "aspectRatio":
3852			this._aspectRatio = !!value;
3853			break;
3854		default:
3855			break;
3856		}
3857	},
3858
3859	_setupHandles: function() {
3860		var o = this.options, handle, i, n, hname, axis, that = this;
3861		this.handles = o.handles ||
3862			( !$( ".ui-resizable-handle", this.element ).length ?
3863				"e,s,se" : {
3864					n: ".ui-resizable-n",
3865					e: ".ui-resizable-e",
3866					s: ".ui-resizable-s",
3867					w: ".ui-resizable-w",
3868					se: ".ui-resizable-se",
3869					sw: ".ui-resizable-sw",
3870					ne: ".ui-resizable-ne",
3871					nw: ".ui-resizable-nw"
3872				} );
3873
3874		this._handles = $();
3875		this._addedHandles = $();
3876		if ( this.handles.constructor === String ) {
3877
3878			if ( this.handles === "all" ) {
3879				this.handles = "n,e,s,w,se,sw,ne,nw";
3880			}
3881
3882			n = this.handles.split( "," );
3883			this.handles = {};
3884
3885			for ( i = 0; i < n.length; i++ ) {
3886
3887				handle = String.prototype.trim.call( n[ i ] );
3888				hname = "ui-resizable-" + handle;
3889				axis = $( "<div>" );
3890				this._addClass( axis, "ui-resizable-handle " + hname );
3891
3892				axis.css( { zIndex: o.zIndex } );
3893
3894				this.handles[ handle ] = ".ui-resizable-" + handle;
3895				if ( !this.element.children( this.handles[ handle ] ).length ) {
3896					this.element.append( axis );
3897					this._addedHandles = this._addedHandles.add( axis );
3898				}
3899			}
3900
3901		}
3902
3903		this._renderAxis = function( target ) {
3904
3905			var i, axis, padPos, padWrapper;
3906
3907			target = target || this.element;
3908
3909			for ( i in this.handles ) {
3910
3911				if ( this.handles[ i ].constructor === String ) {
3912					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
3913				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3914					this.handles[ i ] = $( this.handles[ i ] );
3915					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
3916				}
3917
3918				if ( this.elementIsWrapper &&
3919						this.originalElement[ 0 ]
3920							.nodeName
3921							.match( /^(textarea|input|select|button)$/i ) ) {
3922					axis = $( this.handles[ i ], this.element );
3923
3924					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
3925						axis.outerHeight() :
3926						axis.outerWidth();
3927
3928					padPos = [ "padding",
3929						/ne|nw|n/.test( i ) ? "Top" :
3930						/se|sw|s/.test( i ) ? "Bottom" :
3931						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
3932
3933					target.css( padPos, padWrapper );
3934
3935					this._proportionallyResize();
3936				}
3937
3938				this._handles = this._handles.add( this.handles[ i ] );
3939			}
3940		};
3941
3942		// TODO: make renderAxis a prototype function
3943		this._renderAxis( this.element );
3944
3945		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
3946		this._handles.disableSelection();
3947
3948		this._handles.on( "mouseover", function() {
3949			if ( !that.resizing ) {
3950				if ( this.className ) {
3951					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
3952				}
3953				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
3954			}
3955		} );
3956
3957		if ( o.autoHide ) {
3958			this._handles.hide();
3959			this._addClass( "ui-resizable-autohide" );
3960		}
3961	},
3962
3963	_removeHandles: function() {
3964		this._addedHandles.remove();
3965	},
3966
3967	_mouseCapture: function( event ) {
3968		var i, handle,
3969			capture = false;
3970
3971		for ( i in this.handles ) {
3972			handle = $( this.handles[ i ] )[ 0 ];
3973			if ( handle === event.target || $.contains( handle, event.target ) ) {
3974				capture = true;
3975			}
3976		}
3977
3978		return !this.options.disabled && capture;
3979	},
3980
3981	_mouseStart: function( event ) {
3982
3983		var curleft, curtop, cursor, calculatedSize,
3984			o = this.options,
3985			el = this.element;
3986
3987		this.resizing = true;
3988
3989		this._renderProxy();
3990
3991		curleft = this._num( this.helper.css( "left" ) );
3992		curtop = this._num( this.helper.css( "top" ) );
3993
3994		if ( o.containment ) {
3995			curleft += $( o.containment ).scrollLeft() || 0;
3996			curtop += $( o.containment ).scrollTop() || 0;
3997		}
3998
3999		this.offset = this.helper.offset();
4000		this.position = { left: curleft, top: curtop };
4001
4002		if ( !this._helper ) {
4003			calculatedSize = this._calculateAdjustedElementDimensions( el );
4004		}
4005
4006		this.size = this._helper ? {
4007				width: this.helper.width(),
4008				height: this.helper.height()
4009			} : {
4010				width: calculatedSize.width,
4011				height: calculatedSize.height
4012			};
4013
4014		this.originalSize = this._helper ? {
4015				width: el.outerWidth(),
4016				height: el.outerHeight()
4017			} : {
4018				width: calculatedSize.width,
4019				height: calculatedSize.height
4020			};
4021
4022		this.sizeDiff = {
4023			width: el.outerWidth() - el.width(),
4024			height: el.outerHeight() - el.height()
4025		};
4026
4027		this.originalPosition = { left: curleft, top: curtop };
4028		this.originalMousePosition = { left: event.pageX, top: event.pageY };
4029
4030		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
4031			o.aspectRatio :
4032			( ( this.originalSize.width / this.originalSize.height ) || 1 );
4033
4034		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
4035		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
4036
4037		this._addClass( "ui-resizable-resizing" );
4038		this._propagate( "start", event );
4039		return true;
4040	},
4041
4042	_mouseDrag: function( event ) {
4043
4044		var data, props,
4045			smp = this.originalMousePosition,
4046			a = this.axis,
4047			dx = ( event.pageX - smp.left ) || 0,
4048			dy = ( event.pageY - smp.top ) || 0,
4049			trigger = this._change[ a ];
4050
4051		this._updatePrevProperties();
4052
4053		if ( !trigger ) {
4054			return false;
4055		}
4056
4057		data = trigger.apply( this, [ event, dx, dy ] );
4058
4059		this._updateVirtualBoundaries( event.shiftKey );
4060		if ( this._aspectRatio || event.shiftKey ) {
4061			data = this._updateRatio( data, event );
4062		}
4063
4064		data = this._respectSize( data, event );
4065
4066		this._updateCache( data );
4067
4068		this._propagate( "resize", event );
4069
4070		props = this._applyChanges();
4071
4072		if ( !this._helper && this._proportionallyResizeElements.length ) {
4073			this._proportionallyResize();
4074		}
4075
4076		if ( !$.isEmptyObject( props ) ) {
4077			this._updatePrevProperties();
4078			this._trigger( "resize", event, this.ui() );
4079			this._applyChanges();
4080		}
4081
4082		return false;
4083	},
4084
4085	_mouseStop: function( event ) {
4086
4087		this.resizing = false;
4088		var pr, ista, soffseth, soffsetw, s, left, top,
4089			o = this.options, that = this;
4090
4091		if ( this._helper ) {
4092
4093			pr = this._proportionallyResizeElements;
4094			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
4095			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
4096			soffsetw = ista ? 0 : that.sizeDiff.width;
4097
4098			s = {
4099				width: ( that.helper.width()  - soffsetw ),
4100				height: ( that.helper.height() - soffseth )
4101			};
4102			left = ( parseFloat( that.element.css( "left" ) ) +
4103				( that.position.left - that.originalPosition.left ) ) || null;
4104			top = ( parseFloat( that.element.css( "top" ) ) +
4105				( that.position.top - that.originalPosition.top ) ) || null;
4106
4107			if ( !o.animate ) {
4108				this.element.css( $.extend( s, { top: top, left: left } ) );
4109			}
4110
4111			that.helper.height( that.size.height );
4112			that.helper.width( that.size.width );
4113
4114			if ( this._helper && !o.animate ) {
4115				this._proportionallyResize();
4116			}
4117		}
4118
4119		$( "body" ).css( "cursor", "auto" );
4120
4121		this._removeClass( "ui-resizable-resizing" );
4122
4123		this._propagate( "stop", event );
4124
4125		if ( this._helper ) {
4126			this.helper.remove();
4127		}
4128
4129		return false;
4130
4131	},
4132
4133	_updatePrevProperties: function() {
4134		this.prevPosition = {
4135			top: this.position.top,
4136			left: this.position.left
4137		};
4138		this.prevSize = {
4139			width: this.size.width,
4140			height: this.size.height
4141		};
4142	},
4143
4144	_applyChanges: function() {
4145		var props = {};
4146
4147		if ( this.position.top !== this.prevPosition.top ) {
4148			props.top = this.position.top + "px";
4149		}
4150		if ( this.position.left !== this.prevPosition.left ) {
4151			props.left = this.position.left + "px";
4152		}
4153
4154		this.helper.css( props );
4155
4156		if ( this.size.width !== this.prevSize.width ) {
4157			props.width = this.size.width + "px";
4158			this.helper.width( props.width );
4159		}
4160		if ( this.size.height !== this.prevSize.height ) {
4161			props.height = this.size.height + "px";
4162			this.helper.height( props.height );
4163		}
4164
4165		return props;
4166	},
4167
4168	_updateVirtualBoundaries: function( forceAspectRatio ) {
4169		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
4170			o = this.options;
4171
4172		b = {
4173			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
4174			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
4175			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
4176			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
4177		};
4178
4179		if ( this._aspectRatio || forceAspectRatio ) {
4180			pMinWidth = b.minHeight * this.aspectRatio;
4181			pMinHeight = b.minWidth / this.aspectRatio;
4182			pMaxWidth = b.maxHeight * this.aspectRatio;
4183			pMaxHeight = b.maxWidth / this.aspectRatio;
4184
4185			if ( pMinWidth > b.minWidth ) {
4186				b.minWidth = pMinWidth;
4187			}
4188			if ( pMinHeight > b.minHeight ) {
4189				b.minHeight = pMinHeight;
4190			}
4191			if ( pMaxWidth < b.maxWidth ) {
4192				b.maxWidth = pMaxWidth;
4193			}
4194			if ( pMaxHeight < b.maxHeight ) {
4195				b.maxHeight = pMaxHeight;
4196			}
4197		}
4198		this._vBoundaries = b;
4199	},
4200
4201	_updateCache: function( data ) {
4202		this.offset = this.helper.offset();
4203		if ( this._isNumber( data.left ) ) {
4204			this.position.left = data.left;
4205		}
4206		if ( this._isNumber( data.top ) ) {
4207			this.position.top = data.top;
4208		}
4209		if ( this._isNumber( data.height ) ) {
4210			this.size.height = data.height;
4211		}
4212		if ( this._isNumber( data.width ) ) {
4213			this.size.width = data.width;
4214		}
4215	},
4216
4217	_updateRatio: function( data ) {
4218
4219		var cpos = this.position,
4220			csize = this.size,
4221			a = this.axis;
4222
4223		if ( this._isNumber( data.height ) ) {
4224			data.width = ( data.height * this.aspectRatio );
4225		} else if ( this._isNumber( data.width ) ) {
4226			data.height = ( data.width / this.aspectRatio );
4227		}
4228
4229		if ( a === "sw" ) {
4230			data.left = cpos.left + ( csize.width - data.width );
4231			data.top = null;
4232		}
4233		if ( a === "nw" ) {
4234			data.top = cpos.top + ( csize.height - data.height );
4235			data.left = cpos.left + ( csize.width - data.width );
4236		}
4237
4238		return data;
4239	},
4240
4241	_respectSize: function( data ) {
4242
4243		var o = this._vBoundaries,
4244			a = this.axis,
4245			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
4246			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
4247			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
4248			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
4249			dw = this.originalPosition.left + this.originalSize.width,
4250			dh = this.originalPosition.top + this.originalSize.height,
4251			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
4252		if ( isminw ) {
4253			data.width = o.minWidth;
4254		}
4255		if ( isminh ) {
4256			data.height = o.minHeight;
4257		}
4258		if ( ismaxw ) {
4259			data.width = o.maxWidth;
4260		}
4261		if ( ismaxh ) {
4262			data.height = o.maxHeight;
4263		}
4264
4265		if ( isminw && cw ) {
4266			data.left = dw - o.minWidth;
4267		}
4268		if ( ismaxw && cw ) {
4269			data.left = dw - o.maxWidth;
4270		}
4271		if ( isminh && ch ) {
4272			data.top = dh - o.minHeight;
4273		}
4274		if ( ismaxh && ch ) {
4275			data.top = dh - o.maxHeight;
4276		}
4277
4278		// Fixing jump error on top/left - bug #2330
4279		if ( !data.width && !data.height && !data.left && data.top ) {
4280			data.top = null;
4281		} else if ( !data.width && !data.height && !data.top && data.left ) {
4282			data.left = null;
4283		}
4284
4285		return data;
4286	},
4287
4288	_getPaddingPlusBorderDimensions: function( element ) {
4289		var i = 0,
4290			widths = [],
4291			borders = [
4292				element.css( "borderTopWidth" ),
4293				element.css( "borderRightWidth" ),
4294				element.css( "borderBottomWidth" ),
4295				element.css( "borderLeftWidth" )
4296			],
4297			paddings = [
4298				element.css( "paddingTop" ),
4299				element.css( "paddingRight" ),
4300				element.css( "paddingBottom" ),
4301				element.css( "paddingLeft" )
4302			];
4303
4304		for ( ; i < 4; i++ ) {
4305			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
4306			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
4307		}
4308
4309		return {
4310			height: widths[ 0 ] + widths[ 2 ],
4311			width: widths[ 1 ] + widths[ 3 ]
4312		};
4313	},
4314
4315	_calculateAdjustedElementDimensions: function( element ) {
4316		var elWidth, elHeight, paddingBorder,
4317			ce = element.get( 0 );
4318
4319		if ( element.css( "box-sizing" ) !== "content-box" ||
4320			( !this._hasScroll( ce ) && !this._hasScroll( ce, "left" ) ) ) {
4321				return {
4322					height: parseFloat( element.css( "height" ) ),
4323					width: parseFloat( element.css( "width" ) )
4324				};
4325		}
4326
4327		// Check if CSS inline styles are set and use those (usually from previous resizes)
4328		elWidth = parseFloat( ce.style.width );
4329		elHeight = parseFloat( ce.style.height );
4330
4331		paddingBorder = this._getPaddingPlusBorderDimensions( element );
4332		elWidth = isNaN( elWidth ) ?
4333			this._getElementTheoreticalSize( element, paddingBorder, "width" ) :
4334			elWidth;
4335		elHeight = isNaN( elHeight ) ?
4336			this._getElementTheoreticalSize( element, paddingBorder, "height" ) :
4337			elHeight;
4338
4339		return {
4340			height: elHeight,
4341			width: elWidth
4342		};
4343	},
4344
4345	_getElementTheoreticalSize: function( element, extraSize, dimension ) {
4346
4347		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
4348		var size = Math.max( 0, Math.ceil(
4349			element.get( 0 )[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
4350			extraSize[ dimension ] -
4351			0.5
4352
4353		// If offsetWidth/offsetHeight is unknown, then we can't determine theoretical size.
4354		// Use an explicit zero to avoid NaN.
4355		// See https://github.com/jquery/jquery/issues/3964
4356		) ) || 0;
4357
4358		return size;
4359	},
4360
4361	_proportionallyResize: function() {
4362
4363		if ( !this._proportionallyResizeElements.length ) {
4364			return;
4365		}
4366
4367		var prel,
4368			i = 0,
4369			element = this.helper || this.element;
4370
4371		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
4372
4373			prel = this._proportionallyResizeElements[ i ];
4374
4375			// TODO: Seems like a bug to cache this.outerDimensions
4376			// considering that we are in a loop.
4377			if ( !this.outerDimensions ) {
4378				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
4379			}
4380
4381			prel.css( {
4382				height: ( element.height() - this.outerDimensions.height ) || 0,
4383				width: ( element.width() - this.outerDimensions.width ) || 0
4384			} );
4385
4386		}
4387
4388	},
4389
4390	_renderProxy: function() {
4391
4392		var el = this.element, o = this.options;
4393		this.elementOffset = el.offset();
4394
4395		if ( this._helper ) {
4396
4397			this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } );
4398
4399			this._addClass( this.helper, this._helper );
4400			this.helper.css( {
4401				width: this.element.outerWidth(),
4402				height: this.element.outerHeight(),
4403				position: "absolute",
4404				left: this.elementOffset.left + "px",
4405				top: this.elementOffset.top + "px",
4406				zIndex: ++o.zIndex //TODO: Don't modify option
4407			} );
4408
4409			this.helper
4410				.appendTo( "body" )
4411				.disableSelection();
4412
4413		} else {
4414			this.helper = this.element;
4415		}
4416
4417	},
4418
4419	_change: {
4420		e: function( event, dx ) {
4421			return { width: this.originalSize.width + dx };
4422		},
4423		w: function( event, dx ) {
4424			var cs = this.originalSize, sp = this.originalPosition;
4425			return { left: sp.left + dx, width: cs.width - dx };
4426		},
4427		n: function( event, dx, dy ) {
4428			var cs = this.originalSize, sp = this.originalPosition;
4429			return { top: sp.top + dy, height: cs.height - dy };
4430		},
4431		s: function( event, dx, dy ) {
4432			return { height: this.originalSize.height + dy };
4433		},
4434		se: function( event, dx, dy ) {
4435			return $.extend( this._change.s.apply( this, arguments ),
4436				this._change.e.apply( this, [ event, dx, dy ] ) );
4437		},
4438		sw: function( event, dx, dy ) {
4439			return $.extend( this._change.s.apply( this, arguments ),
4440				this._change.w.apply( this, [ event, dx, dy ] ) );
4441		},
4442		ne: function( event, dx, dy ) {
4443			return $.extend( this._change.n.apply( this, arguments ),
4444				this._change.e.apply( this, [ event, dx, dy ] ) );
4445		},
4446		nw: function( event, dx, dy ) {
4447			return $.extend( this._change.n.apply( this, arguments ),
4448				this._change.w.apply( this, [ event, dx, dy ] ) );
4449		}
4450	},
4451
4452	_propagate: function( n, event ) {
4453		$.ui.plugin.call( this, n, [ event, this.ui() ] );
4454		if ( n !== "resize" ) {
4455			this._trigger( n, event, this.ui() );
4456		}
4457	},
4458
4459	plugins: {},
4460
4461	ui: function() {
4462		return {
4463			originalElement: this.originalElement,
4464			element: this.element,
4465			helper: this.helper,
4466			position: this.position,
4467			size: this.size,
4468			originalSize: this.originalSize,
4469			originalPosition: this.originalPosition
4470		};
4471	}
4472
4473} );
4474
4475/*
4476 * Resizable Extensions
4477 */
4478
4479$.ui.plugin.add( "resizable", "animate", {
4480
4481	stop: function( event ) {
4482		var that = $( this ).resizable( "instance" ),
4483			o = that.options,
4484			pr = that._proportionallyResizeElements,
4485			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
4486			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
4487			soffsetw = ista ? 0 : that.sizeDiff.width,
4488			style = {
4489				width: ( that.size.width - soffsetw ),
4490				height: ( that.size.height - soffseth )
4491			},
4492			left = ( parseFloat( that.element.css( "left" ) ) +
4493				( that.position.left - that.originalPosition.left ) ) || null,
4494			top = ( parseFloat( that.element.css( "top" ) ) +
4495				( that.position.top - that.originalPosition.top ) ) || null;
4496
4497		that.element.animate(
4498			$.extend( style, top && left ? { top: top, left: left } : {} ), {
4499				duration: o.animateDuration,
4500				easing: o.animateEasing,
4501				step: function() {
4502
4503					var data = {
4504						width: parseFloat( that.element.css( "width" ) ),
4505						height: parseFloat( that.element.css( "height" ) ),
4506						top: parseFloat( that.element.css( "top" ) ),
4507						left: parseFloat( that.element.css( "left" ) )
4508					};
4509
4510					if ( pr && pr.length ) {
4511						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
4512					}
4513
4514					// Propagating resize, and updating values for each animation step
4515					that._updateCache( data );
4516					that._propagate( "resize", event );
4517
4518				}
4519			}
4520		);
4521	}
4522
4523} );
4524
4525$.ui.plugin.add( "resizable", "containment", {
4526
4527	start: function() {
4528		var element, p, co, ch, cw, width, height,
4529			that = $( this ).resizable( "instance" ),
4530			o = that.options,
4531			el = that.element,
4532			oc = o.containment,
4533			ce = ( oc instanceof $ ) ?
4534				oc.get( 0 ) :
4535				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
4536
4537		if ( !ce ) {
4538			return;
4539		}
4540
4541		that.containerElement = $( ce );
4542
4543		if ( /document/.test( oc ) || oc === document ) {
4544			that.containerOffset = {
4545				left: 0,
4546				top: 0
4547			};
4548			that.containerPosition = {
4549				left: 0,
4550				top: 0
4551			};
4552
4553			that.parentData = {
4554				element: $( document ),
4555				left: 0,
4556				top: 0,
4557				width: $( document ).width(),
4558				height: $( document ).height() || document.body.parentNode.scrollHeight
4559			};
4560		} else {
4561			element = $( ce );
4562			p = [];
4563			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
4564				p[ i ] = that._num( element.css( "padding" + name ) );
4565			} );
4566
4567			that.containerOffset = element.offset();
4568			that.containerPosition = element.position();
4569			that.containerSize = {
4570				height: ( element.innerHeight() - p[ 3 ] ),
4571				width: ( element.innerWidth() - p[ 1 ] )
4572			};
4573
4574			co = that.containerOffset;
4575			ch = that.containerSize.height;
4576			cw = that.containerSize.width;
4577			width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw );
4578			height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch );
4579
4580			that.parentData = {
4581				element: ce,
4582				left: co.left,
4583				top: co.top,
4584				width: width,
4585				height: height
4586			};
4587		}
4588	},
4589
4590	resize: function( event ) {
4591		var woset, hoset, isParent, isOffsetRelative,
4592			that = $( this ).resizable( "instance" ),
4593			o = that.options,
4594			co = that.containerOffset,
4595			cp = that.position,
4596			pRatio = that._aspectRatio || event.shiftKey,
4597			cop = {
4598				top: 0,
4599				left: 0
4600			},
4601			ce = that.containerElement,
4602			continueResize = true;
4603
4604		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
4605			cop = co;
4606		}
4607
4608		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
4609			that.size.width = that.size.width +
4610				( that._helper ?
4611					( that.position.left - co.left ) :
4612					( that.position.left - cop.left ) );
4613
4614			if ( pRatio ) {
4615				that.size.height = that.size.width / that.aspectRatio;
4616				continueResize = false;
4617			}
4618			that.position.left = o.helper ? co.left : 0;
4619		}
4620
4621		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
4622			that.size.height = that.size.height +
4623				( that._helper ?
4624					( that.position.top - co.top ) :
4625					that.position.top );
4626
4627			if ( pRatio ) {
4628				that.size.width = that.size.height * that.aspectRatio;
4629				continueResize = false;
4630			}
4631			that.position.top = that._helper ? co.top : 0;
4632		}
4633
4634		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
4635		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
4636
4637		if ( isParent && isOffsetRelative ) {
4638			that.offset.left = that.parentData.left + that.position.left;
4639			that.offset.top = that.parentData.top + that.position.top;
4640		} else {
4641			that.offset.left = that.element.offset().left;
4642			that.offset.top = that.element.offset().top;
4643		}
4644
4645		woset = Math.abs( that.sizeDiff.width +
4646			( that._helper ?
4647				that.offset.left - cop.left :
4648				( that.offset.left - co.left ) ) );
4649
4650		hoset = Math.abs( that.sizeDiff.height +
4651			( that._helper ?
4652				that.offset.top - cop.top :
4653				( that.offset.top - co.top ) ) );
4654
4655		if ( woset + that.size.width >= that.parentData.width ) {
4656			that.size.width = that.parentData.width - woset;
4657			if ( pRatio ) {
4658				that.size.height = that.size.width / that.aspectRatio;
4659				continueResize = false;
4660			}
4661		}
4662
4663		if ( hoset + that.size.height >= that.parentData.height ) {
4664			that.size.height = that.parentData.height - hoset;
4665			if ( pRatio ) {
4666				that.size.width = that.size.height * that.aspectRatio;
4667				continueResize = false;
4668			}
4669		}
4670
4671		if ( !continueResize ) {
4672			that.position.left = that.prevPosition.left;
4673			that.position.top = that.prevPosition.top;
4674			that.size.width = that.prevSize.width;
4675			that.size.height = that.prevSize.height;
4676		}
4677	},
4678
4679	stop: function() {
4680		var that = $( this ).resizable( "instance" ),
4681			o = that.options,
4682			co = that.containerOffset,
4683			cop = that.containerPosition,
4684			ce = that.containerElement,
4685			helper = $( that.helper ),
4686			ho = helper.offset(),
4687			w = helper.outerWidth() - that.sizeDiff.width,
4688			h = helper.outerHeight() - that.sizeDiff.height;
4689
4690		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4691			$( this ).css( {
4692				left: ho.left - cop.left - co.left,
4693				width: w,
4694				height: h
4695			} );
4696		}
4697
4698		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4699			$( this ).css( {
4700				left: ho.left - cop.left - co.left,
4701				width: w,
4702				height: h
4703			} );
4704		}
4705	}
4706} );
4707
4708$.ui.plugin.add( "resizable", "alsoResize", {
4709
4710	start: function() {
4711		var that = $( this ).resizable( "instance" ),
4712			o = that.options;
4713
4714		$( o.alsoResize ).each( function() {
4715			var el = $( this ),
4716				elSize = that._calculateAdjustedElementDimensions( el );
4717
4718			el.data( "ui-resizable-alsoresize", {
4719				width: elSize.width, height: elSize.height,
4720				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
4721			} );
4722		} );
4723	},
4724
4725	resize: function( event, ui ) {
4726		var that = $( this ).resizable( "instance" ),
4727			o = that.options,
4728			os = that.originalSize,
4729			op = that.originalPosition,
4730			delta = {
4731				height: ( that.size.height - os.height ) || 0,
4732				width: ( that.size.width - os.width ) || 0,
4733				top: ( that.position.top - op.top ) || 0,
4734				left: ( that.position.left - op.left ) || 0
4735			};
4736
4737			$( o.alsoResize ).each( function() {
4738				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
4739					css = el.parents( ui.originalElement[ 0 ] ).length ?
4740							[ "width", "height" ] :
4741							[ "width", "height", "top", "left" ];
4742
4743				$.each( css, function( i, prop ) {
4744					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
4745					if ( sum && sum >= 0 ) {
4746						style[ prop ] = sum || null;
4747					}
4748				} );
4749
4750				el.css( style );
4751			} );
4752	},
4753
4754	stop: function() {
4755		$( this ).removeData( "ui-resizable-alsoresize" );
4756	}
4757} );
4758
4759$.ui.plugin.add( "resizable", "ghost", {
4760
4761	start: function() {
4762
4763		var that = $( this ).resizable( "instance" ), cs = that.size;
4764
4765		that.ghost = that.originalElement.clone();
4766		that.ghost.css( {
4767			opacity: 0.25,
4768			display: "block",
4769			position: "relative",
4770			height: cs.height,
4771			width: cs.width,
4772			margin: 0,
4773			left: 0,
4774			top: 0
4775		} );
4776
4777		that._addClass( that.ghost, "ui-resizable-ghost" );
4778
4779		// DEPRECATED
4780		// TODO: remove after 1.12
4781		if ( $.uiBackCompat === true && typeof that.options.ghost === "string" ) {
4782
4783			// Ghost option
4784			that.ghost.addClass( this.options.ghost );
4785		}
4786
4787		that.ghost.appendTo( that.helper );
4788
4789	},
4790
4791	resize: function() {
4792		var that = $( this ).resizable( "instance" );
4793		if ( that.ghost ) {
4794			that.ghost.css( {
4795				position: "relative",
4796				height: that.size.height,
4797				width: that.size.width
4798			} );
4799		}
4800	},
4801
4802	stop: function() {
4803		var that = $( this ).resizable( "instance" );
4804		if ( that.ghost && that.helper ) {
4805			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
4806		}
4807	}
4808
4809} );
4810
4811$.ui.plugin.add( "resizable", "grid", {
4812
4813	resize: function() {
4814		var outerDimensions,
4815			that = $( this ).resizable( "instance" ),
4816			o = that.options,
4817			cs = that.size,
4818			os = that.originalSize,
4819			op = that.originalPosition,
4820			a = that.axis,
4821			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4822			gridX = ( grid[ 0 ] || 1 ),
4823			gridY = ( grid[ 1 ] || 1 ),
4824			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
4825			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
4826			newWidth = os.width + ox,
4827			newHeight = os.height + oy,
4828			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
4829			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
4830			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
4831			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
4832
4833		o.grid = grid;
4834
4835		if ( isMinWidth ) {
4836			newWidth += gridX;
4837		}
4838		if ( isMinHeight ) {
4839			newHeight += gridY;
4840		}
4841		if ( isMaxWidth ) {
4842			newWidth -= gridX;
4843		}
4844		if ( isMaxHeight ) {
4845			newHeight -= gridY;
4846		}
4847
4848		if ( /^(se|s|e)$/.test( a ) ) {
4849			that.size.width = newWidth;
4850			that.size.height = newHeight;
4851		} else if ( /^(ne)$/.test( a ) ) {
4852			that.size.width = newWidth;
4853			that.size.height = newHeight;
4854			that.position.top = op.top - oy;
4855		} else if ( /^(sw)$/.test( a ) ) {
4856			that.size.width = newWidth;
4857			that.size.height = newHeight;
4858			that.position.left = op.left - ox;
4859		} else {
4860			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
4861				outerDimensions = that._getPaddingPlusBorderDimensions( this );
4862			}
4863
4864			if ( newHeight - gridY > 0 ) {
4865				that.size.height = newHeight;
4866				that.position.top = op.top - oy;
4867			} else {
4868				newHeight = gridY - outerDimensions.height;
4869				that.size.height = newHeight;
4870				that.position.top = op.top + os.height - newHeight;
4871			}
4872			if ( newWidth - gridX > 0 ) {
4873				that.size.width = newWidth;
4874				that.position.left = op.left - ox;
4875			} else {
4876				newWidth = gridX - outerDimensions.width;
4877				that.size.width = newWidth;
4878				that.position.left = op.left + os.width - newWidth;
4879			}
4880		}
4881	}
4882
4883} );
4884
4885var widgetsResizable = $.ui.resizable;
4886
4887
4888/*!
4889 * jQuery UI 
vendor: 8,269 bytes, lines 4889-5203
4889Selectable 1.14.2
4890 * https://jqueryui.com
4891 *
4892 * Copyright OpenJS Foundation and other contributors
4893 * Released under the MIT license.
4894 * https://jquery.org/license
4895 */
4896
4897//>>label: Selectable
4898//>>group: Interactions
4899//>>description: Allows groups of elements to be selected with the mouse.
4900//>>docs: https://api.jqueryui.com/selectable/
4901//>>demos: https://jqueryui.com/selectable/
4902//>>css.structure: ../../themes/base/selectable.css
4903
4904
4905var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
4906	version: "1.14.2",
4907	options: {
4908		appendTo: "body",
4909		autoRefresh: true,
4910		distance: 0,
4911		filter: "*",
4912		tolerance: "touch",
4913
4914		// Callbacks
4915		selected: null,
4916		selecting: null,
4917		start: null,
4918		stop: null,
4919		unselected: null,
4920		unselecting: null
4921	},
4922	_create: function() {
4923		var that = this;
4924
4925		this._addClass( "ui-selectable" );
4926
4927		this.dragged = false;
4928
4929		// Cache selectee children based on filter
4930		this.refresh = function() {
4931			that.elementPos = $( that.element[ 0 ] ).offset();
4932			that.selectees = $( that.options.filter, that.element[ 0 ] );
4933			that._addClass( that.selectees, "ui-selectee" );
4934			that.selectees.each( function() {
4935				var $this = $( this ),
4936					selecteeOffset = $this.offset(),
4937					pos = {
4938						left: selecteeOffset.left - that.elementPos.left,
4939						top: selecteeOffset.top - that.elementPos.top
4940					};
4941				$.data( this, "selectable-item", {
4942					element: this,
4943					$element: $this,
4944					left: pos.left,
4945					top: pos.top,
4946					right: pos.left + $this.outerWidth(),
4947					bottom: pos.top + $this.outerHeight(),
4948					startselected: false,
4949					selected: $this.hasClass( "ui-selected" ),
4950					selecting: $this.hasClass( "ui-selecting" ),
4951					unselecting: $this.hasClass( "ui-unselecting" )
4952				} );
4953			} );
4954		};
4955		this.refresh();
4956
4957		this._mouseInit();
4958
4959		this.helper = $( "<div>" );
4960		this._addClass( this.helper, "ui-selectable-helper" );
4961	},
4962
4963	_destroy: function() {
4964		this.selectees.removeData( "selectable-item" );
4965		this._mouseDestroy();
4966	},
4967
4968	_mouseStart: function( event ) {
4969		var that = this,
4970			options = this.options;
4971
4972		this.opos = [ event.pageX, event.pageY ];
4973		this.elementPos = $( this.element[ 0 ] ).offset();
4974
4975		if ( this.options.disabled ) {
4976			return;
4977		}
4978
4979		this.selectees = $( options.filter, this.element[ 0 ] );
4980
4981		this._trigger( "start", event );
4982
4983		$( options.appendTo ).append( this.helper );
4984
4985		// position helper (lasso)
4986		this.helper.css( {
4987			"left": event.pageX,
4988			"top": event.pageY,
4989			"width": 0,
4990			"height": 0
4991		} );
4992
4993		if ( options.autoRefresh ) {
4994			this.refresh();
4995		}
4996
4997		this.selectees.filter( ".ui-selected" ).each( function() {
4998			var selectee = $.data( this, "selectable-item" );
4999			selectee.startselected = true;
5000			if ( !event.metaKey && !event.ctrlKey ) {
5001				that._removeClass( selectee.$element, "ui-selected" );
5002				selectee.selected = false;
5003				that._addClass( selectee.$element, "ui-unselecting" );
5004				selectee.unselecting = true;
5005
5006				// selectable UNSELECTING callback
5007				that._trigger( "unselecting", event, {
5008					unselecting: selectee.element
5009				} );
5010			}
5011		} );
5012
5013		$( event.target ).parents().addBack().each( function() {
5014			var doSelect,
5015				selectee = $.data( this, "selectable-item" );
5016			if ( selectee ) {
5017				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
5018					!selectee.$element.hasClass( "ui-selected" );
5019				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
5020					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
5021				selectee.unselecting = !doSelect;
5022				selectee.selecting = doSelect;
5023				selectee.selected = doSelect;
5024
5025				// selectable (UN)SELECTING callback
5026				if ( doSelect ) {
5027					that._trigger( "selecting", event, {
5028						selecting: selectee.element
5029					} );
5030				} else {
5031					that._trigger( "unselecting", event, {
5032						unselecting: selectee.element
5033					} );
5034				}
5035				return false;
5036			}
5037		} );
5038
5039	},
5040
5041	_mouseDrag: function( event ) {
5042
5043		this.dragged = true;
5044
5045		if ( this.options.disabled ) {
5046			return;
5047		}
5048
5049		var tmp,
5050			that = this,
5051			options = this.options,
5052			x1 = this.opos[ 0 ],
5053			y1 = this.opos[ 1 ],
5054			x2 = event.pageX,
5055			y2 = event.pageY;
5056
5057		if ( x1 > x2 ) {
5058			tmp = x2; x2 = x1; x1 = tmp;
5059		}
5060		if ( y1 > y2 ) {
5061			tmp = y2; y2 = y1; y1 = tmp;
5062		}
5063		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
5064
5065		this.selectees.each( function() {
5066			var selectee = $.data( this, "selectable-item" ),
5067				hit = false,
5068				offset = {};
5069
5070			//prevent helper from being selected if appendTo: selectable
5071			if ( !selectee || selectee.element === that.element[ 0 ] ) {
5072				return;
5073			}
5074
5075			offset.left   = selectee.left   + that.elementPos.left;
5076			offset.right  = selectee.right  + that.elementPos.left;
5077			offset.top    = selectee.top    + that.elementPos.top;
5078			offset.bottom = selectee.bottom + that.elementPos.top;
5079
5080			if ( options.tolerance === "touch" ) {
5081				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
5082                    offset.bottom < y1 ) );
5083			} else if ( options.tolerance === "fit" ) {
5084				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
5085                    offset.bottom < y2 );
5086			}
5087
5088			if ( hit ) {
5089
5090				// SELECT
5091				if ( selectee.selected ) {
5092					that._removeClass( selectee.$element, "ui-selected" );
5093					selectee.selected = false;
5094				}
5095				if ( selectee.unselecting ) {
5096					that._removeClass( selectee.$element, "ui-unselecting" );
5097					selectee.unselecting = false;
5098				}
5099				if ( !selectee.selecting ) {
5100					that._addClass( selectee.$element, "ui-selecting" );
5101					selectee.selecting = true;
5102
5103					// selectable SELECTING callback
5104					that._trigger( "selecting", event, {
5105						selecting: selectee.element
5106					} );
5107				}
5108			} else {
5109
5110				// UNSELECT
5111				if ( selectee.selecting ) {
5112					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
5113						that._removeClass( selectee.$element, "ui-selecting" );
5114						selectee.selecting = false;
5115						that._addClass( selectee.$element, "ui-selected" );
5116						selectee.selected = true;
5117					} else {
5118						that._removeClass( selectee.$element, "ui-selecting" );
5119						selectee.selecting = false;
5120						if ( selectee.startselected ) {
5121							that._addClass( selectee.$element, "ui-unselecting" );
5122							selectee.unselecting = true;
5123						}
5124
5125						// selectable UNSELECTING callback
5126						that._trigger( "unselecting", event, {
5127							unselecting: selectee.element
5128						} );
5129					}
5130				}
5131				if ( selectee.selected ) {
5132					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
5133						that._removeClass( selectee.$element, "ui-selected" );
5134						selectee.selected = false;
5135
5136						that._addClass( selectee.$element, "ui-unselecting" );
5137						selectee.unselecting = true;
5138
5139						// selectable UNSELECTING callback
5140						that._trigger( "unselecting", event, {
5141							unselecting: selectee.element
5142						} );
5143					}
5144				}
5145			}
5146		} );
5147
5148		return false;
5149	},
5150
5151	_mouseStop: function( event ) {
5152		var that = this;
5153
5154		this.dragged = false;
5155
5156		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
5157			var selectee = $.data( this, "selectable-item" );
5158			that._removeClass( selectee.$element, "ui-unselecting" );
5159			selectee.unselecting = false;
5160			selectee.startselected = false;
5161			that._trigger( "unselected", event, {
5162				unselected: selectee.element
5163			} );
5164		} );
5165		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
5166			var selectee = $.data( this, "selectable-item" );
5167			that._removeClass( selectee.$element, "ui-selecting" )
5168				._addClass( selectee.$element, "ui-selected" );
5169			selectee.selecting = false;
5170			selectee.selected = true;
5171			selectee.startselected = true;
5172			that._trigger( "selected", event, {
5173				selected: selectee.element
5174			} );
5175		} );
5176		this._trigger( "stop", event );
5177
5178		this.helper.remove();
5179
5180		return false;
5181	}
5182
5183} );
5184
5185
5186/*!
5187 * jQuery UI Sortable 1.14.2
5188 * https://jqueryui.com
5189 *
5190 * Copyright OpenJS Foundation and other contributors
5191 * Released under the MIT license.
5192 * https://jquery.org/license
5193 */
5194
5195//>>label: Sortable
5196//>>group: Interactions
5197//>>description: Enables items in a list to be sorted using the mouse.
5198//>>docs: https://api.jqueryui.com/sortable/
5199//>>demos: https://jqueryui.com/sortable/
5200//>>css.structure: ../../themes/base/sortable.css
5201
5202
5203var widgetsSortable =
vendor: 12,373 bytes, lines 5203-5662
5203 $.widget( "ui.sortable", $.ui.mouse, {
5204	version: "1.14.2",
5205	widgetEventPrefix: "sort",
5206	ready: false,
5207	options: {
5208		appendTo: "parent",
5209		axis: false,
5210		connectWith: false,
5211		containment: false,
5212		cursor: "auto",
5213		cursorAt: false,
5214		dropOnEmpty: true,
5215		forcePlaceholderSize: false,
5216		forceHelperSize: false,
5217		grid: false,
5218		handle: false,
5219		helper: "original",
5220		items: "> *",
5221		opacity: false,
5222		placeholder: false,
5223		revert: false,
5224		scroll: true,
5225		scrollSensitivity: 20,
5226		scrollSpeed: 20,
5227		scope: "default",
5228		tolerance: "intersect",
5229		zIndex: 1000,
5230
5231		// Callbacks
5232		activate: null,
5233		beforeStop: null,
5234		change: null,
5235		deactivate: null,
5236		out: null,
5237		over: null,
5238		receive: null,
5239		remove: null,
5240		sort: null,
5241		start: null,
5242		stop: null,
5243		update: null
5244	},
5245
5246	_isOverAxis: function( x, reference, size ) {
5247		return ( x >= reference ) && ( x < ( reference + size ) );
5248	},
5249
5250	_isFloating: function( item ) {
5251		return ( /left|right/ ).test( item.css( "float" ) ) ||
5252			( /inline|table-cell/ ).test( item.css( "display" ) );
5253	},
5254
5255	_create: function() {
5256		this.containerCache = {};
5257		this._addClass( "ui-sortable" );
5258
5259		//Get the items
5260		this.refresh();
5261
5262		//Let's determine the parent's offset
5263		this.offset = this.element.offset();
5264
5265		//Initialize mouse events for interaction
5266		this._mouseInit();
5267
5268		this._setHandleClassName();
5269
5270		//We're ready to go
5271		this.ready = true;
5272
5273	},
5274
5275	_setOption: function( key, value ) {
5276		this._super( key, value );
5277
5278		if ( key === "handle" ) {
5279			this._setHandleClassName();
5280		}
5281	},
5282
5283	_setHandleClassName: function() {
5284		var that = this;
5285		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
5286		$.each( this.items, function() {
5287			that._addClass(
5288				this.instance.options.handle ?
5289					this.item.find( this.instance.options.handle ) :
5290					this.item,
5291				"ui-sortable-handle"
5292			);
5293		} );
5294	},
5295
5296	_destroy: function() {
5297		this._mouseDestroy();
5298
5299		for ( var i = this.items.length - 1; i >= 0; i-- ) {
5300			this.items[ i ].item.removeData( this.widgetName + "-item" );
5301		}
5302
5303		return this;
5304	},
5305
5306	_mouseCapture: function( event, overrideHandle ) {
5307		var currentItem = null,
5308			validHandle = false,
5309			that = this;
5310
5311		if ( this.reverting ) {
5312			return false;
5313		}
5314
5315		if ( this.options.disabled || this.options.type === "static" ) {
5316			return false;
5317		}
5318
5319		//We have to refresh the items data once first
5320		this._refreshItems( event );
5321
5322		//Find out if the clicked node (or one of its parents) is a actual item in this.items
5323		$( event.target ).parents().each( function() {
5324			if ( $.data( this, that.widgetName + "-item" ) === that ) {
5325				currentItem = $( this );
5326				return false;
5327			}
5328		} );
5329		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
5330			currentItem = $( event.target );
5331		}
5332
5333		if ( !currentItem ) {
5334			return false;
5335		}
5336		if ( this.options.handle && !overrideHandle ) {
5337			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
5338				if ( this === event.target ) {
5339					validHandle = true;
5340				}
5341			} );
5342			if ( !validHandle ) {
5343				return false;
5344			}
5345		}
5346
5347		this.currentItem = currentItem;
5348		this._removeCurrentsFromItems();
5349		return true;
5350
5351	},
5352
5353	_mouseStart: function( event, overrideHandle, noActivation ) {
5354
5355		var i, body,
5356			o = this.options;
5357
5358		this.currentContainer = this;
5359
5360		//We only need to call refreshPositions, because the refreshItems call has been moved to
5361		// mouseCapture
5362		this.refreshPositions();
5363
5364		//Prepare the dragged items parent
5365		this.appendTo = $( o.appendTo !== "parent" ?
5366				o.appendTo :
5367				this.currentItem.parent() );
5368
5369		//Create and append the visible helper
5370		this.helper = this._createHelper( event );
5371
5372		//Cache the helper size
5373		this._cacheHelperProportions();
5374
5375		/*
5376		 * - Position generation -
5377		 * This block generates everything position related - it's the core of draggables.
5378		 */
5379
5380		//Cache the margins of the original element
5381		this._cacheMargins();
5382
5383		//The element's absolute position on the page minus margins
5384		this.offset = this.currentItem.offset();
5385		this.offset = {
5386			top: this.offset.top - this.margins.top,
5387			left: this.offset.left - this.margins.left
5388		};
5389
5390		$.extend( this.offset, {
5391			click: { //Where the click happened, relative to the element
5392				left: event.pageX - this.offset.left,
5393				top: event.pageY - this.offset.top
5394			},
5395
5396			// This is a relative to absolute position minus the actual position calculation -
5397			// only used for relative positioned helper
5398			relative: this._getRelativeOffset()
5399		} );
5400
5401		// After we get the helper offset, but before we get the parent offset we can
5402		// change the helper's position to absolute
5403		// TODO: Still need to figure out a way to make relative sorting possible
5404		this.helper.css( "position", "absolute" );
5405		this.cssPosition = this.helper.css( "position" );
5406
5407		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
5408		if ( o.cursorAt ) {
5409			this._adjustOffsetFromHelper( o.cursorAt );
5410		}
5411
5412		//Cache the former DOM position
5413		this.domPosition = {
5414			prev: this.currentItem.prev()[ 0 ],
5415			parent: this.currentItem.parent()[ 0 ]
5416		};
5417
5418		// If the helper is not the original, hide the original so it's not playing any role during
5419		// the drag, won't cause anything bad this way
5420		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5421			this.currentItem.hide();
5422		}
5423
5424		//Create the placeholder
5425		this._createPlaceholder();
5426
5427		//Get the next scrolling parent
5428		this.scrollParent = this.placeholder.scrollParent();
5429
5430		$.extend( this.offset, {
5431			parent: this._getParentOffset()
5432		} );
5433
5434		//Set a containment if given in the options
5435		if ( o.containment ) {
5436			this._setContainment();
5437		}
5438
5439		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
5440			body = this.document.find( "body" );
5441
5442			this._storedStylesheet =
5443				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
5444		}
5445
5446		// We need to make sure to grab the zIndex before setting the
5447		// opacity, because setting the opacity to anything lower than 1
5448		// causes the zIndex to change from "auto" to 0.
5449		if ( o.zIndex ) { // zIndex option
5450			if ( this.helper.css( "zIndex" ) ) {
5451				this._storedZIndex = this.helper.css( "zIndex" );
5452			}
5453			this.helper.css( "zIndex", o.zIndex );
5454		}
5455
5456		if ( o.opacity ) { // opacity option
5457			if ( this.helper.css( "opacity" ) ) {
5458				this._storedOpacity = this.helper.css( "opacity" );
5459			}
5460			this.helper.css( "opacity", o.opacity );
5461		}
5462
5463		//Prepare scrolling
5464		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5465				this.scrollParent[ 0 ].tagName !== "HTML" ) {
5466			this.overflowOffset = this.scrollParent.offset();
5467		}
5468
5469		//Call callbacks
5470		this._trigger( "start", event, this._uiHash() );
5471
5472		//Recache the helper size
5473		if ( !this._preserveHelperProportions ) {
5474			this._cacheHelperProportions();
5475		}
5476
5477		//Post "activate" events to possible containers
5478		if ( !noActivation ) {
5479			for ( i = this.containers.length - 1; i >= 0; i-- ) {
5480				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
5481			}
5482		}
5483
5484		//Prepare possible droppables
5485		if ( $.ui.ddmanager ) {
5486			$.ui.ddmanager.current = this;
5487		}
5488
5489		if ( $.ui.ddmanager && !o.dropBehaviour ) {
5490			$.ui.ddmanager.prepareOffsets( this, event );
5491		}
5492
5493		this.dragging = true;
5494
5495		this._addClass( this.helper, "ui-sortable-helper" );
5496
5497		//Move the helper, if needed
5498		if ( !this.helper.parent().is( this.appendTo ) ) {
5499			this.helper.detach().appendTo( this.appendTo );
5500
5501			//Update position
5502			this.offset.parent = this._getParentOffset();
5503		}
5504
5505		//Generate the original position
5506		this.position = this.originalPosition = this._generatePosition( event );
5507		this.originalPageX = event.pageX;
5508		this.originalPageY = event.pageY;
5509		this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" );
5510
5511		this._mouseDrag( event );
5512
5513		return true;
5514
5515	},
5516
5517	_scroll: function( event ) {
5518		var o = this.options,
5519			scrolled = false;
5520
5521		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5522				this.scrollParent[ 0 ].tagName !== "HTML" ) {
5523
5524			if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
5525					event.pageY < o.scrollSensitivity ) {
5526				this.scrollParent[ 0 ].scrollTop =
5527					scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
5528			} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
5529				this.scrollParent[ 0 ].scrollTop =
5530					scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
5531			}
5532
5533			if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
5534					event.pageX < o.scrollSensitivity ) {
5535				this.scrollParent[ 0 ].scrollLeft = scrolled =
5536					this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
5537			} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
5538				this.scrollParent[ 0 ].scrollLeft = scrolled =
5539					this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
5540			}
5541
5542		} else {
5543
5544			if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
5545				scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
5546			} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
5547					o.scrollSensitivity ) {
5548				scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
5549			}
5550
5551			if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
5552				scrolled = this.document.scrollLeft(
5553					this.document.scrollLeft() - o.scrollSpeed
5554				);
5555			} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
5556					o.scrollSensitivity ) {
5557				scrolled = this.document.scrollLeft(
5558					this.document.scrollLeft() + o.scrollSpeed
5559				);
5560			}
5561
5562		}
5563
5564		return scrolled;
5565	},
5566
5567	_mouseDrag: function( event ) {
5568		var i, item, itemElement, intersection,
5569			o = this.options;
5570
5571		//Compute the helpers position
5572		this.position = this._generatePosition( event );
5573		this.positionAbs = this._convertPositionTo( "absolute" );
5574
5575		//Set the helper position
5576		if ( !this.options.axis || this.options.axis !== "y" ) {
5577			this.helper[ 0 ].style.left = this.position.left + "px";
5578		}
5579		if ( !this.options.axis || this.options.axis !== "x" ) {
5580			this.helper[ 0 ].style.top = this.position.top + "px";
5581		}
5582
5583		//Do scrolling
5584		if ( o.scroll ) {
5585			if ( this._scroll( event ) !== false ) {
5586
5587				//Update item positions used in position checks
5588				this._refreshItemPositions( true );
5589
5590				if ( $.ui.ddmanager && !o.dropBehaviour ) {
5591					$.ui.ddmanager.prepareOffsets( this, event );
5592				}
5593			}
5594		}
5595
5596		this.dragDirection = {
5597			vertical: this._getDragVerticalDirection(),
5598			horizontal: this._getDragHorizontalDirection()
5599		};
5600
5601		//Rearrange
5602		for ( i = this.items.length - 1; i >= 0; i-- ) {
5603
5604			//Cache variables and intersection, continue if no intersection
5605			item = this.items[ i ];
5606			itemElement = item.item[ 0 ];
5607			intersection = this._intersectsWithPointer( item );
5608			if ( !intersection ) {
5609				continue;
5610			}
5611
5612			// Only put the placeholder inside the current Container, skip all
5613			// items from other containers. This works because when moving
5614			// an item from one container to another the
5615			// currentContainer is switched before the placeholder is moved.
5616			//
5617			// Without this, moving items in "sub-sortables" can cause
5618			// the placeholder to jitter between the outer and inner container.
5619			if ( item.instance !== this.currentContainer ) {
5620				continue;
5621			}
5622
5623			// Cannot intersect with itself
5624			// no useless actions that have been done before
5625			// no action if the item moved is the parent of the item checked
5626			if ( itemElement !== this.currentItem[ 0 ] &&
5627				this.placeholder[ intersection === 1 ?
5628				"next" : "prev" ]()[ 0 ] !== itemElement &&
5629				!$.contains( this.placeholder[ 0 ], itemElement ) &&
5630				( this.options.type === "semi-dynamic" ?
5631					!$.contains( this.element[ 0 ], itemElement ) :
5632					true
5633				)
5634			) {
5635
5636				this.direction = intersection === 1 ? "down" : "up";
5637
5638				if ( this.options.tolerance === "pointer" ||
5639						this._intersectsWithSides( item ) ) {
5640					this._rearrange( event, item );
5641				} else {
5642					break;
5643				}
5644
5645				this._trigger( "change", event, this._uiHash() );
5646				break;
5647			}
5648		}
5649
5650		//Post events to containers
5651		this._contactContainers( event );
5652
5653		//Interconnect with droppables
5654		if ( $.ui.ddmanager ) {
5655			$.ui.ddmanager.drag( this, event );
5656		}
5657
5658		//Call callbacks
5659		this._trigger( "sort", event, this._uiHash() );
5660
5661		this.lastPositionAbs = this.positionAbs;
5662		return false;
vendor: 5,063 bytes, lines 5663-5852
5663
5664	},
5665
5666	_mouseStop: function( event, noPropagation ) {
5667
5668		if ( !event ) {
5669			return;
5670		}
5671
5672		//If we are using droppables, inform the manager about the drop
5673		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
5674			$.ui.ddmanager.drop( this, event );
5675		}
5676
5677		if ( this.options.revert ) {
5678			var that = this,
5679				cur = this.placeholder.offset(),
5680				axis = this.options.axis,
5681				animation = {};
5682
5683			if ( !axis || axis === "x" ) {
5684				animation.left = cur.left - this.offset.parent.left - this.margins.left +
5685					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
5686						0 :
5687						this.offsetParent[ 0 ].scrollLeft
5688					);
5689			}
5690			if ( !axis || axis === "y" ) {
5691				animation.top = cur.top - this.offset.parent.top - this.margins.top +
5692					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
5693						0 :
5694						this.offsetParent[ 0 ].scrollTop
5695					);
5696			}
5697			this.reverting = true;
5698			$( this.helper ).animate(
5699				animation,
5700				parseInt( this.options.revert, 10 ) || 500,
5701				function() {
5702					that._clear( event );
5703				}
5704			);
5705		} else {
5706			this._clear( event, noPropagation );
5707		}
5708
5709		return false;
5710
5711	},
5712
5713	cancel: function() {
5714
5715		if ( this.dragging ) {
5716
5717			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
5718
5719			if ( this.options.helper === "original" ) {
5720				this.currentItem.css( this._storedCSS );
5721				this._removeClass( this.currentItem, "ui-sortable-helper" );
5722			} else {
5723				this.currentItem.show();
5724			}
5725
5726			//Post deactivating events to containers
5727			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
5728				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
5729				if ( this.containers[ i ].containerCache.over ) {
5730					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
5731					this.containers[ i ].containerCache.over = 0;
5732				}
5733			}
5734
5735		}
5736
5737		if ( this.placeholder ) {
5738
5739			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
5740			// it unbinds ALL events from the original node!
5741			if ( this.placeholder[ 0 ].parentNode ) {
5742				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
5743			}
5744			if ( this.options.helper !== "original" && this.helper &&
5745					this.helper[ 0 ].parentNode ) {
5746				this.helper.remove();
5747			}
5748
5749			$.extend( this, {
5750				helper: null,
5751				dragging: false,
5752				reverting: false,
5753				_noFinalSort: null
5754			} );
5755
5756			if ( this.domPosition.prev ) {
5757				$( this.domPosition.prev ).after( this.currentItem );
5758			} else {
5759				$( this.domPosition.parent ).prepend( this.currentItem );
5760			}
5761		}
5762
5763		return this;
5764
5765	},
5766
5767	serialize: function( o ) {
5768
5769		var items = this._getItemsAsjQuery( o && o.connected ),
5770			str = [];
5771		o = o || {};
5772
5773		$( items ).each( function() {
5774			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
5775				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
5776			if ( res ) {
5777				str.push(
5778					( o.key || res[ 1 ] + "[]" ) +
5779					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
5780			}
5781		} );
5782
5783		if ( !str.length && o.key ) {
5784			str.push( o.key + "=" );
5785		}
5786
5787		return str.join( "&" );
5788
5789	},
5790
5791	toArray: function( o ) {
5792
5793		var items = this._getItemsAsjQuery( o && o.connected ),
5794			ret = [];
5795
5796		o = o || {};
5797
5798		items.each( function() {
5799			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
5800		} );
5801		return ret;
5802
5803	},
5804
5805	/* Be careful with the following core functions */
5806	_intersectsWith: function( item ) {
5807
5808		var x1 = this.positionAbs.left,
5809			x2 = x1 + this.helperProportions.width,
5810			y1 = this.positionAbs.top,
5811			y2 = y1 + this.helperProportions.height,
5812			l = item.left,
5813			r = l + item.width,
5814			t = item.top,
5815			b = t + item.height,
5816			dyClick = this.offset.click.top,
5817			dxClick = this.offset.click.left,
5818			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
5819				( y1 + dyClick ) < b ),
5820			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
5821				( x1 + dxClick ) < r ),
5822			isOverElement = isOverElementHeight && isOverElementWidth;
5823
5824		if ( this.options.tolerance === "pointer" ||
5825			this.options.forcePointerForContainers ||
5826			( this.options.tolerance !== "pointer" &&
5827				this.helperProportions[ this.floating ? "width" : "height" ] >
5828				item[ this.floating ? "width" : "height" ] )
5829		) {
5830			return isOverElement;
5831		} else {
5832
5833			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
5834				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
5835				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
5836				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
5837
5838		}
5839	},
5840
5841	_intersectsWithPointer: function( item ) {
5842		var verticalDirection, horizontalDirection,
5843			isOverElementHeight = ( this.options.axis === "x" ) ||
5844				this._isOverAxis(
5845					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
5846			isOverElementWidth = ( this.options.axis === "y" ) ||
5847				this._isOverAxis(
5848					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
5849			isOverElement = isOverElementHeight && isOverElementWidth;
5850
5851		if ( !isOverElement ) {
5852			return false;
vendor: 18,528 bytes, lines 5853-6433
5853		}
5854
5855		verticalDirection = this.dragDirection.vertical;
5856		horizontalDirection = this.dragDirection.horizontal;
5857
5858		return this.floating ?
5859			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) :
5860			( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
5861
5862	},
5863
5864	_intersectsWithSides: function( item ) {
5865
5866		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
5867				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
5868			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
5869				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
5870			verticalDirection = this.dragDirection.vertical,
5871			horizontalDirection = this.dragDirection.horizontal;
5872
5873		if ( this.floating && horizontalDirection ) {
5874			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
5875				( horizontalDirection === "left" && !isOverRightHalf ) );
5876		} else {
5877			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
5878				( verticalDirection === "up" && !isOverBottomHalf ) );
5879		}
5880
5881	},
5882
5883	_getDragVerticalDirection: function() {
5884		var delta = this.positionAbs.top - this.lastPositionAbs.top;
5885		return delta !== 0 && ( delta > 0 ? "down" : "up" );
5886	},
5887
5888	_getDragHorizontalDirection: function() {
5889		var delta = this.positionAbs.left - this.lastPositionAbs.left;
5890		return delta !== 0 && ( delta > 0 ? "right" : "left" );
5891	},
5892
5893	refresh: function( event ) {
5894		this._refreshItems( event );
5895		this._setHandleClassName();
5896		this.refreshPositions();
5897		return this;
5898	},
5899
5900	_connectWith: function() {
5901		var options = this.options;
5902		return options.connectWith.constructor === String ?
5903			[ options.connectWith ] :
5904			options.connectWith;
5905	},
5906
5907	_getItemsAsjQuery: function( connected ) {
5908
5909		var i, j, cur, inst,
5910			items = [],
5911			queries = [],
5912			connectWith = this._connectWith();
5913
5914		if ( connectWith && connected ) {
5915			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5916				cur = $( connectWith[ i ], this.document[ 0 ] );
5917				for ( j = cur.length - 1; j >= 0; j-- ) {
5918					inst = $.data( cur[ j ], this.widgetFullName );
5919					if ( inst && inst !== this && !inst.options.disabled ) {
5920						queries.push( [ typeof inst.options.items === "function" ?
5921							inst.options.items.call( inst.element ) :
5922							$( inst.options.items, inst.element )
5923								.not( ".ui-sortable-helper" )
5924								.not( ".ui-sortable-placeholder" ), inst ] );
5925					}
5926				}
5927			}
5928		}
5929
5930		queries.push( [ typeof this.options.items === "function" ?
5931			this.options.items
5932				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
5933			$( this.options.items, this.element )
5934				.not( ".ui-sortable-helper" )
5935				.not( ".ui-sortable-placeholder" ), this ] );
5936
5937		function addItems() {
5938			items.push( this );
5939		}
5940		for ( i = queries.length - 1; i >= 0; i-- ) {
5941			queries[ i ][ 0 ].each( addItems );
5942		}
5943
5944		return $( items );
5945
5946	},
5947
5948	_removeCurrentsFromItems: function() {
5949
5950		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
5951
5952		this.items = $.grep( this.items, function( item ) {
5953			for ( var j = 0; j < list.length; j++ ) {
5954				if ( list[ j ] === item.item[ 0 ] ) {
5955					return false;
5956				}
5957			}
5958			return true;
5959		} );
5960
5961	},
5962
5963	_refreshItems: function( event ) {
5964
5965		this.items = [];
5966		this.containers = [ this ];
5967
5968		var i, j, cur, inst, targetData, _queries, item, queriesLength,
5969			items = this.items,
5970			queries = [ [ typeof this.options.items === "function" ?
5971				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
5972				$( this.options.items, this.element ), this ] ],
5973			connectWith = this._connectWith();
5974
5975		//Shouldn't be run the first time through due to massive slow-down
5976		if ( connectWith && this.ready ) {
5977			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5978				cur = $( connectWith[ i ], this.document[ 0 ] );
5979				for ( j = cur.length - 1; j >= 0; j-- ) {
5980					inst = $.data( cur[ j ], this.widgetFullName );
5981					if ( inst && inst !== this && !inst.options.disabled ) {
5982						queries.push( [ typeof inst.options.items === "function" ?
5983							inst.options.items
5984								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
5985							$( inst.options.items, inst.element ), inst ] );
5986						this.containers.push( inst );
5987					}
5988				}
5989			}
5990		}
5991
5992		for ( i = queries.length - 1; i >= 0; i-- ) {
5993			targetData = queries[ i ][ 1 ];
5994			_queries = queries[ i ][ 0 ];
5995
5996			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
5997				item = $( _queries[ j ] );
5998
5999				// Data for target checking (mouse manager)
6000				item.data( this.widgetName + "-item", targetData );
6001
6002				items.push( {
6003					item: item,
6004					instance: targetData,
6005					width: 0, height: 0,
6006					left: 0, top: 0
6007				} );
6008			}
6009		}
6010
6011	},
6012
6013	_refreshItemPositions: function( fast ) {
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 ( this.currentContainer && item.instance !== 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
6040	refreshPositions: function( fast ) {
6041
6042		// Determine whether items are being displayed horizontally
6043		this.floating = this.items.length ?
6044			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
6045			false;
6046
6047		// This has to be redone because due to the item being moved out/into the offsetParent,
6048		// the offsetParent's position will change
6049		if ( this.offsetParent && this.helper ) {
6050			this.offset.parent = this._getParentOffset();
6051		}
6052
6053		this._refreshItemPositions( fast );
6054
6055		var i, p;
6056
6057		if ( this.options.custom && this.options.custom.refreshContainers ) {
6058			this.options.custom.refreshContainers.call( this );
6059		} else {
6060			for ( i = this.containers.length - 1; i >= 0; i-- ) {
6061				p = this.containers[ i ].element.offset();
6062				this.containers[ i ].containerCache.left = p.left;
6063				this.containers[ i ].containerCache.top = p.top;
6064				this.containers[ i ].containerCache.width =
6065					this.containers[ i ].element.outerWidth();
6066				this.containers[ i ].containerCache.height =
6067					this.containers[ i ].element.outerHeight();
6068			}
6069		}
6070
6071		return this;
6072	},
6073
6074	_createPlaceholder: function( that ) {
6075		that = that || this;
6076		var className, nodeName,
6077			o = that.options;
6078
6079		if ( !o.placeholder || o.placeholder.constructor === String ) {
6080			className = o.placeholder;
6081			nodeName = that.currentItem[ 0 ].nodeName.toLowerCase();
6082			o.placeholder = {
6083				element: function() {
6084
6085					var element = $( "<" + nodeName + ">", that.document[ 0 ] );
6086
6087					that._addClass( element, "ui-sortable-placeholder",
6088							className || that.currentItem[ 0 ].className )
6089						._removeClass( element, "ui-sortable-helper" );
6090
6091					if ( nodeName === "tbody" ) {
6092						that._createTrPlaceholder(
6093							that.currentItem.find( "tr" ).eq( 0 ),
6094							$( "<tr>", that.document[ 0 ] ).appendTo( element )
6095						);
6096					} else if ( nodeName === "tr" ) {
6097						that._createTrPlaceholder( that.currentItem, element );
6098					} else if ( nodeName === "img" ) {
6099						element.attr( "src", that.currentItem.attr( "src" ) );
6100					}
6101
6102					if ( !className ) {
6103						element.css( "visibility", "hidden" );
6104					}
6105
6106					return element;
6107				},
6108				update: function( container, p ) {
6109
6110					// 1. If a className is set as 'placeholder option, we don't force sizes -
6111					// the class is responsible for that
6112					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
6113					// class name is specified
6114					if ( className && !o.forcePlaceholderSize ) {
6115						return;
6116					}
6117
6118					// If the element doesn't have a actual height or width by itself (without
6119					// styles coming from a stylesheet), it receives the inline height and width
6120					// from the dragged item. Or, if it's a tbody or tr, it's going to have a height
6121					// anyway since we're populating them with <td>s above, but they're unlikely to
6122					// be the correct height on their own if the row heights are dynamic, so we'll
6123					// always assign the height of the dragged item given forcePlaceholderSize
6124					// is true.
6125					if ( !p.height() || ( o.forcePlaceholderSize &&
6126							( nodeName === "tbody" || nodeName === "tr" ) ) ) {
6127						p.height(
6128							that.currentItem.innerHeight() -
6129							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
6130							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
6131					}
6132					if ( !p.width() ) {
6133						p.width(
6134							that.currentItem.innerWidth() -
6135							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
6136							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
6137					}
6138				}
6139			};
6140		}
6141
6142		//Create the placeholder
6143		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
6144
6145		//Append it after the actual current item
6146		that.currentItem.after( that.placeholder );
6147
6148		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
6149		o.placeholder.update( that, that.placeholder );
6150
6151	},
6152
6153	_createTrPlaceholder: function( sourceTr, targetTr ) {
6154		var that = this;
6155
6156		sourceTr.children().each( function() {
6157			$( "<td>&#160;</td>", that.document[ 0 ] )
6158				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
6159				.appendTo( targetTr );
6160		} );
6161	},
6162
6163	_contactContainers: function( event ) {
6164		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
6165			floating, axis,
6166			innermostContainer = null,
6167			innermostIndex = null;
6168
6169		// Get innermost container that intersects with item
6170		for ( i = this.containers.length - 1; i >= 0; i-- ) {
6171
6172			// Never consider a container that's located within the item itself
6173			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
6174				continue;
6175			}
6176
6177			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
6178
6179				// If we've already found a container and it's more "inner" than this, then continue
6180				if ( innermostContainer &&
6181						$.contains(
6182							this.containers[ i ].element[ 0 ],
6183							innermostContainer.element[ 0 ] ) ) {
6184					continue;
6185				}
6186
6187				innermostContainer = this.containers[ i ];
6188				innermostIndex = i;
6189
6190			} else {
6191
6192				// container doesn't intersect. trigger "out" event if necessary
6193				if ( this.containers[ i ].containerCache.over ) {
6194					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
6195					this.containers[ i ].containerCache.over = 0;
6196				}
6197			}
6198
6199		}
6200
6201		// If no intersecting containers found, return
6202		if ( !innermostContainer ) {
6203			return;
6204		}
6205
6206		// Move the item into the container if it's not there already
6207		if ( this.containers.length === 1 ) {
6208			if ( !this.containers[ innermostIndex ].containerCache.over ) {
6209				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
6210				this.containers[ innermostIndex ].containerCache.over = 1;
6211			}
6212		} else {
6213
6214			// When entering a new container, we will find the item with the least distance and
6215			// append our item near it
6216			dist = 10000;
6217			itemWithLeastDistance = null;
6218			floating = innermostContainer.floating || this._isFloating( this.currentItem );
6219			posProperty = floating ? "left" : "top";
6220			sizeProperty = floating ? "width" : "height";
6221			axis = floating ? "pageX" : "pageY";
6222
6223			for ( j = this.items.length - 1; j >= 0; j-- ) {
6224				if ( !$.contains(
6225						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
6226				) {
6227					continue;
6228				}
6229				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
6230					continue;
6231				}
6232
6233				cur = this.items[ j ].item.offset()[ posProperty ];
6234				nearBottom = false;
6235				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
6236					nearBottom = true;
6237				}
6238
6239				if ( Math.abs( event[ axis ] - cur ) < dist ) {
6240					dist = Math.abs( event[ axis ] - cur );
6241					itemWithLeastDistance = this.items[ j ];
6242					this.direction = nearBottom ? "up" : "down";
6243				}
6244			}
6245
6246			//Check if dropOnEmpty is enabled
6247			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
6248				return;
6249			}
6250
6251			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
6252				if ( !this.currentContainer.containerCache.over ) {
6253					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
6254					this.currentContainer.containerCache.over = 1;
6255				}
6256				return;
6257			}
6258
6259			if ( itemWithLeastDistance ) {
6260				this._rearrange( event, itemWithLeastDistance, null, true );
6261			} else {
6262				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
6263			}
6264			this._trigger( "change", event, this._uiHash() );
6265			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
6266			this.currentContainer = this.containers[ innermostIndex ];
6267
6268			//Update the placeholder
6269			this.options.placeholder.update( this.currentContainer, this.placeholder );
6270
6271			//Update scrollParent
6272			this.scrollParent = this.placeholder.scrollParent();
6273
6274			//Update overflowOffset
6275			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6276					this.scrollParent[ 0 ].tagName !== "HTML" ) {
6277				this.overflowOffset = this.scrollParent.offset();
6278			}
6279
6280			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
6281			this.containers[ innermostIndex ].containerCache.over = 1;
6282		}
6283
6284	},
6285
6286	_createHelper: function( event ) {
6287
6288		var o = this.options,
6289			helper = typeof o.helper === "function" ?
6290				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
6291				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
6292
6293		//Add the helper to the DOM if that didn't happen already
6294		if ( !helper.parents( "body" ).length ) {
6295			this.appendTo[ 0 ].appendChild( helper[ 0 ] );
6296		}
6297
6298		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
6299			this._storedCSS = {
6300				width: this.currentItem[ 0 ].style.width,
6301				height: this.currentItem[ 0 ].style.height,
6302				position: this.currentItem.css( "position" ),
6303				top: this.currentItem.css( "top" ),
6304				left: this.currentItem.css( "left" )
6305			};
6306		}
6307
6308		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
6309			helper.width( this.currentItem.width() );
6310		}
6311		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
6312			helper.height( this.currentItem.height() );
6313		}
6314
6315		return helper;
6316
6317	},
6318
6319	_adjustOffsetFromHelper: function( obj ) {
6320		if ( typeof obj === "string" ) {
6321			obj = obj.split( " " );
6322		}
6323		if ( Array.isArray( obj ) ) {
6324			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
6325		}
6326		if ( "left" in obj ) {
6327			this.offset.click.left = obj.left + this.margins.left;
6328		}
6329		if ( "right" in obj ) {
6330			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6331		}
6332		if ( "top" in obj ) {
6333			this.offset.click.top = obj.top + this.margins.top;
6334		}
6335		if ( "bottom" in obj ) {
6336			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6337		}
6338	},
6339
6340	_getParentOffset: function() {
6341
6342		//Get the offsetParent and cache its position
6343		this.offsetParent = this.helper.offsetParent();
6344		var po = this.offsetParent.offset();
6345
6346		// This is a special case where we need to modify a offset calculated on start, since the
6347		// following happened:
6348		// 1. The position of the helper is absolute, so it's position is calculated based on the
6349		// next positioned parent
6350		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
6351		// the document, which means that the scroll is included in the initial calculation of the
6352		// offset of the parent, and never recalculated upon drag
6353		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6354				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
6355			po.left += this.scrollParent.scrollLeft();
6356			po.top += this.scrollParent.scrollTop();
6357		}
6358
6359		// This needs to be actually done for all browsers, since pageX/pageY includes
6360		// this information.
6361		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ) {
6362			po = { top: 0, left: 0 };
6363		}
6364
6365		return {
6366			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
6367			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
6368		};
6369
6370	},
6371
6372	_getRelativeOffset: function() {
6373
6374		if ( this.cssPosition === "relative" ) {
6375			var p = this.currentItem.position();
6376			return {
6377				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
6378					this.scrollParent.scrollTop(),
6379				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
6380					this.scrollParent.scrollLeft()
6381			};
6382		} else {
6383			return { top: 0, left: 0 };
6384		}
6385
6386	},
6387
6388	_cacheMargins: function() {
6389		this.margins = {
6390			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
6391			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
6392		};
6393	},
6394
6395	_cacheHelperProportions: function() {
6396		this.helperProportions = {
6397			width: this.helper.outerWidth(),
6398			height: this.helper.outerHeight()
6399		};
6400	},
6401
6402	_setContainment: function() {
6403
6404		var ce, co, over,
6405			o = this.options;
6406		if ( o.containment === "parent" ) {
6407			o.containment = this.helper[ 0 ].parentNode;
6408		}
6409		if ( o.containment === "document" || o.containment === "window" ) {
6410			this.containment = [
6411				0 - this.offset.relative.left - this.offset.parent.left,
6412				0 - this.offset.relative.top - this.offset.parent.top,
6413				o.containment === "document" ?
6414					this.document.width() :
6415					this.window.width() - this.helperProportions.width - this.margins.left,
6416				( o.containment === "document" ?
6417					( this.document.height() || document.body.parentNode.scrollHeight ) :
6418					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
6419				) - this.helperProportions.height - this.margins.top
6420			];
6421		}
6422
6423		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
6424			ce = $( o.containment )[ 0 ];
6425			co = $( o.containment ).offset();
6426			over = ( $( ce ).css( "overflow" ) !== "hidden" );
6427
6428			this.containment = [
6429				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
6430					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
6431				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
6432					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
6433				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) 
vendor: 1,747 bytes, lines 6433-6485
6433: ce.offsetWidth ) -
6434					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
6435					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
6436					this.helperProportions.width - this.margins.left,
6437				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6438					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
6439					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
6440					this.helperProportions.height - this.margins.top
6441			];
6442		}
6443
6444	},
6445
6446	_convertPositionTo: function( d, pos ) {
6447
6448		if ( !pos ) {
6449			pos = this.position;
6450		}
6451		var mod = d === "absolute" ? 1 : -1,
6452			scroll = this.cssPosition === "absolute" &&
6453				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6454				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
6455					this.offsetParent :
6456					this.scrollParent,
6457			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
6458
6459		return {
6460			top: (
6461
6462				// The absolute mouse position
6463				pos.top	+
6464
6465				// Only for relative positioned nodes: Relative offset from element to offset parent
6466				this.offset.relative.top * mod +
6467
6468				// The offsetParent's offset without borders (offset + border)
6469				this.offset.parent.top * mod -
6470				( ( this.cssPosition === "fixed" ?
6471					-this.scrollParent.scrollTop() :
6472					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
6473			),
6474			left: (
6475
6476				// The absolute mouse position
6477				pos.left +
6478
6479				// Only for relative positioned nodes: Relative offset from element to offset parent
6480				this.offset.relative.left * mod +
6481
6482				// The offsetParent's offset without borders (offset + border)
6483				this.offset.parent.left * mod	-
6484				( ( this.cssPosition === "fixed" ?
6485					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
vendor: 8,856 bytes, lines 6486-6771
6486					scroll.scrollLeft() ) * mod )
6487			)
6488		};
6489
6490	},
6491
6492	_generatePosition: function( event ) {
6493
6494		var top, left,
6495			o = this.options,
6496			pageX = event.pageX,
6497			pageY = event.pageY,
6498			scroll = this.cssPosition === "absolute" &&
6499				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6500				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
6501					this.offsetParent :
6502					this.scrollParent,
6503				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
6504
6505		// This is another very weird special case that only happens for relative elements:
6506		// 1. If the css position is relative
6507		// 2. and the scroll parent is the document or similar to the offset parent
6508		// we have to refresh the relative offset during the scroll so there are no jumps
6509		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6510				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
6511			this.offset.relative = this._getRelativeOffset();
6512		}
6513
6514		/*
6515		 * - Position constraining -
6516		 * Constrain the position to a mix of grid, containment.
6517		 */
6518
6519		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
6520
6521			if ( this.containment ) {
6522				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
6523					pageX = this.containment[ 0 ] + this.offset.click.left;
6524				}
6525				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
6526					pageY = this.containment[ 1 ] + this.offset.click.top;
6527				}
6528				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
6529					pageX = this.containment[ 2 ] + this.offset.click.left;
6530				}
6531				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
6532					pageY = this.containment[ 3 ] + this.offset.click.top;
6533				}
6534			}
6535
6536			if ( o.grid ) {
6537				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
6538					o.grid[ 1 ] ) * o.grid[ 1 ];
6539				pageY = this.containment ?
6540					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
6541						top - this.offset.click.top <= this.containment[ 3 ] ) ?
6542							top :
6543							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
6544								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
6545								top;
6546
6547				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
6548					o.grid[ 0 ] ) * o.grid[ 0 ];
6549				pageX = this.containment ?
6550					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
6551						left - this.offset.click.left <= this.containment[ 2 ] ) ?
6552							left :
6553							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
6554								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
6555								left;
6556			}
6557
6558		}
6559
6560		return {
6561			top: (
6562
6563				// The absolute mouse position
6564				pageY -
6565
6566				// Click offset (relative to the element)
6567				this.offset.click.top -
6568
6569				// Only for relative positioned nodes: Relative offset from element to offset parent
6570				this.offset.relative.top -
6571
6572				// The offsetParent's offset without borders (offset + border)
6573				this.offset.parent.top +
6574				( ( this.cssPosition === "fixed" ?
6575					-this.scrollParent.scrollTop() :
6576					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
6577			),
6578			left: (
6579
6580				// The absolute mouse position
6581				pageX -
6582
6583				// Click offset (relative to the element)
6584				this.offset.click.left -
6585
6586				// Only for relative positioned nodes: Relative offset from element to offset parent
6587				this.offset.relative.left -
6588
6589				// The offsetParent's offset without borders (offset + border)
6590				this.offset.parent.left +
6591				( ( this.cssPosition === "fixed" ?
6592					-this.scrollParent.scrollLeft() :
6593					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
6594			)
6595		};
6596
6597	},
6598
6599	_rearrange: function( event, i, a, hardRefresh ) {
6600
6601		if ( a ) {
6602			a[ 0 ].appendChild( this.placeholder[ 0 ] );
6603		} else {
6604			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
6605				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
6606		}
6607
6608		//Various things done here to improve the performance:
6609		// 1. we create a setTimeout, that calls refreshPositions
6610		// 2. on the instance, we have a counter variable, that get's higher after every append
6611		// 3. on the local scope, we copy the counter variable, and check in the timeout,
6612		// if it's still the same
6613		// 4. this lets only the last addition to the timeout stack through
6614		this.counter = this.counter ? ++this.counter : 1;
6615		var counter = this.counter;
6616
6617		this._delay( function() {
6618			if ( counter === this.counter ) {
6619
6620				//Precompute after each DOM insertion, NOT on mousemove
6621				this.refreshPositions( !hardRefresh );
6622			}
6623		} );
6624
6625	},
6626
6627	_clear: function( event, noPropagation ) {
6628
6629		this.reverting = false;
6630
6631		// We delay all events that have to be triggered to after the point where the placeholder
6632		// has been removed and everything else normalized again
6633		var i,
6634			delayedTriggers = [];
6635
6636		// We first have to update the dom position of the actual currentItem
6637		// Note: don't do it if the current item is already removed (by a user), or it gets
6638		// reappended (see #4088)
6639		if ( !this._noFinalSort && this.currentItem.parent().length ) {
6640			this.placeholder.before( this.currentItem );
6641		}
6642		this._noFinalSort = null;
6643
6644		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
6645			for ( i in this._storedCSS ) {
6646				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
6647					this._storedCSS[ i ] = "";
6648				}
6649			}
6650			this.currentItem.css( this._storedCSS );
6651			this._removeClass( this.currentItem, "ui-sortable-helper" );
6652		} else {
6653			this.currentItem.show();
6654		}
6655
6656		if ( this.fromOutside && !noPropagation ) {
6657			delayedTriggers.push( function( event ) {
6658				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
6659			} );
6660		}
6661		if ( ( this.fromOutside ||
6662				this.domPosition.prev !==
6663				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
6664				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
6665
6666			// Trigger update callback if the DOM position has changed
6667			delayedTriggers.push( function( event ) {
6668				this._trigger( "update", event, this._uiHash() );
6669			} );
6670		}
6671
6672		// Check if the items Container has Changed and trigger appropriate
6673		// events.
6674		if ( this !== this.currentContainer ) {
6675			if ( !noPropagation ) {
6676				delayedTriggers.push( function( event ) {
6677					this._trigger( "remove", event, this._uiHash() );
6678				} );
6679				delayedTriggers.push( ( function( c ) {
6680					return function( event ) {
6681						c._trigger( "receive", event, this._uiHash( this ) );
6682					};
6683				} ).call( this, this.currentContainer ) );
6684				delayedTriggers.push( ( function( c ) {
6685					return function( event ) {
6686						c._trigger( "update", event, this._uiHash( this ) );
6687					};
6688				} ).call( this, this.currentContainer ) );
6689			}
6690		}
6691
6692		//Post events to containers
6693		function delayEvent( type, instance, container ) {
6694			return function( event ) {
6695				container._trigger( type, event, instance._uiHash( instance ) );
6696			};
6697		}
6698		for ( i = this.containers.length - 1; i >= 0; i-- ) {
6699			if ( !noPropagation ) {
6700				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
6701			}
6702			if ( this.containers[ i ].containerCache.over ) {
6703				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
6704				this.containers[ i ].containerCache.over = 0;
6705			}
6706		}
6707
6708		//Do what was originally in plugins
6709		if ( this._storedStylesheet ) {
6710			this._storedStylesheet.remove();
6711			this._storedStylesheet = null;
6712		}
6713		if ( this._storedOpacity ) {
6714			this.helper.css( "opacity", this._storedOpacity );
6715		}
6716		if ( this._storedZIndex ) {
6717			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
6718		}
6719
6720		this.dragging = false;
6721
6722		if ( !noPropagation ) {
6723			this._trigger( "beforeStop", event, this._uiHash() );
6724		}
6725
6726		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
6727		// it unbinds ALL events from the original node!
6728		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
6729
6730		if ( !this.cancelHelperRemoval ) {
6731			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
6732				this.helper.remove();
6733			}
6734			this.helper = null;
6735		}
6736
6737		if ( !noPropagation ) {
6738			for ( i = 0; i < delayedTriggers.length; i++ ) {
6739
6740				// Trigger all delayed events
6741				delayedTriggers[ i ].call( this, event );
6742			}
6743			this._trigger( "stop", event, this._uiHash() );
6744		}
6745
6746		this.fromOutside = false;
6747		return !this.cancelHelperRemoval;
6748
6749	},
6750
6751	_trigger: function() {
6752		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
6753			this.cancel();
6754		}
6755	},
6756
6757	_uiHash: function( _inst ) {
6758		var inst = _inst || this;
6759		return {
6760			helper: inst.helper,
6761			placeholder: inst.placeholder || $( [] ),
6762			position: inst.position,
6763			originalPosition: inst.originalPosition,
6764			offset: inst.positionAbs,
6765			item: inst.currentItem,
6766			sender: _inst ? _inst.element : null
6767		};
6768	}
6769
6770} );
6771
vendor: 21,760 bytes, lines 6772-7612
6772
6773/*!
6774 * jQuery UI Accordion 1.14.2
6775 * https://jqueryui.com
6776 *
6777 * Copyright OpenJS Foundation and other contributors
6778 * Released under the MIT license.
6779 * https://jquery.org/license
6780 */
6781
6782//>>label: Accordion
6783//>>group: Widgets
6784//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
6785//>>docs: https://api.jqueryui.com/accordion/
6786//>>demos: https://jqueryui.com/accordion/
6787//>>css.structure: ../../themes/base/core.css
6788//>>css.structure: ../../themes/base/accordion.css
6789//>>css.theme: ../../themes/base/theme.css
6790
6791
6792var widgetsAccordion = $.widget( "ui.accordion", {
6793	version: "1.14.2",
6794	options: {
6795		active: 0,
6796		animate: {},
6797		classes: {
6798			"ui-accordion-header": "ui-corner-top",
6799			"ui-accordion-header-collapsed": "ui-corner-all",
6800			"ui-accordion-content": "ui-corner-bottom"
6801		},
6802		collapsible: false,
6803		event: "click",
6804		header: function( elem ) {
6805			return elem
6806				.find( "> li > :first-child" )
6807				.add(
6808					elem.find( "> :not(li)" )
6809
6810						// Support: jQuery <3.5 only
6811						// We could use `.even()` but that's unavailable in older jQuery.
6812						.filter( function( i ) {
6813							return i % 2 === 0;
6814						} )
6815				);
6816		},
6817		heightStyle: "auto",
6818		icons: {
6819			activeHeader: "ui-icon-triangle-1-s",
6820			header: "ui-icon-triangle-1-e"
6821		},
6822
6823		// Callbacks
6824		activate: null,
6825		beforeActivate: null
6826	},
6827
6828	hideProps: {
6829		borderTopWidth: "hide",
6830		borderBottomWidth: "hide",
6831		paddingTop: "hide",
6832		paddingBottom: "hide",
6833		height: "hide"
6834	},
6835
6836	showProps: {
6837		borderTopWidth: "show",
6838		borderBottomWidth: "show",
6839		paddingTop: "show",
6840		paddingBottom: "show",
6841		height: "show"
6842	},
6843
6844	_create: function() {
6845		var options = this.options;
6846
6847		this.prevShow = this.prevHide = $();
6848		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
6849		this.element.attr( "role", "tablist" );
6850
6851		// Don't allow collapsible: false and active: false / null
6852		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
6853			options.active = 0;
6854		}
6855
6856		this._processPanels();
6857
6858		// handle negative values
6859		if ( options.active < 0 ) {
6860			options.active += this.headers.length;
6861		}
6862		this._refresh();
6863	},
6864
6865	_getCreateEventData: function() {
6866		return {
6867			header: this.active,
6868			panel: !this.active.length ? $() : this.active.next()
6869		};
6870	},
6871
6872	_createIcons: function() {
6873		var icon, children,
6874			icons = this.options.icons;
6875
6876		if ( icons ) {
6877			icon = $( "<span>" );
6878			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
6879			icon.prependTo( this.headers );
6880			children = this.active.children( ".ui-accordion-header-icon" );
6881			this._removeClass( children, icons.header )
6882				._addClass( children, null, icons.activeHeader )
6883				._addClass( this.headers, "ui-accordion-icons" );
6884		}
6885	},
6886
6887	_destroyIcons: function() {
6888		this._removeClass( this.headers, "ui-accordion-icons" );
6889		this.headers.children( ".ui-accordion-header-icon" ).remove();
6890	},
6891
6892	_destroy: function() {
6893		var contents;
6894
6895		// Clean up main element
6896		this.element.removeAttr( "role" );
6897
6898		// Clean up headers
6899		this.headers
6900			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
6901			.removeUniqueId();
6902
6903		this._destroyIcons();
6904
6905		// Clean up content panels
6906		contents = this.headers.next()
6907			.css( "display", "" )
6908			.removeAttr( "role aria-hidden aria-labelledby" )
6909			.removeUniqueId();
6910
6911		if ( this.options.heightStyle !== "content" ) {
6912			contents.css( "height", "" );
6913		}
6914	},
6915
6916	_setOption: function( key, value ) {
6917		if ( key === "active" ) {
6918
6919			// _activate() will handle invalid values and update this.options
6920			this._activate( value );
6921			return;
6922		}
6923
6924		if ( key === "event" ) {
6925			if ( this.options.event ) {
6926				this._off( this.headers, this.options.event );
6927			}
6928			this._setupEvents( value );
6929		}
6930
6931		this._super( key, value );
6932
6933		// Setting collapsible: false while collapsed; open first panel
6934		if ( key === "collapsible" && !value && this.options.active === false ) {
6935			this._activate( 0 );
6936		}
6937
6938		if ( key === "icons" ) {
6939			this._destroyIcons();
6940			if ( value ) {
6941				this._createIcons();
6942			}
6943		}
6944	},
6945
6946	_setOptionDisabled: function( value ) {
6947		this._super( value );
6948
6949		this.element.attr( "aria-disabled", value );
6950		this._toggleClass( null, "ui-state-disabled", !!value );
6951	},
6952
6953	_keydown: function( event ) {
6954		if ( event.altKey || event.ctrlKey ) {
6955			return;
6956		}
6957
6958		var keyCode = $.ui.keyCode,
6959			length = this.headers.length,
6960			currentIndex = this.headers.index( event.target ),
6961			toFocus = false;
6962
6963		switch ( event.keyCode ) {
6964		case keyCode.RIGHT:
6965		case keyCode.DOWN:
6966			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6967			break;
6968		case keyCode.LEFT:
6969		case keyCode.UP:
6970			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6971			break;
6972		case keyCode.SPACE:
6973		case keyCode.ENTER:
6974			this._eventHandler( event );
6975			break;
6976		case keyCode.HOME:
6977			toFocus = this.headers[ 0 ];
6978			break;
6979		case keyCode.END:
6980			toFocus = this.headers[ length - 1 ];
6981			break;
6982		}
6983
6984		if ( toFocus ) {
6985			$( event.target ).attr( "tabIndex", -1 );
6986			$( toFocus ).attr( "tabIndex", 0 );
6987			$( toFocus ).trigger( "focus" );
6988			event.preventDefault();
6989		}
6990	},
6991
6992	_panelKeyDown: function( event ) {
6993		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6994			$( event.currentTarget ).prev().trigger( "focus" );
6995		}
6996	},
6997
6998	refresh: function() {
6999		var options = this.options;
7000		this._processPanels();
7001
7002		// Was collapsed or no panel
7003		if ( ( options.active === false && options.collapsible === true ) ||
7004				!this.headers.length ) {
7005			options.active = false;
7006			this.active = $();
7007
7008		// active false only when collapsible is true
7009		} else if ( options.active === false ) {
7010			this._activate( 0 );
7011
7012		// was active, but active panel is gone
7013		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
7014
7015			// all remaining panel are disabled
7016			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
7017				options.active = false;
7018				this.active = $();
7019
7020			// activate previous panel
7021			} else {
7022				this._activate( Math.max( 0, options.active - 1 ) );
7023			}
7024
7025		// was active, active panel still exists
7026		} else {
7027
7028			// make sure active index is correct
7029			options.active = this.headers.index( this.active );
7030		}
7031
7032		this._destroyIcons();
7033
7034		this._refresh();
7035	},
7036
7037	_processPanels: function() {
7038		var prevHeaders = this.headers,
7039			prevPanels = this.panels;
7040
7041		if ( typeof this.options.header === "function" ) {
7042			this.headers = this.options.header( this.element );
7043		} else {
7044			this.headers = this.element.find( this.options.header );
7045		}
7046		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
7047			"ui-state-default" );
7048
7049		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
7050		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
7051
7052		// Avoid memory leaks (#10056)
7053		if ( prevPanels ) {
7054			this._off( prevHeaders.not( this.headers ) );
7055			this._off( prevPanels.not( this.panels ) );
7056		}
7057	},
7058
7059	_refresh: function() {
7060		var maxHeight,
7061			options = this.options,
7062			heightStyle = options.heightStyle,
7063			parent = this.element.parent();
7064
7065		this.active = this._findActive( options.active );
7066		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
7067			._removeClass( this.active, "ui-accordion-header-collapsed" );
7068		this._addClass( this.active.next(), "ui-accordion-content-active" );
7069		this.active.next().show();
7070
7071		this.headers
7072			.attr( "role", "tab" )
7073			.each( function() {
7074				var header = $( this ),
7075					headerId = header.uniqueId().attr( "id" ),
7076					panel = header.next(),
7077					panelId = panel.uniqueId().attr( "id" );
7078				header.attr( "aria-controls", panelId );
7079				panel.attr( "aria-labelledby", headerId );
7080			} )
7081			.next()
7082				.attr( "role", "tabpanel" );
7083
7084		this.headers
7085			.not( this.active )
7086				.attr( {
7087					"aria-selected": "false",
7088					"aria-expanded": "false",
7089					tabIndex: -1
7090				} )
7091				.next()
7092					.attr( {
7093						"aria-hidden": "true"
7094					} )
7095					.hide();
7096
7097		// Make sure at least one header is in the tab order
7098		if ( !this.active.length ) {
7099			this.headers.eq( 0 ).attr( "tabIndex", 0 );
7100		} else {
7101			this.active.attr( {
7102				"aria-selected": "true",
7103				"aria-expanded": "true",
7104				tabIndex: 0
7105			} )
7106				.next()
7107					.attr( {
7108						"aria-hidden": "false"
7109					} );
7110		}
7111
7112		this._createIcons();
7113
7114		this._setupEvents( options.event );
7115
7116		if ( heightStyle === "fill" ) {
7117			maxHeight = parent.height();
7118			this.element.siblings( ":visible" ).each( function() {
7119				var elem = $( this ),
7120					position = elem.css( "position" );
7121
7122				if ( position === "absolute" || position === "fixed" ) {
7123					return;
7124				}
7125				maxHeight -= elem.outerHeight( true );
7126			} );
7127
7128			this.headers.each( function() {
7129				maxHeight -= $( this ).outerHeight( true );
7130			} );
7131
7132			this.headers.next()
7133				.each( function() {
7134					$( this ).height( Math.max( 0, maxHeight -
7135						$( this ).innerHeight() + $( this ).height() ) );
7136				} )
7137				.css( "overflow", "auto" );
7138		} else if ( heightStyle === "auto" ) {
7139			maxHeight = 0;
7140			this.headers.next()
7141				.each( function() {
7142					var isVisible = $( this ).is( ":visible" );
7143					if ( !isVisible ) {
7144						$( this ).show();
7145					}
7146					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
7147					if ( !isVisible ) {
7148						$( this ).hide();
7149					}
7150				} )
7151				.height( maxHeight );
7152		}
7153	},
7154
7155	_activate: function( index ) {
7156		var active = this._findActive( index )[ 0 ];
7157
7158		// Trying to activate the already active panel
7159		if ( active === this.active[ 0 ] ) {
7160			return;
7161		}
7162
7163		// Trying to collapse, simulate a click on the currently active header
7164		active = active || this.active[ 0 ];
7165
7166		this._eventHandler( {
7167			target: active,
7168			currentTarget: active,
7169			preventDefault: $.noop
7170		} );
7171	},
7172
7173	_findActive: function( selector ) {
7174		return typeof selector === "number" ? this.headers.eq( selector ) : $();
7175	},
7176
7177	_setupEvents: function( event ) {
7178		var events = {
7179			keydown: "_keydown"
7180		};
7181		if ( event ) {
7182			$.each( event.split( " " ), function( index, eventName ) {
7183				events[ eventName ] = "_eventHandler";
7184			} );
7185		}
7186
7187		this._off( this.headers.add( this.headers.next() ) );
7188		this._on( this.headers, events );
7189		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
7190		this._hoverable( this.headers );
7191		this._focusable( this.headers );
7192	},
7193
7194	_eventHandler: function( event ) {
7195		var activeChildren, clickedChildren,
7196			options = this.options,
7197			active = this.active,
7198			clicked = $( event.currentTarget ),
7199			clickedIsActive = clicked[ 0 ] === active[ 0 ],
7200			collapsing = clickedIsActive && options.collapsible,
7201			toShow = collapsing ? $() : clicked.next(),
7202			toHide = active.next(),
7203			eventData = {
7204				oldHeader: active,
7205				oldPanel: toHide,
7206				newHeader: collapsing ? $() : clicked,
7207				newPanel: toShow
7208			};
7209
7210		event.preventDefault();
7211
7212		if (
7213
7214				// click on active header, but not collapsible
7215				( clickedIsActive && !options.collapsible ) ||
7216
7217				// allow canceling activation
7218				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
7219			return;
7220		}
7221
7222		options.active = collapsing ? false : this.headers.index( clicked );
7223
7224		// When the call to ._toggle() comes after the class changes
7225		// it causes a very odd bug in IE 8 (see #6720)
7226		this.active = clickedIsActive ? $() : clicked;
7227		this._toggle( eventData );
7228
7229		// Switch classes
7230		// corner classes on the previously active header stay after the animation
7231		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
7232		if ( options.icons ) {
7233			activeChildren = active.children( ".ui-accordion-header-icon" );
7234			this._removeClass( activeChildren, null, options.icons.activeHeader )
7235				._addClass( activeChildren, null, options.icons.header );
7236		}
7237
7238		if ( !clickedIsActive ) {
7239			this._removeClass( clicked, "ui-accordion-header-collapsed" )
7240				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
7241			if ( options.icons ) {
7242				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
7243				this._removeClass( clickedChildren, null, options.icons.header )
7244					._addClass( clickedChildren, null, options.icons.activeHeader );
7245			}
7246
7247			this._addClass( clicked.next(), "ui-accordion-content-active" );
7248		}
7249	},
7250
7251	_toggle: function( data ) {
7252		var toShow = data.newPanel,
7253			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
7254
7255		// Handle activating a panel during the animation for another activation
7256		this.prevShow.add( this.prevHide ).stop( true, true );
7257		this.prevShow = toShow;
7258		this.prevHide = toHide;
7259
7260		if ( this.options.animate ) {
7261			this._animate( toShow, toHide, data );
7262		} else {
7263			toHide.hide();
7264			toShow.show();
7265			this._toggleComplete( data );
7266		}
7267
7268		toHide.attr( {
7269			"aria-hidden": "true"
7270		} );
7271		toHide.prev().attr( {
7272			"aria-selected": "false",
7273			"aria-expanded": "false"
7274		} );
7275
7276		// if we're switching panels, remove the old header from the tab order
7277		// if we're opening from collapsed state, remove the previous header from the tab order
7278		// if we're collapsing, then keep the collapsing header in the tab order
7279		if ( toShow.length && toHide.length ) {
7280			toHide.prev().attr( {
7281				"tabIndex": -1,
7282				"aria-expanded": "false"
7283			} );
7284		} else if ( toShow.length ) {
7285			this.headers.filter( function() {
7286				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
7287			} )
7288				.attr( "tabIndex", -1 );
7289		}
7290
7291		toShow
7292			.attr( "aria-hidden", "false" )
7293			.prev()
7294				.attr( {
7295					"aria-selected": "true",
7296					"aria-expanded": "true",
7297					tabIndex: 0
7298				} );
7299	},
7300
7301	_animate: function( toShow, toHide, data ) {
7302		var total, easing, duration,
7303			that = this,
7304			adjust = 0,
7305			boxSizing = toShow.css( "box-sizing" ),
7306			down = toShow.length &&
7307				( !toHide.length || ( toShow.index() < toHide.index() ) ),
7308			animate = this.options.animate || {},
7309			options = down && animate.down || animate,
7310			complete = function() {
7311				that._toggleComplete( data );
7312			};
7313
7314		if ( typeof options === "number" ) {
7315			duration = options;
7316		}
7317		if ( typeof options === "string" ) {
7318			easing = options;
7319		}
7320
7321		// fall back from options to animation in case of partial down settings
7322		easing = easing || options.easing || animate.easing;
7323		duration = duration || options.duration || animate.duration;
7324
7325		if ( !toHide.length ) {
7326			return toShow.animate( this.showProps, duration, easing, complete );
7327		}
7328		if ( !toShow.length ) {
7329			return toHide.animate( this.hideProps, duration, easing, complete );
7330		}
7331
7332		total = toShow.show().outerHeight();
7333		toHide.animate( this.hideProps, {
7334			duration: duration,
7335			easing: easing,
7336			step: function( now, fx ) {
7337				fx.now = Math.round( now );
7338			}
7339		} );
7340		toShow
7341			.hide()
7342			.animate( this.showProps, {
7343				duration: duration,
7344				easing: easing,
7345				complete: complete,
7346				step: function( now, fx ) {
7347					fx.now = Math.round( now );
7348					if ( fx.prop !== "height" ) {
7349						if ( boxSizing === "content-box" ) {
7350							adjust += fx.now;
7351						}
7352					} else if ( that.options.heightStyle !== "content" ) {
7353						fx.now = Math.round( total - toHide.outerHeight() - adjust );
7354						adjust = 0;
7355					}
7356				}
7357			} );
7358	},
7359
7360	_toggleComplete: function( data ) {
7361		var toHide = data.oldPanel,
7362			prev = toHide.prev();
7363
7364		this._removeClass( toHide, "ui-accordion-content-active" );
7365		this._removeClass( prev, "ui-accordion-header-active" )
7366			._addClass( prev, "ui-accordion-header-collapsed" );
7367
7368		this._trigger( "activate", null, data );
7369	}
7370} );
7371
7372
7373/*!
7374 * jQuery UI Menu 1.14.2
7375 * https://jqueryui.com
7376 *
7377 * Copyright OpenJS Foundation and other contributors
7378 * Released under the MIT license.
7379 * https://jquery.org/license
7380 */
7381
7382//>>label: Menu
7383//>>group: Widgets
7384//>>description: Creates nestable menus.
7385//>>docs: https://api.jqueryui.com/menu/
7386//>>demos: https://jqueryui.com/menu/
7387//>>css.structure: ../../themes/base/core.css
7388//>>css.structure: ../../themes/base/menu.css
7389//>>css.theme: ../../themes/base/theme.css
7390
7391
7392var widgetsMenu = $.widget( "ui.menu", {
7393	version: "1.14.2",
7394	defaultElement: "<ul>",
7395	delay: 300,
7396	options: {
7397		icons: {
7398			submenu: "ui-icon-caret-1-e"
7399		},
7400		items: "> *",
7401		menus: "ul",
7402		position: {
7403			my: "left top",
7404			at: "right top"
7405		},
7406		role: "menu",
7407
7408		// Callbacks
7409		blur: null,
7410		focus: null,
7411		select: null
7412	},
7413
7414	_create: function() {
7415		this.activeMenu = this.element;
7416
7417		// Flag used to prevent firing of the click handler
7418		// as the event bubbles up through nested menus
7419		this.mouseHandled = false;
7420		this.lastMousePosition = { x: null, y: null };
7421		this.element
7422			.uniqueId()
7423			.attr( {
7424				role: this.options.role,
7425				tabIndex: 0
7426			} );
7427
7428		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
7429		this._on( {
7430
7431			// Prevent focus from sticking to links inside menu after clicking
7432			// them (focus should always stay on UL during navigation).
7433			"mousedown .ui-menu-item": function( event ) {
7434				event.preventDefault();
7435
7436				this._activateItem( event );
7437			},
7438			"click .ui-menu-item": function( event ) {
7439				var target = $( event.target );
7440				var active = $( this.document[ 0 ].activeElement );
7441				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
7442					this.select( event );
7443
7444					// Only set the mouseHandled flag if the event will bubble, see #9469.
7445					if ( !event.isPropagationStopped() ) {
7446						this.mouseHandled = true;
7447					}
7448
7449					// Open submenu on click
7450					if ( target.has( ".ui-menu" ).length ) {
7451						this.expand( event );
7452					} else if ( !this.element.is( ":focus" ) &&
7453							active.closest( ".ui-menu" ).length ) {
7454
7455						// Redirect focus to the menu
7456						this.element.trigger( "focus", [ true ] );
7457
7458						// If the active item is on the top level, let it stay active.
7459						// Otherwise, blur the active item since it is no longer visible.
7460						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
7461							clearTimeout( this.timer );
7462						}
7463					}
7464				}
7465			},
7466			"mouseenter .ui-menu-item": "_activateItem",
7467			"mousemove .ui-menu-item": "_activateItem",
7468			mouseleave: "collapseAll",
7469			"mouseleave .ui-menu": "collapseAll",
7470			focus: function( event, keepActiveItem ) {
7471
7472				// If there's already an active item, keep it active
7473				// If not, activate the first item
7474				var item = this.active || this._menuItems().first();
7475
7476				if ( !keepActiveItem ) {
7477					this.focus( event, item );
7478				}
7479			},
7480			blur: function( event ) {
7481				this._delay( function() {
7482					var notContained = !$.contains(
7483						this.element[ 0 ],
7484						this.document[ 0 ].activeElement
7485					);
7486					if ( notContained ) {
7487						this.collapseAll( event );
7488					}
7489				} );
7490			},
7491			keydown: "_keydown"
7492		} );
7493
7494		this.refresh();
7495
7496		// Clicks outside of a menu collapse any open menus
7497		this._on( this.document, {
7498			click: function( event ) {
7499				if ( this._closeOnDocumentClick( event ) ) {
7500					this.collapseAll( event, true );
7501				}
7502
7503				// Reset the mouseHandled flag
7504				this.mouseHandled = false;
7505			}
7506		} );
7507	},
7508
7509	_activateItem: function( event ) {
7510
7511		// Ignore mouse events while typeahead is active, see #10458.
7512		// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
7513		// is over an item in the menu
7514		if ( this.previousFilter ) {
7515			return;
7516		}
7517
7518		// If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356)
7519		if ( event.clientX === this.lastMousePosition.x &&
7520				event.clientY === this.lastMousePosition.y ) {
7521			return;
7522		}
7523
7524		this.lastMousePosition = {
7525			x: event.clientX,
7526			y: event.clientY
7527		};
7528
7529		var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
7530			target = $( event.currentTarget );
7531
7532		// Ignore bubbled events on parent items, see #11641
7533		if ( actualTarget[ 0 ] !== target[ 0 ] ) {
7534			return;
7535		}
7536
7537		// If the item is already active, there's nothing to do
7538		if ( target.is( ".ui-state-active" ) ) {
7539			return;
7540		}
7541
7542		// Remove ui-state-active class from siblings of the newly focused menu item
7543		// to avoid a jump caused by adjacent elements both having a class with a border
7544		this._removeClass( target.siblings().children( ".ui-state-active" ),
7545			null, "ui-state-active" );
7546		this.focus( event, target );
7547	},
7548
7549	_destroy: function() {
7550		var items = this.element.find( ".ui-menu-item" )
7551				.removeAttr( "role aria-disabled" ),
7552			submenus = items.children( ".ui-menu-item-wrapper" )
7553				.removeUniqueId()
7554				.removeAttr( "tabIndex role aria-haspopup" );
7555
7556		// Destroy (sub)menus
7557		this.element
7558			.removeAttr( "aria-activedescendant" )
7559			.find( ".ui-menu" ).addBack()
7560				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
7561					"tabIndex" )
7562				.removeUniqueId()
7563				.show();
7564
7565		submenus.children().each( function() {
7566			var elem = $( this );
7567			if ( elem.data( "ui-menu-submenu-caret" ) ) {
7568				elem.remove();
7569			}
7570		} );
7571	},
7572
7573	_keydown: function( event ) {
7574		var match, prev, character, skip,
7575			preventDefault = true;
7576
7577		switch ( event.keyCode ) {
7578		case $.ui.keyCode.PAGE_UP:
7579			this.previousPage( event );
7580			break;
7581		case $.ui.keyCode.PAGE_DOWN:
7582			this.nextPage( event );
7583			break;
7584		case $.ui.keyCode.HOME:
7585			this._move( "first", "first", event );
7586			break;
7587		case $.ui.keyCode.END:
7588			this._move( "last", "last", event );
7589			break;
7590		case $.ui.keyCode.UP:
7591			this.previous( event );
7592			break;
7593		case $.ui.keyCode.DOWN:
7594			this.next( event );
7595			break;
7596		case $.ui.keyCode.LEFT:
7597			this.collapse( event );
7598			break;
7599		case $.ui.keyCode.RIGHT:
7600			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7601				this.expand( event );
7602			}
7603			break;
7604		case $.ui.keyCode.ENTER:
7605		case $.ui.keyCode.SPACE:
7606			this._activate( event );
7607			break;
7608		case $.ui.keyCode.ESCAPE:
7609			this.collapse( event );
7610			break;
7611		default:
7612			preventDefault = false;
vendor: 6,930 bytes, lines 7613-7861
7613			prev = this.previousFilter || "";
7614			skip = false;
7615
7616			// Support number pad values
7617			character = event.keyCode >= 96 && event.keyCode <= 105 ?
7618				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
7619
7620			clearTimeout( this.filterTimer );
7621
7622			if ( character === prev ) {
7623				skip = true;
7624			} else {
7625				character = prev + character;
7626			}
7627
7628			match = this._filterMenuItems( character );
7629			match = skip && match.index( this.active.next() ) !== -1 ?
7630				this.active.nextAll( ".ui-menu-item" ) :
7631				match;
7632
7633			// If no matches on the current filter, reset to the last character pressed
7634			// to move down the menu to the first item that starts with that character
7635			if ( !match.length ) {
7636				character = String.fromCharCode( event.keyCode );
7637				match = this._filterMenuItems( character );
7638			}
7639
7640			if ( match.length ) {
7641				this.focus( event, match );
7642				this.previousFilter = character;
7643				this.filterTimer = this._delay( function() {
7644					delete this.previousFilter;
7645				}, 1000 );
7646			} else {
7647				delete this.previousFilter;
7648			}
7649		}
7650
7651		if ( preventDefault ) {
7652			event.preventDefault();
7653		}
7654	},
7655
7656	_activate: function( event ) {
7657		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7658			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
7659				this.expand( event );
7660			} else {
7661				this.select( event );
7662			}
7663		}
7664	},
7665
7666	refresh: function() {
7667		var menus, items, newSubmenus, newItems, newWrappers,
7668			that = this,
7669			icon = this.options.icons.submenu,
7670			submenus = this.element.find( this.options.menus );
7671
7672		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
7673
7674		// Initialize nested menus
7675		newSubmenus = submenus.filter( ":not(.ui-menu)" )
7676			.hide()
7677			.attr( {
7678				role: this.options.role,
7679				"aria-hidden": "true",
7680				"aria-expanded": "false"
7681			} )
7682			.each( function() {
7683				var menu = $( this ),
7684					item = menu.prev(),
7685					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
7686
7687				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
7688				item
7689					.attr( "aria-haspopup", "true" )
7690					.prepend( submenuCaret );
7691				menu.attr( "aria-labelledby", item.attr( "id" ) );
7692			} );
7693
7694		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
7695
7696		menus = submenus.add( this.element );
7697		items = menus.find( this.options.items );
7698
7699		// Initialize menu-items containing spaces and/or dashes only as dividers
7700		items.not( ".ui-menu-item" ).each( function() {
7701			var item = $( this );
7702			if ( that._isDivider( item ) ) {
7703				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
7704			}
7705		} );
7706
7707		// Don't refresh list items that are already adapted
7708		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
7709		newWrappers = newItems.children()
7710			.not( ".ui-menu" )
7711				.uniqueId()
7712				.attr( {
7713					tabIndex: -1,
7714					role: this._itemRole()
7715				} );
7716		this._addClass( newItems, "ui-menu-item" )
7717			._addClass( newWrappers, "ui-menu-item-wrapper" );
7718
7719		// Add aria-disabled attribute to any disabled menu item
7720		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
7721
7722		// If the active item has been removed, blur the menu
7723		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
7724			this.blur();
7725		}
7726	},
7727
7728	_itemRole: function() {
7729		return {
7730			menu: "menuitem",
7731			listbox: "option"
7732		}[ this.options.role ];
7733	},
7734
7735	_setOption: function( key, value ) {
7736		if ( key === "icons" ) {
7737			var icons = this.element.find( ".ui-menu-icon" );
7738			this._removeClass( icons, null, this.options.icons.submenu )
7739				._addClass( icons, null, value.submenu );
7740		}
7741		this._super( key, value );
7742	},
7743
7744	_setOptionDisabled: function( value ) {
7745		this._super( value );
7746
7747		this.element.attr( "aria-disabled", String( value ) );
7748		this._toggleClass( null, "ui-state-disabled", !!value );
7749	},
7750
7751	focus: function( event, item ) {
7752		var nested, focused, activeParent;
7753		this.blur( event, event && event.type === "focus" );
7754
7755		this._scrollIntoView( item );
7756
7757		this.active = item.first();
7758
7759		focused = this.active.children( ".ui-menu-item-wrapper" );
7760		this._addClass( focused, null, "ui-state-active" );
7761
7762		// Only update aria-activedescendant if there's a role
7763		// otherwise we assume focus is managed elsewhere
7764		if ( this.options.role ) {
7765			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
7766		}
7767
7768		// Highlight active parent menu item, if any
7769		activeParent = this.active
7770			.parent()
7771				.closest( ".ui-menu-item" )
7772					.children( ".ui-menu-item-wrapper" );
7773		this._addClass( activeParent, null, "ui-state-active" );
7774
7775		if ( event && event.type === "keydown" ) {
7776			this._close();
7777		} else {
7778			this.timer = this._delay( function() {
7779				this._close();
7780			}, this.delay );
7781		}
7782
7783		nested = item.children( ".ui-menu" );
7784		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
7785			this._startOpening( nested );
7786		}
7787		this.activeMenu = item.parent();
7788
7789		this._trigger( "focus", event, { item: item } );
7790	},
7791
7792	_scrollIntoView: function( item ) {
7793		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
7794		if ( this._hasScroll() ) {
7795			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
7796			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
7797			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
7798			scroll = this.activeMenu.scrollTop();
7799			elementHeight = this.activeMenu.height();
7800			itemHeight = item.outerHeight();
7801
7802			if ( offset < 0 ) {
7803				this.activeMenu.scrollTop( scroll + offset );
7804			} else if ( offset + itemHeight > elementHeight ) {
7805				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
7806			}
7807		}
7808	},
7809
7810	blur: function( event, fromFocus ) {
7811		if ( !fromFocus ) {
7812			clearTimeout( this.timer );
7813		}
7814
7815		if ( !this.active ) {
7816			return;
7817		}
7818
7819		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
7820			null, "ui-state-active" );
7821
7822		this._trigger( "blur", event, { item: this.active } );
7823		this.active = null;
7824	},
7825
7826	_startOpening: function( submenu ) {
7827		clearTimeout( this.timer );
7828
7829		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
7830		// shift in the submenu position when mousing over the caret icon
7831		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
7832			return;
7833		}
7834
7835		this.timer = this._delay( function() {
7836			this._close();
7837			this._open( submenu );
7838		}, this.delay );
7839	},
7840
7841	_open: function( submenu ) {
7842		var position = $.extend( {
7843			of: this.active
7844		}, this.options.position );
7845
7846		clearTimeout( this.timer );
7847		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
7848			.hide()
7849			.attr( "aria-hidden", "true" );
7850
7851		submenu
7852			.show()
7853			.removeAttr( "aria-hidden" )
7854			.attr( "aria-expanded", "true" )
7855			.position( position );
7856	},
7857
7858	collapseAll: function( event, all ) {
7859		clearTimeout( this.timer );
7860		this.timer = this._delay( function() {
7861
vendor: 51,558 bytes, lines 7862-9739
7862			// If we were passed an event, look for the submenu that contains the event
7863			var currentMenu = all ? this.element :
7864				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
7865
7866			// If we found no valid submenu ancestor, use the main menu to close all
7867			// sub menus anyway
7868			if ( !currentMenu.length ) {
7869				currentMenu = this.element;
7870			}
7871
7872			this._close( currentMenu );
7873
7874			this.blur( event );
7875
7876			// Work around active item staying active after menu is blurred
7877			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
7878
7879			this.activeMenu = currentMenu;
7880		}, all ? 0 : this.delay );
7881	},
7882
7883	// With no arguments, closes the currently active menu - if nothing is active
7884	// it closes all menus.  If passed an argument, it will search for menus BELOW
7885	_close: function( startMenu ) {
7886		if ( !startMenu ) {
7887			startMenu = this.active ? this.active.parent() : this.element;
7888		}
7889
7890		startMenu.find( ".ui-menu" )
7891			.hide()
7892			.attr( "aria-hidden", "true" )
7893			.attr( "aria-expanded", "false" );
7894	},
7895
7896	_closeOnDocumentClick: function( event ) {
7897		return !$( event.target ).closest( ".ui-menu" ).length;
7898	},
7899
7900	_isDivider: function( item ) {
7901
7902		// Match hyphen, em dash, en dash
7903		return !/[^\-\u2014\u2013\s]/.test( item.text() );
7904	},
7905
7906	collapse: function( event ) {
7907		var newItem = this.active &&
7908			this.active.parent().closest( ".ui-menu-item", this.element );
7909		if ( newItem && newItem.length ) {
7910			this._close();
7911			this.focus( event, newItem );
7912		}
7913	},
7914
7915	expand: function( event ) {
7916		var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first();
7917
7918		if ( newItem && newItem.length ) {
7919			this._open( newItem.parent() );
7920
7921			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
7922			this._delay( function() {
7923				this.focus( event, newItem );
7924			} );
7925		}
7926	},
7927
7928	next: function( event ) {
7929		this._move( "next", "first", event );
7930	},
7931
7932	previous: function( event ) {
7933		this._move( "prev", "last", event );
7934	},
7935
7936	isFirstItem: function() {
7937		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
7938	},
7939
7940	isLastItem: function() {
7941		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
7942	},
7943
7944	_menuItems: function( menu ) {
7945		return ( menu || this.element )
7946			.find( this.options.items )
7947			.filter( ".ui-menu-item" );
7948	},
7949
7950	_move: function( direction, filter, event ) {
7951		var next;
7952		if ( this.active ) {
7953			if ( direction === "first" || direction === "last" ) {
7954				next = this.active
7955					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
7956					.last();
7957			} else {
7958				next = this.active
7959					[ direction + "All" ]( ".ui-menu-item" )
7960					.first();
7961			}
7962		}
7963		if ( !next || !next.length || !this.active ) {
7964			next = this._menuItems( this.activeMenu )[ filter ]();
7965		}
7966
7967		this.focus( event, next );
7968	},
7969
7970	nextPage: function( event ) {
7971		var item, base, height;
7972
7973		if ( !this.active ) {
7974			this.next( event );
7975			return;
7976		}
7977		if ( this.isLastItem() ) {
7978			return;
7979		}
7980		if ( this._hasScroll() ) {
7981			base = this.active.offset().top;
7982			height = this.element.innerHeight();
7983
7984			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
7985			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
7986				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
7987			}
7988
7989			this.active.nextAll( ".ui-menu-item" ).each( function() {
7990				item = $( this );
7991				return item.offset().top - base - height < 0;
7992			} );
7993
7994			this.focus( event, item );
7995		} else {
7996			this.focus( event, this._menuItems( this.activeMenu )
7997				[ !this.active ? "first" : "last" ]() );
7998		}
7999	},
8000
8001	previousPage: function( event ) {
8002		var item, base, height;
8003		if ( !this.active ) {
8004			this.next( event );
8005			return;
8006		}
8007		if ( this.isFirstItem() ) {
8008			return;
8009		}
8010		if ( this._hasScroll() ) {
8011			base = this.active.offset().top;
8012			height = this.element.innerHeight();
8013
8014			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
8015			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
8016				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
8017			}
8018
8019			this.active.prevAll( ".ui-menu-item" ).each( function() {
8020				item = $( this );
8021				return item.offset().top - base + height > 0;
8022			} );
8023
8024			this.focus( event, item );
8025		} else {
8026			this.focus( event, this._menuItems( this.activeMenu ).first() );
8027		}
8028	},
8029
8030	_hasScroll: function() {
8031		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
8032	},
8033
8034	select: function( event ) {
8035
8036		// TODO: It should never be possible to not have an active item at this
8037		// point, but the tests don't trigger mouseenter before click.
8038		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
8039		var ui = { item: this.active };
8040		if ( !this.active.has( ".ui-menu" ).length ) {
8041			this.collapseAll( event, true );
8042		}
8043		this._trigger( "select", event, ui );
8044	},
8045
8046	_filterMenuItems: function( character ) {
8047		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
8048			regex = new RegExp( "^" + escapedCharacter, "i" );
8049
8050		return this.activeMenu
8051			.find( this.options.items )
8052
8053				// Only match on items, not dividers or other content (#10571)
8054				.filter( ".ui-menu-item" )
8055					.filter( function() {
8056						return regex.test(
8057							String.prototype.trim.call(
8058								$( this ).children( ".ui-menu-item-wrapper" ).text() ) );
8059					} );
8060	}
8061} );
8062
8063
8064/*!
8065 * jQuery UI Autocomplete 1.14.2
8066 * https://jqueryui.com
8067 *
8068 * Copyright OpenJS Foundation and other contributors
8069 * Released under the MIT license.
8070 * https://jquery.org/license
8071 */
8072
8073//>>label: Autocomplete
8074//>>group: Widgets
8075//>>description: Lists suggested words as the user is typing.
8076//>>docs: https://api.jqueryui.com/autocomplete/
8077//>>demos: https://jqueryui.com/autocomplete/
8078//>>css.structure: ../../themes/base/core.css
8079//>>css.structure: ../../themes/base/autocomplete.css
8080//>>css.theme: ../../themes/base/theme.css
8081
8082
8083$.widget( "ui.autocomplete", {
8084	version: "1.14.2",
8085	defaultElement: "<input>",
8086	options: {
8087		appendTo: null,
8088		autoFocus: false,
8089		delay: 300,
8090		minLength: 1,
8091		position: {
8092			my: "left top",
8093			at: "left bottom",
8094			collision: "none"
8095		},
8096		source: null,
8097
8098		// Callbacks
8099		change: null,
8100		close: null,
8101		focus: null,
8102		open: null,
8103		response: null,
8104		search: null,
8105		select: null
8106	},
8107
8108	requestIndex: 0,
8109	pending: 0,
8110	liveRegionTimer: null,
8111
8112	_create: function() {
8113
8114		// Some browsers only repeat keydown events, not keypress events,
8115		// so we use the suppressKeyPress flag to determine if we've already
8116		// handled the keydown event. #7269
8117		// Unfortunately the code for & in keypress is the same as the up arrow,
8118		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
8119		// events when we know the keydown event was used to modify the
8120		// search term. #7799
8121		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
8122			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
8123			isTextarea = nodeName === "textarea",
8124			isInput = nodeName === "input";
8125
8126		// Textareas are always multi-line
8127		// Inputs are always single-line, even if inside a contentEditable element
8128		// All other element types are determined by whether they're contentEditable
8129		this.isMultiLine = isTextarea ||
8130			!isInput && this.element.prop( "contentEditable" ) === "true";
8131
8132		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
8133		this.isNewMenu = true;
8134
8135		this._addClass( "ui-autocomplete-input" );
8136		this.element.attr( "autocomplete", "off" );
8137
8138		this._on( this.element, {
8139			keydown: function( event ) {
8140				if ( this.element.prop( "readOnly" ) ) {
8141					suppressKeyPress = true;
8142					suppressInput = true;
8143					suppressKeyPressRepeat = true;
8144					return;
8145				}
8146
8147				suppressKeyPress = false;
8148				suppressInput = false;
8149				suppressKeyPressRepeat = false;
8150				var keyCode = $.ui.keyCode;
8151				switch ( event.keyCode ) {
8152				case keyCode.PAGE_UP:
8153					suppressKeyPress = true;
8154					this._move( "previousPage", event );
8155					break;
8156				case keyCode.PAGE_DOWN:
8157					suppressKeyPress = true;
8158					this._move( "nextPage", event );
8159					break;
8160				case keyCode.UP:
8161					suppressKeyPress = true;
8162					this._keyEvent( "previous", event );
8163					break;
8164				case keyCode.DOWN:
8165					suppressKeyPress = true;
8166					this._keyEvent( "next", event );
8167					break;
8168				case keyCode.ENTER:
8169
8170					// when menu is open and has focus
8171					if ( this.menu.active ) {
8172
8173						// #6055 - Opera still allows the keypress to occur
8174						// which causes forms to submit
8175						suppressKeyPress = true;
8176						event.preventDefault();
8177						this.menu.select( event );
8178					}
8179					break;
8180				case keyCode.TAB:
8181					if ( this.menu.active ) {
8182						this.menu.select( event );
8183					}
8184					break;
8185				case keyCode.ESCAPE:
8186					if ( this.menu.element.is( ":visible" ) ) {
8187						if ( !this.isMultiLine ) {
8188							this._value( this.term );
8189						}
8190						this.close( event );
8191
8192						// Different browsers have different default behavior for escape
8193						// Single press can mean undo or clear
8194						event.preventDefault();
8195					}
8196					break;
8197				default:
8198					suppressKeyPressRepeat = true;
8199
8200					// search timeout should be triggered before the input value is changed
8201					this._searchTimeout( event );
8202					break;
8203				}
8204			},
8205			keypress: function( event ) {
8206				if ( suppressKeyPress ) {
8207					suppressKeyPress = false;
8208					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8209						event.preventDefault();
8210					}
8211					return;
8212				}
8213				if ( suppressKeyPressRepeat ) {
8214					return;
8215				}
8216
8217				// Replicate some key handlers to allow them to repeat in Firefox and Opera
8218				var keyCode = $.ui.keyCode;
8219				switch ( event.keyCode ) {
8220				case keyCode.PAGE_UP:
8221					this._move( "previousPage", event );
8222					break;
8223				case keyCode.PAGE_DOWN:
8224					this._move( "nextPage", event );
8225					break;
8226				case keyCode.UP:
8227					this._keyEvent( "previous", event );
8228					break;
8229				case keyCode.DOWN:
8230					this._keyEvent( "next", event );
8231					break;
8232				}
8233			},
8234			input: function( event ) {
8235				if ( suppressInput ) {
8236					suppressInput = false;
8237					event.preventDefault();
8238					return;
8239				}
8240				this._searchTimeout( event );
8241			},
8242			focus: function() {
8243				this.selectedItem = null;
8244				this.previous = this._value();
8245			},
8246			blur: function( event ) {
8247				clearTimeout( this.searching );
8248				this.close( event );
8249				this._change( event );
8250			}
8251		} );
8252
8253		this._initSource();
8254		this.menu = $( "<ul>" )
8255			.appendTo( this._appendTo() )
8256			.menu( {
8257
8258				// disable ARIA support, the live region takes care of that
8259				role: null
8260			} )
8261			.hide()
8262			.menu( "instance" );
8263
8264		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
8265		this._on( this.menu.element, {
8266			mousedown: function( event ) {
8267
8268				// Prevent moving focus out of the text field
8269				event.preventDefault();
8270			},
8271			menufocus: function( event, ui ) {
8272				var label, item;
8273
8274				// Support: Firefox
8275				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
8276				if ( this.isNewMenu ) {
8277					this.isNewMenu = false;
8278					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
8279						this.menu.blur();
8280
8281						this.document.one( "mousemove", function() {
8282							$( event.target ).trigger( event.originalEvent );
8283						} );
8284
8285						return;
8286					}
8287				}
8288
8289				item = ui.item.data( "ui-autocomplete-item" );
8290				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
8291
8292					// use value to match what will end up in the input, if it was a key event
8293					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
8294						this._value( item.value );
8295					}
8296				}
8297
8298				// Announce the value in the liveRegion
8299				label = ui.item.attr( "aria-label" ) || item.value;
8300				if ( label && String.prototype.trim.call( label ).length ) {
8301					clearTimeout( this.liveRegionTimer );
8302					this.liveRegionTimer = this._delay( function() {
8303						this.liveRegion.html( $( "<div>" ).text( label ) );
8304					}, 100 );
8305				}
8306			},
8307			menuselect: function( event, ui ) {
8308				var item = ui.item.data( "ui-autocomplete-item" ),
8309					previous = this.previous;
8310
8311				// Only trigger when focus was lost (click on menu)
8312				if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
8313					this.element.trigger( "focus" );
8314					this.previous = previous;
8315				}
8316
8317				if ( false !== this._trigger( "select", event, { item: item } ) ) {
8318					this._value( item.value );
8319				}
8320
8321				// reset the term after the select event
8322				// this allows custom select handling to work properly
8323				this.term = this._value();
8324
8325				this.close( event );
8326				this.selectedItem = item;
8327			}
8328		} );
8329
8330		this.liveRegion = $( "<div>", {
8331			role: "status",
8332			"aria-live": "assertive",
8333			"aria-relevant": "additions"
8334		} )
8335			.appendTo( this.document[ 0 ].body );
8336
8337		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
8338
8339		// Turning off autocomplete prevents the browser from remembering the
8340		// value when navigating through history, so we re-enable autocomplete
8341		// if the page is unloaded before the widget is destroyed. #7790
8342		this._on( this.window, {
8343			beforeunload: function() {
8344				this.element.removeAttr( "autocomplete" );
8345			}
8346		} );
8347	},
8348
8349	_destroy: function() {
8350		clearTimeout( this.searching );
8351		this.element.removeAttr( "autocomplete" );
8352		this.menu.element.remove();
8353		this.liveRegion.remove();
8354	},
8355
8356	_setOption: function( key, value ) {
8357		this._super( key, value );
8358		if ( key === "source" ) {
8359			this._initSource();
8360		}
8361		if ( key === "appendTo" ) {
8362			this.menu.element.appendTo( this._appendTo() );
8363		}
8364		if ( key === "disabled" && value && this.xhr ) {
8365			this.xhr.abort();
8366		}
8367	},
8368
8369	_isEventTargetInWidget: function( event ) {
8370		var menuElement = this.menu.element[ 0 ];
8371
8372		return event.target === this.element[ 0 ] ||
8373			event.target === menuElement ||
8374			$.contains( menuElement, event.target );
8375	},
8376
8377	_closeOnClickOutside: function( event ) {
8378		if ( !this._isEventTargetInWidget( event ) ) {
8379			this.close();
8380		}
8381	},
8382
8383	_appendTo: function() {
8384		var element = this.options.appendTo;
8385
8386		if ( element ) {
8387			element = element.jquery || element.nodeType ?
8388				$( element ) :
8389				this.document.find( element ).eq( 0 );
8390		}
8391
8392		if ( !element || !element[ 0 ] ) {
8393			element = this.element.closest( ".ui-front, dialog" );
8394		}
8395
8396		if ( !element.length ) {
8397			element = this.document[ 0 ].body;
8398		}
8399
8400		return element;
8401	},
8402
8403	_initSource: function() {
8404		var array, url,
8405			that = this;
8406		if ( Array.isArray( this.options.source ) ) {
8407			array = this.options.source;
8408			this.source = function( request, response ) {
8409				response( $.ui.autocomplete.filter( array, request.term ) );
8410			};
8411		} else if ( typeof this.options.source === "string" ) {
8412			url = this.options.source;
8413			this.source = function( request, response ) {
8414				if ( that.xhr ) {
8415					that.xhr.abort();
8416				}
8417				that.xhr = $.ajax( {
8418					url: url,
8419					data: request,
8420					dataType: "json",
8421					success: function( data ) {
8422						response( data );
8423					},
8424					error: function() {
8425						response( [] );
8426					}
8427				} );
8428			};
8429		} else {
8430			this.source = this.options.source;
8431		}
8432	},
8433
8434	_searchTimeout: function( event ) {
8435		clearTimeout( this.searching );
8436		this.searching = this._delay( function() {
8437
8438			// Search if the value has changed, or if the user retypes the same value (see #7434)
8439			var equalValues = this.term === this._value(),
8440				menuVisible = this.menu.element.is( ":visible" ),
8441				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
8442
8443			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
8444				this.selectedItem = null;
8445				this.search( null, event );
8446			}
8447		}, this.options.delay );
8448	},
8449
8450	search: function( value, event ) {
8451		value = value != null ? value : this._value();
8452
8453		// Always save the actual value, not the one passed as an argument
8454		this.term = this._value();
8455
8456		if ( value.length < this.options.minLength ) {
8457			return this.close( event );
8458		}
8459
8460		if ( this._trigger( "search", event ) === false ) {
8461			return;
8462		}
8463
8464		return this._search( value );
8465	},
8466
8467	_search: function( value ) {
8468		this.pending++;
8469		this._addClass( "ui-autocomplete-loading" );
8470		this.cancelSearch = false;
8471
8472		this.source( { term: value }, this._response() );
8473	},
8474
8475	_response: function() {
8476		var index = ++this.requestIndex;
8477
8478		return function( content ) {
8479			if ( index === this.requestIndex ) {
8480				this.__response( content );
8481			}
8482
8483			this.pending--;
8484			if ( !this.pending ) {
8485				this._removeClass( "ui-autocomplete-loading" );
8486			}
8487		}.bind( this );
8488	},
8489
8490	__response: function( content ) {
8491		if ( content ) {
8492			content = this._normalize( content );
8493		}
8494		this._trigger( "response", null, { content: content } );
8495		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
8496			this._suggest( content );
8497			this._trigger( "open" );
8498		} else {
8499
8500			// use ._close() instead of .close() so we don't cancel future searches
8501			this._close();
8502		}
8503	},
8504
8505	close: function( event ) {
8506		this.cancelSearch = true;
8507		this._close( event );
8508	},
8509
8510	_close: function( event ) {
8511
8512		// Remove the handler that closes the menu on outside clicks
8513		this._off( this.document, "mousedown" );
8514
8515		if ( this.menu.element.is( ":visible" ) ) {
8516			this.menu.element.hide();
8517			this.menu.blur();
8518			this.isNewMenu = true;
8519			this._trigger( "close", event );
8520		}
8521	},
8522
8523	_change: function( event ) {
8524		if ( this.previous !== this._value() ) {
8525			this._trigger( "change", event, { item: this.selectedItem } );
8526		}
8527	},
8528
8529	_normalize: function( items ) {
8530
8531		// assume all items have the right format when the first item is complete
8532		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
8533			return items;
8534		}
8535		return $.map( items, function( item ) {
8536			if ( typeof item === "string" ) {
8537				return {
8538					label: item,
8539					value: item
8540				};
8541			}
8542			return $.extend( {}, item, {
8543				label: item.label || item.value,
8544				value: item.value || item.label
8545			} );
8546		} );
8547	},
8548
8549	_suggest: function( items ) {
8550		var ul = this.menu.element.empty();
8551		this._renderMenu( ul, items );
8552		this.isNewMenu = true;
8553		this.menu.refresh();
8554
8555		// Size and position menu
8556		ul.show();
8557		this._resizeMenu();
8558		ul.position( $.extend( {
8559			of: this.element
8560		}, this.options.position ) );
8561
8562		if ( this.options.autoFocus ) {
8563			this.menu.next();
8564		}
8565
8566		// Listen for interactions outside of the widget (#6642)
8567		this._on( this.document, {
8568			mousedown: "_closeOnClickOutside"
8569		} );
8570	},
8571
8572	_resizeMenu: function() {
8573		var ul = this.menu.element;
8574		ul.outerWidth( Math.max(
8575
8576			// Firefox wraps long text (possibly a rounding bug)
8577			// so we add 1px to avoid the wrapping (#7513)
8578			ul.width( "" ).outerWidth() + 1,
8579			this.element.outerWidth()
8580		) );
8581	},
8582
8583	_renderMenu: function( ul, items ) {
8584		var that = this;
8585		$.each( items, function( index, item ) {
8586			that._renderItemData( ul, item );
8587		} );
8588	},
8589
8590	_renderItemData: function( ul, item ) {
8591		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
8592	},
8593
8594	_renderItem: function( ul, item ) {
8595		return $( "<li>" )
8596			.append( $( "<div>" ).text( item.label ) )
8597			.appendTo( ul );
8598	},
8599
8600	_move: function( direction, event ) {
8601		if ( !this.menu.element.is( ":visible" ) ) {
8602			this.search( null, event );
8603			return;
8604		}
8605		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
8606				this.menu.isLastItem() && /^next/.test( direction ) ) {
8607
8608			if ( !this.isMultiLine ) {
8609				this._value( this.term );
8610			}
8611
8612			this.menu.blur();
8613			return;
8614		}
8615		this.menu[ direction ]( event );
8616	},
8617
8618	widget: function() {
8619		return this.menu.element;
8620	},
8621
8622	_value: function() {
8623		return this.valueMethod.apply( this.element, arguments );
8624	},
8625
8626	_keyEvent: function( keyEvent, event ) {
8627		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8628			this._move( keyEvent, event );
8629
8630			// Prevents moving cursor to beginning/end of the text field in some browsers
8631			event.preventDefault();
8632		}
8633	}
8634} );
8635
8636$.extend( $.ui.autocomplete, {
8637	escapeRegex: function( value ) {
8638		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
8639	},
8640	filter: function( array, term ) {
8641		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
8642		return $.grep( array, function( value ) {
8643			return matcher.test( value.label || value.value || value );
8644		} );
8645	}
8646} );
8647
8648// Live region extension, adding a `messages` option
8649// NOTE: This is an experimental API. We are still investigating
8650// a full solution for string manipulation and internationalization.
8651$.widget( "ui.autocomplete", $.ui.autocomplete, {
8652	options: {
8653		messages: {
8654			noResults: "No search results.",
8655			results: function( amount ) {
8656				return amount + ( amount > 1 ? " results are" : " result is" ) +
8657					" available, use up and down arrow keys to navigate.";
8658			}
8659		}
8660	},
8661
8662	__response: function( content ) {
8663		var message;
8664		this._superApply( arguments );
8665		if ( this.options.disabled || this.cancelSearch ) {
8666			return;
8667		}
8668		if ( content && content.length ) {
8669			message = this.options.messages.results( content.length );
8670		} else {
8671			message = this.options.messages.noResults;
8672		}
8673		clearTimeout( this.liveRegionTimer );
8674		this.liveRegionTimer = this._delay( function() {
8675			this.liveRegion.html( $( "<div>" ).text( message ) );
8676		}, 100 );
8677	}
8678} );
8679
8680var widgetsAutocomplete = $.ui.autocomplete;
8681
8682
8683/*!
8684 * jQuery UI Controlgroup 1.14.2
8685 * https://jqueryui.com
8686 *
8687 * Copyright OpenJS Foundation and other contributors
8688 * Released under the MIT license.
8689 * https://jquery.org/license
8690 */
8691
8692//>>label: Controlgroup
8693//>>group: Widgets
8694//>>description: Visually groups form control widgets
8695//>>docs: https://api.jqueryui.com/controlgroup/
8696//>>demos: https://jqueryui.com/controlgroup/
8697//>>css.structure: ../../themes/base/core.css
8698//>>css.structure: ../../themes/base/controlgroup.css
8699//>>css.theme: ../../themes/base/theme.css
8700
8701
8702var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
8703
8704var widgetsControlgroup = $.widget( "ui.controlgroup", {
8705	version: "1.14.2",
8706	defaultElement: "<div>",
8707	options: {
8708		direction: "horizontal",
8709		disabled: null,
8710		onlyVisible: true,
8711		items: {
8712			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
8713			"controlgroupLabel": ".ui-controlgroup-label",
8714			"checkboxradio": "input[type='checkbox'], input[type='radio']",
8715			"selectmenu": "select",
8716			"spinner": ".ui-spinner-input"
8717		}
8718	},
8719
8720	_create: function() {
8721		this._enhance();
8722	},
8723
8724	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
8725	_enhance: function() {
8726		this.element.attr( "role", "toolbar" );
8727		this.refresh();
8728	},
8729
8730	_destroy: function() {
8731		this._callChildMethod( "destroy" );
8732		this.childWidgets.removeData( "ui-controlgroup-data" );
8733		this.element.removeAttr( "role" );
8734		if ( this.options.items.controlgroupLabel ) {
8735			this.element
8736				.find( this.options.items.controlgroupLabel )
8737				.find( ".ui-controlgroup-label-contents" )
8738				.contents().unwrap();
8739		}
8740	},
8741
8742	_initWidgets: function() {
8743		var that = this,
8744			childWidgets = [];
8745
8746		// First we iterate over each of the items options
8747		$.each( this.options.items, function( widget, selector ) {
8748			var labels;
8749			var options = {};
8750
8751			// Make sure the widget has a selector set
8752			if ( !selector ) {
8753				return;
8754			}
8755
8756			if ( widget === "controlgroupLabel" ) {
8757				labels = that.element.find( selector );
8758				labels.each( function() {
8759					var element = $( this );
8760
8761					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
8762						return;
8763					}
8764					element.contents()
8765						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
8766				} );
8767				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
8768				childWidgets = childWidgets.concat( labels.get() );
8769				return;
8770			}
8771
8772			// Make sure the widget actually exists
8773			if ( !$.fn[ widget ] ) {
8774				return;
8775			}
8776
8777			// We assume everything is in the middle to start because we can't determine
8778			// first / last elements until all enhancments are done.
8779			if ( that[ "_" + widget + "Options" ] ) {
8780				options = that[ "_" + widget + "Options" ]( "middle" );
8781			} else {
8782				options = { classes: {} };
8783			}
8784
8785			// Find instances of this widget inside controlgroup and init them
8786			that.element
8787				.find( selector )
8788				.each( function() {
8789					var element = $( this );
8790					var instance = element[ widget ]( "instance" );
8791
8792					// We need to clone the default options for this type of widget to avoid
8793					// polluting the variable options which has a wider scope than a single widget.
8794					var instanceOptions = $.widget.extend( {}, options );
8795
8796					// If the button is the child of a spinner ignore it
8797					// TODO: Find a more generic solution
8798					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
8799						return;
8800					}
8801
8802					// Create the widget if it doesn't exist
8803					if ( !instance ) {
8804						instance = element[ widget ]()[ widget ]( "instance" );
8805					}
8806					if ( instance ) {
8807						instanceOptions.classes =
8808							that._resolveClassesValues( instanceOptions.classes, instance );
8809					}
8810					element[ widget ]( instanceOptions );
8811
8812					// Store an instance of the controlgroup to be able to reference
8813					// from the outermost element for changing options and refresh
8814					var widgetElement = element[ widget ]( "widget" );
8815					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
8816						instance ? instance : element[ widget ]( "instance" ) );
8817
8818					childWidgets.push( widgetElement[ 0 ] );
8819				} );
8820		} );
8821
8822		this.childWidgets = $( $.uniqueSort( childWidgets ) );
8823		this._addClass( this.childWidgets, "ui-controlgroup-item" );
8824	},
8825
8826	_callChildMethod: function( method ) {
8827		this.childWidgets.each( function() {
8828			var element = $( this ),
8829				data = element.data( "ui-controlgroup-data" );
8830			if ( data && data[ method ] ) {
8831				data[ method ]();
8832			}
8833		} );
8834	},
8835
8836	_updateCornerClass: function( element, position ) {
8837		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
8838		var add = this._buildSimpleOptions( position, "label" ).classes.label;
8839
8840		this._removeClass( element, null, remove );
8841		this._addClass( element, null, add );
8842	},
8843
8844	_buildSimpleOptions: function( position, key ) {
8845		var direction = this.options.direction === "vertical";
8846		var result = {
8847			classes: {}
8848		};
8849		result.classes[ key ] = {
8850			"middle": "",
8851			"first": "ui-corner-" + ( direction ? "top" : "left" ),
8852			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
8853			"only": "ui-corner-all"
8854		}[ position ];
8855
8856		return result;
8857	},
8858
8859	_spinnerOptions: function( position ) {
8860		var options = this._buildSimpleOptions( position, "ui-spinner" );
8861
8862		options.classes[ "ui-spinner-up" ] = "";
8863		options.classes[ "ui-spinner-down" ] = "";
8864
8865		return options;
8866	},
8867
8868	_buttonOptions: function( position ) {
8869		return this._buildSimpleOptions( position, "ui-button" );
8870	},
8871
8872	_checkboxradioOptions: function( position ) {
8873		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
8874	},
8875
8876	_selectmenuOptions: function( position ) {
8877		var direction = this.options.direction === "vertical";
8878		return {
8879			width: direction ? "auto" : false,
8880			classes: {
8881				middle: {
8882					"ui-selectmenu-button-open": "",
8883					"ui-selectmenu-button-closed": ""
8884				},
8885				first: {
8886					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
8887					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
8888				},
8889				last: {
8890					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
8891					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
8892				},
8893				only: {
8894					"ui-selectmenu-button-open": "ui-corner-top",
8895					"ui-selectmenu-button-closed": "ui-corner-all"
8896				}
8897
8898			}[ position ]
8899		};
8900	},
8901
8902	_resolveClassesValues: function( classes, instance ) {
8903		var result = {};
8904		$.each( classes, function( key ) {
8905			var current = instance.options.classes[ key ] || "";
8906			current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) );
8907			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
8908		} );
8909		return result;
8910	},
8911
8912	_setOption: function( key, value ) {
8913		if ( key === "direction" ) {
8914			this._removeClass( "ui-controlgroup-" + this.options.direction );
8915		}
8916
8917		this._super( key, value );
8918		if ( key === "disabled" ) {
8919			this._callChildMethod( value ? "disable" : "enable" );
8920			return;
8921		}
8922
8923		this.refresh();
8924	},
8925
8926	refresh: function() {
8927		var children,
8928			that = this;
8929
8930		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
8931
8932		if ( this.options.direction === "horizontal" ) {
8933			this._addClass( null, "ui-helper-clearfix" );
8934		}
8935		this._initWidgets();
8936
8937		children = this.childWidgets;
8938
8939		// We filter here because we need to track all childWidgets not just the visible ones
8940		if ( this.options.onlyVisible ) {
8941			children = children.filter( ":visible" );
8942		}
8943
8944		if ( children.length ) {
8945
8946			// We do this last because we need to make sure all enhancment is done
8947			// before determining first and last
8948			$.each( [ "first", "last" ], function( index, value ) {
8949				var instance = children[ value ]().data( "ui-controlgroup-data" );
8950
8951				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
8952					var options = that[ "_" + instance.widgetName + "Options" ](
8953						children.length === 1 ? "only" : value
8954					);
8955					options.classes = that._resolveClassesValues( options.classes, instance );
8956					instance.element[ instance.widgetName ]( options );
8957				} else {
8958					that._updateCornerClass( children[ value ](), value );
8959				}
8960			} );
8961
8962			// Finally call the refresh method on each of the child widgets.
8963			this._callChildMethod( "refresh" );
8964		}
8965	}
8966} );
8967
8968/*!
8969 * jQuery UI Checkboxradio 1.14.2
8970 * https://jqueryui.com
8971 *
8972 * Copyright OpenJS Foundation and other contributors
8973 * Released under the MIT license.
8974 * https://jquery.org/license
8975 */
8976
8977//>>label: Checkboxradio
8978//>>group: Widgets
8979//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
8980//>>docs: https://api.jqueryui.com/checkboxradio/
8981//>>demos: https://jqueryui.com/checkboxradio/
8982//>>css.structure: ../../themes/base/core.css
8983//>>css.structure: ../../themes/base/button.css
8984//>>css.structure: ../../themes/base/checkboxradio.css
8985//>>css.theme: ../../themes/base/theme.css
8986
8987
8988$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
8989	version: "1.14.2",
8990	options: {
8991		disabled: null,
8992		label: null,
8993		icon: true,
8994		classes: {
8995			"ui-checkboxradio-label": "ui-corner-all",
8996			"ui-checkboxradio-icon": "ui-corner-all"
8997		}
8998	},
8999
9000	_getCreateOptions: function() {
9001		var disabled, labels, labelContents;
9002		var options = this._super() || {};
9003
9004		// We read the type here, because it makes more sense to throw a element type error first,
9005		// rather then the error for lack of a label. Often if its the wrong type, it
9006		// won't have a label (e.g. calling on a div, btn, etc)
9007		this._readType();
9008
9009		labels = this.element.labels();
9010
9011		// If there are multiple labels, use the last one
9012		this.label = $( labels[ labels.length - 1 ] );
9013		if ( !this.label.length ) {
9014			$.error( "No label found for checkboxradio widget" );
9015		}
9016
9017		this.originalLabel = "";
9018
9019		// We need to get the label text but this may also need to make sure it does not contain the
9020		// input itself.
9021		// The label contents could be text, html, or a mix. We wrap all elements
9022		// and read the wrapper's `innerHTML` to get a string representation of
9023		// the label, without the input as part of it.
9024		labelContents = this.label.contents().not( this.element[ 0 ] );
9025
9026		if ( labelContents.length ) {
9027			this.originalLabel += labelContents
9028				.clone()
9029				.wrapAll( "<div></div>" )
9030				.parent()
9031				.html();
9032		}
9033
9034		// Set the label option if we found label text
9035		if ( this.originalLabel ) {
9036			options.label = this.originalLabel;
9037		}
9038
9039		disabled = this.element[ 0 ].disabled;
9040		if ( disabled != null ) {
9041			options.disabled = disabled;
9042		}
9043		return options;
9044	},
9045
9046	_create: function() {
9047		var checked = this.element[ 0 ].checked;
9048
9049		this._bindFormResetHandler();
9050
9051		if ( this.options.disabled == null ) {
9052			this.options.disabled = this.element[ 0 ].disabled;
9053		}
9054
9055		this._setOption( "disabled", this.options.disabled );
9056		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
9057		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
9058
9059		if ( this.type === "radio" ) {
9060			this._addClass( this.label, "ui-checkboxradio-radio-label" );
9061		}
9062
9063		if ( this.options.label && this.options.label !== this.originalLabel ) {
9064			this._updateLabel();
9065		} else if ( this.originalLabel ) {
9066			this.options.label = this.originalLabel;
9067		}
9068
9069		this._enhance();
9070
9071		if ( checked ) {
9072			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
9073		}
9074
9075		this._on( {
9076			change: "_toggleClasses",
9077			focus: function() {
9078				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
9079			},
9080			blur: function() {
9081				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
9082			}
9083		} );
9084	},
9085
9086	_readType: function() {
9087		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
9088		this.type = this.element[ 0 ].type;
9089		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
9090			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
9091				" and element.type=" + this.type );
9092		}
9093	},
9094
9095	// Support jQuery Mobile enhanced option
9096	_enhance: function() {
9097		this._updateIcon( this.element[ 0 ].checked );
9098	},
9099
9100	widget: function() {
9101		return this.label;
9102	},
9103
9104	_getRadioGroup: function() {
9105		var group;
9106		var name = this.element[ 0 ].name;
9107		var nameSelector = "input[name='" + CSS.escape( name ) + "']";
9108
9109		if ( !name ) {
9110			return $( [] );
9111		}
9112
9113		if ( this.form.length ) {
9114			group = $( this.form[ 0 ].elements ).filter( nameSelector );
9115		} else {
9116
9117			// Not inside a form, check all inputs that also are not inside a form
9118			group = $( nameSelector ).filter( function() {
9119				return $( $( this ).prop( "form" ) ).length === 0;
9120			} );
9121		}
9122
9123		return group.not( this.element );
9124	},
9125
9126	_toggleClasses: function() {
9127		var checked = this.element[ 0 ].checked;
9128		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9129
9130		if ( this.options.icon && this.type === "checkbox" ) {
9131			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
9132				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
9133		}
9134
9135		if ( this.type === "radio" ) {
9136			this._getRadioGroup()
9137				.each( function() {
9138					var instance = $( this ).checkboxradio( "instance" );
9139
9140					if ( instance ) {
9141						instance._removeClass( instance.label,
9142							"ui-checkboxradio-checked", "ui-state-active" );
9143					}
9144				} );
9145		}
9146	},
9147
9148	_destroy: function() {
9149		this._unbindFormResetHandler();
9150
9151		if ( this.icon ) {
9152			this.icon.remove();
9153			this.iconSpace.remove();
9154		}
9155	},
9156
9157	_setOption: function( key, value ) {
9158
9159		// We don't allow the value to be set to nothing
9160		if ( key === "label" && !value ) {
9161			return;
9162		}
9163
9164		this._super( key, value );
9165
9166		if ( key === "disabled" ) {
9167			this._toggleClass( this.label, null, "ui-state-disabled", value );
9168			this.element[ 0 ].disabled = value;
9169
9170			// Don't refresh when setting disabled
9171			return;
9172		}
9173		this.refresh();
9174	},
9175
9176	_updateIcon: function( checked ) {
9177		var toAdd = "ui-icon ui-icon-background ";
9178
9179		if ( this.options.icon ) {
9180			if ( !this.icon ) {
9181				this.icon = $( "<span>" );
9182				this.iconSpace = $( "<span> </span>" );
9183				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
9184			}
9185
9186			if ( this.type === "checkbox" ) {
9187				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
9188				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
9189			} else {
9190				toAdd += "ui-icon-blank";
9191			}
9192			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
9193			if ( !checked ) {
9194				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
9195			}
9196			this.icon.prependTo( this.label ).after( this.iconSpace );
9197		} else if ( this.icon !== undefined ) {
9198			this.icon.remove();
9199			this.iconSpace.remove();
9200			delete this.icon;
9201		}
9202	},
9203
9204	_updateLabel: function() {
9205
9206		// Remove the contents of the label ( minus the icon, icon space, and input )
9207		var contents = this.label.contents().not( this.element[ 0 ] );
9208		if ( this.icon ) {
9209			contents = contents.not( this.icon[ 0 ] );
9210		}
9211		if ( this.iconSpace ) {
9212			contents = contents.not( this.iconSpace[ 0 ] );
9213		}
9214		contents.remove();
9215
9216		this.label.append( this.options.label );
9217	},
9218
9219	refresh: function() {
9220		var checked = this.element[ 0 ].checked,
9221			isDisabled = this.element[ 0 ].disabled;
9222
9223		this._updateIcon( checked );
9224		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9225		if ( this.options.label !== null ) {
9226			this._updateLabel();
9227		}
9228
9229		if ( isDisabled !== this.options.disabled ) {
9230			this._setOptions( { "disabled": isDisabled } );
9231		}
9232	}
9233
9234} ] );
9235
9236var widgetsCheckboxradio = $.ui.checkboxradio;
9237
9238
9239/*!
9240 * jQuery UI Button 1.14.2
9241 * https://jqueryui.com
9242 *
9243 * Copyright OpenJS Foundation and other contributors
9244 * Released under the MIT license.
9245 * https://jquery.org/license
9246 */
9247
9248//>>label: Button
9249//>>group: Widgets
9250//>>description: Enhances a form with themeable buttons.
9251//>>docs: https://api.jqueryui.com/button/
9252//>>demos: https://jqueryui.com/button/
9253//>>css.structure: ../../themes/base/core.css
9254//>>css.structure: ../../themes/base/button.css
9255//>>css.theme: ../../themes/base/theme.css
9256
9257
9258$.widget( "ui.button", {
9259	version: "1.14.2",
9260	defaultElement: "<button>",
9261	options: {
9262		classes: {
9263			"ui-button": "ui-corner-all"
9264		},
9265		disabled: null,
9266		icon: null,
9267		iconPosition: "beginning",
9268		label: null,
9269		showLabel: true
9270	},
9271
9272	_getCreateOptions: function() {
9273		var disabled,
9274
9275			// This is to support cases like in jQuery Mobile where the base widget does have
9276			// an implementation of _getCreateOptions
9277			options = this._super() || {};
9278
9279		this.isInput = this.element.is( "input" );
9280
9281		disabled = this.element[ 0 ].disabled;
9282		if ( disabled != null ) {
9283			options.disabled = disabled;
9284		}
9285
9286		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
9287		if ( this.originalLabel ) {
9288			options.label = this.originalLabel;
9289		}
9290
9291		return options;
9292	},
9293
9294	_create: function() {
9295		if ( !this.option.showLabel & !this.options.icon ) {
9296			this.options.showLabel = true;
9297		}
9298
9299		// We have to check the option again here even though we did in _getCreateOptions,
9300		// because null may have been passed on init which would override what was set in
9301		// _getCreateOptions
9302		if ( this.options.disabled == null ) {
9303			this.options.disabled = this.element[ 0 ].disabled || false;
9304		}
9305
9306		this.hasTitle = !!this.element.attr( "title" );
9307
9308		// Check to see if the label needs to be set or if its already correct
9309		if ( this.options.label && this.options.label !== this.originalLabel ) {
9310			if ( this.isInput ) {
9311				this.element.val( this.options.label );
9312			} else {
9313				this.element.html( this.options.label );
9314			}
9315		}
9316		this._addClass( "ui-button", "ui-widget" );
9317		this._setOption( "disabled", this.options.disabled );
9318		this._enhance();
9319
9320		if ( this.element.is( "a" ) ) {
9321			this._on( {
9322				"keyup": function( event ) {
9323					if ( event.keyCode === $.ui.keyCode.SPACE ) {
9324						event.preventDefault();
9325
9326						// If a native click is available use it, so we
9327						// actually cause navigation. Otherwise, just trigger
9328						// a click event.
9329						if ( this.element[ 0 ].click ) {
9330							this.element[ 0 ].click();
9331						} else {
9332							this.element.trigger( "click" );
9333						}
9334					}
9335				}
9336			} );
9337		}
9338	},
9339
9340	_enhance: function() {
9341		if ( !this.element.is( "button" ) ) {
9342			this.element.attr( "role", "button" );
9343		}
9344
9345		if ( this.options.icon ) {
9346			this._updateIcon( "icon", this.options.icon );
9347			this._updateTooltip();
9348		}
9349	},
9350
9351	_updateTooltip: function() {
9352		this.title = this.element.attr( "title" );
9353
9354		if ( !this.options.showLabel && !this.title ) {
9355			this.element.attr( "title", this.options.label );
9356		}
9357	},
9358
9359	_updateIcon: function( option, value ) {
9360		var icon = option !== "iconPosition",
9361			position = icon ? this.options.iconPosition : value,
9362			displayBlock = position === "top" || position === "bottom";
9363
9364		// Create icon
9365		if ( !this.icon ) {
9366			this.icon = $( "<span>" );
9367
9368			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
9369
9370			if ( !this.options.showLabel ) {
9371				this._addClass( "ui-button-icon-only" );
9372			}
9373		} else if ( icon ) {
9374
9375			// If we are updating the icon remove the old icon class
9376			this._removeClass( this.icon, null, this.options.icon );
9377		}
9378
9379		// If we are updating the icon add the new icon class
9380		if ( icon ) {
9381			this._addClass( this.icon, null, value );
9382		}
9383
9384		this._attachIcon( position );
9385
9386		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
9387		// the iconSpace if there is one.
9388		if ( displayBlock ) {
9389			this._addClass( this.icon, null, "ui-widget-icon-block" );
9390			if ( this.iconSpace ) {
9391				this.iconSpace.remove();
9392			}
9393		} else {
9394
9395			// Position is beginning or end so remove the ui-widget-icon-block class and add the
9396			// space if it does not exist
9397			if ( !this.iconSpace ) {
9398				this.iconSpace = $( "<span> </span>" );
9399				this._addClass( this.iconSpace, "ui-button-icon-space" );
9400			}
9401			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
9402			this._attachIconSpace( position );
9403		}
9404	},
9405
9406	_destroy: function() {
9407		this.element.removeAttr( "role" );
9408
9409		if ( this.icon ) {
9410			this.icon.remove();
9411		}
9412		if ( this.iconSpace ) {
9413			this.iconSpace.remove();
9414		}
9415		if ( !this.hasTitle ) {
9416			this.element.removeAttr( "title" );
9417		}
9418	},
9419
9420	_attachIconSpace: function( iconPosition ) {
9421		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
9422	},
9423
9424	_attachIcon: function( iconPosition ) {
9425		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
9426	},
9427
9428	_setOptions: function( options ) {
9429		var newShowLabel = options.showLabel === undefined ?
9430				this.options.showLabel :
9431				options.showLabel,
9432			newIcon = options.icon === undefined ? this.options.icon : options.icon;
9433
9434		if ( !newShowLabel && !newIcon ) {
9435			options.showLabel = true;
9436		}
9437		this._super( options );
9438	},
9439
9440	_setOption: function( key, value ) {
9441		if ( key === "icon" ) {
9442			if ( value ) {
9443				this._updateIcon( key, value );
9444			} else if ( this.icon ) {
9445				this.icon.remove();
9446				if ( this.iconSpace ) {
9447					this.iconSpace.remove();
9448				}
9449			}
9450		}
9451
9452		if ( key === "iconPosition" ) {
9453			this._updateIcon( key, value );
9454		}
9455
9456		// Make sure we can't end up with a button that has neither text nor icon
9457		if ( key === "showLabel" ) {
9458				this._toggleClass( "ui-button-icon-only", null, !value );
9459				this._updateTooltip();
9460		}
9461
9462		if ( key === "label" ) {
9463			if ( this.isInput ) {
9464				this.element.val( value );
9465			} else {
9466
9467				// If there is an icon, append it, else nothing then append the value
9468				// this avoids removal of the icon when setting label text
9469				this.element.html( value );
9470				if ( this.icon ) {
9471					this._attachIcon( this.options.iconPosition );
9472					this._attachIconSpace( this.options.iconPosition );
9473				}
9474			}
9475		}
9476
9477		this._super( key, value );
9478
9479		if ( key === "disabled" ) {
9480			this._toggleClass( null, "ui-state-disabled", value );
9481			this.element[ 0 ].disabled = value;
9482			if ( value ) {
9483				this.element.trigger( "blur" );
9484			}
9485		}
9486	},
9487
9488	refresh: function() {
9489
9490		// Make sure to only check disabled if its an element that supports this otherwise
9491		// check for the disabled class to determine state
9492		var isDisabled = this.element.is( "input, button" ) ?
9493			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
9494
9495		if ( isDisabled !== this.options.disabled ) {
9496			this._setOptions( { disabled: isDisabled } );
9497		}
9498
9499		this._updateTooltip();
9500	}
9501} );
9502
9503// DEPRECATED
9504if ( $.uiBackCompat === true ) {
9505
9506	// Text and Icons options
9507	$.widget( "ui.button", $.ui.button, {
9508		options: {
9509			text: true,
9510			icons: {
9511				primary: null,
9512				secondary: null
9513			}
9514		},
9515
9516		_create: function() {
9517			if ( this.options.showLabel && !this.options.text ) {
9518				this.options.showLabel = this.options.text;
9519			}
9520			if ( !this.options.showLabel && this.options.text ) {
9521				this.options.text = this.options.showLabel;
9522			}
9523			if ( !this.options.icon && ( this.options.icons.primary ||
9524					this.options.icons.secondary ) ) {
9525				if ( this.options.icons.primary ) {
9526					this.options.icon = this.options.icons.primary;
9527				} else {
9528					this.options.icon = this.options.icons.secondary;
9529					this.options.iconPosition = "end";
9530				}
9531			} else if ( this.options.icon ) {
9532				this.options.icons.primary = this.options.icon;
9533			}
9534			this._super();
9535		},
9536
9537		_setOption: function( key, value ) {
9538			if ( key === "text" ) {
9539				this._super( "showLabel", value );
9540				return;
9541			}
9542			if ( key === "showLabel" ) {
9543				this.options.text = value;
9544			}
9545			if ( key === "icon" ) {
9546				this.options.icons.primary = value;
9547			}
9548			if ( key === "icons" ) {
9549				if ( value.primary ) {
9550					this._super( "icon", value.primary );
9551					this._super( "iconPosition", "beginning" );
9552				} else if ( value.secondary ) {
9553					this._super( "icon", value.secondary );
9554					this._super( "iconPosition", "end" );
9555				}
9556			}
9557			this._superApply( arguments );
9558		}
9559	} );
9560
9561	$.fn.button = ( function( orig ) {
9562		return function( options ) {
9563			var isMethodCall = typeof options === "string";
9564			var args = Array.prototype.slice.call( arguments, 1 );
9565			var returnValue = this;
9566
9567			if ( isMethodCall ) {
9568
9569				// If this is an empty collection, we need to have the instance method
9570				// return undefined instead of the jQuery instance
9571				if ( !this.length && options === "instance" ) {
9572					returnValue = undefined;
9573				} else {
9574					this.each( function() {
9575						var methodValue;
9576						var type = $( this ).attr( "type" );
9577						var name = type !== "checkbox" && type !== "radio" ?
9578							"button" :
9579							"checkboxradio";
9580						var instance = $.data( this, "ui-" + name );
9581
9582						if ( options === "instance" ) {
9583							returnValue = instance;
9584							return false;
9585						}
9586
9587						if ( !instance ) {
9588							return $.error( "cannot call methods on button" +
9589								" prior to initialization; " +
9590								"attempted to call method '" + options + "'" );
9591						}
9592
9593						if ( typeof instance[ options ] !== "function" ||
9594							options.charAt( 0 ) === "_" ) {
9595							return $.error( "no such method '" + options + "' for button" +
9596								" widget instance" );
9597						}
9598
9599						methodValue = instance[ options ].apply( instance, args );
9600
9601						if ( methodValue !== instance && methodValue !== undefined ) {
9602							returnValue = methodValue && methodValue.jquery ?
9603								returnValue.pushStack( methodValue.get() ) :
9604								methodValue;
9605							return false;
9606						}
9607					} );
9608				}
9609			} else {
9610
9611				// Allow multiple hashes to be passed on init
9612				if ( args.length ) {
9613					options = $.widget.extend.apply( null, [ options ].concat( args ) );
9614				}
9615
9616				this.each( function() {
9617					var type = $( this ).attr( "type" );
9618					var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
9619					var instance = $.data( this, "ui-" + name );
9620
9621					if ( instance ) {
9622						instance.option( options || {} );
9623						if ( instance._init ) {
9624							instance._init();
9625						}
9626					} else {
9627						if ( name === "button" ) {
9628							orig.call( $( this ), options );
9629							return;
9630						}
9631
9632						$( this ).checkboxradio( $.extend( { icon: false }, options ) );
9633					}
9634				} );
9635			}
9636
9637			return returnValue;
9638		};
9639	} )( $.fn.button );
9640
9641	$.fn.buttonset = function() {
9642		if ( !$.ui.controlgroup ) {
9643			$.error( "Controlgroup widget missing" );
9644		}
9645		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
9646			return this.controlgroup.apply( this,
9647				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
9648		}
9649		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
9650			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
9651		}
9652		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
9653			arguments[ 0 ].items = {
9654				button: arguments[ 0 ].items
9655			};
9656		}
9657		return this.controlgroup.apply( this, arguments );
9658	};
9659}
9660
9661var widgetsButton = $.ui.button;
9662
9663
9664/* eslint-disable max-len */
9665/*!
9666 * jQuery UI Datepicker 1.14.2
9667 * https://jqueryui.com
9668 *
9669 * Copyright OpenJS Foundation and other contributors
9670 * Released under the MIT license.
9671 * https://jquery.org/license
9672 */
9673
9674//>>label: Datepicker
9675//>>group: Widgets
9676//>>description: Displays a calendar from an input or inline for selecting dates.
9677//>>docs: https://api.jqueryui.com/datepicker/
9678//>>demos: https://jqueryui.com/datepicker/
9679//>>css.structure: ../../themes/base/core.css
9680//>>css.structure: ../../themes/base/datepicker.css
9681//>>css.theme: ../../themes/base/theme.css
9682
9683
9684$.extend( $.ui, { datepicker: { version: "1.14.2" } } );
9685
9686var datepicker_instActive;
9687
9688function datepicker_getZindex( elem ) {
9689	var position, value;
9690	while ( elem.length && elem[ 0 ] !== document ) {
9691
9692		// Ignore z-index if position is set to a value where z-index is ignored by the browser
9693		// This makes behavior of this function consistent across browsers
9694		// WebKit always returns auto if the element is positioned
9695		position = elem.css( "position" );
9696		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
9697
9698			// IE returns 0 when zIndex is not specified
9699			// other browsers return a string
9700			// we ignore the case of nested elements with an explicit value of 0
9701			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
9702			value = parseInt( elem.css( "zIndex" ), 10 );
9703			if ( !isNaN( value ) && value !== 0 ) {
9704				return value;
9705			}
9706		}
9707		elem = elem.parent();
9708	}
9709
9710	return 0;
9711}
9712
9713/* Date picker manager.
9714   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
9715   Settings for (groups of) date pickers are maintained in an instance object,
9716   allowing multiple different settings on the same page. */
9717
9718function Datepicker() {
9719	this._curInst = null; // The current instance in use
9720	this._keyEvent = false; // If the last event was a key event
9721	this._disabledInputs = []; // List of date picker inputs that have been disabled
9722	this._datepickerShowing = false; // True if the popup picker is showing , false if not
9723	this._inDialog = false; // True if showing within a "dialog", false if not
9724	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
9725	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
9726	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
9727	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
9728	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
9729	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
9730	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
9731	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
9732	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
9733	this.regional = []; // Available regional settings, indexed by language code
9734	this.regional[ "" ] = { // Default regional settings
9735		closeText: "Done", // Display text for close link
9736		prevText: "Prev", // Display text for previous month link
9737		nextText: "Next", // Display text for next month link
9738		currentText: "Today", // Display text for current month link
9739		monthNames: [ "January", "February", "March", "April", "May", "June",
vendor: 40,309 bytes, lines 9740-10834
9740			"July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting
9741		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
9742		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
9743		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
9744		dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday
9745		weekHeader: "Wk", // Column header for week of the year
9746		dateFormat: "mm/dd/yy", // See format options on parseDate
9747		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
9748		isRTL: false, // True if right-to-left language, false if left-to-right
9749		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
9750		yearSuffix: "", // Additional text to append to the year in the month headers,
9751		selectMonthLabel: "Select month", // Invisible label for month selector
9752		selectYearLabel: "Select year" // Invisible label for year selector
9753	};
9754	this._defaults = { // Global defaults for all the date picker instances
9755		showOn: "focus", // "focus" for popup on focus,
9756			// "button" for trigger button, or "both" for either
9757		showAnim: "fadeIn", // Name of jQuery animation for popup
9758		showOptions: {}, // Options for enhanced animations
9759		defaultDate: null, // Used when field is blank: actual date,
9760			// +/-number for offset from today, null for today
9761		appendText: "", // Display text following the input box, e.g. showing the format
9762		buttonText: "...", // Text for trigger button
9763		buttonImage: "", // URL for trigger button image
9764		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
9765		hideIfNoPrevNext: false, // True to hide next/previous month links
9766			// if not applicable, false to just disable them
9767		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
9768		gotoCurrent: false, // True if today link goes back to current selection instead
9769		changeMonth: false, // True if month can be selected directly, false if only prev/next
9770		changeYear: false, // True if year can be selected directly, false if only prev/next
9771		yearRange: "c-10:c+10", // Range of years to display in drop-down,
9772			// either relative to today's year (-nn:+nn), relative to currently displayed year
9773			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
9774		showOtherMonths: false, // True to show dates in other months, false to leave blank
9775		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
9776		showWeek: false, // True to show week of the year, false to not show it
9777		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
9778			// takes a Date and returns the number of the week for it
9779		shortYearCutoff: "+10", // Short year values < this are in the current century,
9780			// > this are in the previous century,
9781			// string value starting with "+" for current year + value
9782		minDate: null, // The earliest selectable date, or null for no limit
9783		maxDate: null, // The latest selectable date, or null for no limit
9784		duration: "fast", // Duration of display/closure
9785		beforeShowDay: null, // Function that takes a date and returns an array with
9786			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
9787			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
9788		beforeShow: null, // Function that takes an input field and
9789			// returns a set of custom settings for the date picker
9790		onSelect: null, // Define a callback function when a date is selected
9791		onChangeMonthYear: null, // Define a callback function when the month or year is changed
9792		onClose: null, // Define a callback function when the datepicker is closed
9793		onUpdateDatepicker: null, // Define a callback function when the datepicker is updated
9794		numberOfMonths: 1, // Number of months to show at a time
9795		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
9796		stepMonths: 1, // Number of months to step back/forward
9797		stepBigMonths: 12, // Number of months to step back/forward for the big links
9798		altField: "", // Selector for an alternate field to store selected dates into
9799		altFormat: "", // The date format to use for the alternate field
9800		constrainInput: true, // The input is constrained by the current date format
9801		showButtonPanel: false, // True to show button panel, false to not show it
9802		autoSize: false, // True to size the input for the date format, false to leave as is
9803		disabled: false // The initial disabled state
9804	};
9805	$.extend( this._defaults, this.regional[ "" ] );
9806	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
9807	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
9808	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
9809}
9810
9811$.extend( Datepicker.prototype, {
9812
9813	/* Class name added to elements to indicate already configured with a date picker. */
9814	markerClassName: "hasDatepicker",
9815
9816	//Keep track of the maximum number of rows displayed (see #7043)
9817	maxRows: 4,
9818
9819	// TODO rename to "widget" when switching to widget factory
9820	_widgetDatepicker: function() {
9821		return this.dpDiv;
9822	},
9823
9824	/* Override the default settings for all instances of the date picker.
9825	 * @param  settings  object - the new settings to use as defaults (anonymous object)
9826	 * @return the manager object
9827	 */
9828	setDefaults: function( settings ) {
9829		datepicker_extendRemove( this._defaults, settings || {} );
9830		return this;
9831	},
9832
9833	/* Attach the date picker to a jQuery selection.
9834	 * @param  target	element - the target input field or division or span
9835	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
9836	 */
9837	_attachDatepicker: function( target, settings ) {
9838		var nodeName, inline, inst;
9839		nodeName = target.nodeName.toLowerCase();
9840		inline = ( nodeName === "div" || nodeName === "span" );
9841		if ( !target.id ) {
9842			this.uuid += 1;
9843			target.id = "dp" + this.uuid;
9844		}
9845		inst = this._newInst( $( target ), inline );
9846		inst.settings = $.extend( {}, settings || {} );
9847		if ( nodeName === "input" ) {
9848			this._connectDatepicker( target, inst );
9849		} else if ( inline ) {
9850			this._inlineDatepicker( target, inst );
9851		}
9852	},
9853
9854	/* Create a new instance object. */
9855	_newInst: function( target, inline ) {
9856		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
9857		return { id: id, input: target, // associated target
9858			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
9859			drawMonth: 0, drawYear: 0, // month being drawn
9860			inline: inline, // is datepicker inline or not
9861			dpDiv: ( !inline ? this.dpDiv : // presentation div
9862			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
9863	},
9864
9865	/* Attach the date picker to an input field. */
9866	_connectDatepicker: function( target, inst ) {
9867		var input = $( target );
9868		inst.append = $( [] );
9869		inst.trigger = $( [] );
9870		if ( input.hasClass( this.markerClassName ) ) {
9871			return;
9872		}
9873		this._attachments( input, inst );
9874		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
9875			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
9876		this._autoSize( inst );
9877		$.data( target, "datepicker", inst );
9878
9879		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
9880		if ( inst.settings.disabled ) {
9881			this._disableDatepicker( target );
9882		}
9883	},
9884
9885	/* Make attachments based on settings. */
9886	_attachments: function( input, inst ) {
9887		var showOn, buttonText, buttonImage,
9888			appendText = this._get( inst, "appendText" ),
9889			isRTL = this._get( inst, "isRTL" );
9890
9891		if ( inst.append ) {
9892			inst.append.remove();
9893		}
9894		if ( appendText ) {
9895			inst.append = $( "<span>" )
9896				.addClass( this._appendClass )
9897				.text( appendText );
9898			input[ isRTL ? "before" : "after" ]( inst.append );
9899		}
9900
9901		input.off( "focus", this._showDatepicker );
9902
9903		if ( inst.trigger ) {
9904			inst.trigger.remove();
9905		}
9906
9907		showOn = this._get( inst, "showOn" );
9908		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
9909			input.on( "focus", this._showDatepicker );
9910		}
9911		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
9912			buttonText = this._get( inst, "buttonText" );
9913			buttonImage = this._get( inst, "buttonImage" );
9914
9915			if ( this._get( inst, "buttonImageOnly" ) ) {
9916				inst.trigger = $( "<img>" )
9917					.addClass( this._triggerClass )
9918					.attr( {
9919						src: buttonImage,
9920						alt: buttonText,
9921						title: buttonText
9922					} );
9923			} else {
9924				inst.trigger = $( "<button type='button'>" )
9925					.addClass( this._triggerClass );
9926				if ( buttonImage ) {
9927					inst.trigger.html(
9928						$( "<img>" )
9929							.attr( {
9930								src: buttonImage,
9931								alt: buttonText,
9932								title: buttonText
9933							} )
9934					);
9935				} else {
9936					inst.trigger.text( buttonText );
9937				}
9938			}
9939
9940			input[ isRTL ? "before" : "after" ]( inst.trigger );
9941			inst.trigger.on( "click", function() {
9942				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
9943					$.datepicker._hideDatepicker();
9944				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
9945					$.datepicker._hideDatepicker();
9946					$.datepicker._showDatepicker( input[ 0 ] );
9947				} else {
9948					$.datepicker._showDatepicker( input[ 0 ] );
9949				}
9950				return false;
9951			} );
9952		}
9953	},
9954
9955	/* Apply the maximum length for the date format. */
9956	_autoSize: function( inst ) {
9957		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
9958			var findMax, max, maxI, i,
9959				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
9960				dateFormat = this._get( inst, "dateFormat" );
9961
9962			if ( dateFormat.match( /[DM]/ ) ) {
9963				findMax = function( names ) {
9964					max = 0;
9965					maxI = 0;
9966					for ( i = 0; i < names.length; i++ ) {
9967						if ( names[ i ].length > max ) {
9968							max = names[ i ].length;
9969							maxI = i;
9970						}
9971					}
9972					return maxI;
9973				};
9974				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
9975					"monthNames" : "monthNamesShort" ) ) ) );
9976				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
9977					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
9978			}
9979			inst.input.attr( "size", this._formatDate( inst, date ).length );
9980		}
9981	},
9982
9983	/* Attach an inline date picker to a div. */
9984	_inlineDatepicker: function( target, inst ) {
9985		var divSpan = $( target );
9986		if ( divSpan.hasClass( this.markerClassName ) ) {
9987			return;
9988		}
9989		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
9990		$.data( target, "datepicker", inst );
9991		this._setDate( inst, this._getDefaultDate( inst ), true );
9992		this._updateDatepicker( inst );
9993		this._updateAlternate( inst );
9994
9995		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
9996		if ( inst.settings.disabled ) {
9997			this._disableDatepicker( target );
9998		}
9999
10000		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
10001		// https://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
10002		inst.dpDiv.css( "display", "block" );
10003	},
10004
10005	/* Pop-up the date picker in a "dialog" box.
10006	 * @param  input element - ignored
10007	 * @param  date	string or Date - the initial date to display
10008	 * @param  onSelect  function - the function to call when a date is selected
10009	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
10010	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
10011	 *					event - with x/y coordinates or
10012	 *					leave empty for default (screen centre)
10013	 * @return the manager object
10014	 */
10015	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
10016		var id, browserWidth, browserHeight, scrollX, scrollY,
10017			inst = this._dialogInst; // internal instance
10018
10019		if ( !inst ) {
10020			this.uuid += 1;
10021			id = "dp" + this.uuid;
10022			this._dialogInput = $( "<input type='text' id='" + id +
10023				"' style='position: absolute; top: -100px; width: 0px;'/>" );
10024			this._dialogInput.on( "keydown", this._doKeyDown );
10025			$( "body" ).append( this._dialogInput );
10026			inst = this._dialogInst = this._newInst( this._dialogInput, false );
10027			inst.settings = {};
10028			$.data( this._dialogInput[ 0 ], "datepicker", inst );
10029		}
10030		datepicker_extendRemove( inst.settings, settings || {} );
10031		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
10032		this._dialogInput.val( date );
10033
10034		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
10035		if ( !this._pos ) {
10036			browserWidth = document.documentElement.clientWidth;
10037			browserHeight = document.documentElement.clientHeight;
10038			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
10039			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
10040			this._pos = // should use actual width/height below
10041				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
10042		}
10043
10044		// Move input on screen for focus, but hidden behind dialog
10045		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
10046		inst.settings.onSelect = onSelect;
10047		this._inDialog = true;
10048		this.dpDiv.addClass( this._dialogClass );
10049		this._showDatepicker( this._dialogInput[ 0 ] );
10050		if ( $.blockUI ) {
10051			$.blockUI( this.dpDiv );
10052		}
10053		$.data( this._dialogInput[ 0 ], "datepicker", inst );
10054		return this;
10055	},
10056
10057	/* Detach a datepicker from its control.
10058	 * @param  target	element - the target input field or division or span
10059	 */
10060	_destroyDatepicker: function( target ) {
10061		var nodeName,
10062			$target = $( target ),
10063			inst = $.data( target, "datepicker" );
10064
10065		if ( !$target.hasClass( this.markerClassName ) ) {
10066			return;
10067		}
10068
10069		nodeName = target.nodeName.toLowerCase();
10070		$.removeData( target, "datepicker" );
10071		if ( nodeName === "input" ) {
10072			inst.append.remove();
10073			inst.trigger.remove();
10074			$target.removeClass( this.markerClassName ).
10075				off( "focus", this._showDatepicker ).
10076				off( "keydown", this._doKeyDown ).
10077				off( "keypress", this._doKeyPress ).
10078				off( "keyup", this._doKeyUp );
10079		} else if ( nodeName === "div" || nodeName === "span" ) {
10080			$target.removeClass( this.markerClassName ).empty();
10081		}
10082
10083		$.datepicker._hideDatepicker();
10084		if ( datepicker_instActive === inst ) {
10085			datepicker_instActive = null;
10086			this._curInst = null;
10087		}
10088	},
10089
10090	/* Enable the date picker to a jQuery selection.
10091	 * @param  target	element - the target input field or division or span
10092	 */
10093	_enableDatepicker: function( target ) {
10094		var nodeName, inline,
10095			$target = $( target ),
10096			inst = $.data( target, "datepicker" );
10097
10098		if ( !$target.hasClass( this.markerClassName ) ) {
10099			return;
10100		}
10101
10102		nodeName = target.nodeName.toLowerCase();
10103		if ( nodeName === "input" ) {
10104			target.disabled = false;
10105			inst.trigger.filter( "button" ).
10106				each( function() {
10107					this.disabled = false;
10108				} ).end().
10109				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
10110		} else if ( nodeName === "div" || nodeName === "span" ) {
10111			inline = $target.children( "." + this._inlineClass );
10112			inline.children().removeClass( "ui-state-disabled" );
10113			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
10114				prop( "disabled", false );
10115		}
10116		this._disabledInputs = $.map( this._disabledInputs,
10117
10118			// Delete entry
10119			function( value ) {
10120				return ( value === target ? null : value );
10121			} );
10122	},
10123
10124	/* Disable the date picker to a jQuery selection.
10125	 * @param  target	element - the target input field or division or span
10126	 */
10127	_disableDatepicker: function( target ) {
10128		var nodeName, inline,
10129			$target = $( target ),
10130			inst = $.data( target, "datepicker" );
10131
10132		if ( !$target.hasClass( this.markerClassName ) ) {
10133			return;
10134		}
10135
10136		nodeName = target.nodeName.toLowerCase();
10137		if ( nodeName === "input" ) {
10138			target.disabled = true;
10139			inst.trigger.filter( "button" ).
10140				each( function() {
10141					this.disabled = true;
10142				} ).end().
10143				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
10144		} else if ( nodeName === "div" || nodeName === "span" ) {
10145			inline = $target.children( "." + this._inlineClass );
10146			inline.children().addClass( "ui-state-disabled" );
10147			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
10148				prop( "disabled", true );
10149		}
10150		this._disabledInputs = $.map( this._disabledInputs,
10151
10152			// Delete entry
10153			function( value ) {
10154				return ( value === target ? null : value );
10155			} );
10156		this._disabledInputs[ this._disabledInputs.length ] = target;
10157	},
10158
10159	/* Is the first field in a jQuery collection disabled as a datepicker?
10160	 * @param  target	element - the target input field or division or span
10161	 * @return boolean - true if disabled, false if enabled
10162	 */
10163	_isDisabledDatepicker: function( target ) {
10164		if ( !target ) {
10165			return false;
10166		}
10167		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
10168			if ( this._disabledInputs[ i ] === target ) {
10169				return true;
10170			}
10171		}
10172		return false;
10173	},
10174
10175	/* Retrieve the instance data for the target control.
10176	 * @param  target  element - the target input field or division or span
10177	 * @return  object - the associated instance data
10178	 * @throws  error if a jQuery problem getting data
10179	 */
10180	_getInst: function( target ) {
10181		try {
10182			return $.data( target, "datepicker" );
10183		} catch ( _err ) {
10184			throw "Missing instance data for this datepicker";
10185		}
10186	},
10187
10188	/* Update or retrieve the settings for a date picker attached to an input field or division.
10189	 * @param  target  element - the target input field or division or span
10190	 * @param  name	object - the new settings to update or
10191	 *				string - the name of the setting to change or retrieve,
10192	 *				when retrieving also "all" for all instance settings or
10193	 *				"defaults" for all global defaults
10194	 * @param  value   any - the new value for the setting
10195	 *				(omit if above is an object or to retrieve a value)
10196	 */
10197	_optionDatepicker: function( target, name, value ) {
10198		var settings, date, minDate, maxDate,
10199			inst = this._getInst( target );
10200
10201		if ( arguments.length === 2 && typeof name === "string" ) {
10202			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
10203				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
10204				this._get( inst, name ) ) : null ) );
10205		}
10206
10207		settings = name || {};
10208		if ( typeof name === "string" ) {
10209			settings = {};
10210			settings[ name ] = value;
10211		}
10212
10213		if ( inst ) {
10214			if ( this._curInst === inst ) {
10215				this._hideDatepicker();
10216			}
10217
10218			date = this._getDateDatepicker( target, true );
10219			minDate = this._getMinMaxDate( inst, "min" );
10220			maxDate = this._getMinMaxDate( inst, "max" );
10221			datepicker_extendRemove( inst.settings, settings );
10222
10223			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
10224			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
10225				inst.settings.minDate = this._formatDate( inst, minDate );
10226			}
10227			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
10228				inst.settings.maxDate = this._formatDate( inst, maxDate );
10229			}
10230			if ( "disabled" in settings ) {
10231				if ( settings.disabled ) {
10232					this._disableDatepicker( target );
10233				} else {
10234					this._enableDatepicker( target );
10235				}
10236			}
10237			this._attachments( $( target ), inst );
10238			this._autoSize( inst );
10239			this._setDate( inst, date );
10240			this._updateAlternate( inst );
10241			this._updateDatepicker( inst );
10242		}
10243	},
10244
10245	// Change method deprecated
10246	_changeDatepicker: function( target, name, value ) {
10247		this._optionDatepicker( target, name, value );
10248	},
10249
10250	/* Redraw the date picker attached to an input field or division.
10251	 * @param  target  element - the target input field or division or span
10252	 */
10253	_refreshDatepicker: function( target ) {
10254		var inst = this._getInst( target );
10255		if ( inst ) {
10256			this._updateDatepicker( inst );
10257		}
10258	},
10259
10260	/* Set the dates for a jQuery selection.
10261	 * @param  target element - the target input field or division or span
10262	 * @param  date	Date - the new date
10263	 */
10264	_setDateDatepicker: function( target, date ) {
10265		var inst = this._getInst( target );
10266		if ( inst ) {
10267			this._setDate( inst, date );
10268			this._updateDatepicker( inst );
10269			this._updateAlternate( inst );
10270		}
10271	},
10272
10273	/* Get the date(s) for the first entry in a jQuery selection.
10274	 * @param  target element - the target input field or division or span
10275	 * @param  noDefault boolean - true if no default date is to be used
10276	 * @return Date - the current date
10277	 */
10278	_getDateDatepicker: function( target, noDefault ) {
10279		var inst = this._getInst( target );
10280		if ( inst && !inst.inline ) {
10281			this._setDateFromField( inst, noDefault );
10282		}
10283		return ( inst ? this._getDate( inst ) : null );
10284	},
10285
10286	/* Handle keystrokes. */
10287	_doKeyDown: function( event ) {
10288		var onSelect, dateStr, sel,
10289			inst = $.datepicker._getInst( event.target ),
10290			handled = true,
10291			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
10292
10293		inst._keyEvent = true;
10294		if ( $.datepicker._datepickerShowing ) {
10295			switch ( event.keyCode ) {
10296				case 9: $.datepicker._hideDatepicker();
10297						handled = false;
10298						break; // hide on tab out
10299				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
10300									$.datepicker._currentClass + ")", inst.dpDiv );
10301						if ( sel[ 0 ] ) {
10302							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
10303						}
10304
10305						onSelect = $.datepicker._get( inst, "onSelect" );
10306						if ( onSelect ) {
10307							dateStr = $.datepicker._formatDate( inst );
10308
10309							// Trigger custom callback
10310							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
10311						} else {
10312							$.datepicker._hideDatepicker();
10313						}
10314
10315						return false; // don't submit the form
10316				case 27: $.datepicker._hideDatepicker();
10317						break; // hide on escape
10318				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10319							-$.datepicker._get( inst, "stepBigMonths" ) :
10320							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10321						break; // previous month/year on page up/+ ctrl
10322				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10323							+$.datepicker._get( inst, "stepBigMonths" ) :
10324							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10325						break; // next month/year on page down/+ ctrl
10326				case 35: if ( event.ctrlKey || event.metaKey ) {
10327							$.datepicker._clearDate( event.target );
10328						}
10329						handled = event.ctrlKey || event.metaKey;
10330						break; // clear on ctrl or command +end
10331				case 36: if ( event.ctrlKey || event.metaKey ) {
10332							$.datepicker._gotoToday( event.target );
10333						}
10334						handled = event.ctrlKey || event.metaKey;
10335						break; // current on ctrl or command +home
10336				case 37: if ( event.ctrlKey || event.metaKey ) {
10337							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
10338						}
10339						handled = event.ctrlKey || event.metaKey;
10340
10341						// -1 day on ctrl or command +left
10342						if ( event.originalEvent.altKey ) {
10343							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10344								-$.datepicker._get( inst, "stepBigMonths" ) :
10345								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10346						}
10347
10348						// next month/year on alt +left on Mac
10349						break;
10350				case 38: if ( event.ctrlKey || event.metaKey ) {
10351							$.datepicker._adjustDate( event.target, -7, "D" );
10352						}
10353						handled = event.ctrlKey || event.metaKey;
10354						break; // -1 week on ctrl or command +up
10355				case 39: if ( event.ctrlKey || event.metaKey ) {
10356							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
10357						}
10358						handled = event.ctrlKey || event.metaKey;
10359
10360						// +1 day on ctrl or command +right
10361						if ( event.originalEvent.altKey ) {
10362							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10363								+$.datepicker._get( inst, "stepBigMonths" ) :
10364								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10365						}
10366
10367						// next month/year on alt +right
10368						break;
10369				case 40: if ( event.ctrlKey || event.metaKey ) {
10370							$.datepicker._adjustDate( event.target, +7, "D" );
10371						}
10372						handled = event.ctrlKey || event.metaKey;
10373						break; // +1 week on ctrl or command +down
10374				default: handled = false;
10375			}
10376		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
10377			$.datepicker._showDatepicker( this );
10378		} else {
10379			handled = false;
10380		}
10381
10382		if ( handled ) {
10383			event.preventDefault();
10384			event.stopPropagation();
10385		}
10386	},
10387
10388	/* Filter entered characters - based on date format. */
10389	_doKeyPress: function( event ) {
10390		var chars, chr,
10391			inst = $.datepicker._getInst( event.target );
10392
10393		if ( $.datepicker._get( inst, "constrainInput" ) ) {
10394			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
10395			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
10396			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
10397		}
10398	},
10399
10400	/* Synchronise manual entry and field/alternate field. */
10401	_doKeyUp: function( event ) {
10402		var date,
10403			inst = $.datepicker._getInst( event.target );
10404
10405		if ( inst.input.val() !== inst.lastVal ) {
10406			try {
10407				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
10408					( inst.input ? inst.input.val() : null ),
10409					$.datepicker._getFormatConfig( inst ) );
10410
10411				if ( date ) { // only if valid
10412					$.datepicker._setDateFromField( inst );
10413					$.datepicker._updateAlternate( inst );
10414					$.datepicker._updateDatepicker( inst );
10415				}
10416			} catch ( _err ) {
10417			}
10418		}
10419		return true;
10420	},
10421
10422	/* Pop-up the date picker for a given input field.
10423	 * If false returned from beforeShow event handler do not show.
10424	 * @param  input  element - the input field attached to the date picker or
10425	 *					event - if triggered by focus
10426	 */
10427	_showDatepicker: function( input ) {
10428		input = input.target || input;
10429		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
10430			input = $( "input", input.parentNode )[ 0 ];
10431		}
10432
10433		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
10434			return;
10435		}
10436
10437		var inst, beforeShow, beforeShowSettings, isFixed,
10438			offset, showAnim, duration;
10439
10440		inst = $.datepicker._getInst( input );
10441		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
10442			$.datepicker._curInst.dpDiv.stop( true, true );
10443			if ( inst && $.datepicker._datepickerShowing ) {
10444				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
10445			}
10446		}
10447
10448		beforeShow = $.datepicker._get( inst, "beforeShow" );
10449		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
10450		if ( beforeShowSettings === false ) {
10451			return;
10452		}
10453		datepicker_extendRemove( inst.settings, beforeShowSettings );
10454
10455		inst.lastVal = null;
10456		$.datepicker._lastInput = input;
10457		$.datepicker._setDateFromField( inst );
10458
10459		if ( $.datepicker._inDialog ) { // hide cursor
10460			input.value = "";
10461		}
10462		if ( !$.datepicker._pos ) { // position below input
10463			$.datepicker._pos = $.datepicker._findPos( input );
10464			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
10465		}
10466
10467		isFixed = false;
10468		$( input ).parents().each( function() {
10469			isFixed |= $( this ).css( "position" ) === "fixed";
10470			return !isFixed;
10471		} );
10472
10473		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
10474		$.datepicker._pos = null;
10475
10476		//to avoid flashes on Firefox
10477		inst.dpDiv.empty();
10478
10479		// determine sizing offscreen
10480		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
10481		$.datepicker._updateDatepicker( inst );
10482
10483		// fix width for dynamic number of date pickers
10484		// and adjust position before showing
10485		offset = $.datepicker._checkOffset( inst, offset, isFixed );
10486		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
10487			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
10488			left: offset.left + "px", top: offset.top + "px" } );
10489
10490		if ( !inst.inline ) {
10491			showAnim = $.datepicker._get( inst, "showAnim" );
10492			duration = $.datepicker._get( inst, "duration" );
10493			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
10494			$.datepicker._datepickerShowing = true;
10495
10496			if ( $.effects && $.effects.effect[ showAnim ] ) {
10497				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
10498			} else {
10499				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
10500			}
10501
10502			if ( $.datepicker._shouldFocusInput( inst ) ) {
10503				inst.input.trigger( "focus" );
10504			}
10505
10506			$.datepicker._curInst = inst;
10507		}
10508	},
10509
10510	/* Generate the date picker content. */
10511	_updateDatepicker: function( inst ) {
10512		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
10513		datepicker_instActive = inst; // for delegate hover events
10514		inst.dpDiv.empty().append( this._generateHTML( inst ) );
10515		this._attachHandlers( inst );
10516
10517		var origyearshtml,
10518			numMonths = this._getNumberOfMonths( inst ),
10519			cols = numMonths[ 1 ],
10520			width = 17,
10521			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ),
10522			onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" );
10523
10524		if ( activeCell.length > 0 ) {
10525			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
10526		}
10527
10528		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
10529		if ( cols > 1 ) {
10530			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
10531		}
10532		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
10533			"Class" ]( "ui-datepicker-multi" );
10534		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
10535			"Class" ]( "ui-datepicker-rtl" );
10536
10537		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
10538			inst.input.trigger( "focus" );
10539		}
10540
10541		// Deffered render of the years select (to avoid flashes on Firefox)
10542		if ( inst.yearshtml ) {
10543			origyearshtml = inst.yearshtml;
10544			setTimeout( function() {
10545
10546				//assure that inst.yearshtml didn't change.
10547				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
10548					inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml );
10549				}
10550				origyearshtml = inst.yearshtml = null;
10551			}, 0 );
10552		}
10553
10554		if ( onUpdateDatepicker ) {
10555			onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] );
10556		}
10557	},
10558
10559	_shouldFocusInput: function( inst ) {
10560		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" );
10561	},
10562
10563	/* Check positioning to remain on screen. */
10564	_checkOffset: function( inst, offset, isFixed ) {
10565		var dpWidth = inst.dpDiv.outerWidth(),
10566			dpHeight = inst.dpDiv.outerHeight(),
10567			inputWidth = inst.input ? inst.input.outerWidth() : 0,
10568			inputHeight = inst.input ? inst.input.outerHeight() : 0,
10569			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
10570			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
10571
10572		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
10573		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
10574		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
10575
10576		// Now check if datepicker is showing outside window viewport - move to a better place if so.
10577		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
10578			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
10579		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
10580			Math.abs( dpHeight + inputHeight ) : 0 );
10581
10582		return offset;
10583	},
10584
10585	/* Find an object's position on the screen. */
10586	_findPos: function( obj ) {
10587		var position,
10588			inst = this._getInst( obj ),
10589			isRTL = this._get( inst, "isRTL" );
10590
10591		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) {
10592			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
10593		}
10594
10595		position = $( obj ).offset();
10596		return [ position.left, position.top ];
10597	},
10598
10599	/* Hide the date picker from view.
10600	 * @param  input  element - the input field attached to the date picker
10601	 */
10602	_hideDatepicker: function( input ) {
10603		var showAnim, duration, postProcess, onClose,
10604			inst = this._curInst;
10605
10606		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
10607			return;
10608		}
10609
10610		if ( this._datepickerShowing ) {
10611			showAnim = this._get( inst, "showAnim" );
10612			duration = this._get( inst, "duration" );
10613			postProcess = function() {
10614				$.datepicker._tidyDialog( inst );
10615			};
10616
10617			if ( $.effects && ( $.effects.effect[ showAnim ] ) ) {
10618				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
10619			} else {
10620				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
10621					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
10622			}
10623
10624			if ( !showAnim ) {
10625				postProcess();
10626			}
10627			this._datepickerShowing = false;
10628
10629			onClose = this._get( inst, "onClose" );
10630			if ( onClose ) {
10631				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
10632			}
10633
10634			this._lastInput = null;
10635			if ( this._inDialog ) {
10636				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
10637				if ( $.blockUI ) {
10638					$.unblockUI();
10639					$( "body" ).append( this.dpDiv );
10640				}
10641			}
10642			this._inDialog = false;
10643		}
10644	},
10645
10646	/* Tidy up after a dialog display. */
10647	_tidyDialog: function( inst ) {
10648		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
10649	},
10650
10651	/* Close date picker if clicked elsewhere. */
10652	_checkExternalClick: function( event ) {
10653		if ( !$.datepicker._curInst ) {
10654			return;
10655		}
10656
10657		var $target = $( event.target ),
10658			inst = $.datepicker._getInst( $target[ 0 ] );
10659
10660		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
10661				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
10662				!$target.hasClass( $.datepicker.markerClassName ) &&
10663				!$target.closest( "." + $.datepicker._triggerClass ).length &&
10664				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
10665			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
10666				$.datepicker._hideDatepicker();
10667		}
10668	},
10669
10670	/* Adjust one of the date sub-fields. */
10671	_adjustDate: function( id, offset, period ) {
10672		var target = $( id ),
10673			inst = this._getInst( target[ 0 ] );
10674
10675		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
10676			return;
10677		}
10678		this._adjustInstDate( inst, offset, period );
10679		this._updateDatepicker( inst );
10680	},
10681
10682	/* Action for current link. */
10683	_gotoToday: function( id ) {
10684		var date,
10685			target = $( id ),
10686			inst = this._getInst( target[ 0 ] );
10687
10688		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
10689			inst.selectedDay = inst.currentDay;
10690			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
10691			inst.drawYear = inst.selectedYear = inst.currentYear;
10692		} else {
10693			date = new Date();
10694			inst.selectedDay = date.getDate();
10695			inst.drawMonth = inst.selectedMonth = date.getMonth();
10696			inst.drawYear = inst.selectedYear = date.getFullYear();
10697		}
10698		this._notifyChange( inst );
10699		this._adjustDate( target );
10700	},
10701
10702	/* Action for selecting a new month/year. */
10703	_selectMonthYear: function( id, select, period ) {
10704		var target = $( id ),
10705			inst = this._getInst( target[ 0 ] );
10706
10707		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
10708		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
10709			parseInt( select.options[ select.selectedIndex ].value, 10 );
10710
10711		this._notifyChange( inst );
10712		this._adjustDate( target );
10713	},
10714
10715	/* Action for selecting a day. */
10716	_selectDay: function( id, month, year, td ) {
10717		var inst,
10718			target = $( id );
10719
10720		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
10721			return;
10722		}
10723
10724		inst = this._getInst( target[ 0 ] );
10725		inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) );
10726		inst.selectedMonth = inst.currentMonth = month;
10727		inst.selectedYear = inst.currentYear = year;
10728		this._selectDate( id, this._formatDate( inst,
10729			inst.currentDay, inst.currentMonth, inst.currentYear ) );
10730	},
10731
10732	/* Erase the input field and hide the date picker. */
10733	_clearDate: function( id ) {
10734		var target = $( id );
10735		this._selectDate( target, "" );
10736	},
10737
10738	/* Update the input field with the selected date. */
10739	_selectDate: function( id, dateStr ) {
10740		var onSelect,
10741			target = $( id ),
10742			inst = this._getInst( target[ 0 ] );
10743
10744		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
10745		if ( inst.input ) {
10746			inst.input.val( dateStr );
10747		}
10748		this._updateAlternate( inst );
10749
10750		onSelect = this._get( inst, "onSelect" );
10751		if ( onSelect ) {
10752			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
10753		} else if ( inst.input ) {
10754			inst.input.trigger( "change" ); // fire the change event
10755		}
10756
10757		if ( inst.inline ) {
10758			this._updateDatepicker( inst );
10759		} else {
10760			this._hideDatepicker();
10761			this._lastInput = inst.input[ 0 ];
10762			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
10763				inst.input.trigger( "focus" ); // restore focus
10764			}
10765			this._lastInput = null;
10766		}
10767	},
10768
10769	/* Update any alternate field to synchronise with the main field. */
10770	_updateAlternate: function( inst ) {
10771		var altFormat, date, dateStr,
10772			altField = this._get( inst, "altField" );
10773
10774		if ( altField ) { // update alternate field too
10775			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
10776			date = this._getDate( inst );
10777			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
10778			$( document ).find( altField ).val( dateStr );
10779		}
10780	},
10781
10782	/* Set as beforeShowDay function to prevent selection of weekends.
10783	 * @param  date  Date - the date to customise
10784	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
10785	 */
10786	noWeekends: function( date ) {
10787		var day = date.getDay();
10788		return [ ( day > 0 && day < 6 ), "" ];
10789	},
10790
10791	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
10792	 * @param  date  Date - the date to get the week for
10793	 * @return  number - the number of the week within the year that contains this date
10794	 */
10795	iso8601Week: function( date ) {
10796		var time,
10797			checkDate = new Date( date.getTime() );
10798
10799		// Find Thursday of this week starting on Monday
10800		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
10801
10802		time = checkDate.getTime();
10803		checkDate.setMonth( 0 ); // Compare with Jan 1
10804		checkDate.setDate( 1 );
10805		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
10806	},
10807
10808	/* Parse a string value into a date object.
10809	 * See formatDate below for the possible formats.
10810	 *
10811	 * @param  format string - the expected format of the date
10812	 * @param  value string - the date in the above format
10813	 * @param  settings Object - attributes include:
10814	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
10815	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
10816	 *					dayNames		string[7] - names of the days from Sunday (optional)
10817	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
10818	 *					monthNames		string[12] - names of the months (optional)
10819	 * @return  Date - the extracted date value or null if value is blank
10820	 */
10821	parseDate: function( format, value, settings ) {
10822		if ( format == null || value == null ) {
10823			throw "Invalid arguments";
10824		}
10825
10826		value = ( typeof value === "object" ? value.toString() : value + "" );
10827		if ( value === "" ) {
10828			return null;
10829		}
10830
10831		var iFormat, dim, extra,
10832			iValue = 0,
10833			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
10834			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 5,431 bytes, lines 10834-11024
10834:
10835				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
10836			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
10837			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
10838			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
10839			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
10840			year = -1,
10841			month = -1,
10842			day = -1,
10843			doy = -1,
10844			literal = false,
10845			date,
10846
10847			// Check whether a format character is doubled
10848			lookAhead = function( match ) {
10849				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10850				if ( matches ) {
10851					iFormat++;
10852				}
10853				return matches;
10854			},
10855
10856			// Extract a number from the string value
10857			getNumber = function( match ) {
10858				var isDoubled = lookAhead( match ),
10859					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
10860					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
10861					minSize = ( match === "y" ? size : 1 ),
10862					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
10863					num = value.substring( iValue ).match( digits );
10864				if ( !num ) {
10865					throw "Missing number at position " + iValue;
10866				}
10867				iValue += num[ 0 ].length;
10868				return parseInt( num[ 0 ], 10 );
10869			},
10870
10871			// Extract a name from the string value and convert to an index
10872			getName = function( match, shortNames, longNames ) {
10873				var index = -1,
10874					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
10875						return [ [ k, v ] ];
10876					} ).sort( function( a, b ) {
10877						return -( a[ 1 ].length - b[ 1 ].length );
10878					} );
10879
10880				$.each( names, function( i, pair ) {
10881					var name = pair[ 1 ];
10882					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
10883						index = pair[ 0 ];
10884						iValue += name.length;
10885						return false;
10886					}
10887				} );
10888				if ( index !== -1 ) {
10889					return index + 1;
10890				} else {
10891					throw "Unknown name at position " + iValue;
10892				}
10893			},
10894
10895			// Confirm that a literal character matches the string value
10896			checkLiteral = function() {
10897				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
10898					throw "Unexpected literal at position " + iValue;
10899				}
10900				iValue++;
10901			};
10902
10903		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
10904			if ( literal ) {
10905				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
10906					literal = false;
10907				} else {
10908					checkLiteral();
10909				}
10910			} else {
10911				switch ( format.charAt( iFormat ) ) {
10912					case "d":
10913						day = getNumber( "d" );
10914						break;
10915					case "D":
10916						getName( "D", dayNamesShort, dayNames );
10917						break;
10918					case "o":
10919						doy = getNumber( "o" );
10920						break;
10921					case "m":
10922						month = getNumber( "m" );
10923						break;
10924					case "M":
10925						month = getName( "M", monthNamesShort, monthNames );
10926						break;
10927					case "y":
10928						year = getNumber( "y" );
10929						break;
10930					case "@":
10931						date = new Date( getNumber( "@" ) );
10932						year = date.getFullYear();
10933						month = date.getMonth() + 1;
10934						day = date.getDate();
10935						break;
10936					case "!":
10937						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
10938						year = date.getFullYear();
10939						month = date.getMonth() + 1;
10940						day = date.getDate();
10941						break;
10942					case "'":
10943						if ( lookAhead( "'" ) ) {
10944							checkLiteral();
10945						} else {
10946							literal = true;
10947						}
10948						break;
10949					default:
10950						checkLiteral();
10951				}
10952			}
10953		}
10954
10955		if ( iValue < value.length ) {
10956			extra = value.substr( iValue );
10957			if ( !/^\s+/.test( extra ) ) {
10958				throw "Extra/unparsed characters found in date: " + extra;
10959			}
10960		}
10961
10962		if ( year === -1 ) {
10963			year = new Date().getFullYear();
10964		} else if ( year < 100 ) {
10965			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
10966				( year <= shortYearCutoff ? 0 : -100 );
10967		}
10968
10969		if ( doy > -1 ) {
10970			month = 1;
10971			day = doy;
10972			do {
10973				dim = this._getDaysInMonth( year, month - 1 );
10974				if ( day <= dim ) {
10975					break;
10976				}
10977				month++;
10978				day -= dim;
10979			} while ( true );
10980		}
10981
10982		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
10983		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
10984			throw "Invalid date"; // E.g. 31/02/00
10985		}
10986		return date;
10987	},
10988
10989	/* Standard date formats. */
10990	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
10991	COOKIE: "D, dd M yy",
10992	ISO_8601: "yy-mm-dd",
10993	RFC_822: "D, d M y",
10994	RFC_850: "DD, dd-M-y",
10995	RFC_1036: "D, d M y",
10996	RFC_1123: "D, d M yy",
10997	RFC_2822: "D, d M yy",
10998	RSS: "D, d M y", // RFC 822
10999	TICKS: "!",
11000	TIMESTAMP: "@",
11001	W3C: "yy-mm-dd", // ISO 8601
11002
11003	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
11004		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
11005
11006	/* Format a date object into a string value.
11007	 * The format can be combinations of the following:
11008	 * d  - day of month (no leading zero)
11009	 * dd - day of month (two digit)
11010	 * o  - day of year (no leading zeros)
11011	 * oo - day of year (three digit)
11012	 * D  - day name short
11013	 * DD - day name long
11014	 * m  - month of year (no leading zero)
11015	 * mm - month of year (two digit)
11016	 * M  - month name short
11017	 * MM - month name long
11018	 * y  - year (two digit)
11019	 * yy - year (four digit)
11020	 * @ - Unix timestamp (ms since 01/01/1970)
11021	 * ! - Windows ticks (100ns since 01/01/0001)
11022	 * "..." - literal text
11023	 * '' - single quote
11024	 *
vendor: 6,198 bytes, lines 11025-11224
11025	 * @param  format string - the desired format of the date
11026	 * @param  date Date - the date value to format
11027	 * @param  settings Object - attributes include:
11028	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
11029	 *					dayNames		string[7] - names of the days from Sunday (optional)
11030	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
11031	 *					monthNames		string[12] - names of the months (optional)
11032	 * @return  string - the date in the above format
11033	 */
11034	formatDate: function( format, date, settings ) {
11035		if ( !date ) {
11036			return "";
11037		}
11038
11039		var iFormat,
11040			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
11041			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
11042			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
11043			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
11044
11045			// Check whether a format character is doubled
11046			lookAhead = function( match ) {
11047				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
11048				if ( matches ) {
11049					iFormat++;
11050				}
11051				return matches;
11052			},
11053
11054			// Format a number, with leading zero if necessary
11055			formatNumber = function( match, value, len ) {
11056				var num = "" + value;
11057				if ( lookAhead( match ) ) {
11058					while ( num.length < len ) {
11059						num = "0" + num;
11060					}
11061				}
11062				return num;
11063			},
11064
11065			// Format a name, short or long as requested
11066			formatName = function( match, value, shortNames, longNames ) {
11067				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
11068			},
11069			output = "",
11070			literal = false;
11071
11072		if ( date ) {
11073			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
11074				if ( literal ) {
11075					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
11076						literal = false;
11077					} else {
11078						output += format.charAt( iFormat );
11079					}
11080				} else {
11081					switch ( format.charAt( iFormat ) ) {
11082						case "d":
11083							output += formatNumber( "d", date.getDate(), 2 );
11084							break;
11085						case "D":
11086							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
11087							break;
11088						case "o":
11089							output += formatNumber( "o",
11090								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
11091							break;
11092						case "m":
11093							output += formatNumber( "m", date.getMonth() + 1, 2 );
11094							break;
11095						case "M":
11096							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
11097							break;
11098						case "y":
11099							output += ( lookAhead( "y" ) ? date.getFullYear() :
11100								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
11101							break;
11102						case "@":
11103							output += date.getTime();
11104							break;
11105						case "!":
11106							output += date.getTime() * 10000 + this._ticksTo1970;
11107							break;
11108						case "'":
11109							if ( lookAhead( "'" ) ) {
11110								output += "'";
11111							} else {
11112								literal = true;
11113							}
11114							break;
11115						default:
11116							output += format.charAt( iFormat );
11117					}
11118				}
11119			}
11120		}
11121		return output;
11122	},
11123
11124	/* Extract all possible characters from the date format. */
11125	_possibleChars: function( format ) {
11126		var iFormat,
11127			chars = "",
11128			literal = false,
11129
11130			// Check whether a format character is doubled
11131			lookAhead = function( match ) {
11132				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
11133				if ( matches ) {
11134					iFormat++;
11135				}
11136				return matches;
11137			};
11138
11139		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
11140			if ( literal ) {
11141				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
11142					literal = false;
11143				} else {
11144					chars += format.charAt( iFormat );
11145				}
11146			} else {
11147				switch ( format.charAt( iFormat ) ) {
11148					case "d": case "m": case "y": case "@":
11149						chars += "0123456789";
11150						break;
11151					case "D": case "M":
11152						return null; // Accept anything
11153					case "'":
11154						if ( lookAhead( "'" ) ) {
11155							chars += "'";
11156						} else {
11157							literal = true;
11158						}
11159						break;
11160					default:
11161						chars += format.charAt( iFormat );
11162				}
11163			}
11164		}
11165		return chars;
11166	},
11167
11168	/* Get a setting value, defaulting if necessary. */
11169	_get: function( inst, name ) {
11170		return inst.settings[ name ] !== undefined ?
11171			inst.settings[ name ] : this._defaults[ name ];
11172	},
11173
11174	/* Parse existing date and initialise date picker. */
11175	_setDateFromField: function( inst, noDefault ) {
11176		if ( inst.input.val() === inst.lastVal ) {
11177			return;
11178		}
11179
11180		var dateFormat = this._get( inst, "dateFormat" ),
11181			dates = inst.lastVal = inst.input ? inst.input.val() : null,
11182			defaultDate = this._getDefaultDate( inst ),
11183			date = defaultDate,
11184			settings = this._getFormatConfig( inst );
11185
11186		try {
11187			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
11188		} catch ( _err ) {
11189			dates = ( noDefault ? "" : dates );
11190		}
11191		inst.selectedDay = date.getDate();
11192		inst.drawMonth = inst.selectedMonth = date.getMonth();
11193		inst.drawYear = inst.selectedYear = date.getFullYear();
11194		inst.currentDay = ( dates ? date.getDate() : 0 );
11195		inst.currentMonth = ( dates ? date.getMonth() : 0 );
11196		inst.currentYear = ( dates ? date.getFullYear() : 0 );
11197		this._adjustInstDate( inst );
11198	},
11199
11200	/* Retrieve the default date shown on opening. */
11201	_getDefaultDate: function( inst ) {
11202		return this._restrictMinMax( inst,
11203			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
11204	},
11205
11206	/* A date may be specified as an exact value or a relative one. */
11207	_determineDate: function( inst, date, defaultDate ) {
11208		var offsetNumeric = function( offset ) {
11209				var date = new Date();
11210				date.setDate( date.getDate() + offset );
11211				return date;
11212			},
11213			offsetString = function( offset ) {
11214				try {
11215					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
11216						offset, $.datepicker._getFormatConfig( inst ) );
11217				} catch ( _e ) {
11218
11219					// Ignore
11220				}
11221
11222				var date = ( offset.toLowerCase().match( /^c/ ) ?
11223					$.datepicker._getDate( inst ) : null ) || new Date(),
11224					year = date.getFullYear(),
vendor: 5,359 bytes, lines 11225-11363
11225					month = date.getMonth(),
11226					day = date.getDate(),
11227					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
11228					matches = pattern.exec( offset );
11229
11230				while ( matches ) {
11231					switch ( matches[ 2 ] || "d" ) {
11232						case "d" : case "D" :
11233							day += parseInt( matches[ 1 ], 10 ); break;
11234						case "w" : case "W" :
11235							day += parseInt( matches[ 1 ], 10 ) * 7; break;
11236						case "m" : case "M" :
11237							month += parseInt( matches[ 1 ], 10 );
11238							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11239							break;
11240						case "y": case "Y" :
11241							year += parseInt( matches[ 1 ], 10 );
11242							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11243							break;
11244					}
11245					matches = pattern.exec( offset );
11246				}
11247				return new Date( year, month, day );
11248			},
11249			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
11250				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
11251
11252		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
11253		if ( newDate ) {
11254			newDate.setHours( 0 );
11255			newDate.setMinutes( 0 );
11256			newDate.setSeconds( 0 );
11257			newDate.setMilliseconds( 0 );
11258		}
11259		return this._daylightSavingAdjust( newDate );
11260	},
11261
11262	/* Handle switch to/from daylight saving.
11263	 * Hours may be non-zero on daylight saving cut-over:
11264	 * > 12 when midnight changeover, but then cannot generate
11265	 * midnight datetime, so jump to 1AM, otherwise reset.
11266	 * @param  date  (Date) the date to check
11267	 * @return  (Date) the corrected date
11268	 */
11269	_daylightSavingAdjust: function( date ) {
11270		if ( !date ) {
11271			return null;
11272		}
11273		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
11274		return date;
11275	},
11276
11277	/* Set the date(s) directly. */
11278	_setDate: function( inst, date, noChange ) {
11279		var clear = !date,
11280			origMonth = inst.selectedMonth,
11281			origYear = inst.selectedYear,
11282			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
11283
11284		inst.selectedDay = inst.currentDay = newDate.getDate();
11285		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
11286		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
11287		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
11288			this._notifyChange( inst );
11289		}
11290		this._adjustInstDate( inst );
11291		if ( inst.input ) {
11292			inst.input.val( clear ? "" : this._formatDate( inst ) );
11293		}
11294	},
11295
11296	/* Retrieve the date(s) directly. */
11297	_getDate: function( inst ) {
11298		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
11299			this._daylightSavingAdjust( new Date(
11300			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11301			return startDate;
11302	},
11303
11304	/* Attach the onxxx handlers.  These are declared statically so
11305	 * they work with static code transformers like Caja.
11306	 */
11307	_attachHandlers: function( inst ) {
11308		var stepMonths = this._get( inst, "stepMonths" ),
11309			id = "#" + inst.id.replace( /\\\\/g, "\\" );
11310		inst.dpDiv.find( "[data-handler]" ).map( function() {
11311			var handler = {
11312				prev: function() {
11313					$.datepicker._adjustDate( id, -stepMonths, "M" );
11314				},
11315				next: function() {
11316					$.datepicker._adjustDate( id, +stepMonths, "M" );
11317				},
11318				hide: function() {
11319					$.datepicker._hideDatepicker();
11320				},
11321				today: function() {
11322					$.datepicker._gotoToday( id );
11323				},
11324				selectDay: function() {
11325					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
11326					return false;
11327				},
11328				selectMonth: function() {
11329					$.datepicker._selectMonthYear( id, this, "M" );
11330					return false;
11331				},
11332				selectYear: function() {
11333					$.datepicker._selectMonthYear( id, this, "Y" );
11334					return false;
11335				}
11336			};
11337			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
11338		} );
11339	},
11340
11341	/* Generate the HTML for the current state of the date picker. */
11342	_generateHTML: function( inst ) {
11343		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
11344			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
11345			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
11346			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
11347			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
11348			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
11349			tempDate = new Date(),
11350			today = this._daylightSavingAdjust(
11351				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
11352			isRTL = this._get( inst, "isRTL" ),
11353			showButtonPanel = this._get( inst, "showButtonPanel" ),
11354			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
11355			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
11356			numMonths = this._getNumberOfMonths( inst ),
11357			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
11358			stepMonths = this._get( inst, "stepMonths" ),
11359			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
11360			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
11361				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
11362			minDate = this._getMinMaxDate( inst, "min" ),
11363			maxDate = this._getMinMaxDate( inst, "max" ),
vendor: 21,264 bytes, lines 11364-11879
11364			drawMonth = inst.drawMonth - showCurrentAtPos,
11365			drawYear = inst.drawYear;
11366
11367		if ( drawMonth < 0 ) {
11368			drawMonth += 12;
11369			drawYear--;
11370		}
11371		if ( maxDate ) {
11372			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
11373				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
11374			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
11375			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
11376				drawMonth--;
11377				if ( drawMonth < 0 ) {
11378					drawMonth = 11;
11379					drawYear--;
11380				}
11381			}
11382		}
11383		inst.drawMonth = drawMonth;
11384		inst.drawYear = drawYear;
11385
11386		prevText = this._get( inst, "prevText" );
11387		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
11388			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
11389			this._getFormatConfig( inst ) ) );
11390
11391		if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) {
11392			prev = $( "<a>" )
11393				.attr( {
11394					"class": "ui-datepicker-prev ui-corner-all",
11395					"data-handler": "prev",
11396					"data-event": "click",
11397					title: prevText
11398				} )
11399				.append(
11400					$( "<span>" )
11401						.addClass( "ui-icon ui-icon-circle-triangle-" +
11402							( isRTL ? "e" : "w" ) )
11403						.text( prevText )
11404				)[ 0 ].outerHTML;
11405		} else if ( hideIfNoPrevNext ) {
11406			prev = "";
11407		} else {
11408			prev = $( "<a>" )
11409				.attr( {
11410					"class": "ui-datepicker-prev ui-corner-all ui-state-disabled",
11411					title: prevText
11412				} )
11413				.append(
11414					$( "<span>" )
11415						.addClass( "ui-icon ui-icon-circle-triangle-" +
11416							( isRTL ? "e" : "w" ) )
11417						.text( prevText )
11418				)[ 0 ].outerHTML;
11419		}
11420
11421		nextText = this._get( inst, "nextText" );
11422		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
11423			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
11424			this._getFormatConfig( inst ) ) );
11425
11426		if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) {
11427			next = $( "<a>" )
11428				.attr( {
11429					"class": "ui-datepicker-next ui-corner-all",
11430					"data-handler": "next",
11431					"data-event": "click",
11432					title: nextText
11433				} )
11434				.append(
11435					$( "<span>" )
11436						.addClass( "ui-icon ui-icon-circle-triangle-" +
11437							( isRTL ? "w" : "e" ) )
11438						.text( nextText )
11439				)[ 0 ].outerHTML;
11440		} else if ( hideIfNoPrevNext ) {
11441			next = "";
11442		} else {
11443			next = $( "<a>" )
11444				.attr( {
11445					"class": "ui-datepicker-next ui-corner-all ui-state-disabled",
11446					title: nextText
11447				} )
11448				.append(
11449					$( "<span>" )
11450						.attr( "class", "ui-icon ui-icon-circle-triangle-" +
11451							( isRTL ? "w" : "e" ) )
11452						.text( nextText )
11453				)[ 0 ].outerHTML;
11454		}
11455
11456		currentText = this._get( inst, "currentText" );
11457		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
11458		currentText = ( !navigationAsDateFormat ? currentText :
11459			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
11460
11461		controls = "";
11462		if ( !inst.inline ) {
11463			controls = $( "<button>" )
11464				.attr( {
11465					type: "button",
11466					"class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all",
11467					"data-handler": "hide",
11468					"data-event": "click"
11469				} )
11470				.text( this._get( inst, "closeText" ) )[ 0 ].outerHTML;
11471		}
11472
11473		buttonPanel = "";
11474		if ( showButtonPanel ) {
11475			buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" )
11476				.append( isRTL ? controls : "" )
11477				.append( this._isInRange( inst, gotoDate ) ?
11478					$( "<button>" )
11479						.attr( {
11480							type: "button",
11481							"class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all",
11482							"data-handler": "today",
11483							"data-event": "click"
11484						} )
11485						.text( currentText ) :
11486					"" )
11487				.append( isRTL ? "" : controls )[ 0 ].outerHTML;
11488		}
11489
11490		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
11491		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
11492
11493		showWeek = this._get( inst, "showWeek" );
11494		dayNames = this._get( inst, "dayNames" );
11495		dayNamesMin = this._get( inst, "dayNamesMin" );
11496		monthNames = this._get( inst, "monthNames" );
11497		monthNamesShort = this._get( inst, "monthNamesShort" );
11498		beforeShowDay = this._get( inst, "beforeShowDay" );
11499		showOtherMonths = this._get( inst, "showOtherMonths" );
11500		selectOtherMonths = this._get( inst, "selectOtherMonths" );
11501		defaultDate = this._getDefaultDate( inst );
11502		html = "";
11503
11504		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
11505			group = "";
11506			this.maxRows = 4;
11507			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
11508				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
11509				cornerClass = " ui-corner-all";
11510				calender = "";
11511				if ( isMultiMonth ) {
11512					calender += "<div class='ui-datepicker-group";
11513					if ( numMonths[ 1 ] > 1 ) {
11514						switch ( col ) {
11515							case 0: calender += " ui-datepicker-group-first";
11516								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
11517							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
11518								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
11519							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
11520						}
11521					}
11522					calender += "'>";
11523				}
11524				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
11525					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
11526					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
11527					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
11528					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
11529					"</div><table class='ui-datepicker-calendar'><thead>" +
11530					"<tr>";
11531				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
11532				for ( dow = 0; dow < 7; dow++ ) { // days of the week
11533					day = ( dow + firstDay ) % 7;
11534					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
11535						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
11536				}
11537				calender += thead + "</tr></thead><tbody>";
11538				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
11539				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
11540					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
11541				}
11542				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
11543				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
11544				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
11545				this.maxRows = numRows;
11546				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
11547				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
11548					calender += "<tr>";
11549					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
11550						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
11551					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
11552						daySettings = ( beforeShowDay ?
11553							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
11554						otherMonth = ( printDate.getMonth() !== drawMonth );
11555						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
11556							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
11557						tbody += "<td class='" +
11558							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
11559							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
11560							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
11561							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
11562
11563							// or defaultDate is current printedDate and defaultDate is selectedDate
11564							" " + this._dayOverClass : "" ) + // highlight selected day
11565							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
11566							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
11567							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
11568							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
11569							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
11570							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
11571							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
11572							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
11573							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
11574							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
11575							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
11576							"' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader
11577							"' data-date='" + printDate.getDate() + // store date as data
11578							"'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
11579						printDate.setDate( printDate.getDate() + 1 );
11580						printDate = this._daylightSavingAdjust( printDate );
11581					}
11582					calender += tbody + "</tr>";
11583				}
11584				drawMonth++;
11585				if ( drawMonth > 11 ) {
11586					drawMonth = 0;
11587					drawYear++;
11588				}
11589				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
11590							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
11591				group += calender;
11592			}
11593			html += group;
11594		}
11595		html += buttonPanel;
11596		inst._keyEvent = false;
11597		return html;
11598	},
11599
11600	/* Generate the month and year header. */
11601	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
11602			secondary, monthNames, monthNamesShort ) {
11603
11604		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
11605			changeMonth = this._get( inst, "changeMonth" ),
11606			changeYear = this._get( inst, "changeYear" ),
11607			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
11608			selectMonthLabel = this._get( inst, "selectMonthLabel" ),
11609			selectYearLabel = this._get( inst, "selectYearLabel" ),
11610			html = "<div class='ui-datepicker-title'>",
11611			monthHtml = "";
11612
11613		// Month selection
11614		if ( secondary || !changeMonth ) {
11615			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
11616		} else {
11617			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
11618			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
11619			monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>";
11620			for ( month = 0; month < 12; month++ ) {
11621				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
11622					monthHtml += "<option value='" + month + "'" +
11623						( month === drawMonth ? " selected='selected'" : "" ) +
11624						">" + monthNamesShort[ month ] + "</option>";
11625				}
11626			}
11627			monthHtml += "</select>";
11628		}
11629
11630		if ( !showMonthAfterYear ) {
11631			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
11632		}
11633
11634		// Year selection
11635		if ( !inst.yearshtml ) {
11636			inst.yearshtml = "";
11637			if ( secondary || !changeYear ) {
11638				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
11639			} else {
11640
11641				// determine range of years to display
11642				years = this._get( inst, "yearRange" ).split( ":" );
11643				thisYear = new Date().getFullYear();
11644				determineYear = function( value ) {
11645					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
11646						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
11647						parseInt( value, 10 ) ) );
11648					return ( isNaN( year ) ? thisYear : year );
11649				};
11650				year = determineYear( years[ 0 ] );
11651				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
11652				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
11653				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
11654				inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>";
11655				for ( ; year <= endYear; year++ ) {
11656					inst.yearshtml += "<option value='" + year + "'" +
11657						( year === drawYear ? " selected='selected'" : "" ) +
11658						">" + year + "</option>";
11659				}
11660				inst.yearshtml += "</select>";
11661
11662				html += inst.yearshtml;
11663				inst.yearshtml = null;
11664			}
11665		}
11666
11667		html += this._get( inst, "yearSuffix" );
11668		if ( showMonthAfterYear ) {
11669			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
11670		}
11671		html += "</div>"; // Close datepicker_header
11672		return html;
11673	},
11674
11675	/* Adjust one of the date sub-fields. */
11676	_adjustInstDate: function( inst, offset, period ) {
11677		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
11678			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
11679			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
11680			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
11681
11682		inst.selectedDay = date.getDate();
11683		inst.drawMonth = inst.selectedMonth = date.getMonth();
11684		inst.drawYear = inst.selectedYear = date.getFullYear();
11685		if ( period === "M" || period === "Y" ) {
11686			this._notifyChange( inst );
11687		}
11688	},
11689
11690	/* Ensure a date is within any min/max bounds. */
11691	_restrictMinMax: function( inst, date ) {
11692		var minDate = this._getMinMaxDate( inst, "min" ),
11693			maxDate = this._getMinMaxDate( inst, "max" ),
11694			newDate = ( minDate && date < minDate ? minDate : date );
11695		return ( maxDate && newDate > maxDate ? maxDate : newDate );
11696	},
11697
11698	/* Notify change of month/year. */
11699	_notifyChange: function( inst ) {
11700		var onChange = this._get( inst, "onChangeMonthYear" );
11701		if ( onChange ) {
11702			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
11703				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
11704		}
11705	},
11706
11707	/* Determine the number of months to show. */
11708	_getNumberOfMonths: function( inst ) {
11709		var numMonths = this._get( inst, "numberOfMonths" );
11710		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
11711	},
11712
11713	/* Determine the current maximum date - ensure no time components are set. */
11714	_getMinMaxDate: function( inst, minMax ) {
11715		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
11716	},
11717
11718	/* Find the number of days in a given month. */
11719	_getDaysInMonth: function( year, month ) {
11720		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
11721	},
11722
11723	/* Find the day of the week of the first of a month. */
11724	_getFirstDayOfMonth: function( year, month ) {
11725		return new Date( year, month, 1 ).getDay();
11726	},
11727
11728	/* Determines if we should allow a "next/prev" month display change. */
11729	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
11730		var numMonths = this._getNumberOfMonths( inst ),
11731			date = this._daylightSavingAdjust( new Date( curYear,
11732			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
11733
11734		if ( offset < 0 ) {
11735			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
11736		}
11737		return this._isInRange( inst, date );
11738	},
11739
11740	/* Is the given date in the accepted range? */
11741	_isInRange: function( inst, date ) {
11742		var yearSplit, currentYear,
11743			minDate = this._getMinMaxDate( inst, "min" ),
11744			maxDate = this._getMinMaxDate( inst, "max" ),
11745			minYear = null,
11746			maxYear = null,
11747			years = this._get( inst, "yearRange" );
11748			if ( years ) {
11749				yearSplit = years.split( ":" );
11750				currentYear = new Date().getFullYear();
11751				minYear = parseInt( yearSplit[ 0 ], 10 );
11752				maxYear = parseInt( yearSplit[ 1 ], 10 );
11753				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
11754					minYear += currentYear;
11755				}
11756				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
11757					maxYear += currentYear;
11758				}
11759			}
11760
11761		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
11762			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
11763			( !minYear || date.getFullYear() >= minYear ) &&
11764			( !maxYear || date.getFullYear() <= maxYear ) );
11765	},
11766
11767	/* Provide the configuration settings for formatting/parsing. */
11768	_getFormatConfig: function( inst ) {
11769		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
11770		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
11771			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
11772		return { shortYearCutoff: shortYearCutoff,
11773			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
11774			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
11775	},
11776
11777	/* Format the given date for display. */
11778	_formatDate: function( inst, day, month, year ) {
11779		if ( !day ) {
11780			inst.currentDay = inst.selectedDay;
11781			inst.currentMonth = inst.selectedMonth;
11782			inst.currentYear = inst.selectedYear;
11783		}
11784		var date = ( day ? ( typeof day === "object" ? day :
11785			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
11786			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11787		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
11788	}
11789} );
11790
11791/*
11792 * Bind hover events for datepicker elements.
11793 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
11794 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
11795 */
11796function datepicker_bindHover( dpDiv ) {
11797	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
11798	return dpDiv.on( "mouseout", selector, function() {
11799			$( this ).removeClass( "ui-state-hover" );
11800			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11801				$( this ).removeClass( "ui-datepicker-prev-hover" );
11802			}
11803			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11804				$( this ).removeClass( "ui-datepicker-next-hover" );
11805			}
11806		} )
11807		.on( "mouseover", selector, datepicker_handleMouseover );
11808}
11809
11810function datepicker_handleMouseover() {
11811	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
11812		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
11813		$( this ).addClass( "ui-state-hover" );
11814		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11815			$( this ).addClass( "ui-datepicker-prev-hover" );
11816		}
11817		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11818			$( this ).addClass( "ui-datepicker-next-hover" );
11819		}
11820	}
11821}
11822
11823/* jQuery extend now ignores nulls! */
11824function datepicker_extendRemove( target, props ) {
11825	$.extend( target, props );
11826	for ( var name in props ) {
11827		if ( props[ name ] == null ) {
11828			target[ name ] = props[ name ];
11829		}
11830	}
11831	return target;
11832}
11833
11834/* Invoke the datepicker functionality.
11835   @param  options  string - a command, optionally followed by additional parameters or
11836					Object - settings for attaching new datepicker functionality
11837   @return  jQuery object */
11838$.fn.datepicker = function( options ) {
11839
11840	/* Verify an empty collection wasn't passed - Fixes #6976 */
11841	if ( !this.length ) {
11842		return this;
11843	}
11844
11845	/* Initialise the date picker. */
11846	if ( !$.datepicker.initialized ) {
11847		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
11848		$.datepicker.initialized = true;
11849	}
11850
11851	/* Append datepicker main container to body if not exist. */
11852	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
11853		$( "body" ).append( $.datepicker.dpDiv );
11854	}
11855
11856	var otherArgs = Array.prototype.slice.call( arguments, 1 );
11857	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
11858		return $.datepicker[ "_" + options + "Datepicker" ].
11859			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11860	}
11861	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
11862		return $.datepicker[ "_" + options + "Datepicker" ].
11863			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11864	}
11865	return this.each( function() {
11866		if ( typeof options === "string" ) {
11867			$.datepicker[ "_" + options + "Datepicker" ]
11868				.apply( $.datepicker, [ this ].concat( otherArgs ) );
11869		} else {
11870			$.datepicker._attachDatepicker( this, options );
11871		}
11872	} );
11873};
11874
11875$.datepicker = new Datepicker(); // singleton instance
11876$.datepicker.initialized = false;
11877$.datepicker.uuid = new Date().getTime();
11878$.datepicker.version = "1.14.2";
11879
vendor: 4,962 bytes, lines 11880-12106
11880var widgetsDatepicker = $.datepicker;
11881
11882
11883/*!
11884 * jQuery UI Dialog 1.14.2
11885 * https://jqueryui.com
11886 *
11887 * Copyright OpenJS Foundation and other contributors
11888 * Released under the MIT license.
11889 * https://jquery.org/license
11890 */
11891
11892//>>label: Dialog
11893//>>group: Widgets
11894//>>description: Displays customizable dialog windows.
11895//>>docs: https://api.jqueryui.com/dialog/
11896//>>demos: https://jqueryui.com/dialog/
11897//>>css.structure: ../../themes/base/core.css
11898//>>css.structure: ../../themes/base/dialog.css
11899//>>css.theme: ../../themes/base/theme.css
11900
11901
11902$.widget( "ui.dialog", {
11903	version: "1.14.2",
11904	options: {
11905		appendTo: "body",
11906		autoOpen: true,
11907		buttons: [],
11908		classes: {
11909			"ui-dialog": "ui-corner-all",
11910			"ui-dialog-titlebar": "ui-corner-all"
11911		},
11912		closeOnEscape: true,
11913		closeText: "Close",
11914		draggable: true,
11915		hide: null,
11916		height: "auto",
11917		maxHeight: null,
11918		maxWidth: null,
11919		minHeight: 150,
11920		minWidth: 150,
11921		modal: false,
11922		position: {
11923			my: "center",
11924			at: "center",
11925			of: window,
11926			collision: "fit",
11927
11928			// Ensure the titlebar is always visible
11929			using: function( pos ) {
11930				var topOffset = $( this ).css( pos ).offset().top;
11931				if ( topOffset < 0 ) {
11932					$( this ).css( "top", pos.top - topOffset );
11933				}
11934			}
11935		},
11936		resizable: true,
11937		show: null,
11938		title: null,
11939		uiDialogTitleHeadingLevel: 0,
11940		width: 300,
11941
11942		// Callbacks
11943		beforeClose: null,
11944		close: null,
11945		drag: null,
11946		dragStart: null,
11947		dragStop: null,
11948		focus: null,
11949		open: null,
11950		resize: null,
11951		resizeStart: null,
11952		resizeStop: null
11953	},
11954
11955	sizeRelatedOptions: {
11956		buttons: true,
11957		height: true,
11958		maxHeight: true,
11959		maxWidth: true,
11960		minHeight: true,
11961		minWidth: true,
11962		width: true
11963	},
11964
11965	resizableRelatedOptions: {
11966		maxHeight: true,
11967		maxWidth: true,
11968		minHeight: true,
11969		minWidth: true
11970	},
11971
11972	_create: function() {
11973		this.originalCss = {
11974			display: this.element[ 0 ].style.display,
11975			width: this.element[ 0 ].style.width,
11976			minHeight: this.element[ 0 ].style.minHeight,
11977			maxHeight: this.element[ 0 ].style.maxHeight,
11978			height: this.element[ 0 ].style.height
11979		};
11980		this.originalPosition = {
11981			parent: this.element.parent(),
11982			index: this.element.parent().children().index( this.element )
11983		};
11984		this.originalTitle = this.element.attr( "title" );
11985		if ( this.options.title == null && this.originalTitle != null ) {
11986			this.options.title = this.originalTitle;
11987		}
11988
11989		// Dialogs can't be disabled
11990		if ( this.options.disabled ) {
11991			this.options.disabled = false;
11992		}
11993
11994		this._createWrapper();
11995
11996		this.element
11997			.show()
11998			.removeAttr( "title" )
11999			.appendTo( this.uiDialog );
12000
12001		this._addClass( "ui-dialog-content", "ui-widget-content" );
12002
12003		this._createTitlebar();
12004		this._createButtonPane();
12005
12006		if ( this.options.draggable && $.fn.draggable ) {
12007			this._makeDraggable();
12008		}
12009		if ( this.options.resizable && $.fn.resizable ) {
12010			this._makeResizable();
12011		}
12012
12013		this._isOpen = false;
12014
12015		this._trackFocus();
12016	},
12017
12018	_init: function() {
12019		if ( this.options.autoOpen ) {
12020			this.open();
12021		}
12022	},
12023
12024	_appendTo: function() {
12025		var element = this.options.appendTo;
12026		if ( element && ( element.jquery || element.nodeType ) ) {
12027			return $( element );
12028		}
12029		return this.document.find( element || "body" ).eq( 0 );
12030	},
12031
12032	_destroy: function() {
12033		var next,
12034			originalPosition = this.originalPosition;
12035
12036		this._untrackInstance();
12037		this._destroyOverlay();
12038
12039		this.element
12040			.removeUniqueId()
12041			.css( this.originalCss )
12042
12043			// Without detaching first, the following becomes really slow
12044			.detach();
12045
12046		this.uiDialog.remove();
12047
12048		if ( this.originalTitle ) {
12049			this.element.attr( "title", this.originalTitle );
12050		}
12051
12052		next = originalPosition.parent.children().eq( originalPosition.index );
12053
12054		// Don't try to place the dialog next to itself (#8613)
12055		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12056			next.before( this.element );
12057		} else {
12058			originalPosition.parent.append( this.element );
12059		}
12060	},
12061
12062	widget: function() {
12063		return this.uiDialog;
12064	},
12065
12066	disable: $.noop,
12067	enable: $.noop,
12068
12069	close: function( event ) {
12070		var that = this;
12071
12072		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12073			return;
12074		}
12075
12076		this._isOpen = false;
12077		this._focusedElement = null;
12078		this._destroyOverlay();
12079		this._untrackInstance();
12080
12081		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12082
12083			// Hiding a focused element doesn't trigger blur in WebKit
12084			// so in case we have nothing to focus on, explicitly blur the active element
12085			// https://bugs.webkit.org/show_bug.cgi?id=47182
12086			$( this.document[ 0 ].activeElement ).trigger( "blur" );
12087		}
12088
12089		this._hide( this.uiDialog, this.options.hide, function() {
12090			that._trigger( "close", event );
12091		} );
12092	},
12093
12094	isOpen: function() {
12095		console.log('TESTING')
12096		return this._isOpen;
12097	},
12098
12099	moveToTop: function() {
12100		this._moveToTop();
12101	},
12102
12103	_moveToTop: function( event, silent ) {
12104		var moved = false,
12105			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12106				console.log('TESTING:', $(this))
vendor: 18,047 bytes, lines 12106-12804
12106
12107				return +$( this ).css( "z-index" );
12108			} ).get(),
12109			zIndexMax = Math.max.apply( null, zIndices );
12110
12111		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12112			this.uiDialog.css( "z-index", zIndexMax + 1 );
12113			moved = true;
12114		}
12115
12116		if ( moved && !silent ) {
12117			this._trigger( "focus", event );
12118		}
12119		return moved;
12120	},
12121
12122	open: function() {
12123		var that = this;
12124		if ( this._isOpen ) {
12125			if ( this._moveToTop() ) {
12126				this._focusTabbable();
12127			}
12128			return;
12129		}
12130
12131		this._isOpen = true;
12132		this.opener = $( this.document[ 0 ].activeElement );
12133
12134		this._size();
12135		this._position();
12136		this._createOverlay();
12137		this._moveToTop( null, true );
12138
12139		// Ensure the overlay is moved to the top with the dialog, but only when
12140		// opening. The overlay shouldn't move after the dialog is open so that
12141		// modeless dialogs opened after the modal dialog stack properly.
12142		if ( this.overlay ) {
12143			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12144		}
12145
12146		this._show( this.uiDialog, this.options.show, function() {
12147			that._focusTabbable();
12148			that._trigger( "focus" );
12149		} );
12150
12151		// Track the dialog immediately upon opening in case a focus event
12152		// somehow occurs outside of the dialog before an element inside the
12153		// dialog is focused (#10152)
12154		this._makeFocusTarget();
12155
12156		this._trigger( "open" );
12157	},
12158
12159	_focusTabbable: function() {
12160
12161		// Set focus to the first match:
12162		// 1. An element that was focused previously
12163		// 2. First element inside the dialog matching [autofocus]
12164		// 3. Tabbable element inside the content element
12165		// 4. Tabbable element inside the buttonpane
12166		// 5. The close button
12167		// 6. The dialog itself
12168		var hasFocus = this._focusedElement;
12169		if ( !hasFocus ) {
12170			hasFocus = this.element.find( "[autofocus]" );
12171		}
12172		if ( !hasFocus.length ) {
12173			hasFocus = this.element.find( ":tabbable" );
12174		}
12175		if ( !hasFocus.length ) {
12176			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12177		}
12178		if ( !hasFocus.length ) {
12179			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12180		}
12181		if ( !hasFocus.length ) {
12182			hasFocus = this.uiDialog;
12183		}
12184		hasFocus.eq( 0 ).trigger( "focus" );
12185	},
12186
12187	_restoreTabbableFocus: function() {
12188		var activeElement = this.document[ 0 ].activeElement,
12189			isActive = this.uiDialog[ 0 ] === activeElement ||
12190				$.contains( this.uiDialog[ 0 ], activeElement );
12191		if ( !isActive ) {
12192			this._focusTabbable();
12193		}
12194	},
12195
12196	_keepFocus: function( event ) {
12197		event.preventDefault();
12198		this._restoreTabbableFocus();
12199	},
12200
12201	_createWrapper: function() {
12202		this.uiDialog = $( "<div>" )
12203			.hide()
12204			.attr( {
12205
12206				// Setting tabIndex makes the div focusable
12207				tabIndex: -1,
12208				role: "dialog",
12209				"aria-modal": this.options.modal ? "true" : null
12210			} )
12211			.appendTo( this._appendTo() );
12212
12213		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12214		this._on( this.uiDialog, {
12215			keydown: function( event ) {
12216				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12217						event.keyCode === $.ui.keyCode.ESCAPE ) {
12218					event.preventDefault();
12219					this.close( event );
12220					return;
12221				}
12222
12223				// Prevent tabbing out of dialogs
12224				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12225					return;
12226				}
12227				var tabbables = this.uiDialog.find( ":tabbable" ),
12228					first = tabbables.first(),
12229					last = tabbables.last();
12230
12231				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12232						!event.shiftKey ) {
12233					this._delay( function() {
12234						first.trigger( "focus" );
12235					} );
12236					event.preventDefault();
12237				} else if ( ( event.target === first[ 0 ] ||
12238						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12239					this._delay( function() {
12240						last.trigger( "focus" );
12241					} );
12242					event.preventDefault();
12243				}
12244			},
12245			mousedown: function( event ) {
12246				if ( this._moveToTop( event ) ) {
12247					this._focusTabbable();
12248				}
12249			}
12250		} );
12251
12252		// We assume that any existing aria-describedby attribute means
12253		// that the dialog content is marked up properly
12254		// otherwise we brute force the content as the description
12255		if ( !this.element.find( "[aria-describedby]" ).length ) {
12256			this.uiDialog.attr( {
12257				"aria-describedby": this.element.uniqueId().attr( "id" )
12258			} );
12259		}
12260	},
12261
12262	_createTitlebar: function() {
12263		var uiDialogTitle;
12264
12265		this.uiDialogTitlebar = $( "<div>" );
12266		this._addClass( this.uiDialogTitlebar,
12267			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12268		this._on( this.uiDialogTitlebar, {
12269			mousedown: function( event ) {
12270
12271				// Don't prevent click on close button (#8838)
12272				// Focusing a dialog that is partially scrolled out of view
12273				// causes the browser to scroll it into view, preventing the click event
12274				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12275
12276					// Dialog isn't getting focus when dragging (#8063)
12277					this.uiDialog.trigger( "focus" );
12278				}
12279			}
12280		} );
12281
12282		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12283			.button( {
12284				label: $( "<a>" ).text( this.options.closeText ).html(),
12285				icon: "ui-icon-closethick",
12286				showLabel: false
12287			} )
12288			.appendTo( this.uiDialogTitlebar );
12289
12290		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12291		this._on( this.uiDialogTitlebarClose, {
12292			click: function( event ) {
12293				event.preventDefault();
12294				this.close( event );
12295			}
12296		} );
12297
12298		var uiDialogHeadingLevel = Number.isInteger( this.options.uiDialogTitleHeadingLevel ) &&
12299			this.options.uiDialogTitleHeadingLevel > 0 &&
12300			this.options.uiDialogTitleHeadingLevel <= 6 ?
12301			"h" + this.options.uiDialogTitleHeadingLevel : "span";
12302
12303		uiDialogTitle = $( "<" + uiDialogHeadingLevel + ">" )
12304			.uniqueId().prependTo( this.uiDialogTitlebar );
12305		this._addClass( uiDialogTitle, "ui-dialog-title" );
12306		this._title( uiDialogTitle );
12307
12308		this.uiDialogTitlebar.prependTo( this.uiDialog );
12309
12310		this.uiDialog.attr( {
12311			"aria-labelledby": uiDialogTitle.attr( "id" )
12312		} );
12313	},
12314
12315	_title: function( title ) {
12316		if ( this.options.title ) {
12317			title.text( this.options.title );
12318		} else {
12319			title.html( "&#160;" );
12320		}
12321	},
12322
12323	_createButtonPane: function() {
12324		this.uiDialogButtonPane = $( "<div>" );
12325		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12326			"ui-widget-content ui-helper-clearfix" );
12327
12328		this.uiButtonSet = $( "<div>" )
12329			.appendTo( this.uiDialogButtonPane );
12330		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12331
12332		this._createButtons();
12333	},
12334
12335	_createButtons: function() {
12336		var that = this,
12337			buttons = this.options.buttons;
12338
12339		// If we already have a button pane, remove it
12340		this.uiDialogButtonPane.remove();
12341		this.uiButtonSet.empty();
12342
12343		if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) {
12344			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12345			return;
12346		}
12347
12348		$.each( buttons, function( name, props ) {
12349			var click, buttonOptions;
12350			props = typeof props === "function" ?
12351				{ click: props, text: name } :
12352				props;
12353
12354			// Default to a non-submitting button
12355			props = $.extend( { type: "button" }, props );
12356
12357			// Change the context for the click callback to be the main element
12358			click = props.click;
12359			buttonOptions = {
12360				icon: props.icon,
12361				iconPosition: props.iconPosition,
12362				showLabel: props.showLabel,
12363
12364				// Deprecated options
12365				icons: props.icons,
12366				text: props.text
12367			};
12368
12369			delete props.click;
12370			delete props.icon;
12371			delete props.iconPosition;
12372			delete props.showLabel;
12373
12374			// Deprecated options
12375			delete props.icons;
12376			if ( typeof props.text === "boolean" ) {
12377				delete props.text;
12378			}
12379
12380			$( "<button></button>", props )
12381				.button( buttonOptions )
12382				.appendTo( that.uiButtonSet )
12383				.on( "click", function() {
12384					click.apply( that.element[ 0 ], arguments );
12385				} );
12386		} );
12387		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12388		this.uiDialogButtonPane.appendTo( this.uiDialog );
12389	},
12390
12391	_makeDraggable: function() {
12392		var that = this,
12393			options = this.options;
12394
12395		function filteredUi( ui ) {
12396			return {
12397				position: ui.position,
12398				offset: ui.offset
12399			};
12400		}
12401
12402		this.uiDialog.draggable( {
12403			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12404			handle: ".ui-dialog-titlebar",
12405			containment: "document",
12406			start: function( event, ui ) {
12407				that._addClass( $( this ), "ui-dialog-dragging" );
12408				that._blockFrames();
12409				that._trigger( "dragStart", event, filteredUi( ui ) );
12410			},
12411			drag: function( event, ui ) {
12412				that._trigger( "drag", event, filteredUi( ui ) );
12413			},
12414			stop: function( event, ui ) {
12415				var left = ui.offset.left - that.document.scrollLeft(),
12416					top = ui.offset.top - that.document.scrollTop();
12417
12418				options.position = {
12419					my: "left top",
12420					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12421						"top" + ( top >= 0 ? "+" : "" ) + top,
12422					of: that.window
12423				};
12424				that._removeClass( $( this ), "ui-dialog-dragging" );
12425				that._unblockFrames();
12426				that._trigger( "dragStop", event, filteredUi( ui ) );
12427			}
12428		} );
12429	},
12430
12431	_makeResizable: function() {
12432		var that = this,
12433			options = this.options,
12434			handles = options.resizable,
12435
12436			// .ui-resizable has position: relative defined in the stylesheet
12437			// but dialogs have to use absolute or fixed positioning
12438			position = this.uiDialog.css( "position" ),
12439			resizeHandles = typeof handles === "string" ?
12440				handles :
12441				"n,e,s,w,se,sw,ne,nw";
12442
12443		function filteredUi( ui ) {
12444			return {
12445				originalPosition: ui.originalPosition,
12446				originalSize: ui.originalSize,
12447				position: ui.position,
12448				size: ui.size
12449			};
12450		}
12451
12452		this.uiDialog.resizable( {
12453			cancel: ".ui-dialog-content",
12454			containment: "document",
12455			alsoResize: this.element,
12456			maxWidth: options.maxWidth,
12457			maxHeight: options.maxHeight,
12458			minWidth: options.minWidth,
12459			minHeight: this._minHeight(),
12460			handles: resizeHandles,
12461			start: function( event, ui ) {
12462				that._addClass( $( this ), "ui-dialog-resizing" );
12463				that._blockFrames();
12464				that._trigger( "resizeStart", event, filteredUi( ui ) );
12465			},
12466			resize: function( event, ui ) {
12467				that._trigger( "resize", event, filteredUi( ui ) );
12468			},
12469			stop: function( event, ui ) {
12470				var offset = that.uiDialog.offset(),
12471					left = offset.left - that.document.scrollLeft(),
12472					top = offset.top - that.document.scrollTop();
12473
12474				options.height = that.uiDialog.height();
12475				options.width = that.uiDialog.width();
12476				options.position = {
12477					my: "left top",
12478					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12479						"top" + ( top >= 0 ? "+" : "" ) + top,
12480					of: that.window
12481				};
12482				that._removeClass( $( this ), "ui-dialog-resizing" );
12483				that._unblockFrames();
12484				that._trigger( "resizeStop", event, filteredUi( ui ) );
12485			}
12486		} )
12487			.css( "position", position );
12488	},
12489
12490	_trackFocus: function() {
12491		this._on( this.widget(), {
12492			focusin: function( event ) {
12493				this._makeFocusTarget();
12494				this._focusedElement = $( event.target );
12495			}
12496		} );
12497	},
12498
12499	_makeFocusTarget: function() {
12500		this._untrackInstance();
12501		this._trackingInstances().unshift( this );
12502	},
12503
12504	_untrackInstance: function() {
12505		var instances = this._trackingInstances(),
12506			exists = $.inArray( this, instances );
12507		if ( exists !== -1 ) {
12508			instances.splice( exists, 1 );
12509		}
12510	},
12511
12512	_trackingInstances: function() {
12513		var instances = this.document.data( "ui-dialog-instances" );
12514		if ( !instances ) {
12515			instances = [];
12516			this.document.data( "ui-dialog-instances", instances );
12517		}
12518		return instances;
12519	},
12520
12521	_minHeight: function() {
12522		var options = this.options;
12523
12524		return options.height === "auto" ?
12525			options.minHeight :
12526			Math.min( options.minHeight, options.height );
12527	},
12528
12529	_position: function() {
12530
12531		// Need to show the dialog to get the actual offset in the position plugin
12532		var isVisible = this.uiDialog.is( ":visible" );
12533		if ( !isVisible ) {
12534			this.uiDialog.show();
12535		}
12536		this.uiDialog.position( this.options.position );
12537		if ( !isVisible ) {
12538			this.uiDialog.hide();
12539		}
12540	},
12541
12542	_setOptions: function( options ) {
12543		var that = this,
12544			resize = false,
12545			resizableOptions = {};
12546
12547		$.each( options, function( key, value ) {
12548			that._setOption( key, value );
12549
12550			if ( key in that.sizeRelatedOptions ) {
12551				resize = true;
12552			}
12553			if ( key in that.resizableRelatedOptions ) {
12554				resizableOptions[ key ] = value;
12555			}
12556		} );
12557
12558		if ( resize ) {
12559			this._size();
12560			this._position();
12561		}
12562		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12563			this.uiDialog.resizable( "option", resizableOptions );
12564		}
12565	},
12566
12567	_setOption: function( key, value ) {
12568		var isDraggable, isResizable,
12569			uiDialog = this.uiDialog;
12570
12571		if ( key === "disabled" ) {
12572			return;
12573		}
12574
12575		this._super( key, value );
12576
12577		if ( key === "appendTo" ) {
12578			this.uiDialog.appendTo( this._appendTo() );
12579		}
12580
12581		if ( key === "buttons" ) {
12582			this._createButtons();
12583		}
12584
12585		if ( key === "closeText" ) {
12586			this.uiDialogTitlebarClose.button( {
12587
12588				// Ensure that we always pass a string
12589				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12590			} );
12591		}
12592
12593		if ( key === "draggable" ) {
12594			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12595			if ( isDraggable && !value ) {
12596				uiDialog.draggable( "destroy" );
12597			}
12598
12599			if ( !isDraggable && value ) {
12600				this._makeDraggable();
12601			}
12602		}
12603
12604		if ( key === "position" ) {
12605			this._position();
12606		}
12607
12608		if ( key === "resizable" ) {
12609
12610			// currently resizable, becoming non-resizable
12611			isResizable = uiDialog.is( ":data(ui-resizable)" );
12612			if ( isResizable && !value ) {
12613				uiDialog.resizable( "destroy" );
12614			}
12615
12616			// Currently resizable, changing handles
12617			if ( isResizable && typeof value === "string" ) {
12618				uiDialog.resizable( "option", "handles", value );
12619			}
12620
12621			// Currently non-resizable, becoming resizable
12622			if ( !isResizable && value !== false ) {
12623				this._makeResizable();
12624			}
12625		}
12626
12627		if ( key === "title" ) {
12628			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12629		}
12630
12631		if ( key === "modal" ) {
12632			uiDialog.attr( "aria-modal", value ? "true" : null );
12633		}
12634	},
12635
12636	_size: function() {
12637
12638		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12639		// divs will both have width and height set, so we need to reset them
12640		var nonContentHeight, minContentHeight, maxContentHeight,
12641			options = this.options;
12642
12643		// Reset content sizing
12644		this.element.show().css( {
12645			width: "auto",
12646			minHeight: 0,
12647			maxHeight: "none",
12648			height: 0
12649		} );
12650
12651		if ( options.minWidth > options.width ) {
12652			options.width = options.minWidth;
12653		}
12654
12655		// Reset wrapper sizing
12656		// determine the height of all the non-content elements
12657		nonContentHeight = this.uiDialog.css( {
12658			height: "auto",
12659			width: options.width
12660		} )
12661			.outerHeight();
12662		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12663		maxContentHeight = typeof options.maxHeight === "number" ?
12664			Math.max( 0, options.maxHeight - nonContentHeight ) :
12665			"none";
12666
12667		if ( options.height === "auto" ) {
12668			this.element.css( {
12669				minHeight: minContentHeight,
12670				maxHeight: maxContentHeight,
12671				height: "auto"
12672			} );
12673		} else {
12674			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12675		}
12676
12677		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12678			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12679		}
12680	},
12681
12682	_blockFrames: function() {
12683		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12684			var iframe = $( this );
12685
12686			return $( "<div>" )
12687				.css( {
12688					position: "absolute",
12689					width: iframe.outerWidth(),
12690					height: iframe.outerHeight()
12691				} )
12692				.appendTo( iframe.parent() )
12693				.offset( iframe.offset() )[ 0 ];
12694		} );
12695	},
12696
12697	_unblockFrames: function() {
12698		if ( this.iframeBlocks ) {
12699			this.iframeBlocks.remove();
12700			delete this.iframeBlocks;
12701		}
12702	},
12703
12704	_allowInteraction: function( event ) {
12705		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12706			return true;
12707		}
12708
12709		// TODO: Remove hack when datepicker implements
12710		// the .ui-front logic (#8989)
12711		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12712	},
12713
12714	_createOverlay: function() {
12715		if ( !this.options.modal ) {
12716			return;
12717		}
12718
12719		// We use a delay in case the overlay is created from an
12720		// event that we're going to be cancelling (#2804)
12721		var isOpening = true;
12722		this._delay( function() {
12723			isOpening = false;
12724		} );
12725
12726		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12727
12728			// Prevent use of anchors and inputs
12729			// This doesn't use `_on()` because it is a shared event handler
12730			// across all open modal dialogs.
12731			this.document.on( "focusin.ui-dialog", function( event ) {
12732				if ( isOpening ) {
12733					return;
12734				}
12735
12736				var instance = this._trackingInstances()[ 0 ];
12737				if ( !instance._allowInteraction( event ) ) {
12738					event.preventDefault();
12739					instance._focusTabbable();
12740				}
12741			}.bind( this ) );
12742		}
12743
12744		this.overlay = $( "<div>" )
12745			.appendTo( this._appendTo() );
12746
12747		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12748		this._on( this.overlay, {
12749			mousedown: "_keepFocus"
12750		} );
12751		this.document.data( "ui-dialog-overlays",
12752			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12753	},
12754
12755	_destroyOverlay: function() {
12756		if ( !this.options.modal ) {
12757			return;
12758		}
12759
12760		if ( this.overlay ) {
12761			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12762
12763			if ( !overlays ) {
12764				this.document.off( "focusin.ui-dialog" );
12765				this.document.removeData( "ui-dialog-overlays" );
12766			} else {
12767				this.document.data( "ui-dialog-overlays", overlays );
12768			}
12769
12770			this.overlay.remove();
12771			this.overlay = null;
12772		}
12773	}
12774} );
12775
12776// DEPRECATED
12777// TODO: switch return back to widget declaration at top of file when this is removed
12778if ( $.uiBackCompat === true ) {
12779
12780	// Backcompat for dialogClass option
12781	$.widget( "ui.dialog", $.ui.dialog, {
12782		options: {
12783			dialogClass: ""
12784		},
12785		_createWrapper: function() {
12786			this._super();
12787			this.uiDialog.addClass( this.options.dialogClass );
12788		},
12789		_setOption: function( key, value ) {
12790			if ( key === "dialogClass" ) {
12791				this.uiDialog
12792					.removeClass( this.options.dialogClass )
12793					.addClass( value );
12794			}
12795			this._superApply( arguments );
12796		}
12797	} );
12798}
12799
12800var widgetsDialog = $.ui.dialog;
12801
12802
12803/*!
12804 * jQuery UI 
vendor: 3,870 bytes, lines 12804-12960
12804Progressbar 1.14.2
12805 * https://jqueryui.com
12806 *
12807 * Copyright OpenJS Foundation and other contributors
12808 * Released under the MIT license.
12809 * https://jquery.org/license
12810 */
12811
12812//>>label: Progressbar
12813//>>group: Widgets
12814//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
12815//>>docs: https://api.jqueryui.com/progressbar/
12816//>>demos: https://jqueryui.com/progressbar/
12817//>>css.structure: ../../themes/base/core.css
12818//>>css.structure: ../../themes/base/progressbar.css
12819//>>css.theme: ../../themes/base/theme.css
12820
12821
12822var widgetsProgressbar = $.widget( "ui.progressbar", {
12823	version: "1.14.2",
12824	options: {
12825		classes: {
12826			"ui-progressbar": "ui-corner-all",
12827			"ui-progressbar-value": "ui-corner-left",
12828			"ui-progressbar-complete": "ui-corner-right"
12829		},
12830		max: 100,
12831		value: 0,
12832
12833		change: null,
12834		complete: null
12835	},
12836
12837	min: 0,
12838
12839	_create: function() {
12840
12841		// Constrain initial value
12842		this.oldValue = this.options.value = this._constrainedValue();
12843
12844		this.element.attr( {
12845
12846			// Only set static values; aria-valuenow and aria-valuemax are
12847			// set inside _refreshValue()
12848			role: "progressbar",
12849			"aria-valuemin": this.min
12850		} );
12851		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
12852
12853		this.valueDiv = $( "<div>" ).appendTo( this.element );
12854		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
12855		this._refreshValue();
12856	},
12857
12858	_destroy: function() {
12859		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
12860
12861		this.valueDiv.remove();
12862	},
12863
12864	value: function( newValue ) {
12865		if ( newValue === undefined ) {
12866			return this.options.value;
12867		}
12868
12869		this.options.value = this._constrainedValue( newValue );
12870		this._refreshValue();
12871	},
12872
12873	_constrainedValue: function( newValue ) {
12874		if ( newValue === undefined ) {
12875			newValue = this.options.value;
12876		}
12877
12878		this.indeterminate = newValue === false;
12879
12880		// Sanitize value
12881		if ( typeof newValue !== "number" ) {
12882			newValue = 0;
12883		}
12884
12885		return this.indeterminate ? false :
12886			Math.min( this.options.max, Math.max( this.min, newValue ) );
12887	},
12888
12889	_setOptions: function( options ) {
12890
12891		// Ensure "value" option is set after other values (like max)
12892		var value = options.value;
12893		delete options.value;
12894
12895		this._super( options );
12896
12897		this.options.value = this._constrainedValue( value );
12898		this._refreshValue();
12899	},
12900
12901	_setOption: function( key, value ) {
12902		if ( key === "max" ) {
12903
12904			// Don't allow a max less than min
12905			value = Math.max( this.min, value );
12906		}
12907		this._super( key, value );
12908	},
12909
12910	_setOptionDisabled: function( value ) {
12911		this._super( value );
12912
12913		this.element.attr( "aria-disabled", value );
12914		this._toggleClass( null, "ui-state-disabled", !!value );
12915	},
12916
12917	_percentage: function() {
12918		return this.indeterminate ?
12919			100 :
12920			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12921	},
12922
12923	_refreshValue: function() {
12924		var value = this.options.value,
12925			percentage = this._percentage();
12926
12927		this.valueDiv
12928			.toggle( this.indeterminate || value > this.min )
12929			.width( percentage.toFixed( 0 ) + "%" );
12930
12931		this
12932			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
12933				value === this.options.max )
12934			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
12935
12936		if ( this.indeterminate ) {
12937			this.element.removeAttr( "aria-valuenow" );
12938			if ( !this.overlayDiv ) {
12939				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
12940				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
12941			}
12942		} else {
12943			this.element.attr( {
12944				"aria-valuemax": this.options.max,
12945				"aria-valuenow": value
12946			} );
12947			if ( this.overlayDiv ) {
12948				this.overlayDiv.remove();
12949				this.overlayDiv = null;
12950			}
12951		}
12952
12953		if ( this.oldValue !== value ) {
12954			this.oldValue = value;
12955			this._trigger( "change" );
12956		}
12957		if ( value === this.options.max ) {
12958			this._trigger( "complete" );
12959		}
12960	}
vendor: 19,361 bytes, lines 12960-13768
12960
12961} );
12962
12963
12964/*!
12965 * jQuery UI Selectmenu 1.14.2
12966 * https://jqueryui.com
12967 *
12968 * Copyright OpenJS Foundation and other contributors
12969 * Released under the MIT license.
12970 * https://jquery.org/license
12971 */
12972
12973//>>label: Selectmenu
12974//>>group: Widgets
12975//>>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.
12976//>>docs: https://api.jqueryui.com/selectmenu/
12977//>>demos: https://jqueryui.com/selectmenu/
12978//>>css.structure: ../../themes/base/core.css
12979//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
12980//>>css.theme: ../../themes/base/theme.css
12981
12982
12983var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
12984	version: "1.14.2",
12985	defaultElement: "<select>",
12986	options: {
12987		appendTo: null,
12988		classes: {
12989			"ui-selectmenu-button-open": "ui-corner-top",
12990			"ui-selectmenu-button-closed": "ui-corner-all"
12991		},
12992		disabled: null,
12993		icons: {
12994			button: "ui-icon-triangle-1-s"
12995		},
12996		position: {
12997			my: "left top",
12998			at: "left bottom",
12999			collision: "none"
13000		},
13001		width: false,
13002
13003		// Callbacks
13004		change: null,
13005		close: null,
13006		focus: null,
13007		open: null,
13008		select: null
13009	},
13010
13011	_create: function() {
13012		var selectmenuId = this.element.uniqueId().attr( "id" );
13013		this.ids = {
13014			element: selectmenuId,
13015			button: selectmenuId + "-button",
13016			menu: selectmenuId + "-menu"
13017		};
13018
13019		this._drawButton();
13020		this._drawMenu();
13021		this._bindFormResetHandler();
13022
13023		this._rendered = false;
13024		this.menuItems = $();
13025	},
13026
13027	_drawButton: function() {
13028		var icon,
13029			that = this,
13030			item = this._parseOption(
13031				this.element.find( "option:selected" ),
13032				this.element[ 0 ].selectedIndex
13033			);
13034
13035		// Associate existing label with the new button
13036		this.labels = this.element.labels().attr( "for", this.ids.button );
13037		this._on( this.labels, {
13038			click: function( event ) {
13039				this.button.trigger( "focus" );
13040				event.preventDefault();
13041			}
13042		} );
13043
13044		// Hide original select element
13045		this.element.hide();
13046
13047		// Create button
13048		this.button = $( "<span>", {
13049			tabindex: this.options.disabled ? -1 : 0,
13050			id: this.ids.button,
13051			role: "combobox",
13052			"aria-expanded": "false",
13053			"aria-autocomplete": "list",
13054			"aria-owns": this.ids.menu,
13055			"aria-haspopup": "true",
13056			title: this.element.attr( "title" )
13057		} )
13058			.insertAfter( this.element );
13059
13060		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
13061			"ui-button ui-widget" );
13062
13063		icon = $( "<span>" ).appendTo( this.button );
13064		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
13065		this.buttonItem = this._renderButtonItem( item )
13066			.appendTo( this.button );
13067
13068		if ( this.options.width !== false ) {
13069			this._resizeButton();
13070		}
13071
13072		this._on( this.button, this._buttonEvents );
13073		this.button.one( "focusin", function() {
13074
13075			// Delay rendering the menu items until the button receives focus.
13076			// The menu may have already been rendered via a programmatic open.
13077			if ( !that._rendered ) {
13078				that._refreshMenu();
13079			}
13080		} );
13081	},
13082
13083	_drawMenu: function() {
13084		var that = this;
13085
13086		// Create menu
13087		this.menu = $( "<ul>", {
13088			"aria-hidden": "true",
13089			"aria-labelledby": this.ids.button,
13090			id: this.ids.menu
13091		} );
13092
13093		// Wrap menu
13094		this.menuWrap = $( "<div>" ).append( this.menu );
13095		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
13096		this.menuWrap.appendTo( this._appendTo() );
13097
13098		// Initialize menu widget
13099		this.menuInstance = this.menu
13100			.menu( {
13101				classes: {
13102					"ui-menu": "ui-corner-bottom"
13103				},
13104				role: "listbox",
13105				select: function( event, ui ) {
13106					event.preventDefault();
13107					that._select( ui.item.data( "ui-selectmenu-item" ), event );
13108				},
13109				focus: function( event, ui ) {
13110					var item = ui.item.data( "ui-selectmenu-item" );
13111
13112					// Prevent inital focus from firing and check if its a newly focused item
13113					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
13114						that._trigger( "focus", event, { item: item } );
13115						if ( !that.isOpen ) {
13116							that._select( item, event );
13117						}
13118					}
13119					that.focusIndex = item.index;
13120
13121					that.button.attr( "aria-activedescendant",
13122						that.menuItems.eq( item.index ).attr( "id" ) );
13123				}
13124			} )
13125			.menu( "instance" );
13126
13127		// Don't close the menu on mouseleave
13128		this.menuInstance._off( this.menu, "mouseleave" );
13129
13130		// Cancel the menu's collapseAll on document click
13131		this.menuInstance._closeOnDocumentClick = function() {
13132			return false;
13133		};
13134
13135		// Selects often contain empty items, but never contain dividers
13136		this.menuInstance._isDivider = function() {
13137			return false;
13138		};
13139	},
13140
13141	refresh: function() {
13142		this._refreshMenu();
13143		this.buttonItem.replaceWith(
13144			this.buttonItem = this._renderButtonItem(
13145
13146				// Fall back to an empty object in case there are no options
13147				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
13148			)
13149		);
13150		if ( this.options.width === null ) {
13151			this._resizeButton();
13152		}
13153	},
13154
13155	_refreshMenu: function() {
13156		var item,
13157			options = this.element.find( "option" );
13158
13159		this.menu.empty();
13160
13161		this._parseOptions( options );
13162		this._renderMenu( this.menu, this.items );
13163
13164		this.menuInstance.refresh();
13165		this.menuItems = this.menu.find( "li" )
13166			.not( ".ui-selectmenu-optgroup" )
13167				.find( ".ui-menu-item-wrapper" );
13168
13169		this._rendered = true;
13170
13171		if ( !options.length ) {
13172			return;
13173		}
13174
13175		item = this._getSelectedItem();
13176
13177		// Update the menu to have the correct item focused
13178		this.menuInstance.focus( null, item );
13179		this._setAria( item.data( "ui-selectmenu-item" ) );
13180
13181		// Set disabled state
13182		this._setOption( "disabled", this.element.prop( "disabled" ) );
13183	},
13184
13185	open: function( event ) {
13186		if ( this.options.disabled ) {
13187			return;
13188		}
13189
13190		// If this is the first time the menu is being opened, render the items
13191		if ( !this._rendered ) {
13192			this._refreshMenu();
13193		} else {
13194
13195			// Menu clears focus on close, reset focus to selected item
13196			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
13197			this.menuInstance.focus( null, this._getSelectedItem() );
13198		}
13199
13200		// If there are no options, don't open the menu
13201		if ( !this.menuItems.length ) {
13202			return;
13203		}
13204
13205		this.isOpen = true;
13206		this._toggleAttr();
13207		this._resizeMenu();
13208		this._position();
13209
13210		this._on( this.document, this._documentClick );
13211
13212		this._trigger( "open", event );
13213	},
13214
13215	_position: function() {
13216		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
13217	},
13218
13219	close: function( event ) {
13220		if ( !this.isOpen ) {
13221			return;
13222		}
13223
13224		this.isOpen = false;
13225		this._toggleAttr();
13226
13227		this.range = null;
13228		this._off( this.document );
13229
13230		this._trigger( "close", event );
13231	},
13232
13233	widget: function() {
13234		return this.button;
13235	},
13236
13237	menuWidget: function() {
13238		return this.menu;
13239	},
13240
13241	_renderButtonItem: function( item ) {
13242		var buttonItem = $( "<span>" );
13243
13244		this._setText( buttonItem, item.label );
13245		this._addClass( buttonItem, "ui-selectmenu-text" );
13246
13247		return buttonItem;
13248	},
13249
13250	_renderMenu: function( ul, items ) {
13251		var that = this,
13252			currentOptgroup = "";
13253
13254		$.each( items, function( index, item ) {
13255			var li;
13256
13257			if ( item.optgroup !== currentOptgroup ) {
13258				li = $( "<li>", {
13259					text: item.optgroup
13260				} );
13261				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
13262					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
13263						" ui-state-disabled" :
13264						"" ) );
13265
13266				li.appendTo( ul );
13267
13268				currentOptgroup = item.optgroup;
13269			}
13270
13271			that._renderItemData( ul, item );
13272		} );
13273	},
13274
13275	_renderItemData: function( ul, item ) {
13276		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
13277	},
13278
13279	_renderItem: function( ul, item ) {
13280		var li = $( "<li>" ),
13281			wrapper = $( "<div>", {
13282				title: item.element.attr( "title" )
13283			} );
13284
13285		if ( item.disabled ) {
13286			this._addClass( li, null, "ui-state-disabled" );
13287		}
13288
13289		if ( item.hidden ) {
13290			li.prop( "hidden", true );
13291		} else {
13292			this._setText( wrapper, item.label );
13293		}
13294
13295		return li.append( wrapper ).appendTo( ul );
13296	},
13297
13298	_setText: function( element, value ) {
13299		if ( value ) {
13300			element.text( value );
13301		} else {
13302			element.html( "&#160;" );
13303		}
13304	},
13305
13306	_move: function( direction, event ) {
13307		var item, next,
13308			filter = ".ui-menu-item";
13309
13310		if ( this.isOpen ) {
13311			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13312		} else {
13313			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13314			filter += ":not(.ui-state-disabled)";
13315		}
13316
13317		if ( direction === "first" || direction === "last" ) {
13318			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
13319		} else {
13320			next = item[ direction + "All" ]( filter ).eq( 0 );
13321		}
13322
13323		if ( next.length ) {
13324			this.menuInstance.focus( event, next );
13325		}
13326	},
13327
13328	_getSelectedItem: function() {
13329		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13330	},
13331
13332	_toggle: function( event ) {
13333		this[ this.isOpen ? "close" : "open" ]( event );
13334	},
13335
13336	_setSelection: function() {
13337		var selection;
13338
13339		if ( !this.range ) {
13340			return;
13341		}
13342
13343		selection = window.getSelection();
13344		selection.removeAllRanges();
13345		selection.addRange( this.range );
13346	},
13347
13348	_documentClick: {
13349		mousedown: function( event ) {
13350			if ( !this.isOpen ) {
13351				return;
13352			}
13353
13354			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
13355				CSS.escape( this.ids.button ) ).length ) {
13356				this.close( event );
13357			}
13358		}
13359	},
13360
13361	_buttonEvents: {
13362
13363		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
13364		mousedown: function() {
13365			var selection = window.getSelection();
13366			if ( selection.rangeCount ) {
13367				this.range = selection.getRangeAt( 0 );
13368			}
13369		},
13370
13371		click: function( event ) {
13372			this._setSelection();
13373			this._toggle( event );
13374		},
13375
13376		keydown: function( event ) {
13377			var preventDefault = true;
13378			switch ( event.keyCode ) {
13379			case $.ui.keyCode.TAB:
13380			case $.ui.keyCode.ESCAPE:
13381				this.close( event );
13382				preventDefault = false;
13383				break;
13384			case $.ui.keyCode.ENTER:
13385				if ( this.isOpen ) {
13386					this._selectFocusedItem( event );
13387				}
13388				break;
13389			case $.ui.keyCode.UP:
13390				if ( event.altKey ) {
13391					this._toggle( event );
13392				} else {
13393					this._move( "prev", event );
13394				}
13395				break;
13396			case $.ui.keyCode.DOWN:
13397				if ( event.altKey ) {
13398					this._toggle( event );
13399				} else {
13400					this._move( "next", event );
13401				}
13402				break;
13403			case $.ui.keyCode.SPACE:
13404				if ( this.isOpen ) {
13405					this._selectFocusedItem( event );
13406				} else {
13407					this._toggle( event );
13408				}
13409				break;
13410			case $.ui.keyCode.LEFT:
13411				this._move( "prev", event );
13412				break;
13413			case $.ui.keyCode.RIGHT:
13414				this._move( "next", event );
13415				break;
13416			case $.ui.keyCode.HOME:
13417			case $.ui.keyCode.PAGE_UP:
13418				this._move( "first", event );
13419				break;
13420			case $.ui.keyCode.END:
13421			case $.ui.keyCode.PAGE_DOWN:
13422				this._move( "last", event );
13423				break;
13424			default:
13425				this.menu.trigger( event );
13426				preventDefault = false;
13427			}
13428
13429			if ( preventDefault ) {
13430				event.preventDefault();
13431			}
13432		}
13433	},
13434
13435	_selectFocusedItem: function( event ) {
13436		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13437		if ( !item.hasClass( "ui-state-disabled" ) ) {
13438			this._select( item.data( "ui-selectmenu-item" ), event );
13439		}
13440	},
13441
13442	_select: function( item, event ) {
13443		var oldIndex = this.element[ 0 ].selectedIndex;
13444
13445		// Change native select element
13446		this.element[ 0 ].selectedIndex = item.index;
13447		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
13448		this._setAria( item );
13449		this._trigger( "select", event, { item: item } );
13450
13451		if ( item.index !== oldIndex ) {
13452			this._trigger( "change", event, { item: item } );
13453		}
13454
13455		this.close( event );
13456	},
13457
13458	_setAria: function( item ) {
13459		var id = this.menuItems.eq( item.index ).attr( "id" );
13460
13461		this.button.attr( {
13462			"aria-labelledby": id,
13463			"aria-activedescendant": id
13464		} );
13465		this.menu.attr( "aria-activedescendant", id );
13466	},
13467
13468	_setOption: function( key, value ) {
13469		if ( key === "icons" ) {
13470			var icon = this.button.find( "span.ui-icon" );
13471			this._removeClass( icon, null, this.options.icons.button )
13472				._addClass( icon, null, value.button );
13473		}
13474
13475		this._super( key, value );
13476
13477		if ( key === "appendTo" ) {
13478			this.menuWrap.appendTo( this._appendTo() );
13479		}
13480
13481		if ( key === "width" ) {
13482			this._resizeButton();
13483		}
13484	},
13485
13486	_setOptionDisabled: function( value ) {
13487		this._super( value );
13488
13489		this.menuInstance.option( "disabled", value );
13490		this.button.attr( "aria-disabled", value );
13491		this._toggleClass( this.button, null, "ui-state-disabled", value );
13492
13493		this.element.prop( "disabled", value );
13494		if ( value ) {
13495			this.button.attr( "tabindex", -1 );
13496			this.close();
13497		} else {
13498			this.button.attr( "tabindex", 0 );
13499		}
13500	},
13501
13502	_appendTo: function() {
13503		var element = this.options.appendTo;
13504
13505		if ( element ) {
13506			element = element.jquery || element.nodeType ?
13507				$( element ) :
13508				this.document.find( element ).eq( 0 );
13509		}
13510
13511		if ( !element || !element[ 0 ] ) {
13512			element = this.element.closest( ".ui-front, dialog" );
13513		}
13514
13515		if ( !element.length ) {
13516			element = this.document[ 0 ].body;
13517		}
13518
13519		return element;
13520	},
13521
13522	_toggleAttr: function() {
13523		this.button.attr( "aria-expanded", this.isOpen );
13524
13525		// We can't use two _toggleClass() calls here, because we need to make sure
13526		// we always remove classes first and add them second, otherwise if both classes have the
13527		// same theme class, it will be removed after we add it.
13528		this._removeClass( this.button, "ui-selectmenu-button-" +
13529			( this.isOpen ? "closed" : "open" ) )
13530			._addClass( this.button, "ui-selectmenu-button-" +
13531				( this.isOpen ? "open" : "closed" ) )
13532			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
13533
13534		this.menu.attr( "aria-hidden", !this.isOpen );
13535	},
13536
13537	_resizeButton: function() {
13538		var width = this.options.width;
13539
13540		// For `width: false`, just remove inline style and stop
13541		if ( width === false ) {
13542			this.button.css( "width", "" );
13543			return;
13544		}
13545
13546		// For `width: null`, match the width of the original element
13547		if ( width === null ) {
13548			width = this.element.show().outerWidth();
13549			this.element.hide();
13550		}
13551
13552		this.button.outerWidth( width );
13553	},
13554
13555	_resizeMenu: function() {
13556		this.menu.outerWidth( Math.max(
13557			this.button.outerWidth(),
13558			this.menu.width( "" ).outerWidth()
13559		) );
13560	},
13561
13562	_getCreateOptions: function() {
13563		var options = this._super();
13564
13565		options.disabled = this.element.prop( "disabled" );
13566
13567		return options;
13568	},
13569
13570	_parseOptions: function( options ) {
13571		var that = this,
13572			data = [];
13573		options.each( function( index, item ) {
13574			data.push( that._parseOption( $( item ), index ) );
13575		} );
13576		this.items = data;
13577	},
13578
13579	_parseOption: function( option, index ) {
13580		var optgroup = option.parent( "optgroup" );
13581
13582		return {
13583			element: option,
13584			index: index,
13585			value: option.val(),
13586			label: option.text(),
13587			hidden: optgroup.prop( "hidden" ) || option.prop( "hidden" ),
13588			optgroup: optgroup.attr( "label" ) || "",
13589			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
13590		};
13591	},
13592
13593	_destroy: function() {
13594		this._unbindFormResetHandler();
13595		this.menuWrap.remove();
13596		this.button.remove();
13597		this.element.show();
13598		this.element.removeUniqueId();
13599		this.labels.attr( "for", this.ids.element );
13600	}
13601} ] );
13602
13603
13604/*!
13605 * jQuery UI Slider 1.14.2
13606 * https://jqueryui.com
13607 *
13608 * Copyright OpenJS Foundation and other contributors
13609 * Released under the MIT license.
13610 * https://jquery.org/license
13611 */
13612
13613//>>label: Slider
13614//>>group: Widgets
13615//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
13616//>>docs: https://api.jqueryui.com/slider/
13617//>>demos: https://jqueryui.com/slider/
13618//>>css.structure: ../../themes/base/core.css
13619//>>css.structure: ../../themes/base/slider.css
13620//>>css.theme: ../../themes/base/theme.css
13621
13622
13623var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
13624	version: "1.14.2",
13625	widgetEventPrefix: "slide",
13626
13627	options: {
13628		animate: false,
13629		classes: {
13630			"ui-slider": "ui-corner-all",
13631			"ui-slider-handle": "ui-corner-all",
13632
13633			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
13634			// element, but worked best visually with a variety of themes
13635			"ui-slider-range": "ui-corner-all ui-widget-header"
13636		},
13637		distance: 0,
13638		max: 100,
13639		min: 0,
13640		orientation: "horizontal",
13641		range: false,
13642		step: 1,
13643		value: 0,
13644		values: null,
13645
13646		// Callbacks
13647		change: null,
13648		slide: null,
13649		start: null,
13650		stop: null
13651	},
13652
13653	// Number of pages in a slider
13654	// (how many times can you page up/down to go through the whole range)
13655	numPages: 5,
13656
13657	_create: function() {
13658		this._keySliding = false;
13659		this._mouseSliding = false;
13660		this._animateOff = true;
13661		this._handleIndex = null;
13662		this._detectOrientation();
13663		this._mouseInit();
13664		this._calculateNewMax();
13665
13666		this._addClass( "ui-slider ui-slider-" + this.orientation,
13667			"ui-widget ui-widget-content" );
13668
13669		this._refresh();
13670
13671		this._animateOff = false;
13672	},
13673
13674	_refresh: function() {
13675		this._createRange();
13676		this._createHandles();
13677		this._setupEvents();
13678		this._refreshValue();
13679	},
13680
13681	_createHandles: function() {
13682		var i, handleCount,
13683			options = this.options,
13684			existingHandles = this.element.find( ".ui-slider-handle" ),
13685			handle = "<span tabindex='0'></span>",
13686			handles = [];
13687
13688		handleCount = ( options.values && options.values.length ) || 1;
13689
13690		if ( existingHandles.length > handleCount ) {
13691			existingHandles.slice( handleCount ).remove();
13692			existingHandles = existingHandles.slice( 0, handleCount );
13693		}
13694
13695		for ( i = existingHandles.length; i < handleCount; i++ ) {
13696			handles.push( handle );
13697		}
13698
13699		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
13700
13701		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
13702
13703		this.handle = this.handles.eq( 0 );
13704
13705		this.handles.each( function( i ) {
13706			$( this )
13707				.data( "ui-slider-handle-index", i )
13708				.attr( "tabIndex", 0 );
13709		} );
13710	},
13711
13712	_createRange: function() {
13713		var options = this.options;
13714
13715		if ( options.range ) {
13716			if ( options.range === true ) {
13717				if ( !options.values ) {
13718					options.values = [ this._valueMin(), this._valueMin() ];
13719				} else if ( options.values.length && options.values.length !== 2 ) {
13720					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
13721				} else if ( Array.isArray( options.values ) ) {
13722					options.values = options.values.slice( 0 );
13723				}
13724			}
13725
13726			if ( !this.range || !this.range.length ) {
13727				this.range = $( "<div>" )
13728					.appendTo( this.element );
13729
13730				this._addClass( this.range, "ui-slider-range" );
13731			} else {
13732				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
13733
13734				// Handle range switching from true to min/max
13735				this.range.css( {
13736					"left": "",
13737					"bottom": ""
13738				} );
13739			}
13740			if ( options.range === "min" || options.range === "max" ) {
13741				this._addClass( this.range, "ui-slider-range-" + options.range );
13742			}
13743		} else {
13744			if ( this.range ) {
13745				this.range.remove();
13746			}
13747			this.range = null;
13748		}
13749	},
13750
13751	_setupEvents: function() {
13752		this._off( this.handles );
13753		this._on( this.handles, this._handleEvents );
13754		this._hoverable( this.handles );
13755		this._focusable( this.handles );
13756	},
13757
13758	_destroy: function() {
13759		this.handles.remove();
13760		if ( this.range ) {
13761			this.range.remove();
13762		}
13763
13764		this._mouseDestroy();
13765	},
13766
13767	_mouseCapture: function( event ) {
13768		var position, normValue, distance, closestHandle, index, allowed, offset, mou
vendor: 5,217 bytes, lines 13768-13967
13768seOverHandle,
13769			that = this,
13770			o = this.options;
13771
13772		if ( o.disabled ) {
13773			return false;
13774		}
13775
13776		this.elementSize = {
13777			width: this.element.outerWidth(),
13778			height: this.element.outerHeight()
13779		};
13780		this.elementOffset = this.element.offset();
13781
13782		position = { x: event.pageX, y: event.pageY };
13783		normValue = this._normValueFromMouse( position );
13784		distance = this._valueMax() - this._valueMin() + 1;
13785		this.handles.each( function( i ) {
13786			var thisDistance = Math.abs( normValue - that.values( i ) );
13787			if ( ( distance > thisDistance ) ||
13788				( distance === thisDistance &&
13789					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
13790				distance = thisDistance;
13791				closestHandle = $( this );
13792				index = i;
13793			}
13794		} );
13795
13796		allowed = this._start( event, index );
13797		if ( allowed === false ) {
13798			return false;
13799		}
13800		this._mouseSliding = true;
13801
13802		this._handleIndex = index;
13803
13804		this._addClass( closestHandle, null, "ui-state-active" );
13805		closestHandle.trigger( "focus" );
13806
13807		offset = closestHandle.offset();
13808		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
13809		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
13810			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
13811			top: event.pageY - offset.top -
13812				( closestHandle.height() / 2 ) -
13813				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
13814				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
13815				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
13816		};
13817
13818		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
13819			this._slide( event, index, normValue );
13820		}
13821		this._animateOff = true;
13822		return true;
13823	},
13824
13825	_mouseStart: function() {
13826		return true;
13827	},
13828
13829	_mouseDrag: function( event ) {
13830		var position = { x: event.pageX, y: event.pageY },
13831			normValue = this._normValueFromMouse( position );
13832
13833		this._slide( event, this._handleIndex, normValue );
13834
13835		return false;
13836	},
13837
13838	_mouseStop: function( event ) {
13839		this._removeClass( this.handles, null, "ui-state-active" );
13840		this._mouseSliding = false;
13841
13842		this._stop( event, this._handleIndex );
13843		this._change( event, this._handleIndex );
13844
13845		this._handleIndex = null;
13846		this._clickOffset = null;
13847		this._animateOff = false;
13848
13849		return false;
13850	},
13851
13852	_detectOrientation: function() {
13853		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13854	},
13855
13856	_normValueFromMouse: function( position ) {
13857		var pixelTotal,
13858			pixelMouse,
13859			percentMouse,
13860			valueTotal,
13861			valueMouse;
13862
13863		if ( this.orientation === "horizontal" ) {
13864			pixelTotal = this.elementSize.width;
13865			pixelMouse = position.x - this.elementOffset.left -
13866				( this._clickOffset ? this._clickOffset.left : 0 );
13867		} else {
13868			pixelTotal = this.elementSize.height;
13869			pixelMouse = position.y - this.elementOffset.top -
13870				( this._clickOffset ? this._clickOffset.top : 0 );
13871		}
13872
13873		percentMouse = ( pixelMouse / pixelTotal );
13874		if ( percentMouse > 1 ) {
13875			percentMouse = 1;
13876		}
13877		if ( percentMouse < 0 ) {
13878			percentMouse = 0;
13879		}
13880		if ( this.orientation === "vertical" ) {
13881			percentMouse = 1 - percentMouse;
13882		}
13883
13884		valueTotal = this._valueMax() - this._valueMin();
13885		valueMouse = this._valueMin() + percentMouse * valueTotal;
13886
13887		return this._trimAlignValue( valueMouse );
13888	},
13889
13890	_uiHash: function( index, value, values ) {
13891		var uiHash = {
13892			handle: this.handles[ index ],
13893			handleIndex: index,
13894			value: value !== undefined ? value : this.value()
13895		};
13896
13897		if ( this._hasMultipleValues() ) {
13898			uiHash.value = value !== undefined ? value : this.values( index );
13899			uiHash.values = values || this.values();
13900		}
13901
13902		return uiHash;
13903	},
13904
13905	_hasMultipleValues: function() {
13906		return this.options.values && this.options.values.length;
13907	},
13908
13909	_start: function( event, index ) {
13910		return this._trigger( "start", event, this._uiHash( index ) );
13911	},
13912
13913	_slide: function( event, index, newVal ) {
13914		var allowed, otherVal,
13915			currentValue = this.value(),
13916			newValues = this.values();
13917
13918		if ( this._hasMultipleValues() ) {
13919			otherVal = this.values( index ? 0 : 1 );
13920			currentValue = this.values( index );
13921
13922			if ( this.options.values.length === 2 && this.options.range === true ) {
13923				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
13924			}
13925
13926			newValues[ index ] = newVal;
13927		}
13928
13929		if ( newVal === currentValue ) {
13930			return;
13931		}
13932
13933		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
13934
13935		// A slide can be canceled by returning false from the slide callback
13936		if ( allowed === false ) {
13937			return;
13938		}
13939
13940		if ( this._hasMultipleValues() ) {
13941			this.values( index, newVal );
13942		} else {
13943			this.value( newVal );
13944		}
13945	},
13946
13947	_stop: function( event, index ) {
13948		this._trigger( "stop", event, this._uiHash( index ) );
13949	},
13950
13951	_change: function( event, index ) {
13952		if ( !this._keySliding && !this._mouseSliding ) {
13953
13954			//store the last changed value index for reference when handles overlap
13955			this._lastChangedValue = index;
13956			this._trigger( "change", event, this._uiHash( index ) );
13957		}
13958	},
13959
13960	value: function( newValue ) {
13961		if ( arguments.length ) {
13962			this.options.value = this._trimAlignValue( newValue );
13963			this._refreshValue();
13964			this._change( null, 0 );
13965			return;
13966		}
13967
vendor: 4,358 bytes, lines 13968-14140
13968		return this._value();
13969	},
13970
13971	values: function( index, newValue ) {
13972		var vals,
13973			newValues,
13974			i;
13975
13976		if ( arguments.length > 1 ) {
13977			this.options.values[ index ] = this._trimAlignValue( newValue );
13978			this._refreshValue();
13979			this._change( null, index );
13980			return;
13981		}
13982
13983		if ( arguments.length ) {
13984			if ( Array.isArray( arguments[ 0 ] ) ) {
13985				vals = this.options.values;
13986				newValues = arguments[ 0 ];
13987				for ( i = 0; i < vals.length; i += 1 ) {
13988					vals[ i ] = this._trimAlignValue( newValues[ i ] );
13989					this._change( null, i );
13990				}
13991				this._refreshValue();
13992			} else {
13993				if ( this._hasMultipleValues() ) {
13994					return this._values( index );
13995				} else {
13996					return this.value();
13997				}
13998			}
13999		} else {
14000			return this._values();
14001		}
14002	},
14003
14004	_setOption: function( key, value ) {
14005		var i,
14006			valsLength = 0;
14007
14008		if ( key === "range" && this.options.range === true ) {
14009			if ( value === "min" ) {
14010				this.options.value = this._values( 0 );
14011				this.options.values = null;
14012			} else if ( value === "max" ) {
14013				this.options.value = this._values( this.options.values.length - 1 );
14014				this.options.values = null;
14015			}
14016		}
14017
14018		if ( Array.isArray( this.options.values ) ) {
14019			valsLength = this.options.values.length;
14020		}
14021
14022		this._super( key, value );
14023
14024		switch ( key ) {
14025			case "orientation":
14026				this._detectOrientation();
14027				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14028					._addClass( "ui-slider-" + this.orientation );
14029				this._refreshValue();
14030				if ( this.options.range ) {
14031					this._refreshRange( value );
14032				}
14033
14034				// Reset positioning from previous orientation
14035				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
14036				break;
14037			case "value":
14038				this._animateOff = true;
14039				this._refreshValue();
14040				this._change( null, 0 );
14041				this._animateOff = false;
14042				break;
14043			case "values":
14044				this._animateOff = true;
14045				this._refreshValue();
14046
14047				// Start from the last handle to prevent unreachable handles (#9046)
14048				for ( i = valsLength - 1; i >= 0; i-- ) {
14049					this._change( null, i );
14050				}
14051				this._animateOff = false;
14052				break;
14053			case "step":
14054			case "min":
14055			case "max":
14056				this._animateOff = true;
14057				this._calculateNewMax();
14058				this._refreshValue();
14059				this._animateOff = false;
14060				break;
14061			case "range":
14062				this._animateOff = true;
14063				this._refresh();
14064				this._animateOff = false;
14065				break;
14066		}
14067	},
14068
14069	_setOptionDisabled: function( value ) {
14070		this._super( value );
14071
14072		this._toggleClass( null, "ui-state-disabled", !!value );
14073	},
14074
14075	//internal value getter
14076	// _value() returns value trimmed by min and max, aligned by step
14077	_value: function() {
14078		var val = this.options.value;
14079		val = this._trimAlignValue( val );
14080
14081		return val;
14082	},
14083
14084	//internal values getter
14085	// _values() returns array of values trimmed by min and max, aligned by step
14086	// _values( index ) returns single value trimmed by min and max, aligned by step
14087	_values: function( index ) {
14088		var val,
14089			vals,
14090			i;
14091
14092		if ( arguments.length ) {
14093			val = this.options.values[ index ];
14094			val = this._trimAlignValue( val );
14095
14096			return val;
14097		} else if ( this._hasMultipleValues() ) {
14098
14099			// .slice() creates a copy of the array
14100			// this copy gets trimmed by min and max and then returned
14101			vals = this.options.values.slice();
14102			for ( i = 0; i < vals.length; i += 1 ) {
14103				vals[ i ] = this._trimAlignValue( vals[ i ] );
14104			}
14105
14106			return vals;
14107		} else {
14108			return [];
14109		}
14110	},
14111
14112	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
14113	_trimAlignValue: function( val ) {
14114		if ( val <= this._valueMin() ) {
14115			return this._valueMin();
14116		}
14117		if ( val >= this._valueMax() ) {
14118			return this._valueMax();
14119		}
14120		var step = ( this.options.step > 0 ) ? this.options.step : 1,
14121			valModStep = ( val - this._valueMin() ) % step,
14122			alignValue = val - valModStep;
14123
14124		if ( Math.abs( valModStep ) * 2 >= step ) {
14125			alignValue += ( valModStep > 0 ) ? step : ( -step );
14126		}
14127
14128		// Since JavaScript has problems with large floats, round
14129		// the final value to 5 digits after the decimal point (see #4124)
14130		return parseFloat( alignValue.toFixed( 5 ) );
14131	},
14132
14133	_calculateNewMax: function() {
14134		var max = this.options.max,
14135			min = this._valueMin(),
14136			step = this.options.step,
14137			aboveMin = Math.round( ( max - min ) / step ) * step;
14138		max = aboveMin + min;
14139		if ( max > this.options.max ) {
14140
vendor: 5,583 bytes, lines 14141-14340
14141			//If max is not divisible by step, rounding off may increase its value
14142			max -= step;
14143		}
14144		this.max = parseFloat( max.toFixed( this._precision() ) );
14145	},
14146
14147	_precision: function() {
14148		var precision = this._precisionOf( this.options.step );
14149		if ( this.options.min !== null ) {
14150			precision = Math.max( precision, this._precisionOf( this.options.min ) );
14151		}
14152		return precision;
14153	},
14154
14155	_precisionOf: function( num ) {
14156		var str = num.toString(),
14157			decimal = str.indexOf( "." );
14158		return decimal === -1 ? 0 : str.length - decimal - 1;
14159	},
14160
14161	_valueMin: function() {
14162		return this.options.min;
14163	},
14164
14165	_valueMax: function() {
14166		return this.max;
14167	},
14168
14169	_refreshRange: function( orientation ) {
14170		if ( orientation === "vertical" ) {
14171			this.range.css( { "width": "", "left": "" } );
14172		}
14173		if ( orientation === "horizontal" ) {
14174			this.range.css( { "height": "", "bottom": "" } );
14175		}
14176	},
14177
14178	_refreshValue: function() {
14179		var lastValPercent, valPercent, value, valueMin, valueMax,
14180			oRange = this.options.range,
14181			o = this.options,
14182			that = this,
14183			animate = ( !this._animateOff ) ? o.animate : false,
14184			_set = {};
14185
14186		if ( this._hasMultipleValues() ) {
14187			this.handles.each( function( i ) {
14188				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
14189					that._valueMin() ) * 100;
14190				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
14191				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
14192				if ( that.options.range === true ) {
14193					if ( that.orientation === "horizontal" ) {
14194						if ( i === 0 ) {
14195							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14196								left: valPercent + "%"
14197							}, o.animate );
14198						}
14199						if ( i === 1 ) {
14200							that.range[ animate ? "animate" : "css" ]( {
14201								width: ( valPercent - lastValPercent ) + "%"
14202							}, {
14203								queue: false,
14204								duration: o.animate
14205							} );
14206						}
14207					} else {
14208						if ( i === 0 ) {
14209							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14210								bottom: ( valPercent ) + "%"
14211							}, o.animate );
14212						}
14213						if ( i === 1 ) {
14214							that.range[ animate ? "animate" : "css" ]( {
14215								height: ( valPercent - lastValPercent ) + "%"
14216							}, {
14217								queue: false,
14218								duration: o.animate
14219							} );
14220						}
14221					}
14222				}
14223				lastValPercent = valPercent;
14224			} );
14225		} else {
14226			value = this.value();
14227			valueMin = this._valueMin();
14228			valueMax = this._valueMax();
14229			valPercent = ( valueMax !== valueMin ) ?
14230					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
14231					0;
14232			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
14233			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
14234
14235			if ( oRange === "min" && this.orientation === "horizontal" ) {
14236				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14237					width: valPercent + "%"
14238				}, o.animate );
14239			}
14240			if ( oRange === "max" && this.orientation === "horizontal" ) {
14241				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14242					width: ( 100 - valPercent ) + "%"
14243				}, o.animate );
14244			}
14245			if ( oRange === "min" && this.orientation === "vertical" ) {
14246				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14247					height: valPercent + "%"
14248				}, o.animate );
14249			}
14250			if ( oRange === "max" && this.orientation === "vertical" ) {
14251				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14252					height: ( 100 - valPercent ) + "%"
14253				}, o.animate );
14254			}
14255		}
14256	},
14257
14258	_handleEvents: {
14259		keydown: function( event ) {
14260			var allowed, curVal, newVal, step,
14261				index = $( event.target ).data( "ui-slider-handle-index" );
14262
14263			switch ( event.keyCode ) {
14264				case $.ui.keyCode.HOME:
14265				case $.ui.keyCode.END:
14266				case $.ui.keyCode.PAGE_UP:
14267				case $.ui.keyCode.PAGE_DOWN:
14268				case $.ui.keyCode.UP:
14269				case $.ui.keyCode.RIGHT:
14270				case $.ui.keyCode.DOWN:
14271				case $.ui.keyCode.LEFT:
14272					event.preventDefault();
14273					if ( !this._keySliding ) {
14274						this._keySliding = true;
14275						this._addClass( $( event.target ), null, "ui-state-active" );
14276						allowed = this._start( event, index );
14277						if ( allowed === false ) {
14278							return;
14279						}
14280					}
14281					break;
14282			}
14283
14284			step = this.options.step;
14285			if ( this._hasMultipleValues() ) {
14286				curVal = newVal = this.values( index );
14287			} else {
14288				curVal = newVal = this.value();
14289			}
14290
14291			switch ( event.keyCode ) {
14292				case $.ui.keyCode.HOME:
14293					newVal = this._valueMin();
14294					break;
14295				case $.ui.keyCode.END:
14296					newVal = this._valueMax();
14297					break;
14298				case $.ui.keyCode.PAGE_UP:
14299					newVal = this._trimAlignValue(
14300						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
14301					);
14302					break;
14303				case $.ui.keyCode.PAGE_DOWN:
14304					newVal = this._trimAlignValue(
14305						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
14306					break;
14307				case $.ui.keyCode.UP:
14308				case $.ui.keyCode.RIGHT:
14309					if ( curVal === this._valueMax() ) {
14310						return;
14311					}
14312					newVal = this._trimAlignValue( curVal + step );
14313					break;
14314				case $.ui.keyCode.DOWN:
14315				case $.ui.keyCode.LEFT:
14316					if ( curVal === this._valueMin() ) {
14317						return;
14318					}
14319					newVal = this._trimAlignValue( curVal - step );
14320					break;
14321			}
14322
14323			this._slide( event, index, newVal );
14324		},
14325		keyup: function( event ) {
14326			var index = $( event.target ).data( "ui-slider-handle-index" );
14327
14328			if ( this._keySliding ) {
14329				this._keySliding = false;
14330				this._stop( event, index );
14331				this._change( event, index );
14332				this._removeClass( $( event.target ), null, "ui-state-active" );
14333			}
14334		}
14335	}
14336} );
14337
14338
14339/*!
14340 * jQuery UI S
vendor: 37,718 bytes, lines 14340-15811
14340pinner 1.14.2
14341 * https://jqueryui.com
14342 *
14343 * Copyright OpenJS Foundation and other contributors
14344 * Released under the MIT license.
14345 * https://jquery.org/license
14346 */
14347
14348//>>label: Spinner
14349//>>group: Widgets
14350//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
14351//>>docs: https://api.jqueryui.com/spinner/
14352//>>demos: https://jqueryui.com/spinner/
14353//>>css.structure: ../../themes/base/core.css
14354//>>css.structure: ../../themes/base/spinner.css
14355//>>css.theme: ../../themes/base/theme.css
14356
14357
14358function spinnerModifier( fn ) {
14359	return function() {
14360		var previous = this.element.val();
14361		fn.apply( this, arguments );
14362		this._refresh();
14363		if ( previous !== this.element.val() ) {
14364			this._trigger( "change" );
14365		}
14366	};
14367}
14368
14369$.widget( "ui.spinner", {
14370	version: "1.14.2",
14371	defaultElement: "<input>",
14372	widgetEventPrefix: "spin",
14373	options: {
14374		classes: {
14375			"ui-spinner": "ui-corner-all",
14376			"ui-spinner-down": "ui-corner-br",
14377			"ui-spinner-up": "ui-corner-tr"
14378		},
14379		culture: null,
14380		icons: {
14381			down: "ui-icon-triangle-1-s",
14382			up: "ui-icon-triangle-1-n"
14383		},
14384		incremental: true,
14385		max: null,
14386		min: null,
14387		numberFormat: null,
14388		page: 10,
14389		step: 1,
14390
14391		change: null,
14392		spin: null,
14393		start: null,
14394		stop: null
14395	},
14396
14397	_create: function() {
14398
14399		// handle string values that need to be parsed
14400		this._setOption( "max", this.options.max );
14401		this._setOption( "min", this.options.min );
14402		this._setOption( "step", this.options.step );
14403
14404		// Only format if there is a value, prevents the field from being marked
14405		// as invalid in Firefox, see #9573.
14406		if ( this.value() !== "" ) {
14407
14408			// Format the value, but don't constrain.
14409			this._value( this.element.val(), true );
14410		}
14411
14412		this._draw();
14413		this._on( this._events );
14414		this._refresh();
14415
14416		// Turning off autocomplete prevents the browser from remembering the
14417		// value when navigating through history, so we re-enable autocomplete
14418		// if the page is unloaded before the widget is destroyed. #7790
14419		this._on( this.window, {
14420			beforeunload: function() {
14421				this.element.removeAttr( "autocomplete" );
14422			}
14423		} );
14424	},
14425
14426	_getCreateOptions: function() {
14427		var options = this._super();
14428		var element = this.element;
14429
14430		$.each( [ "min", "max", "step" ], function( i, option ) {
14431			var value = element.attr( option );
14432			if ( value != null && value.length ) {
14433				options[ option ] = value;
14434			}
14435		} );
14436
14437		return options;
14438	},
14439
14440	_events: {
14441		keydown: function( event ) {
14442			if ( this._start( event ) && this._keydown( event ) ) {
14443				event.preventDefault();
14444			}
14445		},
14446		keyup: "_stop",
14447		focus: function() {
14448			this.previous = this.element.val();
14449		},
14450		blur: function( event ) {
14451			this._stop();
14452			this._refresh();
14453			if ( this.previous !== this.element.val() ) {
14454				this._trigger( "change", event );
14455			}
14456		},
14457		wheel: function( event ) {
14458			var activeElement = this.document[ 0 ].activeElement;
14459			var isActive = this.element[ 0 ] === activeElement;
14460			var delta = event.deltaY || event.originalEvent && event.originalEvent.deltaY;
14461
14462			if ( !isActive || !delta ) {
14463				return;
14464			}
14465
14466			if ( !this.spinning && !this._start( event ) ) {
14467				return false;
14468			}
14469
14470			this._spin( ( delta > 0 ? -1 : 1 ) * this.options.step, event );
14471			clearTimeout( this.mousewheelTimer );
14472			this.mousewheelTimer = this._delay( function() {
14473				if ( this.spinning ) {
14474					this._stop( event );
14475				}
14476			}, 100 );
14477			event.preventDefault();
14478		},
14479
14480		// DEPRECATED
14481		// Kept for backwards compatibility. Please use the modern `wheel`
14482		// event. The `delta` parameter is provided by the jQuery Mousewheel
14483		// plugin if one is loaded.
14484		mousewheel: function( event, delta ) {
14485			if ( !event.isTrigger ) {
14486
14487				// If this is not a trigger call, the `wheel` handler will
14488				// fire as well, let's not duplicate it.
14489				return;
14490			}
14491
14492			var wheelEvent = $.Event( event );
14493			wheelEvent.type = "wheel";
14494			if ( delta ) {
14495				wheelEvent.deltaY = -delta;
14496			}
14497			return this._events.wheel.call( this, wheelEvent );
14498		},
14499
14500		"mousedown .ui-spinner-button": function( event ) {
14501			var previous;
14502
14503			// We never want the buttons to have focus; whenever the user is
14504			// interacting with the spinner, the focus should be on the input.
14505			// If the input is focused then this.previous is properly set from
14506			// when the input first received focus. If the input is not focused
14507			// then we need to set this.previous based on the value before spinning.
14508			previous = this.element[ 0 ] === this.document[ 0 ].activeElement ?
14509				this.previous : this.element.val();
14510			function checkFocus() {
14511				var isActive = this.element[ 0 ] === this.document[ 0 ].activeElement;
14512				if ( !isActive ) {
14513					this.element.trigger( "focus" );
14514					this.previous = previous;
14515				}
14516			}
14517
14518			// Ensure focus is on (or stays on) the text field
14519			event.preventDefault();
14520			checkFocus.call( this );
14521
14522			if ( this._start( event ) === false ) {
14523				return;
14524			}
14525
14526			this._repeat( null, $( event.currentTarget )
14527				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14528		},
14529		"mouseup .ui-spinner-button": "_stop",
14530		"mouseenter .ui-spinner-button": function( event ) {
14531
14532			// button will add ui-state-active if mouse was down while mouseleave and kept down
14533			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14534				return;
14535			}
14536
14537			if ( this._start( event ) === false ) {
14538				return false;
14539			}
14540			this._repeat( null, $( event.currentTarget )
14541				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14542		},
14543
14544		// TODO: do we really want to consider this a stop?
14545		// shouldn't we just stop the repeater and wait until mouseup before
14546		// we trigger the stop event?
14547		"mouseleave .ui-spinner-button": "_stop"
14548	},
14549
14550	// Support mobile enhanced option and make backcompat more sane
14551	_enhance: function() {
14552		this.uiSpinner = this.element
14553			.attr( "autocomplete", "off" )
14554			.wrap( "<span>" )
14555			.parent()
14556
14557				// Add buttons
14558				.append(
14559					"<a></a><a></a>"
14560				);
14561	},
14562
14563	_draw: function() {
14564		this._enhance();
14565
14566		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
14567		this._addClass( "ui-spinner-input" );
14568
14569		this.element.attr( "role", "spinbutton" );
14570
14571		// Button bindings
14572		this.buttons = this.uiSpinner.children( "a" )
14573			.attr( "tabIndex", -1 )
14574			.attr( "aria-hidden", true )
14575			.button( {
14576				classes: {
14577					"ui-button": ""
14578				}
14579			} );
14580
14581		// TODO: Right now button does not support classes this is already updated in button PR
14582		this._removeClass( this.buttons, "ui-corner-all" );
14583
14584		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
14585		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
14586		this.buttons.first().button( {
14587			"icon": this.options.icons.up,
14588			"showLabel": false
14589		} );
14590		this.buttons.last().button( {
14591			"icon": this.options.icons.down,
14592			"showLabel": false
14593		} );
14594
14595		// IE 6 doesn't understand height: 50% for the buttons
14596		// unless the wrapper has an explicit height
14597		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
14598				this.uiSpinner.height() > 0 ) {
14599			this.uiSpinner.height( this.uiSpinner.height() );
14600		}
14601	},
14602
14603	_keydown: function( event ) {
14604		var options = this.options,
14605			keyCode = $.ui.keyCode;
14606
14607		switch ( event.keyCode ) {
14608		case keyCode.UP:
14609			this._repeat( null, 1, event );
14610			return true;
14611		case keyCode.DOWN:
14612			this._repeat( null, -1, event );
14613			return true;
14614		case keyCode.PAGE_UP:
14615			this._repeat( null, options.page, event );
14616			return true;
14617		case keyCode.PAGE_DOWN:
14618			this._repeat( null, -options.page, event );
14619			return true;
14620		}
14621
14622		return false;
14623	},
14624
14625	_start: function( event ) {
14626		if ( !this.spinning && this._trigger( "start", event ) === false ) {
14627			return false;
14628		}
14629
14630		if ( !this.counter ) {
14631			this.counter = 1;
14632		}
14633		this.spinning = true;
14634		return true;
14635	},
14636
14637	_repeat: function( i, steps, event ) {
14638		i = i || 500;
14639
14640		clearTimeout( this.timer );
14641		this.timer = this._delay( function() {
14642			this._repeat( 40, steps, event );
14643		}, i );
14644
14645		this._spin( steps * this.options.step, event );
14646	},
14647
14648	_spin: function( step, event ) {
14649		var value = this.value() || 0;
14650
14651		if ( !this.counter ) {
14652			this.counter = 1;
14653		}
14654
14655		value = this._adjustValue( value + step * this._increment( this.counter ) );
14656
14657		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
14658			this._value( value );
14659			this.counter++;
14660		}
14661	},
14662
14663	_increment: function( i ) {
14664		var incremental = this.options.incremental;
14665
14666		if ( incremental ) {
14667			return typeof incremental === "function" ?
14668				incremental( i ) :
14669				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
14670		}
14671
14672		return 1;
14673	},
14674
14675	_precision: function() {
14676		var precision = this._precisionOf( this.options.step );
14677		if ( this.options.min !== null ) {
14678			precision = Math.max( precision, this._precisionOf( this.options.min ) );
14679		}
14680		return precision;
14681	},
14682
14683	_precisionOf: function( num ) {
14684		var str = num.toString(),
14685			decimal = str.indexOf( "." );
14686		return decimal === -1 ? 0 : str.length - decimal - 1;
14687	},
14688
14689	_adjustValue: function( value ) {
14690		var base, aboveMin,
14691			options = this.options;
14692
14693		// Make sure we're at a valid step
14694		// - find out where we are relative to the base (min or 0)
14695		base = options.min !== null ? options.min : 0;
14696		aboveMin = value - base;
14697
14698		// - round to the nearest step
14699		aboveMin = Math.round( aboveMin / options.step ) * options.step;
14700
14701		// - rounding is based on 0, so adjust back to our base
14702		value = base + aboveMin;
14703
14704		// Fix precision from bad JS floating point math
14705		value = parseFloat( value.toFixed( this._precision() ) );
14706
14707		// Clamp the value
14708		if ( options.max !== null && value > options.max ) {
14709			return options.max;
14710		}
14711		if ( options.min !== null && value < options.min ) {
14712			return options.min;
14713		}
14714
14715		return value;
14716	},
14717
14718	_stop: function( event ) {
14719		if ( !this.spinning ) {
14720			return;
14721		}
14722
14723		clearTimeout( this.timer );
14724		clearTimeout( this.mousewheelTimer );
14725		this.counter = 0;
14726		this.spinning = false;
14727		this._trigger( "stop", event );
14728	},
14729
14730	_setOption: function( key, value ) {
14731		var prevValue, first, last;
14732
14733		if ( key === "culture" || key === "numberFormat" ) {
14734			prevValue = this._parse( this.element.val() );
14735			this.options[ key ] = value;
14736			this.element.val( this._format( prevValue ) );
14737			return;
14738		}
14739
14740		if ( key === "max" || key === "min" || key === "step" ) {
14741			if ( typeof value === "string" ) {
14742				value = this._parse( value );
14743			}
14744		}
14745		if ( key === "icons" ) {
14746			first = this.buttons.first().find( ".ui-icon" );
14747			this._removeClass( first, null, this.options.icons.up );
14748			this._addClass( first, null, value.up );
14749			last = this.buttons.last().find( ".ui-icon" );
14750			this._removeClass( last, null, this.options.icons.down );
14751			this._addClass( last, null, value.down );
14752		}
14753
14754		this._super( key, value );
14755	},
14756
14757	_setOptionDisabled: function( value ) {
14758		this._super( value );
14759
14760		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
14761		this.element.prop( "disabled", !!value );
14762		this.buttons.button( value ? "disable" : "enable" );
14763	},
14764
14765	_setOptions: spinnerModifier( function( options ) {
14766		this._super( options );
14767	} ),
14768
14769	_parse: function( val ) {
14770		if ( typeof val === "string" && val !== "" ) {
14771			val = window.Globalize && this.options.numberFormat ?
14772				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
14773		}
14774		return val === "" || isNaN( val ) ? null : val;
14775	},
14776
14777	_format: function( value ) {
14778		if ( value === "" ) {
14779			return "";
14780		}
14781		return window.Globalize && this.options.numberFormat ?
14782			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
14783			value;
14784	},
14785
14786	_refresh: function() {
14787		this.element.attr( {
14788			"aria-valuemin": this.options.min,
14789			"aria-valuemax": this.options.max,
14790
14791			// TODO: what should we do with values that can't be parsed?
14792			"aria-valuenow": this._parse( this.element.val() )
14793		} );
14794	},
14795
14796	isValid: function() {
14797		var value = this.value();
14798
14799		// Null is invalid
14800		if ( value === null ) {
14801			return false;
14802		}
14803
14804		// If value gets adjusted, it's invalid
14805		return value === this._adjustValue( value );
14806	},
14807
14808	// Update the value without triggering change
14809	_value: function( value, allowAny ) {
14810		var parsed;
14811		if ( value !== "" ) {
14812			parsed = this._parse( value );
14813			if ( parsed !== null ) {
14814				if ( !allowAny ) {
14815					parsed = this._adjustValue( parsed );
14816				}
14817				value = this._format( parsed );
14818			}
14819		}
14820		this.element.val( value );
14821		this._refresh();
14822	},
14823
14824	_destroy: function() {
14825		this.element
14826			.prop( "disabled", false )
14827			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
14828
14829		this.uiSpinner.replaceWith( this.element );
14830	},
14831
14832	stepUp: spinnerModifier( function( steps ) {
14833		this._stepUp( steps );
14834	} ),
14835	_stepUp: function( steps ) {
14836		if ( this._start() ) {
14837			this._spin( ( steps || 1 ) * this.options.step );
14838			this._stop();
14839		}
14840	},
14841
14842	stepDown: spinnerModifier( function( steps ) {
14843		this._stepDown( steps );
14844	} ),
14845	_stepDown: function( steps ) {
14846		if ( this._start() ) {
14847			this._spin( ( steps || 1 ) * -this.options.step );
14848			this._stop();
14849		}
14850	},
14851
14852	pageUp: spinnerModifier( function( pages ) {
14853		this._stepUp( ( pages || 1 ) * this.options.page );
14854	} ),
14855
14856	pageDown: spinnerModifier( function( pages ) {
14857		this._stepDown( ( pages || 1 ) * this.options.page );
14858	} ),
14859
14860	value: function( newVal ) {
14861		if ( !arguments.length ) {
14862			return this._parse( this.element.val() );
14863		}
14864		spinnerModifier( this._value ).call( this, newVal );
14865	},
14866
14867	widget: function() {
14868		return this.uiSpinner;
14869	}
14870} );
14871
14872// DEPRECATED
14873// TODO: switch return back to widget declaration at top of file when this is removed
14874if ( $.uiBackCompat === true ) {
14875
14876	// Backcompat for spinner html extension points
14877	$.widget( "ui.spinner", $.ui.spinner, {
14878		_enhance: function() {
14879			this.uiSpinner = this.element
14880				.attr( "autocomplete", "off" )
14881				.wrap( this._uiSpinnerHtml() )
14882				.parent()
14883
14884					// Add buttons
14885					.append( this._buttonHtml() );
14886		},
14887		_uiSpinnerHtml: function() {
14888			return "<span>";
14889		},
14890
14891		_buttonHtml: function() {
14892			return "<a></a><a></a>";
14893		}
14894	} );
14895}
14896
14897var widgetsSpinner = $.ui.spinner;
14898
14899
14900/*!
14901 * jQuery UI Tabs 1.14.2
14902 * https://jqueryui.com
14903 *
14904 * Copyright OpenJS Foundation and other contributors
14905 * Released under the MIT license.
14906 * https://jquery.org/license
14907 */
14908
14909//>>label: Tabs
14910//>>group: Widgets
14911//>>description: Transforms a set of container elements into a tab structure.
14912//>>docs: https://api.jqueryui.com/tabs/
14913//>>demos: https://jqueryui.com/tabs/
14914//>>css.structure: ../../themes/base/core.css
14915//>>css.structure: ../../themes/base/tabs.css
14916//>>css.theme: ../../themes/base/theme.css
14917
14918
14919$.widget( "ui.tabs", {
14920	version: "1.14.2",
14921	delay: 300,
14922	options: {
14923		active: null,
14924		classes: {
14925			"ui-tabs": "ui-corner-all",
14926			"ui-tabs-nav": "ui-corner-all",
14927			"ui-tabs-panel": "ui-corner-bottom",
14928			"ui-tabs-tab": "ui-corner-top"
14929		},
14930		collapsible: false,
14931		event: "click",
14932		heightStyle: "content",
14933		hide: null,
14934		show: null,
14935
14936		// Callbacks
14937		activate: null,
14938		beforeActivate: null,
14939		beforeLoad: null,
14940		load: null
14941	},
14942
14943	_isLocal: function( anchor ) {
14944		var anchorUrl = new URL( anchor.href ),
14945			locationUrl = new URL( location.href );
14946
14947		return anchor.hash.length > 1 &&
14948
14949			// `href` may contain a hash but also username & password;
14950			// we want to ignore them, so we check the three fields
14951			// below instead.
14952			anchorUrl.origin === locationUrl.origin &&
14953			anchorUrl.pathname === locationUrl.pathname &&
14954			anchorUrl.search === locationUrl.search;
14955	},
14956
14957	_create: function() {
14958		var that = this,
14959			options = this.options;
14960
14961		this.running = false;
14962
14963		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
14964		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
14965
14966		this._processTabs();
14967		options.active = this._initialActive();
14968
14969		// Take disabling tabs via class attribute from HTML
14970		// into account and update option properly.
14971		if ( Array.isArray( options.disabled ) ) {
14972			options.disabled = $.uniqueSort( options.disabled.concat(
14973				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
14974					return that.tabs.index( li );
14975				} )
14976			) ).sort();
14977		}
14978
14979		// Check for length avoids error when initializing empty list
14980		if ( this.options.active !== false && this.anchors.length ) {
14981			this.active = this._findActive( options.active );
14982		} else {
14983			this.active = $();
14984		}
14985
14986		this._refresh();
14987
14988		if ( this.active.length ) {
14989			this.load( options.active );
14990		}
14991	},
14992
14993	_initialActive: function() {
14994		var active = this.options.active,
14995			collapsible = this.options.collapsible,
14996			locationHash = location.hash.substring( 1 ),
14997			locationHashDecoded = decodeURIComponent( locationHash );
14998
14999		if ( active === null ) {
15000
15001			// check the fragment identifier in the URL
15002			if ( locationHash ) {
15003				this.tabs.each( function( i, tab ) {
15004					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
15005						active = i;
15006						return false;
15007					}
15008				} );
15009
15010				// If not found, decode the hash & try again.
15011				// See the comment in `_processTabs` under the `_isLocal` check
15012				// for more information.
15013				if ( active === null ) {
15014					this.tabs.each( function( i, tab ) {
15015						if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) {
15016							active = i;
15017							return false;
15018						}
15019					} );
15020				}
15021			}
15022
15023			// Check for a tab marked active via a class
15024			if ( active === null ) {
15025				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
15026			}
15027
15028			// No active tab, set to false
15029			if ( active === null || active === -1 ) {
15030				active = this.tabs.length ? 0 : false;
15031			}
15032		}
15033
15034		// Handle numbers: negative, out of range
15035		if ( active !== false ) {
15036			active = this.tabs.index( this.tabs.eq( active ) );
15037			if ( active === -1 ) {
15038				active = collapsible ? false : 0;
15039			}
15040		}
15041
15042		// Don't allow collapsible: false and active: false
15043		if ( !collapsible && active === false && this.anchors.length ) {
15044			active = 0;
15045		}
15046
15047		return active;
15048	},
15049
15050	_getCreateEventData: function() {
15051		return {
15052			tab: this.active,
15053			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
15054		};
15055	},
15056
15057	_tabKeydown: function( event ) {
15058		var focusedTab = $( this.document[ 0 ].activeElement ).closest( "li" ),
15059			selectedIndex = this.tabs.index( focusedTab ),
15060			goingForward = true;
15061
15062		if ( this._handlePageNav( event ) ) {
15063			return;
15064		}
15065
15066		switch ( event.keyCode ) {
15067		case $.ui.keyCode.RIGHT:
15068		case $.ui.keyCode.DOWN:
15069			selectedIndex++;
15070			break;
15071		case $.ui.keyCode.UP:
15072		case $.ui.keyCode.LEFT:
15073			goingForward = false;
15074			selectedIndex--;
15075			break;
15076		case $.ui.keyCode.END:
15077			selectedIndex = this.anchors.length - 1;
15078			break;
15079		case $.ui.keyCode.HOME:
15080			selectedIndex = 0;
15081			break;
15082		case $.ui.keyCode.SPACE:
15083
15084			// Activate only, no collapsing
15085			event.preventDefault();
15086			clearTimeout( this.activating );
15087			this._activate( selectedIndex );
15088			return;
15089		case $.ui.keyCode.ENTER:
15090
15091			// Toggle (cancel delayed activation, allow collapsing)
15092			event.preventDefault();
15093			clearTimeout( this.activating );
15094
15095			// Determine if we should collapse or activate
15096			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
15097			return;
15098		default:
15099			return;
15100		}
15101
15102		// Focus the appropriate tab, based on which key was pressed
15103		event.preventDefault();
15104		clearTimeout( this.activating );
15105		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
15106
15107		// Navigating with control/command key will prevent automatic activation
15108		if ( !event.ctrlKey && !event.metaKey ) {
15109
15110			// Update aria-selected immediately so that AT think the tab is already selected.
15111			// Otherwise AT may confuse the user by stating that they need to activate the tab,
15112			// but the tab will already be activated by the time the announcement finishes.
15113			focusedTab.attr( "aria-selected", "false" );
15114			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
15115
15116			this.activating = this._delay( function() {
15117				this.option( "active", selectedIndex );
15118			}, this.delay );
15119		}
15120	},
15121
15122	_panelKeydown: function( event ) {
15123		if ( this._handlePageNav( event ) ) {
15124			return;
15125		}
15126
15127		// Ctrl+up moves focus to the current tab
15128		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
15129			event.preventDefault();
15130			this.active.trigger( "focus" );
15131		}
15132	},
15133
15134	// Alt+page up/down moves focus to the previous/next tab (and activates)
15135	_handlePageNav: function( event ) {
15136		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
15137			this._activate( this._focusNextTab( this.options.active - 1, false ) );
15138			return true;
15139		}
15140		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
15141			this._activate( this._focusNextTab( this.options.active + 1, true ) );
15142			return true;
15143		}
15144	},
15145
15146	_findNextTab: function( index, goingForward ) {
15147		var lastTabIndex = this.tabs.length - 1;
15148
15149		function constrain() {
15150			if ( index > lastTabIndex ) {
15151				index = 0;
15152			}
15153			if ( index < 0 ) {
15154				index = lastTabIndex;
15155			}
15156			return index;
15157		}
15158
15159		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
15160			index = goingForward ? index + 1 : index - 1;
15161		}
15162
15163		return index;
15164	},
15165
15166	_focusNextTab: function( index, goingForward ) {
15167		index = this._findNextTab( index, goingForward );
15168		this.tabs.eq( index ).trigger( "focus" );
15169		return index;
15170	},
15171
15172	_setOption: function( key, value ) {
15173		if ( key === "active" ) {
15174
15175			// _activate() will handle invalid values and update this.options
15176			this._activate( value );
15177			return;
15178		}
15179
15180		this._super( key, value );
15181
15182		if ( key === "collapsible" ) {
15183			this._toggleClass( "ui-tabs-collapsible", null, value );
15184
15185			// Setting collapsible: false while collapsed; open first panel
15186			if ( !value && this.options.active === false ) {
15187				this._activate( 0 );
15188			}
15189		}
15190
15191		if ( key === "event" ) {
15192			this._setupEvents( value );
15193		}
15194
15195		if ( key === "heightStyle" ) {
15196			this._setupHeightStyle( value );
15197		}
15198	},
15199
15200	refresh: function() {
15201		var options = this.options,
15202			lis = this.tablist.children( ":has(a[href])" );
15203
15204		// Get disabled tabs from class attribute from HTML
15205		// this will get converted to a boolean if needed in _refresh()
15206		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15207			return lis.index( tab );
15208		} );
15209
15210		this._processTabs();
15211
15212		// Was collapsed or no tabs
15213		if ( options.active === false || !this.anchors.length ) {
15214			options.active = false;
15215			this.active = $();
15216
15217		// was active, but active tab is gone
15218		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15219
15220			// all remaining tabs are disabled
15221			if ( this.tabs.length === options.disabled.length ) {
15222				options.active = false;
15223				this.active = $();
15224
15225			// activate previous tab
15226			} else {
15227				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15228			}
15229
15230		// was active, active tab still exists
15231		} else {
15232
15233			// make sure active index is correct
15234			options.active = this.tabs.index( this.active );
15235		}
15236
15237		this._refresh();
15238	},
15239
15240	_refresh: function() {
15241		this._setOptionDisabled( this.options.disabled );
15242		this._setupEvents( this.options.event );
15243		this._setupHeightStyle( this.options.heightStyle );
15244
15245		this.tabs.not( this.active ).attr( {
15246			"aria-selected": "false",
15247			"aria-expanded": "false",
15248			tabIndex: -1
15249		} );
15250		this.panels.not( this._getPanelForTab( this.active ) )
15251			.hide()
15252			.attr( {
15253				"aria-hidden": "true"
15254			} );
15255
15256		// Make sure one tab is in the tab order
15257		if ( !this.active.length ) {
15258			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15259		} else {
15260			this.active
15261				.attr( {
15262					"aria-selected": "true",
15263					"aria-expanded": "true",
15264					tabIndex: 0
15265				} );
15266			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
15267			this._getPanelForTab( this.active )
15268				.show()
15269				.attr( {
15270					"aria-hidden": "false"
15271				} );
15272		}
15273	},
15274
15275	_processTabs: function() {
15276		var that = this,
15277			prevTabs = this.tabs,
15278			prevAnchors = this.anchors,
15279			prevPanels = this.panels;
15280
15281		this.tablist = this._getList().attr( "role", "tablist" );
15282		this._addClass( this.tablist, "ui-tabs-nav",
15283			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
15284
15285		// Prevent users from focusing disabled tabs via click
15286		this.tablist
15287			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
15288				if ( $( this ).is( ".ui-state-disabled" ) ) {
15289					event.preventDefault();
15290				}
15291			} );
15292
15293		this.tabs = this.tablist.find( "> li:has(a[href])" )
15294			.attr( {
15295				role: "tab",
15296				tabIndex: -1
15297			} );
15298		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
15299
15300		this.anchors = this.tabs.map( function() {
15301			return $( "a", this )[ 0 ];
15302		} )
15303			.attr( {
15304				tabIndex: -1
15305			} );
15306		this._addClass( this.anchors, "ui-tabs-anchor" );
15307
15308		this.panels = $();
15309
15310		this.anchors.each( function( i, anchor ) {
15311			var selector, panel, panelId,
15312				anchorId = $( anchor ).uniqueId().attr( "id" ),
15313				tab = $( anchor ).closest( "li" ),
15314				originalAriaControls = tab.attr( "aria-controls" );
15315
15316			// Inline tab
15317			if ( that._isLocal( anchor ) ) {
15318
15319				// The "scrolling to a fragment" section of the HTML spec:
15320				// https://html.spec.whatwg.org/#scrolling-to-a-fragment
15321				// uses a concept of document's indicated part:
15322				// https://html.spec.whatwg.org/#the-indicated-part-of-the-document
15323				// Slightly below there's an algorithm to compute the indicated
15324				// part:
15325				// https://html.spec.whatwg.org/#the-indicated-part-of-the-document
15326				// First, the algorithm tries the hash as-is, without decoding.
15327				// Then, if one is not found, the same is attempted with a decoded
15328				// hash. Replicate this logic.
15329				selector = anchor.hash;
15330				panelId = selector.substring( 1 );
15331				panel = that.element.find( "#" + CSS.escape( panelId ) );
15332				if ( !panel.length ) {
15333					panelId = decodeURIComponent( panelId );
15334					panel = that.element.find( "#" + CSS.escape( panelId ) );
15335				}
15336
15337			// remote tab
15338			} else {
15339
15340				// If the tab doesn't already have aria-controls,
15341				// generate an id by using a throw-away element
15342				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15343				selector = "#" + panelId;
15344				panel = that.element.find( selector );
15345				if ( !panel.length ) {
15346					panel = that._createPanel( panelId );
15347					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15348				}
15349				panel.attr( "aria-live", "polite" );
15350			}
15351
15352			if ( panel.length ) {
15353				that.panels = that.panels.add( panel );
15354			}
15355			if ( originalAriaControls ) {
15356				tab.data( "ui-tabs-aria-controls", originalAriaControls );
15357			}
15358			tab.attr( {
15359				"aria-controls": panelId,
15360				"aria-labelledby": anchorId
15361			} );
15362			panel.attr( "aria-labelledby", anchorId );
15363		} );
15364
15365		this.panels.attr( "role", "tabpanel" );
15366		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
15367
15368		// Avoid memory leaks (#10056)
15369		if ( prevTabs ) {
15370			this._off( prevTabs.not( this.tabs ) );
15371			this._off( prevAnchors.not( this.anchors ) );
15372			this._off( prevPanels.not( this.panels ) );
15373		}
15374	},
15375
15376	// Allow overriding how to find the list for rare usage scenarios (#7715)
15377	_getList: function() {
15378		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
15379	},
15380
15381	_createPanel: function( id ) {
15382		return $( "<div>" )
15383			.attr( "id", id )
15384			.data( "ui-tabs-destroy", true );
15385	},
15386
15387	_setOptionDisabled: function( disabled ) {
15388		var currentItem, li, i;
15389
15390		if ( Array.isArray( disabled ) ) {
15391			if ( !disabled.length ) {
15392				disabled = false;
15393			} else if ( disabled.length === this.anchors.length ) {
15394				disabled = true;
15395			}
15396		}
15397
15398		// Disable tabs
15399		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
15400			currentItem = $( li );
15401			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15402				currentItem.attr( "aria-disabled", "true" );
15403				this._addClass( currentItem, null, "ui-state-disabled" );
15404			} else {
15405				currentItem.removeAttr( "aria-disabled" );
15406				this._removeClass( currentItem, null, "ui-state-disabled" );
15407			}
15408		}
15409
15410		this.options.disabled = disabled;
15411
15412		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
15413			disabled === true );
15414	},
15415
15416	_setupEvents: function( event ) {
15417		var events = {};
15418		if ( event ) {
15419			$.each( event.split( " " ), function( index, eventName ) {
15420				events[ eventName ] = "_eventHandler";
15421			} );
15422		}
15423
15424		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15425
15426		// Always prevent the default action, even when disabled
15427		this._on( true, this.anchors, {
15428			click: function( event ) {
15429				event.preventDefault();
15430			}
15431		} );
15432		this._on( this.anchors, events );
15433		this._on( this.tabs, { keydown: "_tabKeydown" } );
15434		this._on( this.panels, { keydown: "_panelKeydown" } );
15435
15436		this._focusable( this.tabs );
15437		this._hoverable( this.tabs );
15438	},
15439
15440	_setupHeightStyle: function( heightStyle ) {
15441		var maxHeight,
15442			parent = this.element.parent();
15443
15444		if ( heightStyle === "fill" ) {
15445			maxHeight = parent.height();
15446			maxHeight -= this.element.outerHeight() - this.element.height();
15447
15448			this.element.siblings( ":visible" ).each( function() {
15449				var elem = $( this ),
15450					position = elem.css( "position" );
15451
15452				if ( position === "absolute" || position === "fixed" ) {
15453					return;
15454				}
15455				maxHeight -= elem.outerHeight( true );
15456			} );
15457
15458			this.element.children().not( this.panels ).each( function() {
15459				maxHeight -= $( this ).outerHeight( true );
15460			} );
15461
15462			this.panels.each( function() {
15463				$( this ).height( Math.max( 0, maxHeight -
15464					$( this ).innerHeight() + $( this ).height() ) );
15465			} )
15466				.css( "overflow", "auto" );
15467		} else if ( heightStyle === "auto" ) {
15468			maxHeight = 0;
15469			this.panels.each( function() {
15470				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15471			} ).height( maxHeight );
15472		}
15473	},
15474
15475	_eventHandler: function( event ) {
15476		var options = this.options,
15477			active = this.active,
15478			anchor = $( event.currentTarget ),
15479			tab = anchor.closest( "li" ),
15480			clickedIsActive = tab[ 0 ] === active[ 0 ],
15481			collapsing = clickedIsActive && options.collapsible,
15482			toShow = collapsing ? $() : this._getPanelForTab( tab ),
15483			toHide = !active.length ? $() : this._getPanelForTab( active ),
15484			eventData = {
15485				oldTab: active,
15486				oldPanel: toHide,
15487				newTab: collapsing ? $() : tab,
15488				newPanel: toShow
15489			};
15490
15491		event.preventDefault();
15492
15493		if ( tab.hasClass( "ui-state-disabled" ) ||
15494
15495				// tab is already loading
15496				tab.hasClass( "ui-tabs-loading" ) ||
15497
15498				// can't switch durning an animation
15499				this.running ||
15500
15501				// click on active header, but not collapsible
15502				( clickedIsActive && !options.collapsible ) ||
15503
15504				// allow canceling activation
15505				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15506			return;
15507		}
15508
15509		options.active = collapsing ? false : this.tabs.index( tab );
15510
15511		this.active = clickedIsActive ? $() : tab;
15512		if ( this.xhr ) {
15513			this.xhr.abort();
15514		}
15515
15516		if ( !toHide.length && !toShow.length ) {
15517			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15518		}
15519
15520		if ( toShow.length ) {
15521			this.load( this.tabs.index( tab ), event );
15522		}
15523		this._toggle( event, eventData );
15524	},
15525
15526	// Handles show/hide for selecting tabs
15527	_toggle: function( event, eventData ) {
15528		var that = this,
15529			toShow = eventData.newPanel,
15530			toHide = eventData.oldPanel;
15531
15532		this.running = true;
15533
15534		function complete() {
15535			that.running = false;
15536			that._trigger( "activate", event, eventData );
15537		}
15538
15539		function show() {
15540			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
15541
15542			if ( toShow.length && that.options.show ) {
15543				that._show( toShow, that.options.show, complete );
15544			} else {
15545				toShow.show();
15546				complete();
15547			}
15548		}
15549
15550		// Start out by hiding, then showing, then completing
15551		if ( toHide.length && this.options.hide ) {
15552			this._hide( toHide, this.options.hide, function() {
15553				that._removeClass( eventData.oldTab.closest( "li" ),
15554					"ui-tabs-active", "ui-state-active" );
15555				show();
15556			} );
15557		} else {
15558			this._removeClass( eventData.oldTab.closest( "li" ),
15559				"ui-tabs-active", "ui-state-active" );
15560			toHide.hide();
15561			show();
15562		}
15563
15564		toHide.attr( "aria-hidden", "true" );
15565		eventData.oldTab.attr( {
15566			"aria-selected": "false",
15567			"aria-expanded": "false"
15568		} );
15569
15570		// If we're switching tabs, remove the old tab from the tab order.
15571		// If we're opening from collapsed state, remove the previous tab from the tab order.
15572		// If we're collapsing, then keep the collapsing tab in the tab order.
15573		if ( toShow.length && toHide.length ) {
15574			eventData.oldTab.attr( "tabIndex", -1 );
15575		} else if ( toShow.length ) {
15576			this.tabs.filter( function() {
15577				return $( this ).attr( "tabIndex" ) === 0;
15578			} )
15579				.attr( "tabIndex", -1 );
15580		}
15581
15582		toShow.attr( "aria-hidden", "false" );
15583		eventData.newTab.attr( {
15584			"aria-selected": "true",
15585			"aria-expanded": "true",
15586			tabIndex: 0
15587		} );
15588	},
15589
15590	_activate: function( index ) {
15591		var anchor,
15592			active = this._findActive( index );
15593
15594		// Trying to activate the already active panel
15595		if ( active[ 0 ] === this.active[ 0 ] ) {
15596			return;
15597		}
15598
15599		// Trying to collapse, simulate a click on the current active header
15600		if ( !active.length ) {
15601			active = this.active;
15602		}
15603
15604		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15605		this._eventHandler( {
15606			target: anchor,
15607			currentTarget: anchor,
15608			preventDefault: $.noop
15609		} );
15610	},
15611
15612	_findActive: function( index ) {
15613		return index === false ? $() : this.tabs.eq( index );
15614	},
15615
15616	_getIndex: function( index ) {
15617
15618		// meta-function to give users option to provide a href string instead of a numerical index.
15619		if ( typeof index === "string" ) {
15620			index = this.anchors.index( this.anchors.filter( "[href$='" +
15621				CSS.escape( index ) + "']" ) );
15622		}
15623
15624		return index;
15625	},
15626
15627	_destroy: function() {
15628		if ( this.xhr ) {
15629			this.xhr.abort();
15630		}
15631
15632		this.tablist
15633			.removeAttr( "role" )
15634			.off( this.eventNamespace );
15635
15636		this.anchors
15637			.removeAttr( "role tabIndex" )
15638			.removeUniqueId();
15639
15640		this.tabs.add( this.panels ).each( function() {
15641			if ( $.data( this, "ui-tabs-destroy" ) ) {
15642				$( this ).remove();
15643			} else {
15644				$( this ).removeAttr( "role tabIndex " +
15645					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
15646			}
15647		} );
15648
15649		this.tabs.each( function() {
15650			var li = $( this ),
15651				prev = li.data( "ui-tabs-aria-controls" );
15652			if ( prev ) {
15653				li
15654					.attr( "aria-controls", prev )
15655					.removeData( "ui-tabs-aria-controls" );
15656			} else {
15657				li.removeAttr( "aria-controls" );
15658			}
15659		} );
15660
15661		this.panels.show();
15662
15663		if ( this.options.heightStyle !== "content" ) {
15664			this.panels.css( "height", "" );
15665		}
15666	},
15667
15668	enable: function( index ) {
15669		var disabled = this.options.disabled;
15670		if ( disabled === false ) {
15671			return;
15672		}
15673
15674		if ( index === undefined ) {
15675			disabled = false;
15676		} else {
15677			index = this._getIndex( index );
15678			if ( Array.isArray( disabled ) ) {
15679				disabled = $.map( disabled, function( num ) {
15680					return num !== index ? num : null;
15681				} );
15682			} else {
15683				disabled = $.map( this.tabs, function( li, num ) {
15684					return num !== index ? num : null;
15685				} );
15686			}
15687		}
15688		this._setOptionDisabled( disabled );
15689	},
15690
15691	disable: function( index ) {
15692		var disabled = this.options.disabled;
15693		if ( disabled === true ) {
15694			return;
15695		}
15696
15697		if ( index === undefined ) {
15698			disabled = true;
15699		} else {
15700			index = this._getIndex( index );
15701			if ( $.inArray( index, disabled ) !== -1 ) {
15702				return;
15703			}
15704			if ( Array.isArray( disabled ) ) {
15705				disabled = $.merge( [ index ], disabled ).sort();
15706			} else {
15707				disabled = [ index ];
15708			}
15709		}
15710		this._setOptionDisabled( disabled );
15711	},
15712
15713	load: function( index, event ) {
15714		index = this._getIndex( index );
15715		var that = this,
15716			tab = this.tabs.eq( index ),
15717			anchor = tab.find( ".ui-tabs-anchor" ),
15718			panel = this._getPanelForTab( tab ),
15719			eventData = {
15720				tab: tab,
15721				panel: panel
15722			},
15723			complete = function( jqXHR, status ) {
15724				if ( status === "abort" ) {
15725					that.panels.stop( false, true );
15726				}
15727
15728				that._removeClass( tab, "ui-tabs-loading" );
15729				panel.removeAttr( "aria-busy" );
15730
15731				if ( jqXHR === that.xhr ) {
15732					delete that.xhr;
15733				}
15734			};
15735
15736		// Not remote
15737		if ( this._isLocal( anchor[ 0 ] ) ) {
15738			return;
15739		}
15740
15741		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
15742
15743		if ( this.xhr.statusText !== "canceled" ) {
15744			this._addClass( tab, "ui-tabs-loading" );
15745			panel.attr( "aria-busy", "true" );
15746
15747			this.xhr
15748				.done( function( response, status, jqXHR ) {
15749					panel.html( response );
15750					that._trigger( "load", event, eventData );
15751
15752					complete( jqXHR, status );
15753				} )
15754				.fail( function( jqXHR, status ) {
15755					complete( jqXHR, status );
15756				} );
15757		}
15758	},
15759
15760	_ajaxSettings: function( anchor, event, eventData ) {
15761		var that = this;
15762		return {
15763			url: anchor.attr( "href" ),
15764			beforeSend: function( jqXHR, settings ) {
15765				return that._trigger( "beforeLoad", event,
15766					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
15767			}
15768		};
15769	},
15770
15771	_getPanelForTab: function( tab ) {
15772		var id = $( tab ).attr( "aria-controls" );
15773		return this.element.find( "#" + CSS.escape( id ) );
15774	}
15775} );
15776
15777// DEPRECATED
15778// TODO: Switch return back to widget declaration at top of file when this is removed
15779if ( $.uiBackCompat === true ) {
15780
15781	// Backcompat for ui-tab class (now ui-tabs-tab)
15782	$.widget( "ui.tabs", $.ui.tabs, {
15783		_processTabs: function() {
15784			this._superApply( arguments );
15785			this._addClass( this.tabs, "ui-tab" );
15786		}
15787	} );
15788}
15789
15790var widgetsTabs = $.ui.tabs;
15791
15792
15793/*!
15794 * jQuery UI Tooltip 1.14.2
15795 * https://jqueryui.com
15796 *
15797 * Copyright OpenJS Foundation and other contributors
15798 * Released under the MIT license.
15799 * https://jquery.org/license
15800 */
15801
15802//>>label: Tooltip
15803//>>group: Widgets
15804//>>description: Shows additional information for any element on hover or focus.
15805//>>docs: https://api.jqueryui.com/tooltip/
15806//>>demos: https://jqueryui.com/tooltip/
15807//>>css.structure: ../../themes/base/core.css
15808//>>css.structure: ../../themes/base/tooltip.css
15809//>>css.theme: ../../themes/base/theme.css
15810
15811
15812if (0) 
vendor: 77,811 bytes, lines 15812-18841
15812$.widget( "ui.tooltip", {
15813	version: "1.14.2",
15814	options: {
15815		classes: {
15816			"ui-tooltip": "ui-corner-all ui-widget-shadow"
15817		},
15818		content: function() {
15819			var title = $( this ).attr( "title" );
15820
15821			// Escape title, since we're going from an attribute to raw HTML
15822			return $( "<a>" ).text( title ).html();
15823		},
15824		hide: true,
15825
15826		// Disabled elements have inconsistent behavior across browsers (#8661)
15827		items: "[title]:not([disabled])",
15828		position: {
15829			my: "left top+15",
15830			at: "left bottom",
15831			collision: "flipfit flip"
15832		},
15833		show: true,
15834		track: false,
15835
15836		// Callbacks
15837		close: null,
15838		open: null
15839	},
15840
15841	_addDescribedBy: function( elem, id ) {
15842		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
15843		describedby.push( id );
15844		elem
15845			.data( "ui-tooltip-id", id )
15846			.attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) );
15847	},
15848
15849	_removeDescribedBy: function( elem ) {
15850		var id = elem.data( "ui-tooltip-id" ),
15851			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
15852			index = $.inArray( id, describedby );
15853
15854		if ( index !== -1 ) {
15855			describedby.splice( index, 1 );
15856		}
15857
15858		elem.removeData( "ui-tooltip-id" );
15859		describedby = String.prototype.trim.call( describedby.join( " " ) );
15860		if ( describedby ) {
15861			elem.attr( "aria-describedby", describedby );
15862		} else {
15863			elem.removeAttr( "aria-describedby" );
15864		}
15865	},
15866
15867	_create: function() {
15868		this._on( {
15869			mouseover: "open",
15870			focusin: "open"
15871		} );
15872
15873		// IDs of generated tooltips, needed for destroy
15874		this.tooltips = {};
15875
15876		// IDs of parent tooltips where we removed the title attribute
15877		this.parents = {};
15878
15879		// Append the aria-live region so tooltips announce correctly
15880		this.liveRegion = $( "<div>" )
15881			.attr( {
15882				role: "log",
15883				"aria-live": "assertive",
15884				"aria-relevant": "additions"
15885			} )
15886			.appendTo( this.document[ 0 ].body );
15887		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
15888
15889		this.disabledTitles = $( [] );
15890	},
15891
15892	_setOption: function( key, value ) {
15893		var that = this;
15894
15895		this._super( key, value );
15896
15897		if ( key === "content" ) {
15898			$.each( this.tooltips, function( id, tooltipData ) {
15899				that._updateContent( tooltipData.element );
15900			} );
15901		}
15902	},
15903
15904	_setOptionDisabled: function( value ) {
15905		this[ value ? "_disable" : "_enable" ]();
15906	},
15907
15908	_disable: function() {
15909		var that = this;
15910
15911		// Close open tooltips
15912		$.each( this.tooltips, function( id, tooltipData ) {
15913			var event = $.Event( "blur" );
15914			event.target = event.currentTarget = tooltipData.element[ 0 ];
15915			that.close( event, true );
15916		} );
15917
15918		// Remove title attributes to prevent native tooltips
15919		this.disabledTitles = this.disabledTitles.add(
15920			this.element.find( this.options.items ).addBack()
15921				.filter( function() {
15922					var element = $( this );
15923					if ( element.is( "[title]" ) ) {
15924						return element
15925							.data( "ui-tooltip-title", element.attr( "title" ) )
15926							.removeAttr( "title" );
15927					}
15928				} )
15929		);
15930	},
15931
15932	_enable: function() {
15933
15934		// restore title attributes
15935		this.disabledTitles.each( function() {
15936			var element = $( this );
15937			if ( element.data( "ui-tooltip-title" ) ) {
15938				element.attr( "title", element.data( "ui-tooltip-title" ) );
15939			}
15940		} );
15941		this.disabledTitles = $( [] );
15942	},
15943
15944	open: function( event ) {
15945		var that = this,
15946			target = $( event ? event.target : this.element )
15947
15948				// we need closest here due to mouseover bubbling,
15949				// but always pointing at the same event target
15950				.closest( this.options.items );
15951
15952		// No element to show a tooltip for or the tooltip is already open
15953		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
15954			return;
15955		}
15956
15957		if ( target.attr( "title" ) ) {
15958			target.data( "ui-tooltip-title", target.attr( "title" ) );
15959		}
15960
15961		target.data( "ui-tooltip-open", true );
15962
15963		// Kill parent tooltips, custom or native, for hover
15964		if ( event && event.type === "mouseover" ) {
15965			target.parents().each( function() {
15966				var parent = $( this ),
15967					blurEvent;
15968				if ( parent.data( "ui-tooltip-open" ) ) {
15969					blurEvent = $.Event( "blur" );
15970					blurEvent.target = blurEvent.currentTarget = this;
15971					that.close( blurEvent, true );
15972				}
15973				if ( parent.attr( "title" ) ) {
15974					parent.uniqueId();
15975					that.parents[ this.id ] = {
15976						element: this,
15977						title: parent.attr( "title" )
15978					};
15979					parent.attr( "title", "" );
15980				}
15981			} );
15982		}
15983
15984		this._registerCloseHandlers( event, target );
15985		this._updateContent( target, event );
15986	},
15987
15988	_updateContent: function( target, event ) {
15989		var content,
15990			contentOption = this.options.content,
15991			that = this,
15992			eventType = event ? event.type : null;
15993
15994		if ( typeof contentOption === "string" || contentOption.nodeType ||
15995				contentOption.jquery ) {
15996			return this._open( event, target, contentOption );
15997		}
15998
15999		content = contentOption.call( target[ 0 ], function( response ) {
16000
16001			// Ignore async response if tooltip was closed already
16002			if ( !target.data( "ui-tooltip-open" ) ) {
16003				return;
16004			}
16005
16006			// JQuery creates a special event for focusin when it doesn't
16007			// exist natively. To improve performance, the native event
16008			// object is reused and the type is changed. Therefore, we can't
16009			// rely on the type being correct after the event finished
16010			// bubbling, so we set it back to the previous value. (#8740)
16011			if ( event ) {
16012				event.type = eventType;
16013			}
16014			that._open( event, target, response );
16015		} );
16016		if ( content ) {
16017			this._open( event, target, content );
16018		}
16019	},
16020
16021	_open: function( event, target, content ) {
16022		var tooltipData, tooltip, delayedShow, a11yContent,
16023			positionOption = $.extend( {}, this.options.position );
16024
16025		if ( !content ) {
16026			return;
16027		}
16028
16029		// Content can be updated multiple times. If the tooltip already
16030		// exists, then just update the content and bail.
16031		tooltipData = this._find( target );
16032		if ( tooltipData ) {
16033			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
16034			return;
16035		}
16036
16037		// If we have a title, clear it to prevent the native tooltip
16038		// we have to check first to avoid defining a title if none exists
16039		// (we don't want to cause an element to start matching [title])
16040		//
16041		// We use removeAttr only for key events, to allow IE to export the correct
16042		// accessible attributes. For mouse events, set to empty string to avoid
16043		// native tooltip showing up (happens only when removing inside mouseover).
16044		if ( target.is( "[title]" ) ) {
16045			if ( event && event.type === "mouseover" ) {
16046				target.attr( "title", "" );
16047			} else {
16048				target.removeAttr( "title" );
16049			}
16050		}
16051
16052		tooltipData = this._tooltip( target );
16053		tooltip = tooltipData.tooltip;
16054		this._addDescribedBy( target, tooltip.attr( "id" ) );
16055		tooltip.find( ".ui-tooltip-content" ).html( content );
16056
16057		// Support: Voiceover on OS X, JAWS on IE <= 9
16058		// JAWS announces deletions even when aria-relevant="additions"
16059		// Voiceover will sometimes re-read the entire log region's contents from the beginning
16060		this.liveRegion.children().hide();
16061		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
16062		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
16063		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
16064		a11yContent.appendTo( this.liveRegion );
16065
16066		function position( event ) {
16067			positionOption.of = event;
16068			if ( tooltip.is( ":hidden" ) ) {
16069				return;
16070			}
16071			tooltip.position( positionOption );
16072		}
16073		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
16074			this._on( this.document, {
16075				mousemove: position
16076			} );
16077
16078			// trigger once to override element-relative positioning
16079			position( event );
16080		} else {
16081			tooltip.position( $.extend( {
16082				of: target
16083			}, this.options.position ) );
16084		}
16085
16086		tooltip.hide();
16087
16088		this._show( tooltip, this.options.show );
16089
16090		// Handle tracking tooltips that are shown with a delay (#8644). As soon
16091		// as the tooltip is visible, position the tooltip using the most recent
16092		// event.
16093		// Adds the check to add the timers only when both delay and track options are set (#14682)
16094		if ( this.options.track && this.options.show && this.options.show.delay ) {
16095			delayedShow = this.delayedShow = setInterval( function() {
16096				if ( tooltip.is( ":visible" ) ) {
16097					position( positionOption.of );
16098					clearInterval( delayedShow );
16099				}
16100			}, 13 );
16101		}
16102
16103		this._trigger( "open", event, { tooltip: tooltip } );
16104	},
16105
16106	_registerCloseHandlers: function( event, target ) {
16107		var events = {
16108			keyup: function( event ) {
16109				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
16110					var fakeEvent = $.Event( event );
16111					fakeEvent.currentTarget = target[ 0 ];
16112					this.close( fakeEvent, true );
16113				}
16114			}
16115		};
16116
16117		// Only bind remove handler for delegated targets. Non-delegated
16118		// tooltips will handle this in destroy.
16119		if ( target[ 0 ] !== this.element[ 0 ] ) {
16120			events.remove = function() {
16121				var targetElement = this._find( target );
16122				if ( targetElement ) {
16123					this._removeTooltip( targetElement.tooltip );
16124				}
16125			};
16126		}
16127
16128		if ( !event || event.type === "mouseover" ) {
16129			events.mouseleave = "close";
16130		}
16131		if ( !event || event.type === "focusin" ) {
16132			events.focusout = "close";
16133		}
16134		this._on( true, target, events );
16135	},
16136
16137	close: function( event ) {
16138		var tooltip,
16139			that = this,
16140			target = $( event ? event.currentTarget : this.element ),
16141			tooltipData = this._find( target );
16142
16143		// The tooltip may already be closed
16144		if ( !tooltipData ) {
16145
16146			// We set ui-tooltip-open immediately upon open (in open()), but only set the
16147			// additional data once there's actually content to show (in _open()). So even if the
16148			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
16149			// the period between open() and _open().
16150			target.removeData( "ui-tooltip-open" );
16151			return;
16152		}
16153
16154		tooltip = tooltipData.tooltip;
16155
16156		// Disabling closes the tooltip, so we need to track when we're closing
16157		// to avoid an infinite loop in case the tooltip becomes disabled on close
16158		if ( tooltipData.closing ) {
16159			return;
16160		}
16161
16162		// Clear the interval for delayed tracking tooltips
16163		clearInterval( this.delayedShow );
16164
16165		// Only set title if we had one before (see comment in _open())
16166		// If the title attribute has changed since open(), don't restore
16167		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16168			target.attr( "title", target.data( "ui-tooltip-title" ) );
16169		}
16170
16171		this._removeDescribedBy( target );
16172
16173		tooltipData.hiding = true;
16174		tooltip.stop( true );
16175		this._hide( tooltip, this.options.hide, function() {
16176			that._removeTooltip( $( this ) );
16177		} );
16178
16179		target.removeData( "ui-tooltip-open" );
16180		this._off( target, "mouseleave focusout keyup" );
16181
16182		// Remove 'remove' binding only on delegated targets
16183		if ( target[ 0 ] !== this.element[ 0 ] ) {
16184			this._off( target, "remove" );
16185		}
16186		this._off( this.document, "mousemove" );
16187
16188		if ( event && event.type === "mouseleave" ) {
16189			$.each( this.parents, function( id, parent ) {
16190				$( parent.element ).attr( "title", parent.title );
16191				delete that.parents[ id ];
16192			} );
16193		}
16194
16195		tooltipData.closing = true;
16196		this._trigger( "close", event, { tooltip: tooltip } );
16197		if ( !tooltipData.hiding ) {
16198			tooltipData.closing = false;
16199		}
16200	},
16201
16202	_tooltip: function( element ) {
16203		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
16204			content = $( "<div>" ).appendTo( tooltip ),
16205			id = tooltip.uniqueId().attr( "id" );
16206
16207		this._addClass( content, "ui-tooltip-content" );
16208		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
16209
16210		tooltip.appendTo( this._appendTo( element ) );
16211
16212		return this.tooltips[ id ] = {
16213			element: element,
16214			tooltip: tooltip
16215		};
16216	},
16217
16218	_find: function( target ) {
16219		var id = target.data( "ui-tooltip-id" );
16220		return id ? this.tooltips[ id ] : null;
16221	},
16222
16223	_removeTooltip: function( tooltip ) {
16224
16225		// Clear the interval for delayed tracking tooltips
16226		clearInterval( this.delayedShow );
16227
16228		tooltip.remove();
16229		delete this.tooltips[ tooltip.attr( "id" ) ];
16230	},
16231
16232	_appendTo: function( target ) {
16233		var element = target.closest( ".ui-front, dialog" );
16234
16235		if ( !element.length ) {
16236			element = this.document[ 0 ].body;
16237		}
16238
16239		return element;
16240	},
16241
16242	_destroy: function() {
16243		var that = this;
16244
16245		// Close open tooltips
16246		$.each( this.tooltips, function( id, tooltipData ) {
16247
16248			// Delegate to close method to handle common cleanup
16249			var event = $.Event( "blur" ),
16250				element = tooltipData.element;
16251			event.target = event.currentTarget = element[ 0 ];
16252			that.close( event, true );
16253
16254			// Remove immediately; destroying an open tooltip doesn't use the
16255			// hide animation
16256			$( "#" + id ).remove();
16257
16258			// Restore the title
16259			if ( element.data( "ui-tooltip-title" ) ) {
16260
16261				// If the title attribute has changed since open(), don't restore
16262				if ( !element.attr( "title" ) ) {
16263					element.attr( "title", element.data( "ui-tooltip-title" ) );
16264				}
16265				element.removeData( "ui-tooltip-title" );
16266			}
16267		} );
16268		this.liveRegion.remove();
16269	}
16270} );
16271
16272// DEPRECATED
16273// TODO: Switch return back to widget declaration at top of file when this is removed
16274if ( $.uiBackCompat === true ) {
16275
16276	// Backcompat for tooltipClass option
16277	$.widget( "ui.tooltip", $.ui.tooltip, {
16278		options: {
16279			tooltipClass: null
16280		},
16281		_tooltip: function() {
16282			var tooltipData = this._superApply( arguments );
16283			if ( this.options.tooltipClass ) {
16284				tooltipData.tooltip.addClass( this.options.tooltipClass );
16285			}
16286			return tooltipData;
16287		}
16288	} );
16289}
16290
16291var widgetsTooltip = $.ui.tooltip;
16292
16293
16294
16295// Create a local jQuery because jQuery Color relies on it and the
16296// global may not exist with AMD and a custom build (#10199).
16297// This module is a noop if used as a regular AMD module.
16298// eslint-disable-next-line no-unused-vars
16299var jQuery = $;
16300
16301
16302/*!
16303 * jQuery Color Animations v3.0.0
16304 * https://github.com/jquery/jquery-color
16305 *
16306 * Copyright OpenJS Foundation and other contributors
16307 * Released under the MIT license.
16308 * https://jquery.org/license
16309 *
16310 * Date: Wed May 15 16:49:44 2024 +0200
16311 */
16312
16313
16314	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
16315		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
16316
16317	class2type = {},
16318	toString = class2type.toString,
16319
16320	// plusequals test for += 100 -= 100
16321	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
16322
16323	// a set of RE's that can match strings and generate color tuples.
16324	stringParsers = [ {
16325			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16326			parse: function( execResult ) {
16327				return [
16328					execResult[ 1 ],
16329					execResult[ 2 ],
16330					execResult[ 3 ],
16331					execResult[ 4 ]
16332				];
16333			}
16334		}, {
16335			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16336			parse: function( execResult ) {
16337				return [
16338					execResult[ 1 ] * 2.55,
16339					execResult[ 2 ] * 2.55,
16340					execResult[ 3 ] * 2.55,
16341					execResult[ 4 ]
16342				];
16343			}
16344		}, {
16345
16346			// this regex ignores A-F because it's compared against an already lowercased string
16347			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/,
16348			parse: function( execResult ) {
16349				return [
16350					parseInt( execResult[ 1 ], 16 ),
16351					parseInt( execResult[ 2 ], 16 ),
16352					parseInt( execResult[ 3 ], 16 ),
16353					execResult[ 4 ] ?
16354						( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) :
16355						1
16356				];
16357			}
16358		}, {
16359
16360			// this regex ignores A-F because it's compared against an already lowercased string
16361			re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/,
16362			parse: function( execResult ) {
16363				return [
16364					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
16365					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
16366					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ),
16367					execResult[ 4 ] ?
16368						( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 )
16369							.toFixed( 2 ) :
16370						1
16371				];
16372			}
16373		}, {
16374			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16375			space: "hsla",
16376			parse: function( execResult ) {
16377				return [
16378					execResult[ 1 ],
16379					execResult[ 2 ] / 100,
16380					execResult[ 3 ] / 100,
16381					execResult[ 4 ]
16382				];
16383			}
16384		} ],
16385
16386	// jQuery.Color( )
16387	color = jQuery.Color = function( color, green, blue, alpha ) {
16388		return new jQuery.Color.fn.parse( color, green, blue, alpha );
16389	},
16390	spaces = {
16391		rgba: {
16392			props: {
16393				red: {
16394					idx: 0,
16395					type: "byte"
16396				},
16397				green: {
16398					idx: 1,
16399					type: "byte"
16400				},
16401				blue: {
16402					idx: 2,
16403					type: "byte"
16404				}
16405			}
16406		},
16407
16408		hsla: {
16409			props: {
16410				hue: {
16411					idx: 0,
16412					type: "degrees"
16413				},
16414				saturation: {
16415					idx: 1,
16416					type: "percent"
16417				},
16418				lightness: {
16419					idx: 2,
16420					type: "percent"
16421				}
16422			}
16423		}
16424	},
16425	propTypes = {
16426		"byte": {
16427			floor: true,
16428			max: 255
16429		},
16430		"percent": {
16431			max: 1
16432		},
16433		"degrees": {
16434			mod: 360,
16435			floor: true
16436		}
16437	},
16438
16439	// colors = jQuery.Color.names
16440	colors,
16441
16442	// local aliases of functions called often
16443	each = jQuery.each;
16444
16445// define cache name and alpha properties
16446// for rgba and hsla spaces
16447each( spaces, function( spaceName, space ) {
16448	space.cache = "_" + spaceName;
16449	space.props.alpha = {
16450		idx: 3,
16451		type: "percent",
16452		def: 1
16453	};
16454} );
16455
16456// Populate the class2type map
16457jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
16458	function( _i, name ) {
16459		class2type[ "[object " + name + "]" ] = name.toLowerCase();
16460	} );
16461
16462function getType( obj ) {
16463	if ( obj == null ) {
16464		return obj + "";
16465	}
16466
16467	return typeof obj === "object" ?
16468		class2type[ toString.call( obj ) ] || "object" :
16469		typeof obj;
16470}
16471
16472function clamp( value, prop, allowEmpty ) {
16473	var type = propTypes[ prop.type ] || {};
16474
16475	if ( value == null ) {
16476		return ( allowEmpty || !prop.def ) ? null : prop.def;
16477	}
16478
16479	// ~~ is an short way of doing floor for positive numbers
16480	value = type.floor ? ~~value : parseFloat( value );
16481
16482	if ( type.mod ) {
16483
16484		// we add mod before modding to make sure that negatives values
16485		// get converted properly: -10 -> 350
16486		return ( value + type.mod ) % type.mod;
16487	}
16488
16489	// for now all property types without mod have min and max
16490	return Math.min( type.max, Math.max( 0, value ) );
16491}
16492
16493function stringParse( string ) {
16494	var inst = color(),
16495		rgba = inst._rgba = [];
16496
16497	string = string.toLowerCase();
16498
16499	each( stringParsers, function( _i, parser ) {
16500		var parsed,
16501			match = parser.re.exec( string ),
16502			values = match && parser.parse( match ),
16503			spaceName = parser.space || "rgba";
16504
16505		if ( values ) {
16506			parsed = inst[ spaceName ]( values );
16507
16508			// if this was an rgba parse the assignment might happen twice
16509			// oh well....
16510			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
16511			rgba = inst._rgba = parsed._rgba;
16512
16513			// exit each( stringParsers ) here because we matched
16514			return false;
16515		}
16516	} );
16517
16518	// Found a stringParser that handled it
16519	if ( rgba.length ) {
16520
16521		// if this came from a parsed string, force "transparent" when alpha is 0
16522		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
16523		if ( rgba.join() === "0,0,0,0" ) {
16524			jQuery.extend( rgba, colors.transparent );
16525		}
16526		return inst;
16527	}
16528
16529	// named colors
16530	return colors[ string ];
16531}
16532
16533color.fn = jQuery.extend( color.prototype, {
16534	parse: function( red, green, blue, alpha ) {
16535		if ( red === undefined ) {
16536			this._rgba = [ null, null, null, null ];
16537			return this;
16538		}
16539		if ( red.jquery || red.nodeType ) {
16540			red = jQuery( red ).css( green );
16541			green = undefined;
16542		}
16543
16544		var inst = this,
16545			type = getType( red ),
16546			rgba = this._rgba = [];
16547
16548		// more than 1 argument specified - assume ( red, green, blue, alpha )
16549		if ( green !== undefined ) {
16550			red = [ red, green, blue, alpha ];
16551			type = "array";
16552		}
16553
16554		if ( type === "string" ) {
16555			return this.parse( stringParse( red ) || colors._default );
16556		}
16557
16558		if ( type === "array" ) {
16559			each( spaces.rgba.props, function( _key, prop ) {
16560				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
16561			} );
16562			return this;
16563		}
16564
16565		if ( type === "object" ) {
16566			if ( red instanceof color ) {
16567				each( spaces, function( _spaceName, space ) {
16568					if ( red[ space.cache ] ) {
16569						inst[ space.cache ] = red[ space.cache ].slice();
16570					}
16571				} );
16572			} else {
16573				each( spaces, function( _spaceName, space ) {
16574					var cache = space.cache;
16575					each( space.props, function( key, prop ) {
16576
16577						// if the cache doesn't exist, and we know how to convert
16578						if ( !inst[ cache ] && space.to ) {
16579
16580							// if the value was null, we don't need to copy it
16581							// if the key was alpha, we don't need to copy it either
16582							if ( key === "alpha" || red[ key ] == null ) {
16583								return;
16584							}
16585							inst[ cache ] = space.to( inst._rgba );
16586						}
16587
16588						// this is the only case where we allow nulls for ALL properties.
16589						// call clamp with alwaysAllowEmpty
16590						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
16591					} );
16592
16593					// everything defined but alpha?
16594					if ( inst[ cache ] && jQuery.inArray(
16595						null,
16596						inst[ cache ].slice( 0, 3 )
16597					) < 0 ) {
16598
16599						// use the default of 1
16600						if ( inst[ cache ][ 3 ] == null ) {
16601							inst[ cache ][ 3 ] = 1;
16602						}
16603
16604						if ( space.from ) {
16605							inst._rgba = space.from( inst[ cache ] );
16606						}
16607					}
16608				} );
16609			}
16610			return this;
16611		}
16612	},
16613	is: function( compare ) {
16614		var is = color( compare ),
16615			same = true,
16616			inst = this;
16617
16618		each( spaces, function( _, space ) {
16619			var localCache,
16620				isCache = is[ space.cache ];
16621			if ( isCache ) {
16622				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
16623				each( space.props, function( _, prop ) {
16624					if ( isCache[ prop.idx ] != null ) {
16625						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
16626						return same;
16627					}
16628				} );
16629			}
16630			return same;
16631		} );
16632		return same;
16633	},
16634	_space: function() {
16635		var used = [],
16636			inst = this;
16637		each( spaces, function( spaceName, space ) {
16638			if ( inst[ space.cache ] ) {
16639				used.push( spaceName );
16640			}
16641		} );
16642		return used.pop();
16643	},
16644	transition: function( other, distance ) {
16645		var end = color( other ),
16646			spaceName = end._space(),
16647			space = spaces[ spaceName ],
16648			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
16649			start = startColor[ space.cache ] || space.to( startColor._rgba ),
16650			result = start.slice();
16651
16652		end = end[ space.cache ];
16653		each( space.props, function( _key, prop ) {
16654			var index = prop.idx,
16655				startValue = start[ index ],
16656				endValue = end[ index ],
16657				type = propTypes[ prop.type ] || {};
16658
16659			// if null, don't override start value
16660			if ( endValue === null ) {
16661				return;
16662			}
16663
16664			// if null - use end
16665			if ( startValue === null ) {
16666				result[ index ] = endValue;
16667			} else {
16668				if ( type.mod ) {
16669					if ( endValue - startValue > type.mod / 2 ) {
16670						startValue += type.mod;
16671					} else if ( startValue - endValue > type.mod / 2 ) {
16672						startValue -= type.mod;
16673					}
16674				}
16675				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
16676			}
16677		} );
16678		return this[ spaceName ]( result );
16679	},
16680	blend: function( opaque ) {
16681
16682		// if we are already opaque - return ourself
16683		if ( this._rgba[ 3 ] === 1 ) {
16684			return this;
16685		}
16686
16687		var rgb = this._rgba.slice(),
16688			a = rgb.pop(),
16689			blend = color( opaque )._rgba;
16690
16691		return color( jQuery.map( rgb, function( v, i ) {
16692			return ( 1 - a ) * blend[ i ] + a * v;
16693		} ) );
16694	},
16695	toRgbaString: function() {
16696		var prefix = "rgba(",
16697			rgba = jQuery.map( this._rgba, function( v, i ) {
16698				if ( v != null ) {
16699					return v;
16700				}
16701				return i > 2 ? 1 : 0;
16702			} );
16703
16704		if ( rgba[ 3 ] === 1 ) {
16705			rgba.pop();
16706			prefix = "rgb(";
16707		}
16708
16709		return prefix + rgba.join( ", " ) + ")";
16710	},
16711	toHslaString: function() {
16712		var prefix = "hsla(",
16713			hsla = jQuery.map( this.hsla(), function( v, i ) {
16714				if ( v == null ) {
16715					v = i > 2 ? 1 : 0;
16716				}
16717
16718				// catch 1 and 2
16719				if ( i && i < 3 ) {
16720					v = Math.round( v * 100 ) + "%";
16721				}
16722				return v;
16723			} );
16724
16725		if ( hsla[ 3 ] === 1 ) {
16726			hsla.pop();
16727			prefix = "hsl(";
16728		}
16729		return prefix + hsla.join( ", " ) + ")";
16730	},
16731	toHexString: function( includeAlpha ) {
16732		var rgba = this._rgba.slice(),
16733			alpha = rgba.pop();
16734
16735		if ( includeAlpha ) {
16736			rgba.push( ~~( alpha * 255 ) );
16737		}
16738
16739		return "#" + jQuery.map( rgba, function( v ) {
16740
16741			// default to 0 when nulls exist
16742			return ( "0" + ( v || 0 ).toString( 16 ) ).substr( -2 );
16743		} ).join( "" );
16744	},
16745	toString: function() {
16746		return this.toRgbaString();
16747	}
16748} );
16749color.fn.parse.prototype = color.fn;
16750
16751// hsla conversions adapted from:
16752// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
16753
16754function hue2rgb( p, q, h ) {
16755	h = ( h + 1 ) % 1;
16756	if ( h * 6 < 1 ) {
16757		return p + ( q - p ) * h * 6;
16758	}
16759	if ( h * 2 < 1 ) {
16760		return q;
16761	}
16762	if ( h * 3 < 2 ) {
16763		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
16764	}
16765	return p;
16766}
16767
16768spaces.hsla.to = function( rgba ) {
16769	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
16770		return [ null, null, null, rgba[ 3 ] ];
16771	}
16772	var r = rgba[ 0 ] / 255,
16773		g = rgba[ 1 ] / 255,
16774		b = rgba[ 2 ] / 255,
16775		a = rgba[ 3 ],
16776		max = Math.max( r, g, b ),
16777		min = Math.min( r, g, b ),
16778		diff = max - min,
16779		add = max + min,
16780		l = add * 0.5,
16781		h, s;
16782
16783	if ( min === max ) {
16784		h = 0;
16785	} else if ( r === max ) {
16786		h = ( 60 * ( g - b ) / diff ) + 360;
16787	} else if ( g === max ) {
16788		h = ( 60 * ( b - r ) / diff ) + 120;
16789	} else {
16790		h = ( 60 * ( r - g ) / diff ) + 240;
16791	}
16792
16793	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
16794	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
16795	if ( diff === 0 ) {
16796		s = 0;
16797	} else if ( l <= 0.5 ) {
16798		s = diff / add;
16799	} else {
16800		s = diff / ( 2 - add );
16801	}
16802	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
16803};
16804
16805spaces.hsla.from = function( hsla ) {
16806	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
16807		return [ null, null, null, hsla[ 3 ] ];
16808	}
16809	var h = hsla[ 0 ] / 360,
16810		s = hsla[ 1 ],
16811		l = hsla[ 2 ],
16812		a = hsla[ 3 ],
16813		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
16814		p = 2 * l - q;
16815
16816	return [
16817		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
16818		Math.round( hue2rgb( p, q, h ) * 255 ),
16819		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
16820		a
16821	];
16822};
16823
16824
16825each( spaces, function( spaceName, space ) {
16826	var props = space.props,
16827		cache = space.cache,
16828		to = space.to,
16829		from = space.from;
16830
16831	// makes rgba() and hsla()
16832	color.fn[ spaceName ] = function( value ) {
16833
16834		// generate a cache for this space if it doesn't exist
16835		if ( to && !this[ cache ] ) {
16836			this[ cache ] = to( this._rgba );
16837		}
16838		if ( value === undefined ) {
16839			return this[ cache ].slice();
16840		}
16841
16842		var ret,
16843			type = getType( value ),
16844			arr = ( type === "array" || type === "object" ) ? value : arguments,
16845			local = this[ cache ].slice();
16846
16847		each( props, function( key, prop ) {
16848			var val = arr[ type === "object" ? key : prop.idx ];
16849			if ( val == null ) {
16850				val = local[ prop.idx ];
16851			}
16852			local[ prop.idx ] = clamp( val, prop );
16853		} );
16854
16855		if ( from ) {
16856			ret = color( from( local ) );
16857			ret[ cache ] = local;
16858			return ret;
16859		} else {
16860			return color( local );
16861		}
16862	};
16863
16864	// makes red() green() blue() alpha() hue() saturation() lightness()
16865	each( props, function( key, prop ) {
16866
16867		// alpha is included in more than one space
16868		if ( color.fn[ key ] ) {
16869			return;
16870		}
16871		color.fn[ key ] = function( value ) {
16872			var local, cur, match, fn,
16873				vtype = getType( value );
16874
16875			if ( key === "alpha" ) {
16876				fn = this._hsla ? "hsla" : "rgba";
16877			} else {
16878				fn = spaceName;
16879			}
16880			local = this[ fn ]();
16881			cur = local[ prop.idx ];
16882
16883			if ( vtype === "undefined" ) {
16884				return cur;
16885			}
16886
16887			if ( vtype === "function" ) {
16888				value = value.call( this, cur );
16889				vtype = getType( value );
16890			}
16891			if ( value == null && prop.empty ) {
16892				return this;
16893			}
16894			if ( vtype === "string" ) {
16895				match = rplusequals.exec( value );
16896				if ( match ) {
16897					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
16898				}
16899			}
16900			local[ prop.idx ] = value;
16901			return this[ fn ]( local );
16902		};
16903	} );
16904} );
16905
16906// add cssHook and .fx.step function for each named hook.
16907// accept a space separated string of properties
16908color.hook = function( hook ) {
16909	var hooks = hook.split( " " );
16910	each( hooks, function( _i, hook ) {
16911		jQuery.cssHooks[ hook ] = {
16912			set: function( elem, value ) {
16913				var parsed;
16914
16915				if ( value !== "transparent" &&
16916					( getType( value ) !== "string" ||
16917						( parsed = stringParse( value ) ) ) ) {
16918					value = color( parsed || value );
16919					value = value.toRgbaString();
16920				}
16921				elem.style[ hook ] = value;
16922			}
16923		};
16924		jQuery.fx.step[ hook ] = function( fx ) {
16925			if ( !fx.colorInit ) {
16926				fx.start = color( fx.elem, hook );
16927				fx.end = color( fx.end );
16928				fx.colorInit = true;
16929			}
16930			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
16931		};
16932	} );
16933
16934};
16935
16936color.hook( stepHooks );
16937
16938jQuery.cssHooks.borderColor = {
16939	expand: function( value ) {
16940		var expanded = {};
16941
16942		each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) {
16943			expanded[ "border" + part + "Color" ] = value;
16944		} );
16945		return expanded;
16946	}
16947};
16948
16949// Basic color names only.
16950// Usage of any of the other color names requires adding yourself or including
16951// jquery.color.svg-names.js.
16952colors = jQuery.Color.names = {
16953
16954	// 4.1. Basic color keywords
16955	aqua: "#00ffff",
16956	black: "#000000",
16957	blue: "#0000ff",
16958	fuchsia: "#ff00ff",
16959	gray: "#808080",
16960	green: "#008000",
16961	lime: "#00ff00",
16962	maroon: "#800000",
16963	navy: "#000080",
16964	olive: "#808000",
16965	purple: "#800080",
16966	red: "#ff0000",
16967	silver: "#c0c0c0",
16968	teal: "#008080",
16969	white: "#ffffff",
16970	yellow: "#ffff00",
16971
16972	// 4.2.3. "transparent" color keyword
16973	transparent: [ null, null, null, 0 ],
16974
16975	_default: "#ffffff"
16976};
16977
16978
16979/*!
16980 * jQuery UI Effects 1.14.2
16981 * https://jqueryui.com
16982 *
16983 * Copyright OpenJS Foundation and other contributors
16984 * Released under the MIT license.
16985 * https://jquery.org/license
16986 */
16987
16988//>>label: Effects Core
16989//>>group: Effects
16990//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
16991//>>docs: https://api.jqueryui.com/category/effects-core/
16992//>>demos: https://jqueryui.com/effect/
16993
16994
16995var dataSpace = "ui-effects-",
16996	dataSpaceStyle = "ui-effects-style",
16997	dataSpaceAnimated = "ui-effects-animated";
16998
16999$.effects = {
17000	effect: {}
17001};
17002
17003/******************************************************************************/
17004/****************************** CLASS ANIMATIONS ******************************/
17005/******************************************************************************/
17006( function() {
17007
17008var classAnimationActions = [ "add", "remove", "toggle" ],
17009	shorthandStyles = {
17010		border: 1,
17011		borderBottom: 1,
17012		borderColor: 1,
17013		borderLeft: 1,
17014		borderRight: 1,
17015		borderTop: 1,
17016		borderWidth: 1,
17017		margin: 1,
17018		padding: 1
17019	};
17020
17021$.each(
17022	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
17023	function( _, prop ) {
17024		$.fx.step[ prop ] = function( fx ) {
17025			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
17026				jQuery.style( fx.elem, prop, fx.end );
17027				fx.setAttr = true;
17028			}
17029		};
17030	}
17031);
17032
17033function camelCase( string ) {
17034	return string.replace( /-([\da-z])/gi, function( all, letter ) {
17035		return letter.toUpperCase();
17036	} );
17037}
17038
17039function getElementStyles( elem ) {
17040	var key, len,
17041		style = elem.ownerDocument.defaultView.getComputedStyle( elem ),
17042		styles = {};
17043
17044	len = style.length;
17045	while ( len-- ) {
17046		key = style[ len ];
17047		if ( typeof style[ key ] === "string" ) {
17048			styles[ camelCase( key ) ] = style[ key ];
17049		}
17050	}
17051
17052	return styles;
17053}
17054
17055function styleDifference( oldStyle, newStyle ) {
17056	var diff = {},
17057		name, value;
17058
17059	for ( name in newStyle ) {
17060		value = newStyle[ name ];
17061		if ( oldStyle[ name ] !== value ) {
17062			if ( !shorthandStyles[ name ] ) {
17063				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
17064					diff[ name ] = value;
17065				}
17066			}
17067		}
17068	}
17069
17070	return diff;
17071}
17072
17073$.effects.animateClass = function( value, duration, easing, callback ) {
17074	var o = $.speed( duration, easing, callback );
17075
17076	return this.queue( function() {
17077		var animated = $( this ),
17078			baseClass = animated.attr( "class" ) || "",
17079			applyClassChange,
17080			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
17081
17082		// Map the animated objects to store the original styles.
17083		allAnimations = allAnimations.map( function() {
17084			var el = $( this );
17085			return {
17086				el: el,
17087				start: getElementStyles( this )
17088			};
17089		} );
17090
17091		// Apply class change
17092		applyClassChange = function() {
17093			$.each( classAnimationActions, function( i, action ) {
17094				if ( value[ action ] ) {
17095					animated[ action + "Class" ]( value[ action ] );
17096				}
17097			} );
17098		};
17099		applyClassChange();
17100
17101		// Map all animated objects again - calculate new styles and diff
17102		allAnimations = allAnimations.map( function() {
17103			this.end = getElementStyles( this.el[ 0 ] );
17104			this.diff = styleDifference( this.start, this.end );
17105			return this;
17106		} );
17107
17108		// Apply original class
17109		animated.attr( "class", baseClass );
17110
17111		// Map all animated objects again - this time collecting a promise
17112		allAnimations = allAnimations.map( function() {
17113			var styleInfo = this,
17114				dfd = $.Deferred(),
17115				opts = $.extend( {}, o, {
17116					queue: false,
17117					complete: function() {
17118						dfd.resolve( styleInfo );
17119					}
17120				} );
17121
17122			this.el.animate( this.diff, opts );
17123			return dfd.promise();
17124		} );
17125
17126		// Once all animations have completed:
17127		$.when.apply( $, allAnimations.get() ).done( function() {
17128
17129			// Set the final class
17130			applyClassChange();
17131
17132			// For each animated element,
17133			// clear all css properties that were animated
17134			$.each( arguments, function() {
17135				var el = this.el;
17136				$.each( this.diff, function( key ) {
17137					el.css( key, "" );
17138				} );
17139			} );
17140
17141			// This is guarnteed to be there if you use jQuery.speed()
17142			// it also handles dequeuing the next anim...
17143			o.complete.call( animated[ 0 ] );
17144		} );
17145	} );
17146};
17147
17148$.fn.extend( {
17149	addClass: ( function( orig ) {
17150		return function( classNames, speed, easing, callback ) {
17151			return speed ?
17152				$.effects.animateClass.call( this,
17153					{ add: classNames }, speed, easing, callback ) :
17154				orig.apply( this, arguments );
17155		};
17156	} )( $.fn.addClass ),
17157
17158	removeClass: ( function( orig ) {
17159		return function( classNames, speed, easing, callback ) {
17160			return arguments.length > 1 ?
17161				$.effects.animateClass.call( this,
17162					{ remove: classNames }, speed, easing, callback ) :
17163				orig.apply( this, arguments );
17164		};
17165	} )( $.fn.removeClass ),
17166
17167	toggleClass: ( function( orig ) {
17168		return function( classNames, force, speed, easing, callback ) {
17169			if ( typeof force === "boolean" || force === undefined ) {
17170				if ( !speed ) {
17171
17172					// Without speed parameter
17173					return orig.apply( this, arguments );
17174				} else {
17175					return $.effects.animateClass.call( this,
17176						( force ? { add: classNames } : { remove: classNames } ),
17177						speed, easing, callback );
17178				}
17179			} else {
17180
17181				// Without force parameter
17182				return $.effects.animateClass.call( this,
17183					{ toggle: classNames }, force, speed, easing );
17184			}
17185		};
17186	} )( $.fn.toggleClass ),
17187
17188	switchClass: function( remove, add, speed, easing, callback ) {
17189		return $.effects.animateClass.call( this, {
17190			add: add,
17191			remove: remove
17192		}, speed, easing, callback );
17193	}
17194} );
17195
17196} )();
17197
17198/******************************************************************************/
17199/*********************************** EFFECTS **********************************/
17200/******************************************************************************/
17201
17202( function() {
17203
17204if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) {
17205	$.expr.pseudos.animated = ( function( orig ) {
17206		return function( elem ) {
17207			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
17208		};
17209	} )( $.expr.pseudos.animated );
17210}
17211
17212if ( $.uiBackCompat === true ) {
17213	$.extend( $.effects, {
17214
17215		// Saves a set of properties in a data storage
17216		save: function( element, set ) {
17217			var i = 0, length = set.length;
17218			for ( ; i < length; i++ ) {
17219				if ( set[ i ] !== null ) {
17220					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
17221				}
17222			}
17223		},
17224
17225		// Restores a set of previously saved properties from a data storage
17226		restore: function( element, set ) {
17227			var val, i = 0, length = set.length;
17228			for ( ; i < length; i++ ) {
17229				if ( set[ i ] !== null ) {
17230					val = element.data( dataSpace + set[ i ] );
17231					element.css( set[ i ], val );
17232				}
17233			}
17234		},
17235
17236		setMode: function( el, mode ) {
17237			if ( mode === "toggle" ) {
17238				mode = el.is( ":hidden" ) ? "show" : "hide";
17239			}
17240			return mode;
17241		},
17242
17243		// Wraps the element around a wrapper that copies position properties
17244		createWrapper: function( element ) {
17245
17246			// If the element is already wrapped, return it
17247			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
17248				return element.parent();
17249			}
17250
17251			// Wrap the element
17252			var props = {
17253					width: element.outerWidth( true ),
17254					height: element.outerHeight( true ),
17255					"float": element.css( "float" )
17256				},
17257				wrapper = $( "<div></div>" )
17258					.addClass( "ui-effects-wrapper" )
17259					.css( {
17260						fontSize: "100%",
17261						background: "transparent",
17262						border: "none",
17263						margin: 0,
17264						padding: 0
17265					} ),
17266
17267				// Store the size in case width/height are defined in % - Fixes #5245
17268				size = {
17269					width: element.width(),
17270					height: element.height()
17271				},
17272				active = document.activeElement;
17273
17274			// Support: Firefox
17275			// Firefox incorrectly exposes anonymous content
17276			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
17277			try {
17278				// eslint-disable-next-line no-unused-expressions
17279				active.id;
17280			} catch ( _e ) {
17281				active = document.body;
17282			}
17283
17284			element.wrap( wrapper );
17285
17286			// Fixes #7595 - Elements lose focus when wrapped.
17287			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
17288				$( active ).trigger( "focus" );
17289			}
17290
17291			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
17292			// lose the reference to the wrapped element
17293			wrapper = element.parent();
17294
17295			// Transfer positioning properties to the wrapper
17296			if ( element.css( "position" ) === "static" ) {
17297				wrapper.css( { position: "relative" } );
17298				element.css( { position: "relative" } );
17299			} else {
17300				$.extend( props, {
17301					position: element.css( "position" ),
17302					zIndex: element.css( "z-index" )
17303				} );
17304				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
17305					props[ pos ] = element.css( pos );
17306					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
17307						props[ pos ] = "auto";
17308					}
17309				} );
17310				element.css( {
17311					position: "relative",
17312					top: 0,
17313					left: 0,
17314					right: "auto",
17315					bottom: "auto"
17316				} );
17317			}
17318			element.css( size );
17319
17320			return wrapper.css( props ).show();
17321		},
17322
17323		removeWrapper: function( element ) {
17324			var active = document.activeElement;
17325
17326			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
17327				element.parent().replaceWith( element );
17328
17329				// Fixes #7595 - Elements lose focus when wrapped.
17330				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
17331					$( active ).trigger( "focus" );
17332				}
17333			}
17334
17335			return element;
17336		}
17337	} );
17338}
17339
17340$.extend( $.effects, {
17341	version: "1.14.2",
17342
17343	define: function( name, mode, effect ) {
17344		if ( !effect ) {
17345			effect = mode;
17346			mode = "effect";
17347		}
17348
17349		$.effects.effect[ name ] = effect;
17350		$.effects.effect[ name ].mode = mode;
17351
17352		return effect;
17353	},
17354
17355	scaledDimensions: function( element, percent, direction ) {
17356		if ( percent === 0 ) {
17357			return {
17358				height: 0,
17359				width: 0,
17360				outerHeight: 0,
17361				outerWidth: 0
17362			};
17363		}
17364
17365		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
17366			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
17367
17368		return {
17369			height: element.height() * y,
17370			width: element.width() * x,
17371			outerHeight: element.outerHeight() * y,
17372			outerWidth: element.outerWidth() * x
17373		};
17374
17375	},
17376
17377	clipToBox: function( animation ) {
17378		return {
17379			width: animation.clip.right - animation.clip.left,
17380			height: animation.clip.bottom - animation.clip.top,
17381			left: animation.clip.left,
17382			top: animation.clip.top
17383		};
17384	},
17385
17386	// Injects recently queued functions to be first in line (after "inprogress")
17387	unshift: function( element, queueLength, count ) {
17388		var queue = element.queue();
17389
17390		if ( queueLength > 1 ) {
17391			queue.splice.apply( queue,
17392				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
17393		}
17394		element.dequeue();
17395	},
17396
17397	saveStyle: function( element ) {
17398		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
17399	},
17400
17401	restoreStyle: function( element ) {
17402		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
17403		element.removeData( dataSpaceStyle );
17404	},
17405
17406	mode: function( element, mode ) {
17407		var hidden = element.is( ":hidden" );
17408
17409		if ( mode === "toggle" ) {
17410			mode = hidden ? "show" : "hide";
17411		}
17412		if ( hidden ? mode === "hide" : mode === "show" ) {
17413			mode = "none";
17414		}
17415		return mode;
17416	},
17417
17418	// Translates a [top,left] array into a baseline value
17419	getBaseline: function( origin, original ) {
17420		var y, x;
17421
17422		switch ( origin[ 0 ] ) {
17423		case "top":
17424			y = 0;
17425			break;
17426		case "middle":
17427			y = 0.5;
17428			break;
17429		case "bottom":
17430			y = 1;
17431			break;
17432		default:
17433			y = origin[ 0 ] / original.height;
17434		}
17435
17436		switch ( origin[ 1 ] ) {
17437		case "left":
17438			x = 0;
17439			break;
17440		case "center":
17441			x = 0.5;
17442			break;
17443		case "right":
17444			x = 1;
17445			break;
17446		default:
17447			x = origin[ 1 ] / original.width;
17448		}
17449
17450		return {
17451			x: x,
17452			y: y
17453		};
17454	},
17455
17456	// Creates a placeholder element so that the original element can be made absolute
17457	createPlaceholder: function( element ) {
17458		var placeholder,
17459			cssPosition = element.css( "position" ),
17460			position = element.position();
17461
17462		// Lock in margins first to account for form elements, which
17463		// will change margin if you explicitly set height
17464		// see: https://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
17465		// Support: Safari
17466		element.css( {
17467			marginTop: element.css( "marginTop" ),
17468			marginBottom: element.css( "marginBottom" ),
17469			marginLeft: element.css( "marginLeft" ),
17470			marginRight: element.css( "marginRight" )
17471		} )
17472		.outerWidth( element.outerWidth() )
17473		.outerHeight( element.outerHeight() );
17474
17475		if ( /^(static|relative)/.test( cssPosition ) ) {
17476			cssPosition = "absolute";
17477
17478			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
17479
17480				// Convert inline to inline block to account for inline elements
17481				// that turn to inline block based on content (like img)
17482				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
17483					"inline-block" :
17484					"block",
17485				visibility: "hidden",
17486
17487				// Margins need to be set to account for margin collapse
17488				marginTop: element.css( "marginTop" ),
17489				marginBottom: element.css( "marginBottom" ),
17490				marginLeft: element.css( "marginLeft" ),
17491				marginRight: element.css( "marginRight" ),
17492				"float": element.css( "float" )
17493			} )
17494			.outerWidth( element.outerWidth() )
17495			.outerHeight( element.outerHeight() )
17496			.addClass( "ui-effects-placeholder" );
17497
17498			element.data( dataSpace + "placeholder", placeholder );
17499		}
17500
17501		element.css( {
17502			position: cssPosition,
17503			left: position.left,
17504			top: position.top
17505		} );
17506
17507		return placeholder;
17508	},
17509
17510	removePlaceholder: function( element ) {
17511		var dataKey = dataSpace + "placeholder",
17512				placeholder = element.data( dataKey );
17513
17514		if ( placeholder ) {
17515			placeholder.remove();
17516			element.removeData( dataKey );
17517		}
17518	},
17519
17520	// Removes a placeholder if it exists and restores
17521	// properties that were modified during placeholder creation
17522	cleanUp: function( element ) {
17523		$.effects.restoreStyle( element );
17524		$.effects.removePlaceholder( element );
17525	},
17526
17527	setTransition: function( element, list, factor, value ) {
17528		value = value || {};
17529		$.each( list, function( i, x ) {
17530			var unit = element.cssUnit( x );
17531			if ( unit[ 0 ] > 0 ) {
17532				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
17533			}
17534		} );
17535		return value;
17536	}
17537} );
17538
17539// Return an effect options object for the given parameters:
17540function _normalizeArguments( effect, options, speed, callback ) {
17541
17542	// Allow passing all options as the first parameter
17543	if ( $.isPlainObject( effect ) ) {
17544		options = effect;
17545		effect = effect.effect;
17546	}
17547
17548	// Convert to an object
17549	effect = { effect: effect };
17550
17551	// Catch (effect, null, ...)
17552	if ( options == null ) {
17553		options = {};
17554	}
17555
17556	// Catch (effect, callback)
17557	if ( typeof options === "function" ) {
17558		callback = options;
17559		speed = null;
17560		options = {};
17561	}
17562
17563	// Catch (effect, speed, ?)
17564	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
17565		callback = speed;
17566		speed = options;
17567		options = {};
17568	}
17569
17570	// Catch (effect, options, callback)
17571	if ( typeof speed === "function" ) {
17572		callback = speed;
17573		speed = null;
17574	}
17575
17576	// Add options to effect
17577	if ( options ) {
17578		$.extend( effect, options );
17579	}
17580
17581	speed = speed || options.duration;
17582	effect.duration = $.fx.off ? 0 :
17583		typeof speed === "number" ? speed :
17584		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
17585		$.fx.speeds._default;
17586
17587	effect.complete = callback || options.complete;
17588
17589	return effect;
17590}
17591
17592function standardAnimationOption( option ) {
17593
17594	// Valid standard speeds (nothing, number, named speed)
17595	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
17596		return true;
17597	}
17598
17599	// Invalid strings - treat as "normal" speed
17600	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
17601		return true;
17602	}
17603
17604	// Complete callback
17605	if ( typeof option === "function" ) {
17606		return true;
17607	}
17608
17609	// Options hash (but not naming an effect)
17610	if ( typeof option === "object" && !option.effect ) {
17611		return true;
17612	}
17613
17614	// Didn't match any standard API
17615	return false;
17616}
17617
17618$.fn.extend( {
17619	effect: function( /* effect, options, speed, callback */ ) {
17620		var args = _normalizeArguments.apply( this, arguments ),
17621			effectMethod = $.effects.effect[ args.effect ],
17622			defaultMode = effectMethod.mode,
17623			queue = args.queue,
17624			queueName = queue || "fx",
17625			complete = args.complete,
17626			mode = args.mode,
17627			modes = [],
17628			prefilter = function( next ) {
17629				var el = $( this ),
17630					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
17631
17632				// Sentinel for duck-punching the :animated pseudo-selector
17633				el.data( dataSpaceAnimated, true );
17634
17635				// Save effect mode for later use,
17636				// we can't just call $.effects.mode again later,
17637				// as the .show() below destroys the initial state
17638				modes.push( normalizedMode );
17639
17640				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.14
17641				if ( defaultMode && ( normalizedMode === "show" ||
17642						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
17643					el.show();
17644				}
17645
17646				if ( !defaultMode || normalizedMode !== "none" ) {
17647					$.effects.saveStyle( el );
17648				}
17649
17650				if ( typeof next === "function" ) {
17651					next();
17652				}
17653			};
17654
17655		if ( $.fx.off || !effectMethod ) {
17656
17657			// Delegate to the original method (e.g., .show()) if possible
17658			if ( mode ) {
17659				return this[ mode ]( args.duration, complete );
17660			} else {
17661				return this.each( function() {
17662					if ( complete ) {
17663						complete.call( this );
17664					}
17665				} );
17666			}
17667		}
17668
17669		function run( next ) {
17670			var elem = $( this );
17671
17672			function cleanup() {
17673				elem.removeData( dataSpaceAnimated );
17674
17675				$.effects.cleanUp( elem );
17676
17677				if ( args.mode === "hide" ) {
17678					elem.hide();
17679				}
17680
17681				done();
17682			}
17683
17684			function done() {
17685				if ( typeof complete === "function" ) {
17686					complete.call( elem[ 0 ] );
17687				}
17688
17689				if ( typeof next === "function" ) {
17690					next();
17691				}
17692			}
17693
17694			// Override mode option on a per element basis,
17695			// as toggle can be either show or hide depending on element state
17696			args.mode = modes.shift();
17697
17698			if ( $.uiBackCompat === true && !defaultMode ) {
17699				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
17700
17701					// Call the core method to track "olddisplay" properly
17702					elem[ mode ]();
17703					done();
17704				} else {
17705					effectMethod.call( elem[ 0 ], args, done );
17706				}
17707			} else {
17708				if ( args.mode === "none" ) {
17709
17710					// Call the core method to track "olddisplay" properly
17711					elem[ mode ]();
17712					done();
17713				} else {
17714					effectMethod.call( elem[ 0 ], args, cleanup );
17715				}
17716			}
17717		}
17718
17719		// Run prefilter on all elements first to ensure that
17720		// any showing or hiding happens before placeholder creation,
17721		// which ensures that any layout changes are correctly captured.
17722		return queue === false ?
17723			this.each( prefilter ).each( run ) :
17724			this.queue( queueName, prefilter ).queue( queueName, run );
17725	},
17726
17727	show: ( function( orig ) {
17728		return function( option ) {
17729			if ( standardAnimationOption( option ) ) {
17730				return orig.apply( this, arguments );
17731			} else {
17732				var args = _normalizeArguments.apply( this, arguments );
17733				args.mode = "show";
17734				return this.effect.call( this, args );
17735			}
17736		};
17737	} )( $.fn.show ),
17738
17739	hide: ( function( orig ) {
17740		return function( option ) {
17741			if ( standardAnimationOption( option ) ) {
17742				return orig.apply( this, arguments );
17743			} else {
17744				var args = _normalizeArguments.apply( this, arguments );
17745				args.mode = "hide";
17746				return this.effect.call( this, args );
17747			}
17748		};
17749	} )( $.fn.hide ),
17750
17751	toggle: ( function( orig ) {
17752		return function( option ) {
17753			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
17754				return orig.apply( this, arguments );
17755			} else {
17756				var args = _normalizeArguments.apply( this, arguments );
17757				args.mode = "toggle";
17758				return this.effect.call( this, args );
17759			}
17760		};
17761	} )( $.fn.toggle ),
17762
17763	cssUnit: function( key ) {
17764		var style = this.css( key ),
17765			val = [];
17766
17767		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
17768			if ( style.indexOf( unit ) > 0 ) {
17769				val = [ parseFloat( style ), unit ];
17770			}
17771		} );
17772		return val;
17773	},
17774
17775	cssClip: function( clipObj ) {
17776		if ( clipObj ) {
17777			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
17778				clipObj.bottom + "px " + clipObj.left + "px)" );
17779		}
17780		return parseClip( this.css( "clip" ), this );
17781	},
17782
17783	transfer: function( options, done ) {
17784		var element = $( this ),
17785			target = $( options.to ),
17786			targetFixed = target.css( "position" ) === "fixed",
17787			body = $( "body" ),
17788			fixTop = targetFixed ? body.scrollTop() : 0,
17789			fixLeft = targetFixed ? body.scrollLeft() : 0,
17790			endPosition = target.offset(),
17791			animation = {
17792				top: endPosition.top - fixTop,
17793				left: endPosition.left - fixLeft,
17794				height: target.innerHeight(),
17795				width: target.innerWidth()
17796			},
17797			startPosition = element.offset(),
17798			transfer = $( "<div class='ui-effects-transfer'></div>" );
17799
17800		transfer
17801			.appendTo( "body" )
17802			.addClass( options.className )
17803			.css( {
17804				top: startPosition.top - fixTop,
17805				left: startPosition.left - fixLeft,
17806				height: element.innerHeight(),
17807				width: element.innerWidth(),
17808				position: targetFixed ? "fixed" : "absolute"
17809			} )
17810			.animate( animation, options.duration, options.easing, function() {
17811				transfer.remove();
17812				if ( typeof done === "function" ) {
17813					done();
17814				}
17815			} );
17816	}
17817} );
17818
17819function parseClip( str, element ) {
17820		var outerWidth = element.outerWidth(),
17821			outerHeight = element.outerHeight(),
17822			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)\)$/,
17823			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
17824
17825		return {
17826			top: parseFloat( values[ 1 ] ) || 0,
17827			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
17828			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
17829			left: parseFloat( values[ 4 ] ) || 0
17830		};
17831}
17832
17833$.fx.step.clip = function( fx ) {
17834	if ( !fx.clipInit ) {
17835		fx.start = $( fx.elem ).cssClip();
17836		if ( typeof fx.end === "string" ) {
17837			fx.end = parseClip( fx.end, fx.elem );
17838		}
17839		fx.clipInit = true;
17840	}
17841
17842	$( fx.elem ).cssClip( {
17843		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
17844		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
17845		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
17846		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
17847	} );
17848};
17849
17850} )();
17851
17852/******************************************************************************/
17853/*********************************** EASING ***********************************/
17854/******************************************************************************/
17855
17856( function() {
17857
17858// Based on easing equations from Robert Penner (http://robertpenner.com/easing)
17859
17860var baseEasings = {};
17861
17862$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
17863	baseEasings[ name ] = function( p ) {
17864		return Math.pow( p, i + 2 );
17865	};
17866} );
17867
17868$.extend( baseEasings, {
17869	Sine: function( p ) {
17870		return 1 - Math.cos( p * Math.PI / 2 );
17871	},
17872	Circ: function( p ) {
17873		return 1 - Math.sqrt( 1 - p * p );
17874	},
17875	Elastic: function( p ) {
17876		return p === 0 || p === 1 ? p :
17877			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
17878	},
17879	Back: function( p ) {
17880		return p * p * ( 3 * p - 2 );
17881	},
17882	Bounce: function( p ) {
17883		var pow2,
17884			bounce = 4;
17885
17886		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
17887		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
17888	}
17889} );
17890
17891$.each( baseEasings, function( name, easeIn ) {
17892	$.easing[ "easeIn" + name ] = easeIn;
17893	$.easing[ "easeOut" + name ] = function( p ) {
17894		return 1 - easeIn( 1 - p );
17895	};
17896	$.easing[ "easeInOut" + name ] = function( p ) {
17897		return p < 0.5 ?
17898			easeIn( p * 2 ) / 2 :
17899			1 - easeIn( p * -2 + 2 ) / 2;
17900	};
17901} );
17902
17903} )();
17904
17905var effect = $.effects;
17906
17907
17908/*!
17909 * jQuery UI Effects Blind 1.14.2
17910 * https://jqueryui.com
17911 *
17912 * Copyright OpenJS Foundation and other contributors
17913 * Released under the MIT license.
17914 * https://jquery.org/license
17915 */
17916
17917//>>label: Blind Effect
17918//>>group: Effects
17919//>>description: Blinds the element.
17920//>>docs: https://api.jqueryui.com/blind-effect/
17921//>>demos: https://jqueryui.com/effect/
17922
17923
17924var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
17925	var map = {
17926			up: [ "bottom", "top" ],
17927			vertical: [ "bottom", "top" ],
17928			down: [ "top", "bottom" ],
17929			left: [ "right", "left" ],
17930			horizontal: [ "right", "left" ],
17931			right: [ "left", "right" ]
17932		},
17933		element = $( this ),
17934		direction = options.direction || "up",
17935		start = element.cssClip(),
17936		animate = { clip: $.extend( {}, start ) },
17937		placeholder = $.effects.createPlaceholder( element );
17938
17939	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
17940
17941	if ( options.mode === "show" ) {
17942		element.cssClip( animate.clip );
17943		if ( placeholder ) {
17944			placeholder.css( $.effects.clipToBox( animate ) );
17945		}
17946
17947		animate.clip = start;
17948	}
17949
17950	if ( placeholder ) {
17951		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
17952	}
17953
17954	element.animate( animate, {
17955		queue: false,
17956		duration: options.duration,
17957		easing: options.easing,
17958		complete: done
17959	} );
17960} );
17961
17962
17963/*!
17964 * jQuery UI Effects Bounce 1.14.2
17965 * https://jqueryui.com
17966 *
17967 * Copyright OpenJS Foundation and other contributors
17968 * Released under the MIT license.
17969 * https://jquery.org/license
17970 */
17971
17972//>>label: Bounce Effect
17973//>>group: Effects
17974//>>description: Bounces an element horizontally or vertically n times.
17975//>>docs: https://api.jqueryui.com/bounce-effect/
17976//>>demos: https://jqueryui.com/effect/
17977
17978
17979var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
17980	var upAnim, downAnim, refValue,
17981		element = $( this ),
17982
17983		// Defaults:
17984		mode = options.mode,
17985		hide = mode === "hide",
17986		show = mode === "show",
17987		direction = options.direction || "up",
17988		distance = options.distance,
17989		times = options.times || 5,
17990
17991		// Number of internal animations
17992		anims = times * 2 + ( show || hide ? 1 : 0 ),
17993		speed = options.duration / anims,
17994		easing = options.easing,
17995
17996		// Utility:
17997		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17998		motion = ( direction === "up" || direction === "left" ),
17999		i = 0,
18000
18001		queuelen = element.queue().length;
18002
18003	$.effects.createPlaceholder( element );
18004
18005	refValue = element.css( ref );
18006
18007	// Default distance for the BIGGEST bounce is the outer Distance / 3
18008	if ( !distance ) {
18009		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
18010	}
18011
18012	if ( show ) {
18013		downAnim = { opacity: 1 };
18014		downAnim[ ref ] = refValue;
18015
18016		// If we are showing, force opacity 0 and set the initial position
18017		// then do the "first" animation
18018		element
18019			.css( "opacity", 0 )
18020			.css( ref, motion ? -distance * 2 : distance * 2 )
18021			.animate( downAnim, speed, easing );
18022	}
18023
18024	// Start at the smallest distance if we are hiding
18025	if ( hide ) {
18026		distance = distance / Math.pow( 2, times - 1 );
18027	}
18028
18029	downAnim = {};
18030	downAnim[ ref ] = refValue;
18031
18032	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
18033	for ( ; i < times; i++ ) {
18034		upAnim = {};
18035		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
18036
18037		element
18038			.animate( upAnim, speed, easing )
18039			.animate( downAnim, speed, easing );
18040
18041		distance = hide ? distance * 2 : distance / 2;
18042	}
18043
18044	// Last Bounce when Hiding
18045	if ( hide ) {
18046		upAnim = { opacity: 0 };
18047		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
18048
18049		element.animate( upAnim, speed, easing );
18050	}
18051
18052	element.queue( done );
18053
18054	$.effects.unshift( element, queuelen, anims + 1 );
18055} );
18056
18057
18058/*!
18059 * jQuery UI Effects Clip 1.14.2
18060 * https://jqueryui.com
18061 *
18062 * Copyright OpenJS Foundation and other contributors
18063 * Released under the MIT license.
18064 * https://jquery.org/license
18065 */
18066
18067//>>label: Clip Effect
18068//>>group: Effects
18069//>>description: Clips the element on and off like an old TV.
18070//>>docs: https://api.jqueryui.com/clip-effect/
18071//>>demos: https://jqueryui.com/effect/
18072
18073
18074var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
18075	var start,
18076		animate = {},
18077		element = $( this ),
18078		direction = options.direction || "vertical",
18079		both = direction === "both",
18080		horizontal = both || direction === "horizontal",
18081		vertical = both || direction === "vertical";
18082
18083	start = element.cssClip();
18084	animate.clip = {
18085		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
18086		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
18087		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
18088		left: horizontal ? ( start.right - start.left ) / 2 : start.left
18089	};
18090
18091	$.effects.createPlaceholder( element );
18092
18093	if ( options.mode === "show" ) {
18094		element.cssClip( animate.clip );
18095		animate.clip = start;
18096	}
18097
18098	element.animate( animate, {
18099		queue: false,
18100		duration: options.duration,
18101		easing: options.easing,
18102		complete: done
18103	} );
18104
18105} );
18106
18107
18108/*!
18109 * jQuery UI Effects Drop 1.14.2
18110 * https://jqueryui.com
18111 *
18112 * Copyright OpenJS Foundation and other contributors
18113 * Released under the MIT license.
18114 * https://jquery.org/license
18115 */
18116
18117//>>label: Drop Effect
18118//>>group: Effects
18119//>>description: Moves an element in one direction and hides it at the same time.
18120//>>docs: https://api.jqueryui.com/drop-effect/
18121//>>demos: https://jqueryui.com/effect/
18122
18123
18124var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
18125
18126	var distance,
18127		element = $( this ),
18128		mode = options.mode,
18129		show = mode === "show",
18130		direction = options.direction || "left",
18131		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
18132		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
18133		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
18134		animation = {
18135			opacity: 0
18136		};
18137
18138	$.effects.createPlaceholder( element );
18139
18140	distance = options.distance ||
18141		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
18142
18143	animation[ ref ] = motion + distance;
18144
18145	if ( show ) {
18146		element.css( animation );
18147
18148		animation[ ref ] = oppositeMotion + distance;
18149		animation.opacity = 1;
18150	}
18151
18152	// Animate
18153	element.animate( animation, {
18154		queue: false,
18155		duration: options.duration,
18156		easing: options.easing,
18157		complete: done
18158	} );
18159} );
18160
18161
18162/*!
18163 * jQuery UI Effects Explode 1.14.2
18164 * https://jqueryui.com
18165 *
18166 * Copyright OpenJS Foundation and other contributors
18167 * Released under the MIT license.
18168 * https://jquery.org/license
18169 */
18170
18171//>>label: Explode Effect
18172//>>group: Effects
18173//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
18174//>>docs: https://api.jqueryui.com/explode-effect/
18175//>>demos: https://jqueryui.com/effect/
18176
18177
18178var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
18179
18180	var i, j, left, top, mx, my,
18181		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
18182		cells = rows,
18183		element = $( this ),
18184		mode = options.mode,
18185		show = mode === "show",
18186
18187		// Show and then visibility:hidden the element before calculating offset
18188		offset = element.show().css( "visibility", "hidden" ).offset(),
18189
18190		// Width and height of a piece
18191		width = Math.ceil( element.outerWidth() / cells ),
18192		height = Math.ceil( element.outerHeight() / rows ),
18193		pieces = [];
18194
18195	// Children animate complete:
18196	function childComplete() {
18197		pieces.push( this );
18198		if ( pieces.length === rows * cells ) {
18199			animComplete();
18200		}
18201	}
18202
18203	// Clone the element for each row and cell.
18204	for ( i = 0; i < rows; i++ ) { // ===>
18205		top = offset.top + i * height;
18206		my = i - ( rows - 1 ) / 2;
18207
18208		for ( j = 0; j < cells; j++ ) { // |||
18209			left = offset.left + j * width;
18210			mx = j - ( cells - 1 ) / 2;
18211
18212			// Create a clone of the now hidden main element that will be absolute positioned
18213			// within a wrapper div off the -left and -top equal to size of our pieces
18214			element
18215				.clone()
18216				.appendTo( "body" )
18217				.wrap( "<div></div>" )
18218				.css( {
18219					position: "absolute",
18220					visibility: "visible",
18221					left: -j * width,
18222					top: -i * height
18223				} )
18224
18225				// Select the wrapper - make it overflow: hidden and absolute positioned based on
18226				// where the original was located +left and +top equal to the size of pieces
18227				.parent()
18228					.addClass( "ui-effects-explode" )
18229					.css( {
18230						position: "absolute",
18231						overflow: "hidden",
18232						width: width,
18233						height: height,
18234						left: left + ( show ? mx * width : 0 ),
18235						top: top + ( show ? my * height : 0 ),
18236						opacity: show ? 0 : 1
18237					} )
18238					.animate( {
18239						left: left + ( show ? 0 : mx * width ),
18240						top: top + ( show ? 0 : my * height ),
18241						opacity: show ? 1 : 0
18242					}, options.duration || 500, options.easing, childComplete );
18243		}
18244	}
18245
18246	function animComplete() {
18247		element.css( {
18248			visibility: "visible"
18249		} );
18250		$( pieces ).remove();
18251		done();
18252	}
18253} );
18254
18255
18256/*!
18257 * jQuery UI Effects Fade 1.14.2
18258 * https://jqueryui.com
18259 *
18260 * Copyright OpenJS Foundation and other contributors
18261 * Released under the MIT license.
18262 * https://jquery.org/license
18263 */
18264
18265//>>label: Fade Effect
18266//>>group: Effects
18267//>>description: Fades the element.
18268//>>docs: https://api.jqueryui.com/fade-effect/
18269//>>demos: https://jqueryui.com/effect/
18270
18271
18272var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
18273	var show = options.mode === "show";
18274
18275	$( this )
18276		.css( "opacity", show ? 0 : 1 )
18277		.animate( {
18278			opacity: show ? 1 : 0
18279		}, {
18280			queue: false,
18281			duration: options.duration,
18282			easing: options.easing,
18283			complete: done
18284		} );
18285} );
18286
18287
18288/*!
18289 * jQuery UI Effects Fold 1.14.2
18290 * https://jqueryui.com
18291 *
18292 * Copyright OpenJS Foundation and other contributors
18293 * Released under the MIT license.
18294 * https://jquery.org/license
18295 */
18296
18297//>>label: Fold Effect
18298//>>group: Effects
18299//>>description: Folds an element first horizontally and then vertically.
18300//>>docs: https://api.jqueryui.com/fold-effect/
18301//>>demos: https://jqueryui.com/effect/
18302
18303
18304var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
18305
18306	// Create element
18307	var element = $( this ),
18308		mode = options.mode,
18309		show = mode === "show",
18310		hide = mode === "hide",
18311		size = options.size || 15,
18312		percent = /([0-9]+)%/.exec( size ),
18313		horizFirst = !!options.horizFirst,
18314		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
18315		duration = options.duration / 2,
18316
18317		placeholder = $.effects.createPlaceholder( element ),
18318
18319		start = element.cssClip(),
18320		animation1 = { clip: $.extend( {}, start ) },
18321		animation2 = { clip: $.extend( {}, start ) },
18322
18323		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
18324
18325		queuelen = element.queue().length;
18326
18327	if ( percent ) {
18328		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
18329	}
18330	animation1.clip[ ref[ 0 ] ] = size;
18331	animation2.clip[ ref[ 0 ] ] = size;
18332	animation2.clip[ ref[ 1 ] ] = 0;
18333
18334	if ( show ) {
18335		element.cssClip( animation2.clip );
18336		if ( placeholder ) {
18337			placeholder.css( $.effects.clipToBox( animation2 ) );
18338		}
18339
18340		animation2.clip = start;
18341	}
18342
18343	// Animate
18344	element
18345		.queue( function( next ) {
18346			if ( placeholder ) {
18347				placeholder
18348					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
18349					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
18350			}
18351
18352			next();
18353		} )
18354		.animate( animation1, duration, options.easing )
18355		.animate( animation2, duration, options.easing )
18356		.queue( done );
18357
18358	$.effects.unshift( element, queuelen, 4 );
18359} );
18360
18361
18362/*!
18363 * jQuery UI Effects Highlight 1.14.2
18364 * https://jqueryui.com
18365 *
18366 * Copyright OpenJS Foundation and other contributors
18367 * Released under the MIT license.
18368 * https://jquery.org/license
18369 */
18370
18371//>>label: Highlight Effect
18372//>>group: Effects
18373//>>description: Highlights the background of an element in a defined color for a custom duration.
18374//>>docs: https://api.jqueryui.com/highlight-effect/
18375//>>demos: https://jqueryui.com/effect/
18376
18377
18378var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
18379	var element = $( this ),
18380		animation = {
18381			backgroundColor: element.css( "backgroundColor" )
18382		};
18383
18384	if ( options.mode === "hide" ) {
18385		animation.opacity = 0;
18386	}
18387
18388	$.effects.saveStyle( element );
18389
18390	element
18391		.css( {
18392			backgroundImage: "none",
18393			backgroundColor: options.color || "#ffff99"
18394		} )
18395		.animate( animation, {
18396			queue: false,
18397			duration: options.duration,
18398			easing: options.easing,
18399			complete: done
18400		} );
18401} );
18402
18403
18404/*!
18405 * jQuery UI Effects Size 1.14.2
18406 * https://jqueryui.com
18407 *
18408 * Copyright OpenJS Foundation and other contributors
18409 * Released under the MIT license.
18410 * https://jquery.org/license
18411 */
18412
18413//>>label: Size Effect
18414//>>group: Effects
18415//>>description: Resize an element to a specified width and height.
18416//>>docs: https://api.jqueryui.com/size-effect/
18417//>>demos: https://jqueryui.com/effect/
18418
18419
18420var effectsEffectSize = $.effects.define( "size", function( options, done ) {
18421
18422	// Create element
18423	var baseline, factor, temp,
18424		element = $( this ),
18425
18426		// Copy for children
18427		cProps = [ "fontSize" ],
18428		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
18429		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
18430
18431		// Set options
18432		mode = options.mode,
18433		restore = mode !== "effect",
18434		scale = options.scale || "both",
18435		origin = options.origin || [ "middle", "center" ],
18436		position = element.css( "position" ),
18437		pos = element.position(),
18438		original = $.effects.scaledDimensions( element ),
18439		from = options.from || original,
18440		to = options.to || $.effects.scaledDimensions( element, 0 );
18441
18442	$.effects.createPlaceholder( element );
18443
18444	if ( mode === "show" ) {
18445		temp = from;
18446		from = to;
18447		to = temp;
18448	}
18449
18450	// Set scaling factor
18451	factor = {
18452		from: {
18453			y: from.height / original.height,
18454			x: from.width / original.width
18455		},
18456		to: {
18457			y: to.height / original.height,
18458			x: to.width / original.width
18459		}
18460	};
18461
18462	// Scale the css box
18463	if ( scale === "box" || scale === "both" ) {
18464
18465		// Vertical props scaling
18466		if ( factor.from.y !== factor.to.y ) {
18467			from = $.effects.setTransition( element, vProps, factor.from.y, from );
18468			to = $.effects.setTransition( element, vProps, factor.to.y, to );
18469		}
18470
18471		// Horizontal props scaling
18472		if ( factor.from.x !== factor.to.x ) {
18473			from = $.effects.setTransition( element, hProps, factor.from.x, from );
18474			to = $.effects.setTransition( element, hProps, factor.to.x, to );
18475		}
18476	}
18477
18478	// Scale the content
18479	if ( scale === "content" || scale === "both" ) {
18480
18481		// Vertical props scaling
18482		if ( factor.from.y !== factor.to.y ) {
18483			from = $.effects.setTransition( element, cProps, factor.from.y, from );
18484			to = $.effects.setTransition( element, cProps, factor.to.y, to );
18485		}
18486	}
18487
18488	// Adjust the position properties based on the provided origin points
18489	if ( origin ) {
18490		baseline = $.effects.getBaseline( origin, original );
18491		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
18492		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
18493		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
18494		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
18495	}
18496	delete from.outerHeight;
18497	delete from.outerWidth;
18498	element.css( from );
18499
18500	// Animate the children if desired
18501	if ( scale === "content" || scale === "both" ) {
18502
18503		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
18504		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
18505
18506		// Only animate children with width attributes specified
18507		// TODO: is this right? should we include anything with css width specified as well
18508		element.find( "*[width]" ).each( function() {
18509			var child = $( this ),
18510				childOriginal = $.effects.scaledDimensions( child ),
18511				childFrom = {
18512					height: childOriginal.height * factor.from.y,
18513					width: childOriginal.width * factor.from.x,
18514					outerHeight: childOriginal.outerHeight * factor.from.y,
18515					outerWidth: childOriginal.outerWidth * factor.from.x
18516				},
18517				childTo = {
18518					height: childOriginal.height * factor.to.y,
18519					width: childOriginal.width * factor.to.x,
18520					outerHeight: childOriginal.height * factor.to.y,
18521					outerWidth: childOriginal.width * factor.to.x
18522				};
18523
18524			// Vertical props scaling
18525			if ( factor.from.y !== factor.to.y ) {
18526				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
18527				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
18528			}
18529
18530			// Horizontal props scaling
18531			if ( factor.from.x !== factor.to.x ) {
18532				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
18533				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
18534			}
18535
18536			if ( restore ) {
18537				$.effects.saveStyle( child );
18538			}
18539
18540			// Animate children
18541			child.css( childFrom );
18542			child.animate( childTo, options.duration, options.easing, function() {
18543
18544				// Restore children
18545				if ( restore ) {
18546					$.effects.restoreStyle( child );
18547				}
18548			} );
18549		} );
18550	}
18551
18552	// Animate
18553	element.animate( to, {
18554		queue: false,
18555		duration: options.duration,
18556		easing: options.easing,
18557		complete: function() {
18558
18559			var offset = element.offset();
18560
18561			if ( to.opacity === 0 ) {
18562				element.css( "opacity", from.opacity );
18563			}
18564
18565			if ( !restore ) {
18566				element
18567					.css( "position", position === "static" ? "relative" : position )
18568					.offset( offset );
18569
18570				// Need to save style here so that automatic style restoration
18571				// doesn't restore to the original styles from before the animation.
18572				$.effects.saveStyle( element );
18573			}
18574
18575			done();
18576		}
18577	} );
18578
18579} );
18580
18581
18582/*!
18583 * jQuery UI Effects Scale 1.14.2
18584 * https://jqueryui.com
18585 *
18586 * Copyright OpenJS Foundation and other contributors
18587 * Released under the MIT license.
18588 * https://jquery.org/license
18589 */
18590
18591//>>label: Scale Effect
18592//>>group: Effects
18593//>>description: Grows or shrinks an element and its content.
18594//>>docs: https://api.jqueryui.com/scale-effect/
18595//>>demos: https://jqueryui.com/effect/
18596
18597
18598var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
18599
18600	// Create element
18601	var el = $( this ),
18602		mode = options.mode,
18603		percent = parseInt( options.percent, 10 ) ||
18604			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
18605
18606		newOptions = $.extend( true, {
18607			from: $.effects.scaledDimensions( el ),
18608			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
18609			origin: options.origin || [ "middle", "center" ]
18610		}, options );
18611
18612	// Fade option to support puff
18613	if ( options.fade ) {
18614		newOptions.from.opacity = 1;
18615		newOptions.to.opacity = 0;
18616	}
18617
18618	$.effects.effect.size.call( this, newOptions, done );
18619} );
18620
18621
18622/*!
18623 * jQuery UI Effects Puff 1.14.2
18624 * https://jqueryui.com
18625 *
18626 * Copyright OpenJS Foundation and other contributors
18627 * Released under the MIT license.
18628 * https://jquery.org/license
18629 */
18630
18631//>>label: Puff Effect
18632//>>group: Effects
18633//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
18634//>>docs: https://api.jqueryui.com/puff-effect/
18635//>>demos: https://jqueryui.com/effect/
18636
18637
18638var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
18639	var newOptions = $.extend( true, {}, options, {
18640		fade: true,
18641		percent: parseInt( options.percent, 10 ) || 150
18642	} );
18643
18644	$.effects.effect.scale.call( this, newOptions, done );
18645} );
18646
18647
18648/*!
18649 * jQuery UI Effects Pulsate 1.14.2
18650 * https://jqueryui.com
18651 *
18652 * Copyright OpenJS Foundation and other contributors
18653 * Released under the MIT license.
18654 * https://jquery.org/license
18655 */
18656
18657//>>label: Pulsate Effect
18658//>>group: Effects
18659//>>description: Pulsates an element n times by changing the opacity to zero and back.
18660//>>docs: https://api.jqueryui.com/pulsate-effect/
18661//>>demos: https://jqueryui.com/effect/
18662
18663
18664var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
18665	var element = $( this ),
18666		mode = options.mode,
18667		show = mode === "show",
18668		hide = mode === "hide",
18669		showhide = show || hide,
18670
18671		// Showing or hiding leaves off the "last" animation
18672		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
18673		duration = options.duration / anims,
18674		animateTo = 0,
18675		i = 1,
18676		queuelen = element.queue().length;
18677
18678	if ( show || !element.is( ":visible" ) ) {
18679		element.css( "opacity", 0 ).show();
18680		animateTo = 1;
18681	}
18682
18683	// Anims - 1 opacity "toggles"
18684	for ( ; i < anims; i++ ) {
18685		element.animate( { opacity: animateTo }, duration, options.easing );
18686		animateTo = 1 - animateTo;
18687	}
18688
18689	element.animate( { opacity: animateTo }, duration, options.easing );
18690
18691	element.queue( done );
18692
18693	$.effects.unshift( element, queuelen, anims + 1 );
18694} );
18695
18696
18697/*!
18698 * jQuery UI Effects Shake 1.14.2
18699 * https://jqueryui.com
18700 *
18701 * Copyright OpenJS Foundation and other contributors
18702 * Released under the MIT license.
18703 * https://jquery.org/license
18704 */
18705
18706//>>label: Shake Effect
18707//>>group: Effects
18708//>>description: Shakes an element horizontally or vertically n times.
18709//>>docs: https://api.jqueryui.com/shake-effect/
18710//>>demos: https://jqueryui.com/effect/
18711
18712
18713var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
18714
18715	var i = 1,
18716		element = $( this ),
18717		direction = options.direction || "left",
18718		distance = options.distance || 20,
18719		times = options.times || 3,
18720		anims = times * 2 + 1,
18721		speed = Math.round( options.duration / anims ),
18722		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
18723		positiveMotion = ( direction === "up" || direction === "left" ),
18724		animation = {},
18725		animation1 = {},
18726		animation2 = {},
18727
18728		queuelen = element.queue().length;
18729
18730	$.effects.createPlaceholder( element );
18731
18732	// Animation
18733	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
18734	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
18735	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
18736
18737	// Animate
18738	element.animate( animation, speed, options.easing );
18739
18740	// Shakes
18741	for ( ; i < times; i++ ) {
18742		element
18743			.animate( animation1, speed, options.easing )
18744			.animate( animation2, speed, options.easing );
18745	}
18746
18747	element
18748		.animate( animation1, speed, options.easing )
18749		.animate( animation, speed / 2, options.easing )
18750		.queue( done );
18751
18752	$.effects.unshift( element, queuelen, anims + 1 );
18753} );
18754
18755
18756/*!
18757 * jQuery UI Effects Slide 1.14.2
18758 * https://jqueryui.com
18759 *
18760 * Copyright OpenJS Foundation and other contributors
18761 * Released under the MIT license.
18762 * https://jquery.org/license
18763 */
18764
18765//>>label: Slide Effect
18766//>>group: Effects
18767//>>description: Slides an element in and out of the viewport.
18768//>>docs: https://api.jqueryui.com/slide-effect/
18769//>>demos: https://jqueryui.com/effect/
18770
18771
18772var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
18773	var startClip, startRef,
18774		element = $( this ),
18775		map = {
18776			up: [ "bottom", "top" ],
18777			down: [ "top", "bottom" ],
18778			left: [ "right", "left" ],
18779			right: [ "left", "right" ]
18780		},
18781		mode = options.mode,
18782		direction = options.direction || "left",
18783		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
18784		positiveMotion = ( direction === "up" || direction === "left" ),
18785		distance = options.distance ||
18786			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
18787		animation = {};
18788
18789	$.effects.createPlaceholder( element );
18790
18791	startClip = element.cssClip();
18792	startRef = element.position()[ ref ];
18793
18794	// Define hide animation
18795	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
18796	animation.clip = element.cssClip();
18797	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
18798
18799	// Reverse the animation if we're showing
18800	if ( mode === "show" ) {
18801		element.cssClip( animation.clip );
18802		element.css( ref, animation[ ref ] );
18803		animation.clip = startClip;
18804		animation[ ref ] = startRef;
18805	}
18806
18807	// Actually animate
18808	element.animate( animation, {
18809		queue: false,
18810		duration: options.duration,
18811		easing: options.easing,
18812		complete: done
18813	} );
18814} );
18815
18816
18817/*!
18818 * jQuery UI Effects Transfer 1.14.2
18819 * https://jqueryui.com
18820 *
18821 * Copyright OpenJS Foundation and other contributors
18822 * Released under the MIT license.
18823 * https://jquery.org/license
18824 */
18825
18826//>>label: Transfer Effect
18827//>>group: Effects
18828//>>description: Displays a transfer effect from one element to another.
18829//>>docs: https://api.jqueryui.com/transfer-effect/
18830//>>demos: https://jqueryui.com/effect/
18831
18832
18833var effect;
18834if ( $.uiBackCompat === true ) {
18835	effect = $.effects.define( "transfer", function( options, done ) {
18836		$( this ).transfer( options, done );
18837	} );
18838}
18839var effectsEffectTransfer = effect;
18840
18841
18842
18843
18844} );

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.